Skip to content

Commit 1635019

Browse files
authored
Merge pull request #2730 from pi-hole/update/dnsmasq
Update embedded dnsmasq to 2.92rc1
2 parents 96554dd + de1d273 commit 1635019

10 files changed

Lines changed: 181 additions & 106 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ set(CMAKE_C_STANDARD 17)
1616

1717
project(PIHOLE_FTL C)
1818

19-
set(DNSMASQ_VERSION pi-hole-v2.92test21)
19+
set(DNSMASQ_VERSION pi-hole-v2.92rc1)
2020

2121
add_subdirectory(src)

src/dnsmasq/arp.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,22 +111,26 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
111111

112112
again:
113113

114-
/* If the database is less then INTERVAL old, look in there */
115-
if (difftime(now, last) < INTERVAL)
114+
/* If the database is less then INTERVAL old, look in there.
115+
116+
If we're a child process, we always rely on the existing cache we
117+
inherited from the parent, since we don't have a netlink socket.
118+
*/
119+
if (difftime(now, last) < INTERVAL || daemon->pipe_to_parent != -1)
116120
{
117121
/* addr == NULL -> just make cache up-to-date */
118122
if (!addr)
119123
return 0;
120-
124+
121125
for (arp = arps; arp; arp = arp->next)
122126
{
123127
if (addr->sa.sa_family != arp->family)
124128
continue;
125-
129+
126130
if (arp->family == AF_INET &&
127131
arp->addr.addr4.s_addr != addr->in.sin_addr.s_addr)
128132
continue;
129-
133+
130134
if (arp->family == AF_INET6 &&
131135
!IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, &addr->in6.sin6_addr))
132136
continue;
@@ -141,6 +145,10 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
141145
}
142146
}
143147

148+
/* Not in cache in child, no go. */
149+
if (daemon->pipe_to_parent != -1)
150+
return 0;
151+
144152
/* Not found, try the kernel */
145153
if (!updated)
146154
{

src/dnsmasq/dbus.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
530530
union all_addr addr;
531531
time_t now = dnsmasq_time();
532532
unsigned char dhcp_chaddr[DHCP_CHADDR_MAX];
533-
534533
DBusMessageIter iter, array_iter;
534+
535535
if (!dbus_message_iter_init(message, &iter))
536536
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
537537
"Failed to initialize dbus message iter");
@@ -599,6 +599,10 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
599599

600600
if (inet_pton(AF_INET, ipaddr, &addr.addr4))
601601
{
602+
if (!daemon->dhcp)
603+
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
604+
"DHCPv4 not configured");
605+
602606
if (ia_id != 0 || is_temporary)
603607
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
604608
"ia_id and is_temporary must be zero for IPv4 lease");
@@ -609,16 +613,25 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
609613
#ifdef HAVE_DHCP6
610614
else if (inet_pton(AF_INET6, ipaddr, &addr.addr6))
611615
{
616+
if (!daemon->doing_dhcp6)
617+
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
618+
"DHCPv6 not configured");
619+
612620
if (!(lease = lease6_find_by_addr(&addr.addr6, 128, 0)))
613621
lease = lease6_allocate(&addr.addr6,
614622
is_temporary ? LEASE_TA : LEASE_NA);
615-
lease_set_iaid(lease, ia_id);
623+
if (lease)
624+
lease_set_iaid(lease, ia_id);
616625
}
617626
#endif
618627
else
619628
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
620629
"Invalid IP address '%s'", ipaddr);
621-
630+
631+
if (!lease)
632+
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
633+
"unable to allocate lease for IP address '%s'", ipaddr);
634+
622635
hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
623636
if (hw_len < 0)
624637
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
@@ -641,7 +654,7 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
641654

