net: Let makesock() continue on setsockopt() failure.
[paraslash.git] / net.c
diff --git a/net.c b/net.c
index 740dfa182d4a162f2b493ac77ecebc8140c6f0ae..822f70def6aee8f6cf6e202832ab02c4553628b8 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,65 +422,37 @@ 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;
        int ret = -E_MAKESOCK, on = 1, sockfd = -1;
 
-       if (passive) {
-               local = ai;
-               remote = NULL;
-       } else {
-               local = NULL;
-               remote = 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);
+       for (; ai; ai = ai->ai_next) {
+               ret = socket(ai->ai_family, sock_type(l4type), l4type);
                if (ret < 0)
-                       goto get_next_dst;
+                       continue;
                sockfd = ret;
+               flowopt_setopts(sockfd, fo);
+               if (!passive) {
+                       if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
+                               return sockfd;
+                       close(sockfd);
+                       continue;
+               }
                /*
                 * 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);
+               if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on,
+                               sizeof(on)) == -1) {
                        close(sockfd);
-                       PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
-                               para_strerror(-ret));
-                       break;
-               }
-               flowopt_setopts(sockfd, fo);
-
-               if (src) {
-                       if (bind(sockfd, src->ai_addr, src->ai_addrlen) < 0) {
-                               close(sockfd);
-                               goto get_next_src;
-                       }
-                       if (!dst) /* bind-only completed successfully */
-                               break;
+                       continue;
                }
-
-               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))
+               if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
+                       close(sockfd);
                        continue;
-get_next_src:
-               if (src && (src = src->ai_next)) /* restart inner loop */
-                       dst = remote;
+               }
+               return sockfd;
        }
-       if (src == NULL && dst == NULL)
-               return ret < 0? ret : -E_MAKESOCK;
-       return sockfd;
+       return -E_MAKESOCK;
 }
 
 /**