From: Arran Cudbard-Bell Date: Mon, 5 Jun 2017 21:21:47 +0000 (-0400) Subject: Remove fr_socket() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c83dc9cea097373f009b77cf4c7d65fea106ec6;p=thirdparty%2Ffreeradius-server.git Remove fr_socket() Most of the calls use fr_socket_server_udp now. Which sort of works but isn't great. The issue is a lot of the code assumes unconnected UDP sockets, whereas it should be updated to use connected ones. Seems like connect()ing a UDP socket and then trying to set the destination IP address will probably produce obscure errors. --- diff --git a/src/include/libradius.h b/src/include/libradius.h index c383e70ec0f..dcb5985f471 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -247,7 +247,7 @@ unsigned int fr_fifo_num_elements(fr_fifo_t *fi); /* * socket.c */ -int fr_socket_ipaddr_is_inaddr_any(fr_ipaddr_t *ipaddr); + bool fr_socket_is_valid_proto(int proto); int fr_socket_client_unix(char const *path, bool async); @@ -257,11 +257,9 @@ int fr_socket_client_tcp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ uint16_t dst_port, bool async); int fr_socket_wait_for_connect(int sockfd, struct timeval const *timeout); -int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async); -int fr_socket_server_tcp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async); -int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface); - -int fr_socket(fr_ipaddr_t const *ipaddr, uint16_t port); +int fr_socket_server_udp(fr_ipaddr_t const *ipaddr, uint16_t *port, char const *port_name, bool async); +int fr_socket_server_tcp(fr_ipaddr_t const *ipaddr, uint16_t *port, char const *port_name, bool async); +int fr_socket_bind(int sockfd, fr_ipaddr_t const *ipaddr, uint16_t *port, char const *interface); #ifdef __cplusplus } #endif diff --git a/src/lib/util/socket.c b/src/lib/util/socket.c index 770ed01632d..ea9616db2d1 100644 --- a/src/lib/util/socket.c +++ b/src/lib/util/socket.c @@ -24,7 +24,6 @@ * * @copyright 2015 The FreeRADIUS project */ - #include #include @@ -59,7 +58,7 @@ static int socket_type_from_proto(int proto) * - > 0 the port port_name resolves to. * - < 0 on error. */ -static int socket_port_from_service(int proto, char const *port_name) +static uint16_t socket_port_from_service(int proto, char const *port_name) { struct servent *service; char const *proto_name; @@ -220,9 +219,9 @@ bool fr_socket_is_valid_proto(int proto) if (fr_blocking(sockfd) < 0) goto error; @endcode * - * @param path to the file bound to the unix socket. - * @param async Whether to set the socket to nonblocking, allowing use of - * #fr_socket_wait_for_connect. + * @param path to the file bound to the unix socket. + * @param async Whether to set the socket to nonblocking, allowing use of + * #fr_socket_wait_for_connect. * @return * - Socket FD on success. * - -1 on failure. @@ -298,11 +297,14 @@ int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async) } #endif /* WITH_SYS_UN_H */ -/** Establish a connected TCP socket +/** Establish a connected UDP socket + * + * Connected UDP sockets can be used with write(), unlike unconnected sockets + * which must be used with sendto and recvfrom. * * The following code demonstrates using this function with a connection timeout: @code {.c} - sockfd = fr_socket_client_tcp(NULL, ipaddr, port, true); + sockfd = fr_socket_client_udp(NULL, ipaddr, port, true); if (sockfd < 0) { fr_perror(); exit(1); @@ -317,27 +319,27 @@ int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async) if (fr_blocking(sockfd) < 0) goto error; @endcode * - * @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific - * address. - * @param dst_ipaddr Where to connect to. - * @param dst_port Where to connect to. - * @param async Whether to set the socket to nonblocking, allowing use of - * #fr_socket_wait_for_connect. + * @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific + * address. + * @param dst_ipaddr Where to send datagrams. + * @param dst_port Where to send datagrams. + * @param async Whether to set the socket to nonblocking, allowing use of + * #fr_socket_wait_for_connect. * @return - * - FD on success + * - FD on success. * - -1 on failure. */ -int fr_socket_client_tcp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async) +int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async) { int sockfd; - struct sockaddr_storage salocal; + struct sockaddr_storage salocal; socklen_t salen; if (!dst_ipaddr) return -1; - sockfd = socket(dst_ipaddr->af, SOCK_STREAM, 0); + sockfd = socket(dst_ipaddr->af, SOCK_DGRAM, 0); if (sockfd < 0) { - fr_strerror_printf("Error creating TCP socket: %s", fr_syserror(errno)); + fr_strerror_printf("Error creating UDP socket: %s", fr_syserror(errno)); return sockfd; } @@ -401,49 +403,46 @@ int fr_socket_client_tcp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_i return sockfd; } -/** Establish a connected UDP socket - * - * Connected UDP sockets can be used with write(), unlike unconnected sockets - * which must be used with sendto and recvfrom. +/** Establish a connected TCP socket * * The following code demonstrates using this function with a connection timeout: @code {.c} - sockfd = fr_socket_client_udp(NULL, ipaddr, port, true); + sockfd = fr_socket_client_tcp(NULL, ipaddr, port, true); if (sockfd < 0) { fr_perror(); exit(1); -} + } if ((errno == EINPROGRESS) && (fr_socket_wait_for_connect(sockfd, timeout) < 0)) { error: fr_perror(); close(sockfd); goto error; -} -//Optionally, if blocking operation is required + } + //Optionally, if blocking operation is required if (fr_blocking(sockfd) < 0) goto error; @endcode * - * @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific - * address. - * @param dst_ipaddr Where to send datagrams. - * @param dst_port Where to send datagrams. - * @param async Whether to set the socket to nonblocking, allowing use of - * #fr_socket_wait_for_connect. + * @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific + * address. + * @param dst_ipaddr Where to connect to. + * @param dst_port Where to connect to. + * @param async Whether to set the socket to nonblocking, allowing use of + * #fr_socket_wait_for_connect. * @return - * - FD on success. + * - FD on success * - -1 on failure. */ -int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async) +int fr_socket_client_tcp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async) { int sockfd; - struct sockaddr_storage salocal; + struct sockaddr_storage salocal; socklen_t salen; if (!dst_ipaddr) return -1; - sockfd = socket(dst_ipaddr->af, SOCK_DGRAM, 0); + sockfd = socket(dst_ipaddr->af, SOCK_STREAM, 0); if (sockfd < 0) { - fr_strerror_printf("Error creating UDP socket: %s", fr_syserror(errno)); + fr_strerror_printf("Error creating TCP socket: %s", fr_syserror(errno)); return sockfd; } @@ -571,10 +570,13 @@ int fr_socket_wait_for_connect(int sockfd, struct timeval const *timeout) } } -/** Open an IPv4/IPv6 UDP socket +/** Open an IPv4/IPv6 unconnected UDP socket * - * @param[in] ipaddr The IP address to listen on - * @param[in,out] port the port to listen on. If *port == 0, the resolved + * Function name is a bit of a misnomer as it can also be used to create client sockets too, + * such is the nature of UDP. + * + * @param[in] src_ipaddr The IP address to listen on + * @param[in,out] src_port the port to listen on. If *port == 0, the resolved * service port will be written here. * @param[in] port_name if *port == 0, the name of the port * @param[in] async whether we block or not on reads and writes @@ -582,14 +584,17 @@ int fr_socket_wait_for_connect(int sockfd, struct timeval const *timeout) * - Socket FD on success. * - -1 on failure. */ -int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async) +int fr_socket_server_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async) { - int sockfd; + int sockfd; + uint16_t my_port = 0; + + if (src_port) my_port = *src_port; /* * Check IP looks OK */ - if (!ipaddr || ((ipaddr->af != AF_INET) && (ipaddr->af != AF_INET6))) { + if (!src_ipaddr || ((src_ipaddr->af != AF_INET) && (src_ipaddr->af != AF_INET6))) { fr_strerror_printf("No address specified"); return -1; } @@ -597,24 +602,19 @@ int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, /* * Check we have a port value or stuff we can resolve to a port */ - if (!*port) { + if (!my_port && port_name) { int ret; - if (!port_name) { - fr_strerror_printf("No port or port_name specified"); - return -1; - } - ret = socket_port_from_service(IPPROTO_UDP, port_name); if (ret < 0) return -1; - *port = ret; + my_port = ret; } /* * Open the socket */ - sockfd = socket(ipaddr->af, socket_type_from_proto(IPPROTO_UDP), IPPROTO_UDP); + sockfd = socket(src_ipaddr->af, socket_type_from_proto(IPPROTO_UDP), IPPROTO_UDP); if (sockfd < 0) { fr_strerror_printf("Failed creating UNIX socket: %s", fr_syserror(errno)); return -1; @@ -647,7 +647,7 @@ int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, /* * Make sure we don't get v4 and v6 packets on inaddr_any sockets. */ - if (socket_inaddr_any_v6only(sockfd, ipaddr)) goto error; + if (socket_inaddr_any_v6only(sockfd, src_ipaddr)) goto error; #if (defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)) || defined(IP_DONTFRAG) /* @@ -655,7 +655,7 @@ int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, * routers don't have good support for fragmented UDP * packets. */ - if ((proto == IPPROTO_UDP) && (ipaddr->af == AF_INET)) { + if (src_ipaddr->af == AF_INET) { int flag; # if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) @@ -706,28 +706,34 @@ int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, } #endif + *src_port = my_port; + return sockfd; } /** Open an IPv4/IPv6 TCP socket * - * @param[in] ipaddr The IP address to listen on - * @param[in,out] port the port to listen on. If *port == 0, the resolved + * @param[in] src_ipaddr The IP address to listen on + * @param[in,out] src_port the port to listen on. If *port == 0, the resolved * service port will be written here. + * NULL if any port is allowed. * @param[in] port_name if *port == 0, the name of the port * @param[in] async whether we block or not on reads and writes * @return * - Socket FD on success. * - -1 on failure. */ -int fr_socket_server_tcp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async) +int fr_socket_server_tcp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async) { - int sockfd; + int sockfd; + uint16_t my_port = 0; + + if (src_port) my_port = *src_port; /* * Check IP looks OK */ - if (!ipaddr || ((ipaddr->af != AF_INET) && (ipaddr->af != AF_INET6))) { + if (!src_ipaddr || ((src_ipaddr->af != AF_INET) && (src_ipaddr->af != AF_INET6))) { fr_strerror_printf("No address specified"); return -1; } @@ -735,24 +741,19 @@ int fr_socket_server_tcp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, /* * Check we have a port value or stuff we can resolve to a port */ - if (!*port) { + if (!my_port && port_name) { int ret; - if (!port_name) { - fr_strerror_printf("No port or port_name specified"); - return -1; - } - ret = socket_port_from_service(IPPROTO_TCP, port_name); if (ret < 0) return -1; - *port = ret; + my_port = ret; } /* * Open the socket */ - sockfd = socket(ipaddr->af, socket_type_from_proto(IPPROTO_TCP), IPPROTO_TCP); + sockfd = socket(src_ipaddr->af, socket_type_from_proto(IPPROTO_TCP), IPPROTO_TCP); if (sockfd < 0) { fr_strerror_printf("Failed creating UNIX socket: %s", fr_syserror(errno)); return -1; @@ -775,7 +776,7 @@ int fr_socket_server_tcp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, /* * Make sure we don't get v4 and v6 packets on inaddr_any sockets. */ - if (socket_inaddr_any_v6only(sockfd, ipaddr)) goto error; + if (socket_inaddr_any_v6only(sockfd, src_ipaddr)) goto error; { int on = 1; @@ -787,32 +788,37 @@ int fr_socket_server_tcp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, } } + if (src_port) *src_port = my_port; + return sockfd; } -/** Bind to an IPv4/IPv6, UDP/TCP socket +/** Bind a UDP/TCP v4/v6 socket to a given ipaddr src port, and interface. * - * Use one of - * - fr_socket_server_udp + * Use one of: + * - fr_socket_client_udp - for a connected socket. + * - fr_socket_server_udp - for non-connected socket. * - fr_socket_server_tcp - * - * To open a file descriptor, then call this function to bind the socket to an IP address. + * ...to open a file descriptor, then call this function to bind the socket to an IP address. * * @param[in] sockfd the socket which opened by fr_socket_server_*. - * @param[in,out] ipaddr The IP address to bind to - * @param[in] port the port to bind to + * @param[in,out] src_ipaddr The IP address to bind to. + * @param[in] src_port the port to bind to. NULL if any port is allowed. * @param[in] interface to bind to. * @return * - 0 on success * - -1 on failure. */ -int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface) +int fr_socket_bind(int sockfd, fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *interface) { int rcode; - uint16_t my_port; + uint16_t my_port = 0; + fr_ipaddr_t my_ipaddr = *src_ipaddr; struct sockaddr_storage salocal; socklen_t salen; + if (src_port) my_port = *src_port; + /* * Bind to a device BEFORE touching IP addresses. */ @@ -842,10 +848,10 @@ int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const * been defined, set the scope to the scope of * the interface. */ - if (ipaddr->af == AF_INET6) { - if (ipaddr->scope_id == 0) { - ipaddr->scope_id = if_nametoindex(interface); - if (ipaddr->scope_id == 0) { + if (my_ipaddr.af == AF_INET6) { + if (my_ipaddr.scope_id == 0) { + my_ipaddr.scope_id = if_nametoindex(interface); + if (my_ipaddr.scope_id == 0) { fr_strerror_printf("Failed finding interface %s: %s", interface, fr_syserror(errno)); return -1; @@ -866,15 +872,10 @@ int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const #endif } /* else no interface */ - if (!port) return 0; - /* * Set up sockaddr stuff. */ - my_port = *port; - if (!fr_ipaddr_to_sockaddr(ipaddr, my_port, &salocal, &salen)) { - return -1; - } + if (!fr_ipaddr_to_sockaddr(&my_ipaddr, my_port, &salocal, &salen)) return -1; rcode = bind(sockfd, (struct sockaddr *) &salocal, salen); if (rcode < 0) return rcode; @@ -891,111 +892,8 @@ int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const return -1; } - if (!fr_ipaddr_from_sockaddr(&salocal, salen, ipaddr, &my_port)) return -1; - - *port = my_port; + if (!fr_ipaddr_from_sockaddr(&salocal, salen, &my_ipaddr, &my_port)) return -1; + if (src_port) *src_port = my_port; return 0; } - -/* - * Open a socket on the given IP and port. - */ -int fr_socket(fr_ipaddr_t const *ipaddr, uint16_t port) -{ - int sockfd; - struct sockaddr_storage salocal; - socklen_t salen; - - sockfd = socket(ipaddr->af, SOCK_DGRAM, 0); - if (sockfd < 0) { - fr_strerror_printf("cannot open socket: %s", fr_syserror(errno)); - return sockfd; - } - -#ifdef WITH_UDPFROMTO - /* - * Initialize udpfromto for all sockets. - */ - if (udpfromto_init(sockfd) != 0) { - close(sockfd); - fr_strerror_printf("cannot initialize udpfromto: %s", fr_syserror(errno)); - return -1; - } -#endif - - if (!fr_ipaddr_to_sockaddr(ipaddr, port, &salocal, &salen)) { - return sockfd; - } - -#ifdef HAVE_STRUCT_SOCKADDR_IN6 - if (ipaddr->af == AF_INET6) { - /* - * Listening on '::' does NOT get you IPv4 to - * IPv6 mapping. You've got to listen on an IPv4 - * address, too. This makes the rest of the server - * design a little simpler. - */ -#ifdef IPV6_V6ONLY - - if (IN6_IS_ADDR_UNSPECIFIED(&ipaddr->addr.v6)) { - int on = 1; - - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, - (char *)&on, sizeof(on)) < 0) { - close(sockfd); - fr_strerror_printf("Failed setting sockopt " - "IPPROTO_IPV6 - IPV6_V6ONLY" - ": %s", fr_syserror(errno)); - return -1; - } - } -#endif /* IPV6_V6ONLY */ - } -#endif /* HAVE_STRUCT_SOCKADDR_IN6 */ - -#if (defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)) || defined(IP_DONTFRAG) - if (ipaddr->af == AF_INET) { - int flag; - -#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) - - /* - * Disable PMTU discovery. On Linux, this - * also makes sure that the "don't fragment" - * flag is zero. - */ - flag = IP_PMTUDISC_DONT; - if (setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &flag, sizeof(flag)) < 0) { - close(sockfd); - fr_strerror_printf("Failed setting sockopt " - "IPPROTO_IP - IP_MTU_DISCOVER: %s", - fr_syserror(errno)); - return -1; - } -#endif - -#if defined(IP_DONTFRAG) - /* - * Ensure that the "don't fragment" flag is zero. - */ - flag = 0; - if (setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &flag, sizeof(flag)) < 0) { - close(sockfd); - fr_strerror_printf("Failed setting sockopt " - "IPPROTO_IP - IP_DONTFRAG: %s", - fr_syserror(errno)); - return -1; - } -#endif - } -#endif - - if (bind(sockfd, (struct sockaddr *) &salocal, salen) < 0) { - close(sockfd); - fr_strerror_printf("Cannot bind socket: %s", fr_syserror(errno)); - return -1; - } - - return sockfd; -} diff --git a/src/main/listen.c b/src/main/listen.c index 40de6491e1b..1a428616f5e 100644 --- a/src/main/listen.c +++ b/src/main/listen.c @@ -2714,7 +2714,8 @@ static int init_pcap(rad_listen_t *this) */ static int listen_bind(rad_listen_t *this) { - int rcode, port; + int rcode; + uint16_t port = 0; listen_socket_t *sock = this->data; char const *port_name = NULL; @@ -2822,7 +2823,7 @@ static int listen_bind(rad_listen_t *this) */ port = sock->my_port; rad_suid_up(); - rcode = fr_socket_server_bind(this->fd, &sock->my_ipaddr, &port, sock->interface); + rcode = fr_socket_bind(this->fd, &sock->my_ipaddr, &port, sock->interface); rad_suid_down(); sock->my_port = port; @@ -3011,14 +3012,15 @@ rad_listen_t *proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t } else #endif { - this->fd = fr_socket(&home->src_ipaddr, src_port); - if (this->fd >= 0) fr_nonblock(this->fd); + this->fd = fr_socket_server_udp(&home->src_ipaddr, &src_port, NULL, true); + if ((this->fd >= 0) && (fr_socket_bind(this->fd, &home->src_ipaddr, &src_port, NULL) < 0)) { + this->fd = -1; + } } if (this->fd < 0) { this->print(this, buffer,sizeof(buffer)); - ERROR("Failed opening new proxy socket '%s' : %s", - buffer, fr_strerror()); + PERROR("Failed opening new proxy socket '%s'", buffer); home->last_failed_open = now; listen_free(&this); return NULL; diff --git a/src/main/radclient.c b/src/main/radclient.c index 64e337694aa..5e71bbd2729 100644 --- a/src/main/radclient.c +++ b/src/main/radclient.c @@ -829,6 +829,7 @@ static int send_one_packet(rc_request_t *request) rcode = fr_packet_list_id_alloc(packet_list, ipproto, &request->packet, NULL); if (!rcode) { int mysockfd; + uint16_t port = 0; #ifdef WITH_TCP if (proto) { @@ -837,11 +838,17 @@ static int send_one_packet(rc_request_t *request) request->packet->dst_port, false); } else #endif - mysockfd = fr_socket(&client_ipaddr, 0); - if (mysockfd < 0) { - ERROR("Failed opening socket"); - exit(1); + sockfd = fr_socket_server_udp(&client_ipaddr, &port, NULL, true); + if (sockfd < 0) { + ERROR("Error opening socket: %s", fr_strerror()); + return 0; + } + + if (fr_socket_bind(sockfd, &client_ipaddr, &port, NULL) < 0) { + ERROR("Error binding socket: %s", fr_strerror()); + return 0; } + if (!fr_packet_list_socket_add(packet_list, mysockfd, ipproto, &request->packet->dst_ipaddr, request->packet->dst_port, NULL)) { @@ -1429,10 +1436,16 @@ int main(int argc, char **argv) sockfd = fr_socket_client_tcp(NULL, &server_ipaddr, server_port, false); } else #endif - sockfd = fr_socket(&client_ipaddr, client_port); + + sockfd = fr_socket_server_udp(&client_ipaddr, &client_port, NULL, false); if (sockfd < 0) { - ERROR("Error opening socket"); - exit(1); + ERROR("Error opening socket: %s", fr_strerror()); + return -1; + } + + if (fr_socket_bind(sockfd, &client_ipaddr, &client_port, NULL) < 0) { + ERROR("Error binding socket: %s", fr_strerror()); + return -1; } packet_list = fr_packet_list_create(1); diff --git a/src/modules/proto_bfd/proto_bfd.c b/src/modules/proto_bfd/proto_bfd.c index e7c8ce1596f..78cead9fab0 100644 --- a/src/modules/proto_bfd/proto_bfd.c +++ b/src/modules/proto_bfd/proto_bfd.c @@ -1742,7 +1742,7 @@ static int bfd_socket_parse(CONF_SECTION *cs, rad_listen_t *this) static int bfd_socket_open(CONF_SECTION *cs, rad_listen_t *this) { int rcode; - int port; + uint16_t port; bfd_socket_t *sock = this->data; port = sock->my_port; @@ -1758,7 +1758,7 @@ static int bfd_socket_open(CONF_SECTION *cs, rad_listen_t *this) } rad_suid_up(); - rcode = fr_socket_server_bind(this->fd, &sock->my_ipaddr, &port, sock->interface); + rcode = fr_socket_bind(this->fd, &sock->my_ipaddr, &port, sock->interface); rad_suid_down(); sock->my_port = port; diff --git a/src/modules/proto_dhcp/dhcpclient.c b/src/modules/proto_dhcp/dhcpclient.c index 1581a0a0578..1c688f564f2 100644 --- a/src/modules/proto_dhcp/dhcpclient.c +++ b/src/modules/proto_dhcp/dhcpclient.c @@ -384,17 +384,26 @@ static int send_with_socket(RADIUS_PACKET **reply, RADIUS_PACKET *request) #ifdef HAVE_LINUX_IF_PACKET_H if (raw_mode) { sockfd = fr_socket_packet(iface_ind, &ll); + if (sockfd < 0) { + ERROR("Error opening socket"); + return -1; + } } else #endif { - sockfd = fr_socket(&request->src_ipaddr, request->src_port); - } + sockfd = fr_socket_server_udp(&request->src_ipaddr, &request->src_port, NULL, false); + if (sockfd < 0) { + ERROR("Error opening socket: %s", fr_strerror()); + return -1; + } - if (sockfd < 0) { - ERROR("Error opening socket"); - return -1; + if (fr_socket_bind(sockfd, &request->src_ipaddr, &request->src_port, NULL) < 0) { + ERROR("Error binding socket: %s", fr_strerror()); + return -1; + } } + /* * Set option 'receive timeout' on socket. * Note: in case of a timeout, the error will be "Resource temporarily unavailable". diff --git a/src/modules/rlm_radius_client/rlm_radius_client.c b/src/modules/rlm_radius_client/rlm_radius_client.c index 24dbb782628..ee5a6badb44 100644 --- a/src/modules/rlm_radius_client/rlm_radius_client.c +++ b/src/modules/rlm_radius_client/rlm_radius_client.c @@ -348,16 +348,16 @@ static int mod_fd_add(fr_event_list_t *el, rlm_radius_client_conn_t *conn, rlm_r return -1; } - sockfd = fr_socket(server_ipaddr, server_port); + sockfd = fr_socket_server_udp(server_ipaddr, &server_port, NULL, true); if (sockfd < 0) { - ERROR("Error opening socket"); + PERROR("Error opening socket"); return 0; } - /* - * Always set the socket as non-blocking. - */ - fr_nonblock(sockfd); + if (fr_socket_bind(sockfd, server_ipaddr, &server_port, NULL) < 0) { + PERROR("Error binding socket"); + return 0; + } /* * The default destination is anywhere. diff --git a/src/modules/rlm_replicate/rlm_replicate.c b/src/modules/rlm_replicate/rlm_replicate.c index 919d6cb6273..8b5ff8b7f9e 100644 --- a/src/modules/rlm_replicate/rlm_replicate.c +++ b/src/modules/rlm_replicate/rlm_replicate.c @@ -184,12 +184,18 @@ static rlm_rcode_t replicate_packet(UNUSED void const *instance, REQUEST *reques */ if (pass1) { packet->id = fr_rand() & 0xff; - packet->sockfd = fr_socket(&home->src_ipaddr, 0); + packet->sockfd = fr_socket_server_udp(&home->src_ipaddr, NULL, NULL, false); if (packet->sockfd < 0) { RPEDEBUG("Failed opening socket"); rcode = RLM_MODULE_FAIL; goto done; } + if (fr_socket_bind(packet->sockfd, &home->src_ipaddr, NULL, NULL) < 0) { + RPEDEBUG("Failed binding socket"); + rcode = RLM_MODULE_FAIL; + goto done; + } + pass1 = false; } else { size_t i; diff --git a/src/tests/util/radius1_test.c b/src/tests/util/radius1_test.c index af135c02afa..95508992cb4 100644 --- a/src/tests/util/radius1_test.c +++ b/src/tests/util/radius1_test.c @@ -53,7 +53,7 @@ RCSID("$Id$") * Declare these here until we move all of the new field to the REQUEST. */ extern int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async); -extern int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface); +extern int fr_socket_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface); typedef struct fr_schedule_worker_t { @@ -242,7 +242,7 @@ static void master_process(TALLOC_CTX *ctx) exit(1); } - if (fr_socket_server_bind(sockfd, &my_ipaddr, &my_port, NULL) < 0) { + if (fr_socket_bind(sockfd, &my_ipaddr, &my_port, NULL) < 0) { fprintf(stderr, "radius_test: Failed binding to socket: %s\n", fr_strerror()); exit(1); } diff --git a/src/tests/util/radius_schedule_test.c b/src/tests/util/radius_schedule_test.c index 291998ed972..9e094551b6f 100644 --- a/src/tests/util/radius_schedule_test.c +++ b/src/tests/util/radius_schedule_test.c @@ -64,7 +64,7 @@ static fr_packet_ctx_t packet_ctx = { 0 }; * Declare these here until we move all of the new field to the REQUEST. */ extern int fr_socket_server_udp(fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async); -extern int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface); +extern int fr_socket_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface); extern int fr_fault_setup(char const *cmd, char const *program); static fr_transport_final_t test_process(REQUEST *request, fr_transport_action_t action) @@ -245,7 +245,7 @@ int main(int argc, char *argv[]) exit(1); } - if (fr_socket_server_bind(sockfd, &my_ipaddr, &my_port, NULL) < 0) { + if (fr_socket_bind(sockfd, &my_ipaddr, &my_port, NULL) < 0) { fprintf(stderr, "radius_test: Failed binding to socket: %s\n", fr_strerror()); exit(1); }