ntp+cmdmon: fix responding to link-local addresses
After commit e49aececce
("socket: don't set interface for sent
packets") the NTP and cmdmon server stopped responding to requests from
link-local addresses.
Set the interface specifically for packets sent to a link-local address.
This commit is contained in:
parent
99e3c67a81
commit
4e747da4b4
4 changed files with 28 additions and 4 deletions
6
cmdmon.c
6
cmdmon.c
|
@ -301,8 +301,10 @@ transmit_reply(int sock_fd, SCK_Message *message)
|
|||
{
|
||||
message->length = PKL_ReplyLength((CMD_Reply *)message->data);
|
||||
|
||||
/* Don't require the response to use the same interface */
|
||||
message->if_index = INVALID_IF_INDEX;
|
||||
/* Don't require responses to non-link-local addresses to use the same
|
||||
interface */
|
||||
if (!SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
|
||||
message->if_index = INVALID_IF_INDEX;
|
||||
|
||||
if (!SCK_SendMessage(sock_fd, message, 0))
|
||||
return;
|
||||
|
|
6
ntp_io.c
6
ntp_io.c
|
@ -454,8 +454,10 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
|
|||
|
||||
message.local_addr.ip = local_addr->ip_addr;
|
||||
|
||||
/* Don't require the response to use the same interface */
|
||||
message.if_index = INVALID_IF_INDEX;
|
||||
/* Don't require responses to non-link-local addresses to use the same
|
||||
interface */
|
||||
message.if_index = SCK_IsLinkLocalIPAddress(&message.remote_addr.ip.ip_addr) ?
|
||||
local_addr->if_index : INVALID_IF_INDEX;
|
||||
|
||||
#if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR)
|
||||
/* On FreeBSD a local IPv4 address cannot be specified on bound socket */
|
||||
|
|
17
socket.c
17
socket.c
|
@ -1228,6 +1228,23 @@ SCK_GetLoopbackIPAddress(int family, IPAddr *local_addr)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
SCK_IsLinkLocalIPAddress(IPAddr *addr)
|
||||
{
|
||||
switch (addr->family) {
|
||||
case IPADDR_INET4:
|
||||
/* 169.254.0.0/16 */
|
||||
return (addr->addr.in4 & 0xffff0000) == 0xa9fe0000;
|
||||
case IPADDR_INET6:
|
||||
/* fe80::/10 */
|
||||
return addr->addr.in6[0] == 0xfe && (addr->addr.in6[1] & 0xc0) == 0x80;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SCK_SetPrivBind(int (*function)(int sock_fd, struct sockaddr *address,
|
||||
socklen_t address_len))
|
||||
|
|
3
socket.h
3
socket.h
|
@ -87,6 +87,9 @@ extern int SCK_IsIpFamilyEnabled(int family);
|
|||
extern void SCK_GetAnyLocalIPAddress(int family, IPAddr *local_addr);
|
||||
extern void SCK_GetLoopbackIPAddress(int family, IPAddr *local_addr);
|
||||
|
||||
/* Check if an IP address is a link-local address */
|
||||
extern int SCK_IsLinkLocalIPAddress(IPAddr *addr);
|
||||
|
||||
/* Specify a bind()-like function for binding sockets to privileged ports when
|
||||
running in a restricted process (e.g. after dropping root privileges) */
|
||||
extern void SCK_SetPrivBind(int (*function)(int sock_fd, struct sockaddr *address,
|
||||
|
|
Loading…
Reference in a new issue