mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Handle errors when sending ICMP6 pings better.
This commit is contained in:
@@ -911,9 +911,9 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
union mysockaddr *local_addr, struct in_addr netmask);
|
union mysockaddr *local_addr, struct in_addr netmask);
|
||||||
void server_gone(struct server *server);
|
void server_gone(struct server *server);
|
||||||
struct frec *get_new_frec(time_t now, int *wait);
|
struct frec *get_new_frec(time_t now, int *wait);
|
||||||
void send_from(int fd, int nowild, char *packet, size_t len,
|
int send_from(int fd, int nowild, char *packet, size_t len,
|
||||||
union mysockaddr *to, struct all_addr *source,
|
union mysockaddr *to, struct all_addr *source,
|
||||||
unsigned int iface);
|
unsigned int iface, int *errp);
|
||||||
|
|
||||||
/* network.c */
|
/* network.c */
|
||||||
int indextoname(int fd, int index, char *name);
|
int indextoname(int fd, int index, char *name);
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ static struct randfd *allocate_rfd(int family);
|
|||||||
|
|
||||||
/* Send a UDP packet with its source address set as "source"
|
/* Send a UDP packet with its source address set as "source"
|
||||||
unless nowild is true, when we just send it with the kernel default */
|
unless nowild is true, when we just send it with the kernel default */
|
||||||
void send_from(int fd, int nowild, char *packet, size_t len,
|
int send_from(int fd, int nowild, char *packet, size_t len,
|
||||||
union mysockaddr *to, struct all_addr *source,
|
union mysockaddr *to, struct all_addr *source,
|
||||||
unsigned int iface)
|
unsigned int iface, int *errp)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
@@ -110,8 +110,15 @@ void send_from(int fd, int nowild, char *packet, size_t len,
|
|||||||
if (retry_send())
|
if (retry_send())
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
|
if (errp)
|
||||||
|
*errp = errno;
|
||||||
|
else
|
||||||
|
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int search_servers(time_t now, struct all_addr **addrpp,
|
static unsigned int search_servers(time_t now, struct all_addr **addrpp,
|
||||||
@@ -432,7 +439,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
if (udpfd != -1)
|
if (udpfd != -1)
|
||||||
{
|
{
|
||||||
plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
|
plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
|
||||||
send_from(udpfd, option_bool(OPT_NOWILD), (char *)header, plen, udpaddr, dst_addr, dst_iface);
|
send_from(udpfd, option_bool(OPT_NOWILD), (char *)header, plen, udpaddr, dst_addr, dst_iface, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -621,7 +628,7 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
header->id = htons(forward->orig_id);
|
header->id = htons(forward->orig_id);
|
||||||
header->hb4 |= HB4_RA; /* recursion if available */
|
header->hb4 |= HB4_RA; /* recursion if available */
|
||||||
send_from(forward->fd, option_bool(OPT_NOWILD), daemon->packet, nn,
|
send_from(forward->fd, option_bool(OPT_NOWILD), daemon->packet, nn,
|
||||||
&forward->source, &forward->dest, forward->iface);
|
&forward->source, &forward->dest, forward->iface, NULL);
|
||||||
}
|
}
|
||||||
free_frec(forward); /* cancel */
|
free_frec(forward); /* cancel */
|
||||||
}
|
}
|
||||||
@@ -816,7 +823,7 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
if (m >= 1)
|
if (m >= 1)
|
||||||
{
|
{
|
||||||
send_from(listen->fd, option_bool(OPT_NOWILD), (char *)header,
|
send_from(listen->fd, option_bool(OPT_NOWILD), (char *)header,
|
||||||
m, &source_addr, &dst_addr, if_index);
|
m, &source_addr, &dst_addr, if_index, NULL);
|
||||||
daemon->local_answer++;
|
daemon->local_answer++;
|
||||||
}
|
}
|
||||||
else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
|
else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
inet_pton(AF_INET6, ALL_HOSTS, &addr.sin6_addr);
|
inet_pton(AF_INET6, ALL_HOSTS, &addr.sin6_addr);
|
||||||
|
|
||||||
send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
||||||
(union mysockaddr *)&addr, (struct all_addr *)&parm.link_local, iface);
|
(union mysockaddr *)&addr, (struct all_addr *)&parm.link_local, iface, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
src/slaac.c
27
src/slaac.c
@@ -131,14 +131,15 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
|
|||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
for (slaac = lease->slaac_address; slaac; slaac = slaac->next)
|
for (slaac = lease->slaac_address; slaac; slaac = slaac->next)
|
||||||
{
|
{
|
||||||
/* confirmed? */
|
/* confirmed or given up? */
|
||||||
if (slaac->backoff == 0)
|
if (slaac->backoff == 0 || slaac->ping_time == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (difftime(slaac->ping_time, now) <= 0.0)
|
if (difftime(slaac->ping_time, now) <= 0.0)
|
||||||
{
|
{
|
||||||
struct ping_packet *ping;
|
struct ping_packet *ping;
|
||||||
struct sockaddr_in6 addr;
|
struct sockaddr_in6 addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
save_counter(0);
|
save_counter(0);
|
||||||
ping = expand(sizeof(struct ping_packet));
|
ping = expand(sizeof(struct ping_packet));
|
||||||
@@ -155,16 +156,22 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
|
|||||||
addr.sin6_port = htons(IPPROTO_ICMPV6);
|
addr.sin6_port = htons(IPPROTO_ICMPV6);
|
||||||
addr.sin6_addr = slaac->addr;
|
addr.sin6_addr = slaac->addr;
|
||||||
|
|
||||||
send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
if (send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
||||||
(union mysockaddr *)&addr, (struct all_addr *)&slaac->local, lease->last_interface);
|
(union mysockaddr *)&addr, (struct all_addr *)&slaac->local,
|
||||||
|
lease->last_interface, &err))
|
||||||
slaac->ping_time += (1 << (slaac->backoff - 1)) + (rand16()/21785); /* 0 - 3 */
|
{
|
||||||
if (slaac->backoff > 4)
|
slaac->ping_time += (1 << (slaac->backoff - 1)) + (rand16()/21785); /* 0 - 3 */
|
||||||
slaac->ping_time += rand16()/4000; /* 0 - 15 */
|
if (slaac->backoff > 4)
|
||||||
slaac->backoff++;
|
slaac->ping_time += rand16()/4000; /* 0 - 15 */
|
||||||
|
if (slaac->backoff < 12)
|
||||||
|
slaac->backoff++;
|
||||||
|
}
|
||||||
|
else if (err == EHOSTUNREACH)
|
||||||
|
slaac->ping_time = 0; /* Give up */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_event == 0 || difftime(next_event, slaac->ping_time) >= 0.0)
|
if (slaac->ping_time != 0 &&
|
||||||
|
(next_event == 0 || difftime(next_event, slaac->ping_time) >= 0.0))
|
||||||
next_event = slaac->ping_time;
|
next_event = slaac->ping_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user