socket: enable only specified IP families

Allow an IP family to be specified in the socket initialization in order
to globally disable the other family. This replaces the ntp_io and
cmdmon code handling the -4/-6 options and fixes a case where the NTP
client could still use a disabled family if the source was specified
with an IP address.
This commit is contained in:
Miroslav Lichvar 2020-06-17 12:06:21 +02:00
parent 80316de3b8
commit 27e20a568b
12 changed files with 52 additions and 50 deletions

View file

@ -3601,7 +3601,7 @@ main(int argc, char **argv)
UTI_SetQuitSignalsHandler(signal_handler, 0); UTI_SetQuitSignalsHandler(signal_handler, 0);
SCK_Initialise(); SCK_Initialise(IPADDR_UNSPEC);
server_addresses = get_addresses(hostnames, port); server_addresses = get_addresses(hostnames, port);
if (!open_io()) if (!open_io())

View file

@ -165,7 +165,7 @@ open_socket(int family)
case IPADDR_INET4: case IPADDR_INET4:
case IPADDR_INET6: case IPADDR_INET6:
port = CNF_GetCommandPort(); port = CNF_GetCommandPort();
if (port == 0 || !SCK_IsFamilySupported(family)) if (port == 0 || !SCK_IsIpFamilyEnabled(family))
return INVALID_SOCK_FD; return INVALID_SOCK_FD;
CNF_GetBindCommandAddress(family, &local_addr.ip_addr); CNF_GetBindCommandAddress(family, &local_addr.ip_addr);
@ -237,22 +237,17 @@ do_size_checks(void)
/* ================================================== */ /* ================================================== */
void void
CAM_Initialise(int family) CAM_Initialise(void)
{ {
assert(!initialised); assert(!initialised);
assert(sizeof (permissions) / sizeof (permissions[0]) == N_REQUEST_TYPES); assert(sizeof (permissions) / sizeof (permissions[0]) == N_REQUEST_TYPES);
do_size_checks(); do_size_checks();
initialised = 1; initialised = 1;
sock_fdu = INVALID_SOCK_FD; sock_fdu = INVALID_SOCK_FD;
sock_fd4 = INVALID_SOCK_FD; sock_fd4 = open_socket(IPADDR_INET4);
sock_fd6 = INVALID_SOCK_FD; sock_fd6 = open_socket(IPADDR_INET6);
if (family == IPADDR_UNSPEC || family == IPADDR_INET4)
sock_fd4 = open_socket(IPADDR_INET4);
if (family == IPADDR_UNSPEC || family == IPADDR_INET6)
sock_fd6 = open_socket(IPADDR_INET6);
access_auth_table = ADF_CreateTable(); access_auth_table = ADF_CreateTable();
} }

View file

@ -29,7 +29,7 @@
#include "addressing.h" #include "addressing.h"
extern void CAM_Initialise(int family); extern void CAM_Initialise(void);
extern void CAM_Finalise(void); extern void CAM_Finalise(void);

6
main.c
View file

@ -568,11 +568,11 @@ int main
SRC_Initialise(); SRC_Initialise();
RCL_Initialise(); RCL_Initialise();
KEY_Initialise(); KEY_Initialise();
SCK_Initialise(); SCK_Initialise(address_family);
/* Open privileged ports before dropping root */ /* Open privileged ports before dropping root */
CAM_Initialise(address_family); CAM_Initialise();
NIO_Initialise(address_family); NIO_Initialise();
NCR_Initialise(); NCR_Initialise();
CNF_SetupAccessRestrictions(); CNF_SetupAccessRestrictions();

View file