642655
static DBusMessage *dbus_del_lease(DBusMessage* message)
643656
{
644-
struct dhcp_lease *lease;
657+
struct dhcp_lease *lease = NULL;
645658
DBusMessageIter iter;
646659
const char *ipaddr;
647660
DBusMessage *reply;
@@ -659,10 +672,10 @@ static DBusMessage *dbus_del_lease(DBusMessage* message)
659672

660673
dbus_message_iter_get_basic(&iter, &ipaddr);
661674

662-
if (inet_pton(AF_INET, ipaddr, &addr.addr4))
675+
if (inet_pton(AF_INET, ipaddr, &addr.addr4) && daemon->dhcp)
663676
lease = lease_find_by_addr(addr.addr4);
664677
#ifdef HAVE_DHCP6
665-
else if (inet_pton(AF_INET6, ipaddr, &addr.addr6))
678+
else if (inet_pton(AF_INET6, ipaddr, &addr.addr6) && daemon->doing_dhcp6)
666679
lease = lease6_find_by_addr(&addr.addr6, 128, 0);
667680
#endif
668681
else

src/dnsmasq/dhcp-common.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,8 @@ const struct opttab_t {
709709
{ "client-machine-id", 97, 0 },
710710
{ "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
711711
{ "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
712-
{ "ipv6-only", 108, 4 | OT_DEC }, /* RFC 8925 */
712+
{ "ipv6-only", 108, 4 | OT_DEC }, /* RFC 8925 */
713+
{ "captive-portal", 114, OT_NAME }, /* RFC 8910 */
713714
{ "subnet-select", 118, OT_INTERNAL },
714715
{ "domain-search", 119, OT_RFC1035_NAME },
715716
{ "sip-server", 120, 0 },
@@ -751,6 +752,7 @@ static const struct opttab_t opttab6[] = {
751752
{ "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
752753
{ "bootfile-url", 59, OT_NAME },
753754
{ "bootfile-param", 60, OT_CSTRING },
755+
{ "captive-portal", 103, OT_NAME }, /* RFC 8910 */
754756
{ NULL, 0, 0 }
755757
};
756758
#endif

src/dnsmasq/dhcp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ struct dhcp_context *address_available(struct dhcp_context *context,
696696
struct dhcp_context *tmp;
697697

698698
for (tmp = context; tmp; tmp = tmp->current)
699-
if (taddr.s_addr == context->router.s_addr)
699+
if (taddr.s_addr == tmp->router.s_addr)
700700
return NULL;
701701

702702
for (tmp = context; tmp; tmp = tmp->current)

src/dnsmasq/dnsmasq.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ int main_dnsmasq (int argc, char **argv)
134134
This might be increased is EDNS packet size if greater than the minimum. */
135135
daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
136136
daemon->packet = safe_malloc(daemon->packet_buff_sz);
137+
daemon->pipe_to_parent = -1;
137138

138139
if (option_bool(OPT_EXTRALOG))
139140
daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
@@ -1089,8 +1090,6 @@ int main_dnsmasq (int argc, char **argv)
10891090

10901091
pid = getpid();
10911092

1092-
daemon->pipe_to_parent = -1;
1093-
10941093
#ifdef HAVE_INOTIFY
10951094
/* Using inotify, have to select a resolv file at startup */
10961095
poll_resolv(1, 0, now);
@@ -2065,9 +2064,24 @@ static void do_tcp_connection(struct listener *listener, time_t now, int slot)
20652064

20662065
if (!option_bool(OPT_DEBUG))
20672066
{
2067+
/* The code in edns0.c qthat decorates queries with the source MAC address depends
2068+
on the code in arp.c, which populates a cache with the contents of the ARP table
2069+
using netlink. Since the child process can't use netlink, we pre-populate
2070+
the cache with the ARP table entry for our source here, including a negative entry
2071+
if there is nothing for our address in the ARP table.
2072+
2073+
When the edns0 code calls find_mac() in the child process, it will
2074+
get the correct answer from the cache inherited from the parent
2075+
without having to use netlink to consult the kernel ARP table.
2076+
2077+
edns0_needs_mac() simply calls find_mac if any EDNS0 options
2078+
which need a MAC address are enabled. */
2079+
2080+
edns0_needs_mac(&tcp_addr, now);
2081+
20682082
if (pipe(pipefd) == -1)
20692083
goto closeconandreturn; /* pipe failed */
2070-
2084+
20712085
if ((p = fork()) == -1)
20722086
{
20732087
/* fork failed */

src/dnsmasq/dnsmasq.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ struct ping_result {
11241124

11251125
struct tftp_file {
11261126
int refcount, fd;
1127-
off_t size;
1127+
off_t size, posn;
11281128
dev_t dev;
11291129
ino_t inode;
11301130
char filename[];
@@ -1139,7 +1139,7 @@ struct tftp_transfer {
11391139
union mysockaddr peer;
11401140
union all_addr source;
11411141
int if_index;
1142-
unsigned char opt_blocksize, opt_transize, opt_windowsize, opt_timeout, netascii, carrylf, backoff;
1142+
unsigned char opt_blocksize, opt_transize, opt_windowsize, opt_timeout, netascii, carrylf, lastcarrylf, backoff;
11431143
struct tftp_file *file;
11441144
struct tftp_transfer *next;
11451145
};
@@ -1293,7 +1293,7 @@ extern struct daemon {
12931293
struct serverfd *sfds;
12941294
struct irec *interfaces;
12951295
struct listener *listeners;
1296-
struct server *srv_save; /* Used for resend on DoD */
1296+
void *srv_save; /* Used for resend on DoD and tftp prefetch */
12971297
size_t packet_len; /* " " */
12981298
int fd_save; /* " " */
12991299
pid_t *tcp_pids;
@@ -1937,6 +1937,7 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
19371937
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
19381938
int optno, unsigned char *opt, size_t optlen, int set_do, int replace);
19391939
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit);
1940+
void edns0_needs_mac(union mysockaddr *addr, time_t now);
19401941
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
19411942
union mysockaddr *source, time_t now, int *cacheable);
19421943
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);

src/dnsmasq/edns0.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@ static void encoder(unsigned char *in, char *out)
265265
out[3] = char64(in[2]);
266266
}
267267

268+
/* This function needs to call find_mac if any option which requires a MAC address is enabled
269+
and used below. If you add a new MAC consumer, modify this, otherwise your
270+
new EDNS0 option won't work in TCP mode. */
271+
void edns0_needs_mac(union mysockaddr *addr, time_t now)
272+
{
273+
if (option_bool(OPT_MAC_B64) || option_bool(OPT_MAC_HEX) || option_bool(OPT_ADD_MAC))
274+
find_mac(addr, NULL, 0, now);
275+
}
276+
268277
/* OPT_ADD_MAC = MAC is added (if available)
269278
OPT_ADD_MAC + OPT_STRIP_MAC = MAC is replaced, if not available, it is only removed
270279
OPT_STRIP_MAC = MAC is removed */
@@ -562,3 +571,4 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
562571

563572
return plen;
564573
}
574+

src/dnsmasq/netlink.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ int iface_enumerate(int family, void *parm, callback_t callback)
165165
struct rtgenmsg g;
166166
} req;
167167

168+
/* The netlink socket is not available in child processes. */
169+
if (daemon->pipe_to_parent != -1)
170+
{
171+
my_syslog(LOG_ERR, _("BUG: called iface_enumerate() in child process"));
172+
return 0;
173+
}
174+
168175
memset(&req, 0, sizeof(req));
169176
memset(&addr, 0, sizeof(addr));
170177

0 commit comments

Comments
 (0)