Compare commits

...

5 Commits

Author SHA1 Message Date
Giacomo Tazzari
797a7afba4 Fix crash on SERVFAIL when --conntrack in use. 2013-04-22 13:16:37 +01:00
Simon Kelley
4b5ea12e90 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.
2013-04-22 10:22:55 +01:00
Simon Kelley
2b6390fdc9 Bump Debian version number. 2013-04-19 10:23:50 +01:00
Simon Kelley
bd08ae67f9 Allow option number zero in encapsulated DHCP options. 2013-04-19 10:22:06 +01:00
Dave Reisner
4582c0efe7 Fix wrong size in memset() call.
Thanks to Dave Reisner.
2013-04-18 21:02:41 +01:00
7 changed files with 54 additions and 40 deletions

View File

@@ -1,3 +1,9 @@
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.
version 2.66
Add the ability to act as an authoritative DNS
server. Dnsmasq can now answer queries from the wider 'net

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
dnsmasq (2.67-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 19 Apr 2013 10:23:31 +0000
dnsmasq (2.66-1) unstable; urgency=low
* New upstream.

View File

@@ -512,7 +512,7 @@ void display_opts6(void)
}
#endif
u16 lookup_dhcp_opt(int prot, char *name)
int lookup_dhcp_opt(int prot, char *name)
{
const struct opttab_t *t;
int i;
@@ -528,10 +528,10 @@ u16 lookup_dhcp_opt(int prot, char *name)
if (strcasecmp(t[i].name, name) == 0)
return t[i].val;
return 0;
return -1;
}
u16 lookup_dhcp_len(int prot, u16 val)
int lookup_dhcp_len(int prot, int val)
{
const struct opttab_t *t;
int i;

View File

@@ -1216,8 +1216,8 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
void dhcp_update_configs(struct dhcp_config *configs);
void display_opts(void);
u16 lookup_dhcp_opt(int prot, char *name);
u16 lookup_dhcp_len(int prot, u16 val);
int lookup_dhcp_opt(int prot, char *name);
int lookup_dhcp_len(int prot, int val);
char *option_string(int prot, unsigned int opt, unsigned char *val,
int opt_len, char *buf, int buf_len);
#ifdef HAVE_LINUX_NETWORK

View File

@@ -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
@@ -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;
}
}

View File

@@ -110,7 +110,7 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
return -1;
}
memset(buffer, 0, sizeof(buffer));
memset(buffer, 0, BUFF_SZ);
nlh = (struct nlmsghdr *)buffer;
nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr));

View File

@@ -750,6 +750,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
struct dhcp_netid *np = NULL;
u16 opt_len = 0;
int is6 = 0;
int option_ok = 0;
new->len = 0;
new->flags = flags;
@@ -769,16 +770,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{
new->opt = atoi(arg);
opt_len = 0;
option_ok = 1;
break;
}
if (strstr(arg, "option:") == arg)
{
new->opt = lookup_dhcp_opt(AF_INET, arg+7);
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option:<optname> must follow tag and vendor string. */
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
new->opt = 0;
if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option:<optname> must follow tag and vendor string. */
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
break;
}
#ifdef HAVE_DHCP6
@@ -792,13 +796,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{
new->opt = atoi(arg+8);
opt_len = 0;
option_ok = 1;
}
else
{
new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
new->opt = 0;
if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
}
/* option6:<opt>|<optname> must follow tag and vendor string. */
is6 = 1;
@@ -821,7 +828,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
new->flags |= DHOPT_RFC3925;
if (flags == DHOPT_MATCH)
{
new->opt = 1; /* avoid error below */
option_ok = 1;
break;
}
}
@@ -848,16 +855,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (opt_len == 0 &&
!(new->flags & DHOPT_RFC3925))
opt_len = lookup_dhcp_len(AF_INET6 ,new->opt);
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
}
else
#endif
if (opt_len == 0 &&
!(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
opt_len = lookup_dhcp_len(AF_INET ,new->opt);
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option may be missing with rfc3925 match */
if (new->opt == 0)
if (!option_ok)
ret_err(_("bad dhcp-option"));
if (comma)