@ -86,7 +86,7 @@ open_socket(int family, int local_port, int client_only, IPSockAddr *remote_addr
int sock_fd, sock_flags, events = SCH_FILE_INPUT; int sock_fd, sock_flags, events = SCH_FILE_INPUT;
IPSockAddr local_addr; IPSockAddr local_addr;
if (!SCK_IsFamilySupported(family)) if (!SCK_IsIpFamilyEnabled(family))
return INVALID_SOCK_FD; return INVALID_SOCK_FD;
if (!client_only) if (!client_only)
@ -152,7 +152,7 @@ close_socket(int sock_fd)
/* ================================================== */ /* ================================================== */
void void
NIO_Initialise(int family) NIO_Initialise(void)
{ {
int server_port, client_port; int server_port, client_port;
@ -191,25 +191,18 @@ NIO_Initialise(int family)
server_sock_ref4 = 0; server_sock_ref4 = 0;
server_sock_ref6 = 0; server_sock_ref6 = 0;
if (family == IPADDR_UNSPEC || family == IPADDR_INET4) { if (permanent_server_sockets && server_port) {
if (permanent_server_sockets && server_port) server_sock_fd4 = open_socket(IPADDR_INET4, server_port, 0, NULL);
server_sock_fd4 = open_socket(IPADDR_INET4, server_port, 0, NULL); server_sock_fd6 = open_socket(IPADDR_INET6, server_port, 0, NULL);
if (!separate_client_sockets) {
if (client_port != server_port || !server_port)
client_sock_fd4 = open_socket(IPADDR_INET4, client_port, 1, NULL);
else
client_sock_fd4 = server_sock_fd4;
}
} }
if (family == IPADDR_UNSPEC || family == IPADDR_INET6) { if (!separate_client_sockets) {
if (permanent_server_sockets && server_port) if (client_port != server_port || !server_port) {
server_sock_fd6 = open_socket(IPADDR_INET6, server_port, 0, NULL); client_sock_fd4 = open_socket(IPADDR_INET4, client_port, 1, NULL);
if (!separate_client_sockets) { client_sock_fd6 = open_socket(IPADDR_INET6, client_port, 1, NULL);
if (client_port != server_port || !server_port) } else {
client_sock_fd6 = open_socket(IPADDR_INET6, client_port, 1, NULL); client_sock_fd4 = server_sock_fd4;
else client_sock_fd6 = server_sock_fd6;
client_sock_fd6 = server_sock_fd6;
} }
} }

View file

@ -33,7 +33,7 @@
#include "addressing.h" #include "addressing.h"
/* Function to initialise the module. */ /* Function to initialise the module. */
extern void NIO_Initialise(int family); extern void NIO_Initialise(void);
/* Function to finalise the module */ /* Function to finalise the module */
extern void NIO_Finalise(void); extern void NIO_Finalise(void);

View file

@ -258,7 +258,7 @@ open_socket(int family, int port)
IPSockAddr local_addr; IPSockAddr local_addr;
int sock_fd; int sock_fd;
if (!SCK_IsFamilySupported(family)) if (!SCK_IsIpFamilyEnabled(family))
return INVALID_SOCK_FD; return INVALID_SOCK_FD;
CNF_GetBindAddress(family, &local_addr.ip_addr); CNF_GetBindAddress(family, &local_addr.ip_addr);

View file

@ -82,6 +82,10 @@ struct MessageHeader {
static int initialised; static int initialised;
/* Flags indicating in which IP families sockets can be requested */
static int ip4_enabled;
static int ip6_enabled;
/* Flags supported by socket() */ /* Flags supported by socket() */
static int supported_socket_flags; static int supported_socket_flags;
@ -412,10 +416,14 @@ open_ip_socket(IPSockAddr *remote_addr, IPSockAddr *local_addr, int type, int fl
switch (family) { switch (family) {
case IPADDR_INET4: case IPADDR_INET4:
if (!ip4_enabled)
return INVALID_SOCK_FD;
domain = AF_INET; domain = AF_INET;
break; break;
#ifdef FEAT_IPV6 #ifdef FEAT_IPV6
case IPADDR_INET6: case IPADDR_INET6:
if (!ip6_enabled)
return INVALID_SOCK_FD;
domain = AF_INET6; domain = AF_INET6;
break; break;
#endif #endif
@ -1090,8 +1098,15 @@ send_message(int sock_fd, SCK_Message *message, int flags)
/* ================================================== */ /* ================================================== */
void void
SCK_Initialise(void) SCK_Initialise(int family)
{ {
ip4_enabled = family == IPADDR_INET4 || family == IPADDR_UNSPEC;
#ifdef FEAT_IPV6
ip6_enabled = family == IPADDR_INET6 || family == IPADDR_UNSPEC;
#else
ip6_enabled = 0;
#endif
recv_messages = ARR_CreateInstance(sizeof (struct Message)); recv_messages = ARR_CreateInstance(sizeof (struct Message));
ARR_SetSize(recv_messages, MAX_RECV_MESSAGES); ARR_SetSize(recv_messages, MAX_RECV_MESSAGES);
recv_headers = ARR_CreateInstance(sizeof (struct MessageHeader)); recv_headers = ARR_CreateInstance(sizeof (struct MessageHeader));
@ -1131,15 +1146,13 @@ SCK_Finalise(void)
/* ================================================== */ /* ================================================== */
int int
SCK_IsFamilySupported(int family) SCK_IsIpFamilyEnabled(int family)
{ {
switch (family) { switch (family) {
case IPADDR_INET4: case IPADDR_INET4:
return 1; return ip4_enabled;
case IPADDR_INET6: case IPADDR_INET6:
#ifdef FEAT_IPV6 return ip6_enabled;
return 1;
#endif
default: default:
return 0; return 0;
} }

View file

@ -73,14 +73,15 @@ typedef struct {
int descriptor; int descriptor;
} SCK_Message; } SCK_Message;
/* Initialisation function */ /* Initialisation function (the specified IP family is enabled,
extern void SCK_Initialise(void); or all if IPADDR_UNSPEC) */
extern void SCK_Initialise(int family);
/* Finalisation function */ /* Finalisation function */
extern void SCK_Finalise(void); extern void SCK_Finalise(void);
/* Check if support for the IP family was enabled in the build */ /* Check if support for the IP family is enabled */
extern int SCK_IsFamilySupported(int family); extern int SCK_IsIpFamilyEnabled(int family);
/* Get the 0.0.0.0/::0 or 127.0.0.1/::1 address */ /* Get the 0.0.0.0/::0 or 127.0.0.1/::1 address */
extern void SCK_GetAnyLocalIPAddress(int family, IPAddr *local_addr); extern void SCK_GetAnyLocalIPAddress(int family, IPAddr *local_addr);

View file

@ -112,7 +112,7 @@ DNS_Name2IPAddressAsync(const char *name, DNS_NameResolveHandler handler, void *
#ifndef FEAT_CMDMON #ifndef FEAT_CMDMON
void void
CAM_Initialise(int family) CAM_Initialise(void)
{ {
} }
@ -174,7 +174,7 @@ NCR_CheckAccessRestriction(IPAddr *ip_addr)
} }
void void
NIO_Initialise(int family) NIO_Initialise(void)
{ {
} }

View file

@ -322,7 +322,7 @@ test_unit(void)
TST_RegisterDummyDrivers(); TST_RegisterDummyDrivers();
SCH_Initialise(); SCH_Initialise();
SRC_Initialise(); SRC_Initialise();
NIO_Initialise(IPADDR_UNSPEC); NIO_Initialise();
NCR_Initialise(); NCR_Initialise();
REF_Initialise(); REF_Initialise();

View file

@ -44,7 +44,7 @@ test_unit(void)
LCL_Initialise(); LCL_Initialise();
SCH_Initialise(); SCH_Initialise();
SRC_Initialise(); SRC_Initialise();
NIO_Initialise(IPADDR_UNSPEC); NIO_Initialise();
NCR_Initialise(); NCR_Initialise();
NSR_Initialise(); NSR_Initialise();