net: makesock(): Combine code for passive sockets.
[paraslash.git] / net.c
diff --git a/net.c b/net.c
index 740dfa182d4a162f2b493ac77ecebc8140c6f0ae..dfbbc1ee6b6135d74eb72fda7857f21843cdda81 100644 (file)
--- a/net.c
+++ b/net.c
  */
 #define _GNU_SOURCE
 
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <netdb.h>
 
 /* At least NetBSD needs these. */
@@ -417,7 +422,7 @@ static int lookup_address(unsigned l4type, bool passive, const char *host,
 static int makesock_addrinfo(unsigned l4type, bool passive, struct addrinfo *ai,
                struct flowopts *fo)
 {
-       struct addrinfo *local, *remote, *src = NULL, *dst = NULL;
+       struct addrinfo *local, *remote, *src, *dst;
        int ret = -E_MAKESOCK, on = 1, sockfd = -1;
 
        if (passive) {
@@ -430,41 +435,37 @@ static int makesock_addrinfo(unsigned l4type, bool passive, struct addrinfo *ai,
 
        /* Iterate over all src/dst combination, exhausting dst first */
        for (src = local, dst = remote; src != NULL || dst != NULL; /* no op */ ) {
-               if (src && dst && src->ai_family == AF_INET
-                               && dst->ai_family == AF_INET6)
-                       goto get_next_dst; /* v4 -> v6 is not possible */
-
                ret = socket(src ? src->ai_family : dst->ai_family,
                        sock_type(l4type), l4type);
                if (ret < 0)
                        goto get_next_dst;
                sockfd = ret;
-               /*
-                * Reuse the address on passive sockets to avoid failure on
-                * restart (protocols using listen()) and when creating
-                * multiple listener instances (UDP multicast).
-                */
-               if (passive && setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
-                                                 &on, sizeof(on)) == -1) {
-                       ret = -ERRNO_TO_PARA_ERROR(errno);
-                       close(sockfd);
-                       PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
-                               para_strerror(-ret));
-                       break;
-               }
                flowopt_setopts(sockfd, fo);
-
-               if (src) {
+               if (passive) {
+                       /*
+                        * Reuse the address on passive sockets to avoid
+                        * failure on restart (protocols using listen()) and
+                        * when creating multiple listener instances (UDP
+                        * multicast).
+                        */
+                       if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on,
+                                       sizeof(on)) == -1) {
+                               ret = -ERRNO_TO_PARA_ERROR(errno);
+                               close(sockfd);
+                               PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
+                                       para_strerror(-ret));
+                               break;
+                       }
                        if (bind(sockfd, src->ai_addr, src->ai_addrlen) < 0) {
                                close(sockfd);
                                goto get_next_src;
                        }
-                       if (!dst) /* bind-only completed successfully */
-                               break;
+                       /* bind completed successfully */
+                       break;
+               } else {
+                       if (connect(sockfd, dst->ai_addr, dst->ai_addrlen) == 0)
+                               break; /* connection completed successfully */
                }
-
-               if (dst && connect(sockfd, dst->ai_addr, dst->ai_addrlen) == 0)
-                       break; /* connection completed successfully */
                close(sockfd);
 get_next_dst:
                if (dst && (dst = dst->ai_next))