diff --git a/dnsmasq-2.66-Fix-crash-on-SERVFAIL-when-using-conntrack.patch b/dnsmasq-2.66-Fix-crash-on-SERVFAIL-when-using-conntrack.patch new file mode 100644 index 0000000..d3f0341 --- /dev/null +++ b/dnsmasq-2.66-Fix-crash-on-SERVFAIL-when-using-conntrack.patch @@ -0,0 +1,50 @@ +From 797a7afba477390bc016c647cfb792c85ee6102d Mon Sep 17 00:00:00 2001 +From: Giacomo Tazzari +Date: Mon, 22 Apr 2013 13:16:37 +0100 +Subject: [PATCH] Fix crash on SERVFAIL when --conntrack in use. + +--- + CHANGELOG | 5 ++++++ + src/forward.c | 6 +++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 93aaf18..6cb1b51 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,8 @@ ++ Fix crash if upstream server returns SERVFAIL when ++ --conntrack in use. Thanks to Giacomo Tazzari for finding ++ this and supplying the patch. ++ ++ + version 2.66 + Add the ability to act as an authoritative DNS + server. Dnsmasq can now answer queries from the wider 'net +diff --git a/src/forward.c b/src/forward.c +index 77d6849..78495ca 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -328,8 +328,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + struct server *firstsentto = start; + int forwarded = 0; + +- if (udpaddr && option_bool(OPT_ADD_MAC)) +- plen = add_mac(header, plen, ((char *) header) + PACKETSZ, udpaddr); ++ if (option_bool(OPT_ADD_MAC)) ++ plen = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source); + + while (1) + { +@@ -372,7 +372,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + if (option_bool(OPT_CONNTRACK)) + { + unsigned int mark; +- if (get_incoming_mark(udpaddr, dst_addr, 0, &mark)) ++ if (get_incoming_mark(&forward->source, &forward->dest, 0, &mark)) + setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int)); + } + #endif +-- +1.8.1.4 + diff --git a/dnsmasq-2.66-Fix-regression-in-dhcp_lease_time-utility.patch b/dnsmasq-2.66-Fix-regression-in-dhcp_lease_time-utility.patch new file mode 100644 index 0000000..d523603 --- /dev/null +++ b/dnsmasq-2.66-Fix-regression-in-dhcp_lease_time-utility.patch @@ -0,0 +1,103 @@ +From aa63a21ce0b20dfe988e0bcdf14b8b930de20311 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 22 Apr 2013 15:01:52 +0100 +Subject: [PATCH] Fix regression in dhcp_lease_time utility. + +--- + CHANGELOG | 9 +++++++++ + contrib/wrt/dhcp_lease_time.c | 9 ++++++++- + src/rfc2131.c | 17 ++++++++++++++++- + 3 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 6cb1b51..268b64d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,15 @@ version 2.67 + Fix crash if upstream server returns SERVFAIL when + --conntrack in use. Thanks to Giacomo Tazzari for finding + this and supplying the patch. ++ ++ Repair regression in 2.64. That release stopped sending ++ lease-time information in the reply to DHCPINFORM ++ requests, on the correct grounds that it was a standards ++ violation. However, this broke the dnsmasq-specific ++ dhcp_lease_time utility. Now, DHCPINFORM returns ++ lease-time only if it's specifically requested ++ (maintaining standards) and the dhcp_lease_time utility ++ has been taught to ask for it (restoring functionality). + + + version 2.66 +diff --git a/contrib/wrt/dhcp_lease_time.c b/contrib/wrt/dhcp_lease_time.c +index 2866bb5..b438ef7 100644 +--- a/contrib/wrt/dhcp_lease_time.c ++++ b/contrib/wrt/dhcp_lease_time.c +@@ -20,7 +20,7 @@ + nothing is sent to stdout a message is sent to stderr and a + non-zero error code is returned. + +- Requires dnsmasq 2.40 or later. ++ This version requires dnsmasq 2.66 or later. + */ + + #include +@@ -46,6 +46,7 @@ + #define OPTION_LEASE_TIME 51 + #define OPTION_OVERLOAD 52 + #define OPTION_MESSAGE_TYPE 53 ++#define OPTION_REQUESTED_OPTIONS 55 + #define OPTION_END 255 + #define DHCPINFORM 8 + #define DHCP_SERVER_PORT 67 +@@ -167,6 +168,12 @@ int main(int argc, char **argv) + *(p++) = 1; + *(p++) = DHCPINFORM; + ++ /* Explicity request the lease time, it won't be sent otherwise: ++ this is a dnsmasq extension, not standard. */ ++ *(p++) = OPTION_REQUESTED_OPTIONS; ++ *(p++) = 1; ++ *(p++) = OPTION_LEASE_TIME; ++ + *(p++) = OPTION_END; + + dest.sin_family = AF_INET; +diff --git a/src/rfc2131.c b/src/rfc2131.c +index 92974c0..013a446 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -39,6 +39,7 @@ static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt + static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize); + static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end); + static void clear_packet(struct dhcp_packet *mess, unsigned char *end); ++static int in_list(unsigned char *list, int opt); + static void do_options(struct dhcp_context *context, + struct dhcp_packet *mess, + unsigned char *real_end, +@@ -1410,7 +1411,21 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + clear_packet(mess, end); + option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK); + option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); +- ++ ++ /* RFC 2131 says that DHCPINFORM shouldn't include lease-time parameters, but ++ we supply a utility which makes DHCPINFORM requests to get this information. ++ Only include lease time if OPTION_LEASE_TIME is in the parameter request list, ++ which won't be true for ordinary clients, but will be true for the ++ dhcp_lease_time utility. */ ++ if (lease && in_list(req_options, OPTION_LEASE_TIME)) ++ { ++ if (lease->expires == 0) ++ time = 0xffffffff; ++ else ++ time = (unsigned int)difftime(lease->expires, now); ++ option_put(mess, end, OPTION_LEASE_TIME, 4, time); ++ } ++ + do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr), + netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now); + +-- +1.8.1.4 + diff --git a/dnsmasq-2.66-Manpage-typos.patch b/dnsmasq-2.66-Manpage-typos.patch new file mode 100644 index 0000000..de7c44a --- /dev/null +++ b/dnsmasq-2.66-Manpage-typos.patch @@ -0,0 +1,97 @@ +From a66d36ea1112c861ad2f11ed40cc26973873e5be Mon Sep 17 00:00:00 2001 +From: Tomas Hozza +Date: Mon, 22 Apr 2013 15:08:07 +0100 +Subject: [PATCH] Manpage typos. + +--- + man/dnsmasq.8 | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 +index 96d8938..fc12b1c 100644 +--- a/man/dnsmasq.8 ++++ b/man/dnsmasq.8 +@@ -559,7 +559,7 @@ needed for a client to do validation itself. + .B --auth-zone=[,[,.....]] + Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain + will be served, except that A and AAAA records must be in one of the +-specified subnets, or in a subnet corresponding to a contructed DHCP ++specified subnets, or in a subnet corresponding to a constructed DHCP + range. The subnet(s) are also used to define in-addr.arpa and + ipv6.arpa domains which are served for reverse-DNS queries. For IPv4 + subnets, the prefix length is limited to the values 8, 16 or 24. +@@ -763,7 +763,7 @@ This is + useful when there is another DHCP server on the network which should + be used by some machines. + +-The set: contruct sets the tag ++The set: construct sets the tag + whenever this dhcp-host directive is in use. This can be used to + selectively send DHCP options just for this host. More than one tag + can be set in a dhcp-host directive (but not in other places where +@@ -978,7 +978,7 @@ agent ID and one provided by a relay agent, the tag is set. + (IPv4 only) A normal DHCP relay agent is only used to forward the initial parts of + a DHCP interaction to the DHCP server. Once a client is configured, it + communicates directly with the server. This is undesirable if the +-relay agent is addding extra information to the DHCP packets, such as ++relay agent is adding extra information to the DHCP packets, such as + that used by + .B dhcp-circuitid + and +@@ -995,7 +995,7 @@ relays at those addresses are affected. + Without a value, set the tag if the client sends a DHCP + option of the given number or name. When a value is given, set the tag only if + the option is sent and matches the value. The value may be of the form +-"01:ff:*:02" in which case the value must match (apart from widcards) ++"01:ff:*:02" in which case the value must match (apart from wildcards) + but the option sent may have unmatched data past the end of the + value. The value may also be of the same form as in + .B dhcp-option +@@ -1008,7 +1008,7 @@ will set the tag "efi-ia32" if the the number 6 appears in the list of + architectures sent by the client in option 93. (See RFC 4578 for + details.) If the value is a string, substring matching is used. + +-The special form with vi-encap: matches against ++The special form with vi-encap: matches against + vendor-identifying vendor classes for the specified enterprise. Please + see RFC 3925 for more details of these rare and interesting beasts. + .TP +@@ -1036,7 +1036,7 @@ dhcp-host configuration in dnsmasq and the contents of /etc/hosts and + .TP + .B --dhcp-generate-names=tag:[,tag:] + (IPv4 only) Generate a name for DHCP clients which do not otherwise have one, +-using the MAC address expressed in hex, seperated by dashes. Note that ++using the MAC address expressed in hex, separated by dashes. Note that + if a host provides a name, it will be used by preference to this, + unless + .B --dhcp-ignore-names +@@ -1113,7 +1113,7 @@ timeout has elapsed with no keyboard input, the first available menu + option will be automatically executed. If the timeout is zero then the first available menu + item will be executed immediately. If + .B pxe-prompt +-is ommitted the system will wait for user input if there are multiple ++is omitted the system will wait for user input if there are multiple + items in the menu, but boot immediately if + there is only one. See + .B pxe-service +@@ -1412,7 +1412,7 @@ In the default mode, dnsmasq inserts the unqualified names of + DHCP clients into the DNS. For this reason, the names must be unique, + even if two clients which have the same name are in different + domains. If a second DHCP client appears which has the same name as an +-existing client, the name is transfered to the new client. If ++existing client, the name is transferred to the new client. If + .B --dhcp-fqdn + is set, this behaviour changes: the unqualified name is no longer + put in the DNS, only the qualified name. Two DHCP clients with the +@@ -1666,7 +1666,7 @@ used to allocate the address, one from any matching + The tag "bootp" is set for BOOTP requests, and a tag whose name is the + name of the interface on which the request arrived is also set. + +-Any configuration lines which includes one or more tag: contructs ++Any configuration lines which include one or more tag: constructs + will only be valid if all that tags are matched in the set derived + above. Typically this is dhcp-option. + .B dhcp-option +-- +1.8.1.4 + diff --git a/dnsmasq-2.66-Note-that-dhcp_lease_time-and-dhcp_release-work-for-IPv4.patch b/dnsmasq-2.66-Note-that-dhcp_lease_time-and-dhcp_release-work-for-IPv4.patch new file mode 100644 index 0000000..9da0a80 --- /dev/null +++ b/dnsmasq-2.66-Note-that-dhcp_lease_time-and-dhcp_release-work-for-IPv4.patch @@ -0,0 +1,45 @@ +From 1c10b9de118c951a5aedc130e55101987dcc3feb Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 23 Apr 2013 10:58:35 +0100 +Subject: [PATCH] Note that dhcp_lease_time and dhcp_release only work for + IPv4. + +--- + contrib/wrt/dhcp_lease_time.1 | 6 ++++-- + contrib/wrt/dhcp_release.1 | 2 ++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/contrib/wrt/dhcp_lease_time.1 b/contrib/wrt/dhcp_lease_time.1 +index 2720b71..2fa78d3 100644 +--- a/contrib/wrt/dhcp_lease_time.1 ++++ b/contrib/wrt/dhcp_lease_time.1 +@@ -12,9 +12,11 @@ If an error occurs or no lease exists for the given address, + nothing is sent to stdout a message is sent to stderr and a + non-zero error code is returned. + +-Requires dnsmasq 2.40 or later and may not work with other DHCP servers. ++Requires dnsmasq 2.66 or later and may not work with other DHCP servers. + +-The address argument is a dotted-quad IP addresses and mandatory. ++The address argument is a dotted-quad IP addresses and mandatory. ++.SH LIMITATIONS ++Only works with IPv4 addresses and DHCP leases. + .SH SEE ALSO + .BR dnsmasq (8) + .SH AUTHOR +diff --git a/contrib/wrt/dhcp_release.1 b/contrib/wrt/dhcp_release.1 +index eb5307a..e71aba0 100644 +--- a/contrib/wrt/dhcp_release.1 ++++ b/contrib/wrt/dhcp_release.1 +@@ -27,6 +27,8 @@ for ethernet. This encoding is the one used in dnsmasq lease files. + The client-id is optional. If it is "*" then it treated as being missing. + .SH NOTES + MUST be run as root - will fail otherwise. ++.SH LIMITATIONS ++Only usable on IPv4 DHCP leases. + .SH SEE ALSO + .BR dnsmasq (8) + .SH AUTHOR +-- +1.8.1.4 + diff --git a/dnsmasq-2.66-Send-TCP-DNS-messages-in-one-write-call.patch b/dnsmasq-2.66-Send-TCP-DNS-messages-in-one-write-call.patch new file mode 100644 index 0000000..ffeafb5 --- /dev/null +++ b/dnsmasq-2.66-Send-TCP-DNS-messages-in-one-write-call.patch @@ -0,0 +1,90 @@ +From 4b5ea12e90024ade5033b3b83a8b2620035952ba Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 22 Apr 2013 10:18:26 +0100 +Subject: [PATCH] Send TCP DNS messages in one write() call. Stops TCP stream + fragmenting. + +This is an optimisation, not a bugfix. Thanks to Jim Bos for spotting it. +--- + src/forward.c | 31 +++++++++++++------------------ + 1 file changed, 13 insertions(+), 18 deletions(-) + +diff --git a/src/forward.c b/src/forward.c +index 1ea25dd..77d6849 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -880,9 +880,12 @@ unsigned char *tcp_request(int confd, time_t now, + unsigned short qtype; + unsigned int gotname; + unsigned char c1, c2; +- /* Max TCP packet + slop */ +- unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ); +- struct dns_header *header; ++ /* Max TCP packet + slop + size */ ++ unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16)); ++ unsigned char *payload = &packet[2]; ++ /* largest field in header is 16-bits, so this is still sufficiently aligned */ ++ struct dns_header *header = (struct dns_header *)payload; ++ u16 *length = (u16 *)packet; + struct server *last_server; + struct in_addr dst_addr_4; + union mysockaddr peer_addr; +@@ -896,14 +899,12 @@ unsigned char *tcp_request(int confd, time_t now, + if (!packet || + !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) || + !(size = c1 << 8 | c2) || +- !read_write(confd, packet, size, 1)) ++ !read_write(confd, payload, size, 1)) + return packet; + + if (size < (int)sizeof(struct dns_header)) + continue; + +- header = (struct dns_header *)packet; +- + /* save state of "cd" flag in query */ + checking_disabled = header->hb4 & HB4_CD; + +@@ -1020,12 +1021,9 @@ unsigned char *tcp_request(int confd, time_t now, + #endif + } + +- c1 = size >> 8; +- c2 = size; ++ *length = htons(size); + +- if (!read_write(last_server->tcpfd, &c1, 1, 0) || +- !read_write(last_server->tcpfd, &c2, 1, 0) || +- !read_write(last_server->tcpfd, packet, size, 0) || ++ if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) || + !read_write(last_server->tcpfd, &c1, 1, 1) || + !read_write(last_server->tcpfd, &c2, 1, 1)) + { +@@ -1035,7 +1033,7 @@ unsigned char *tcp_request(int confd, time_t now, + } + + m = (c1 << 8) | c2; +- if (!read_write(last_server->tcpfd, packet, m, 1)) ++ if (!read_write(last_server->tcpfd, payload, m, 1)) + return packet; + + if (!gotname) +@@ -1071,12 +1069,9 @@ unsigned char *tcp_request(int confd, time_t now, + + check_log_writer(NULL); + +- c1 = m>>8; +- c2 = m; +- if (m == 0 || +- !read_write(confd, &c1, 1, 0) || +- !read_write(confd, &c2, 1, 0) || +- !read_write(confd, packet, m, 0)) ++ *length = htons(m); ++ ++ if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0)) + return packet; + } + } +-- +1.8.1.4 + diff --git a/dnsmasq-2.66-dhcp-match-now-work-with-BOOTP.patch b/dnsmasq-2.66-dhcp-match-now-work-with-BOOTP.patch new file mode 100644 index 0000000..c452e96 --- /dev/null +++ b/dnsmasq-2.66-dhcp-match-now-work-with-BOOTP.patch @@ -0,0 +1,282 @@ +From 86e92f998379d219e10517dfa2c42f544ba164ce Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 23 Apr 2013 11:31:39 +0100 +Subject: [PATCH] --dhcp-match et al now work with BOOTP as well as DHCP. + +--- + CHANGELOG | 4 ++ + src/rfc2131.c | 227 +++++++++++++++++++++++++++++----------------------------- + 2 files changed, 117 insertions(+), 114 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 268b64d..0a34b64 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,10 @@ version 2.67 + lease-time only if it's specifically requested + (maintaining standards) and the dhcp_lease_time utility + has been taught to ask for it (restoring functionality). ++ ++ Fix --dhcp-match, --dhcp-vendorclass and --dhcp-userclass ++ to work with BOOTP and well as DHCP. Thanks to Peter ++ Korsgaard for spotting the problem. + + + version 2.66 +diff --git a/src/rfc2131.c b/src/rfc2131.c +index 013a446..54e444b 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -355,6 +355,117 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end)); + } + } ++ ++ /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match. ++ Otherwise assume the option is an array, and look for a matching element. ++ If no data given, existance of the option is enough. This code handles ++ rfc3925 V-I classes too. */ ++ for (o = daemon->dhcp_match; o; o = o->next) ++ { ++ unsigned int len, elen, match = 0; ++ size_t offset, o2; ++ ++ if (o->flags & DHOPT_RFC3925) ++ { ++ if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT, 5))) ++ continue; ++ ++ for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5) ++ { ++ len = option_uint(opt, offset + 4 , 1); ++ /* Need to take care that bad data can't run us off the end of the packet */ ++ if ((offset + len + 5 <= (option_len(opt))) && ++ (option_uint(opt, offset, 4) == (unsigned int)o->u.encap)) ++ for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1) ++ { ++ elen = option_uint(opt, o2, 1); ++ if ((o2 + elen + 1 <= option_len(opt)) && ++ (match = match_bytes(o, option_ptr(opt, o2 + 1), elen))) ++ break; ++ } ++ if (match) ++ break; ++ } ++ } ++ else ++ { ++ if (!(opt = option_find(mess, sz, o->opt, 1))) ++ continue; ++ ++ match = match_bytes(o, option_ptr(opt, 0), option_len(opt)); ++ } ++ ++ if (match) ++ { ++ o->netid->next = netid; ++ netid = o->netid; ++ } ++ } ++ ++ /* user-class options are, according to RFC3004, supposed to contain ++ a set of counted strings. Here we check that this is so (by seeing ++ if the counts are consistent with the overall option length) and if ++ so zero the counts so that we don't get spurious matches between ++ the vendor string and the counts. If the lengths don't add up, we ++ assume that the option is a single string and non RFC3004 compliant ++ and just do the substring match. dhclient provides these broken options. ++ The code, later, which sends user-class data to the lease-change script ++ relies on the transformation done here. ++ */ ++ ++ if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) ++ { ++ unsigned char *ucp = option_ptr(opt, 0); ++ int tmp, j; ++ for (j = 0; j < option_len(opt); j += ucp[j] + 1); ++ if (j == option_len(opt)) ++ for (j = 0; j < option_len(opt); j = tmp) ++ { ++ tmp = j + ucp[j] + 1; ++ ucp[j] = 0; ++ } ++ } ++ ++ for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) ++ { ++ int mopt; ++ ++ if (vendor->match_type == MATCH_VENDOR) ++ mopt = OPTION_VENDOR_ID; ++ else if (vendor->match_type == MATCH_USER) ++ mopt = OPTION_USER_CLASS; ++ else ++ continue; ++ ++ if ((opt = option_find(mess, sz, mopt, 1))) ++ { ++ int i; ++ for (i = 0; i <= (option_len(opt) - vendor->len); i++) ++ if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0) ++ { ++ vendor->netid.next = netid; ++ netid = &vendor->netid; ++ break; ++ } ++ } ++ } ++ ++ /* mark vendor-encapsulated options which match the client-supplied vendor class, ++ save client-supplied vendor class */ ++ if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1))) ++ { ++ memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt)); ++ vendor_class_len = option_len(opt); ++ } ++ match_vendor_opts(opt, daemon->dhcp_opts); ++ ++ if (option_bool(OPT_LOG_OPTS)) ++ { ++ if (sanitise(opt, daemon->namebuff)) ++ my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %s"), ntohl(mess->xid), daemon->namebuff); ++ if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff)) ++ my_syslog(MS_DHCP | LOG_INFO, _("%u user class: %s"), ntohl(mess->xid), daemon->namebuff); ++ } + + mess->op = BOOTREPLY; + +@@ -494,9 +605,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + lease_set_interface(lease, int_index, now); + + clear_packet(mess, end); +- match_vendor_opts(NULL, daemon->dhcp_opts); /* clear flags */ + do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), +- netid, subnet_addr, 0, 0, -1, NULL, 0, now); ++ netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now); + } + } + +@@ -623,119 +733,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + } + } + +- /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match. +- Otherwise assume the option is an array, and look for a matching element. +- If no data given, existance of the option is enough. This code handles +- rfc3925 V-I classes too. */ +- for (o = daemon->dhcp_match; o; o = o->next) +- { +- unsigned int len, elen, match = 0; +- size_t offset, o2; +- +- if (o->flags & DHOPT_RFC3925) +- { +- if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT, 5))) +- continue; +- +- for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5) +- { +- len = option_uint(opt, offset + 4 , 1); +- /* Need to take care that bad data can't run us off the end of the packet */ +- if ((offset + len + 5 <= (option_len(opt))) && +- (option_uint(opt, offset, 4) == (unsigned int)o->u.encap)) +- for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1) +- { +- elen = option_uint(opt, o2, 1); +- if ((o2 + elen + 1 <= option_len(opt)) && +- (match = match_bytes(o, option_ptr(opt, o2 + 1), elen))) +- break; +- } +- if (match) +- break; +- } +- } +- else +- { +- if (!(opt = option_find(mess, sz, o->opt, 1))) +- continue; +- +- match = match_bytes(o, option_ptr(opt, 0), option_len(opt)); +- } +- +- if (match) +- { +- o->netid->next = netid; +- netid = o->netid; +- } +- } +- +- /* user-class options are, according to RFC3004, supposed to contain +- a set of counted strings. Here we check that this is so (by seeing +- if the counts are consistent with the overall option length) and if +- so zero the counts so that we don't get spurious matches between +- the vendor string and the counts. If the lengths don't add up, we +- assume that the option is a single string and non RFC3004 compliant +- and just do the substring match. dhclient provides these broken options. +- The code, later, which sends user-class data to the lease-change script +- relies on the transformation done here. +- */ +- +- if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) +- { +- unsigned char *ucp = option_ptr(opt, 0); +- int tmp, j; +- for (j = 0; j < option_len(opt); j += ucp[j] + 1); +- if (j == option_len(opt)) +- for (j = 0; j < option_len(opt); j = tmp) +- { +- tmp = j + ucp[j] + 1; +- ucp[j] = 0; +- } +- } +- +- for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) +- { +- int mopt; +- +- if (vendor->match_type == MATCH_VENDOR) +- mopt = OPTION_VENDOR_ID; +- else if (vendor->match_type == MATCH_USER) +- mopt = OPTION_USER_CLASS; +- else +- continue; +- +- if ((opt = option_find(mess, sz, mopt, 1))) +- { +- int i; +- for (i = 0; i <= (option_len(opt) - vendor->len); i++) +- if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0) +- { +- vendor->netid.next = netid; +- netid = &vendor->netid; +- break; +- } +- } +- } +- +- /* mark vendor-encapsulated options which match the client-supplied vendor class, +- save client-supplied vendor class */ +- if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1))) +- { +- memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt)); +- vendor_class_len = option_len(opt); +- } +- match_vendor_opts(opt, daemon->dhcp_opts); +- +- if (option_bool(OPT_LOG_OPTS)) +- { +- if (sanitise(opt, daemon->namebuff)) +- my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %s"), ntohl(mess->xid), daemon->namebuff); +- if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff)) +- my_syslog(MS_DHCP | LOG_INFO, _("%u user class: %s"), ntohl(mess->xid), daemon->namebuff); +- } +- + tagif_netid = run_tag_if(netid); +- ++ + /* if all the netids in the ignore list are present, ignore this client */ + for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next) + if (match_netid(id_list->list, tagif_netid, 0)) +-- +1.8.1.4 + diff --git a/dnsmasq.spec b/dnsmasq.spec index 4e544ce..a49a3e2 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -11,7 +11,7 @@ Name: dnsmasq Version: 2.66 -Release: 3%{?extraversion}%{?dist} +Release: 4%{?extraversion}%{?dist} Summary: A lightweight DHCP/caching DNS server Group: System Environment/Daemons @@ -25,6 +25,18 @@ Source1: %{name}.service Patch0: %{name}-2.66-Fix-wrong_size_in_memset_call.patch # commit bd08ae67f9a0cae2ce15be885254cad9449d4551 Patch1: %{name}-2.66-Allow-option_number_zero_in_encapsulated_DHCP_options.patch +# commit 4b5ea12e90024ade5033b3b83a8b2620035952ba +Patch2: %{name}-2.66-Send-TCP-DNS-messages-in-one-write-call.patch +# commit 797a7afba477390bc016c647cfb792c85ee6102d +Patch3: %{name}-2.66-Fix-crash-on-SERVFAIL-when-using-conntrack.patch +# commit aa63a21ce0b20dfe988e0bcdf14b8b930de20311 +Patch4: %{name}-2.66-Fix-regression-in-dhcp_lease_time-utility.patch +# commit a66d36ea1112c861ad2f11ed40cc26973873e5be +Patch5: %{name}-2.66-Manpage-typos.patch +# commit 1c10b9de118c951a5aedc130e55101987dcc3feb +Patch6: %{name}-2.66-Note-that-dhcp_lease_time-and-dhcp_release-work-for-IPv4.patch +# commit 86e92f998379d219e10517dfa2c42f544ba164ce +Patch7: %{name}-2.66-dhcp-match-now-work-with-BOOTP.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -62,6 +74,12 @@ query/remove a DHCP server's leases. %patch0 -p1 -b .wrong_size %patch1 -p1 -b .zero_DHCP_option +%patch2 -p1 -b .tcp_dns_in_one_packet +%patch3 -p1 -b .SERVFAIL_crash +%patch4 -p1 -b .dhcp_lease_time-regression +%patch5 -p1 +%patch6 -p1 -b .utils_work_only_ipv4 +%patch7 -p1 -b .dhcp-match_bootp # use /var/lib/dnsmasq instead of /var/lib/misc for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do @@ -146,6 +164,15 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/dhcp_* %changelog +* Thu Apr 25 2013 Tomas Hozza - 2.66-4 +- include several fixes from upstream repo: + - Send TCP DNS messages in one packet + - Fix crash on SERVFAIL when using --conntrack option + - Fix regression in dhcp_lease_time utility + - Man page typos fixes + - Note that dhcp_lease_time and dhcp_release work only for IPv4 + - Fix for --dhcp-match option to work also with BOOTP protocol + * Sat Apr 20 2013 Tomas Hozza - 2.66-3 - Use Full RELRO when linking the daemon - compile the daemon with PIE