]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Remove fr_socket()
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Jun 2017 21:21:47 +0000 (17:21 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Jun 2017 21:21:47 +0000 (17:21 -0400)
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.

src/include/libradius.h
src/lib/util/socket.c
src/main/listen.c
src/main/radclient.c
src/modules/proto_bfd/proto_bfd.c
src/modules/proto_dhcp/dhcpclient.c
src/modules/rlm_radius_client/rlm_radius_client.c
src/modules/rlm_replicate/rlm_replicate.c
src/tests/util/radius1_test.c
src/tests/util/radius_schedule_test.c

index c383e70ec0f1442c9b9c75fcfac74fc96389a430..dcb5985f4712b8f83b530abe00cf3904f91c20d0 100644 (file)
@@ -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
index 770ed01632d23e21e58cab1202c5d2a8f3efac2e..ea9616db2d13b541608f4735c290616a942b0b4e 100644 (file)
@@ -24,7 +24,6 @@
  *
  * @copyright 2015 The FreeRADIUS project
  */
-
 #include <freeradius-devel/libradius.h>
 #include <freeradius-devel/udpfromto.h>
 
@@ -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;
-}
index 40de6491e1bd8d5662260b482975ac264066902c..1a428616f5e4d2cf6b96618830d85d4abce24630 100644 (file)
@@ -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;
index 64e337694aaf6863868d6b26d9c6126cb37a28df..5e71bbd27291f7254c24468a5146bc951e699bf0 100644 (file)
@@ -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);
index e7c8ce1596fe2a7c6b3ef80e2b8bd118de531396..78cead9fab0138827b9584e25fc1e6285c123bc7 100644 (file)
@@ -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;
 
index 1581a0a0578c61d3c74a06b1a50fd5b9841f5a00..1c688f564f281f935320f9a7da2163689777771c 100644 (file)
@@ -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".
index 24dbb78262836de77b4629223a799876d3135c8b..ee5a6badb4425c236c4c981bc49ba5da50f6cb44 100644 (file)
@@ -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.
index 919d6cb627341d87f9f21c272b5b6dbf592f1ef4..8b5ff8b7f9e79da4241ea64c0d9a16f89b20e14a 100644 (file)
@@ -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;
index af135c02afa6112c3a71885a903823aff52ce5f4..95508992cb472d53ceb3d7060064a58547956cc2 100644 (file)
@@ -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);
        }
index 291998ed972eac4925dffe57525bf6ce172323c7..9e094551b6f416700436f963f4ace8d1517f451c 100644 (file)
@@ -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);
        }