mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-05 07:35:07 -05:00
socket: add support for binding sockets to device
As a Linux-specific feature, allow sockets to be bound to a device using the SO_BINDTODEVICE socket option. The CAP_NET_RAW capability is required for setting the option.
This commit is contained in:
31
socket.c
31
socket.c
@@ -336,6 +336,23 @@ is_any_address(IPAddr *addr)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
bind_device(int sock_fd, const char *iface)
|
||||
{
|
||||
#ifdef SO_BINDTODEVICE
|
||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) < 0) {
|
||||
DEBUG_LOG("Could not bind socket to %s : %s", iface, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
DEBUG_LOG("Could not bind socket to %s : %s", "Not supported");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
bind_ip_address(int sock_fd, IPSockAddr *addr, int flags)
|
||||
{
|
||||
@@ -403,7 +420,8 @@ connect_ip_address(int sock_fd, IPSockAddr *addr)
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
open_ip_socket(IPSockAddr *remote_addr, IPSockAddr *local_addr, int type, int flags)
|
||||
open_ip_socket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface,
|
||||
int type, int flags)
|
||||
{
|
||||
int domain, family, sock_fd;
|
||||
|
||||
@@ -442,6 +460,9 @@ open_ip_socket(IPSockAddr *remote_addr, IPSockAddr *local_addr, int type, int fl
|
||||
if (!set_ip_options(sock_fd, family, flags))
|
||||
goto error;
|
||||
|
||||
if (iface && !bind_device(sock_fd, iface))
|
||||
goto error;
|
||||
|
||||
/* Bind the socket if a non-any local address/port was specified */
|
||||
if (local_addr && local_addr->ip_addr.family != IPADDR_UNSPEC &&
|
||||
(local_addr->port != 0 || !is_any_address(&local_addr->ip_addr)) &&
|
||||
@@ -1213,17 +1234,17 @@ SCK_SetPrivBind(int (*function)(int sock_fd, struct sockaddr *address,
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
SCK_OpenUdpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, int flags)
|
||||
SCK_OpenUdpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface, int flags)
|
||||
{
|
||||
return open_ip_socket(remote_addr, local_addr, SOCK_DGRAM, flags);
|
||||
return open_ip_socket(remote_addr, local_addr, iface, SOCK_DGRAM, flags);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
SCK_OpenTcpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, int flags)
|
||||
SCK_OpenTcpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface, int flags)
|
||||
{
|
||||
return open_ip_socket(remote_addr, local_addr, SOCK_STREAM, flags);
|
||||
return open_ip_socket(remote_addr, local_addr, iface, SOCK_STREAM, flags);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
Reference in New Issue
Block a user