mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Handle changing interface indexes when binding DHCP sockets.
This commit is contained in:
@@ -39,6 +39,14 @@ version 2.87
|
|||||||
a local NODATA answer. The pre-2.86 behaviour is still available,
|
a local NODATA answer. The pre-2.86 behaviour is still available,
|
||||||
by configuring --address=/example.com/1.2.3.4 --local=/example.com/
|
by configuring --address=/example.com/1.2.3.4 --local=/example.com/
|
||||||
|
|
||||||
|
Fix problem with binding DHCP sockets to an individual interface.
|
||||||
|
Despite the fact that the system call tales the interface _name_ as
|
||||||
|
a parameter, it actually, binds the socket to interface _index_.
|
||||||
|
Deleting the interface and creating a new one with the same name
|
||||||
|
leaves the socket bound to the old index. (Creating new sockets
|
||||||
|
always allocates a fresh index, they are not reused). We now
|
||||||
|
take this behaviour into account and keep up with changing indexes.
|
||||||
|
|
||||||
|
|
||||||
version 2.86
|
version 2.86
|
||||||
Handle DHCPREBIND requests in the DHCPv6 server code.
|
Handle DHCPREBIND requests in the DHCPv6 server code.
|
||||||
|
|||||||
@@ -566,12 +566,16 @@ char *whichdevice(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
return found->name;
|
{
|
||||||
|
char *ret = safe_malloc(strlen(found->name)+1);
|
||||||
|
strcpy(ret, found->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindtodevice(char *device, int fd)
|
static int bindtodevice(char *device, int fd)
|
||||||
{
|
{
|
||||||
size_t len = strlen(device)+1;
|
size_t len = strlen(device)+1;
|
||||||
if (len > IFNAMSIZ)
|
if (len > IFNAMSIZ)
|
||||||
@@ -579,7 +583,33 @@ void bindtodevice(char *device, int fd)
|
|||||||
/* only allowed by root. */
|
/* only allowed by root. */
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
|
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
|
||||||
errno != EPERM)
|
errno != EPERM)
|
||||||
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
return 2;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bind_dhcp_devices(char *bound_device)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (bound_device)
|
||||||
|
{
|
||||||
|
if (daemon->dhcp)
|
||||||
|
{
|
||||||
|
if (!daemon->relay4)
|
||||||
|
ret |= bindtodevice(bound_device, daemon->dhcpfd);
|
||||||
|
|
||||||
|
if (daemon->enable_pxe && daemon->pxefd != -1)
|
||||||
|
ret |= bindtodevice(bound_device, daemon->pxefd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_DHCP6)
|
||||||
|
if (daemon->doing_dhcp6 && !daemon->relay6)
|
||||||
|
ret |= bindtodevice(bound_device, daemon->dhcp6fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -388,27 +388,8 @@ int main (int argc, char **argv)
|
|||||||
/* after enumerate_interfaces() */
|
/* after enumerate_interfaces() */
|
||||||
bound_device = whichdevice();
|
bound_device = whichdevice();
|
||||||
|
|
||||||
if (daemon->dhcp)
|
if ((did_bind = bind_dhcp_devices(bound_device)) & 2)
|
||||||
{
|
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
||||||
if (!daemon->relay4 && bound_device)
|
|
||||||
{
|
|
||||||
bindtodevice(bound_device, daemon->dhcpfd);
|
|
||||||
did_bind = 1;
|
|
||||||
}
|
|
||||||
if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
|
|
||||||
{
|
|
||||||
bindtodevice(bound_device, daemon->pxefd);
|
|
||||||
did_bind = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
|
|
||||||
if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
|
|
||||||
{
|
|
||||||
bindtodevice(bound_device, daemon->dhcp6fd);
|
|
||||||
did_bind = 1;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1100,6 +1081,17 @@ int main (int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
|
# if defined(HAVE_LINUX_NETWORK)
|
||||||
|
if (bind_dhcp_devices(bound_device) & 2)
|
||||||
|
{
|
||||||
|
static int warned = 0;
|
||||||
|
if (!warned)
|
||||||
|
{
|
||||||
|
my_syslog(LOG_ERR, _("error binding DHCP socket to device %s"), bound_device);
|
||||||
|
warned = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
if (daemon->dhcp || daemon->relay4)
|
if (daemon->dhcp || daemon->relay4)
|
||||||
{
|
{
|
||||||
poll_listen(daemon->dhcpfd, POLLIN);
|
poll_listen(daemon->dhcpfd, POLLIN);
|
||||||
|
|||||||
@@ -1715,7 +1715,7 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
char *whichdevice(void);
|
char *whichdevice(void);
|
||||||
void bindtodevice(char *device, int fd);
|
int bind_dhcp_devices(char *bound_device);
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_DHCP6
|
# ifdef HAVE_DHCP6
|
||||||
void display_opts6(void);
|
void display_opts6(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user