]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - net.c
net: Let maksock() callers perform flowopt cleanup.
[paraslash.git] / net.c
diff --git a/net.c b/net.c
index 28d11d664c937404e034d65760c00e5fa8cc1a3a..70cf6a87dfb27bbba74912bb50467a0a74f966bd 100644 (file)
--- a/net.c
+++ b/net.c
@@ -333,7 +333,14 @@ static void flowopt_setopts(int sockfd, struct flowopts *fo)
                }
 }
 
-static void flowopt_cleanup(struct flowopts *fo)
+/**
+ * Deallocate all resources of a flowopts structure.
+ *
+ * \param fo A pointer as returned from flowopt_new().
+ *
+ * It's OK to pass \p NULL here in which case the function does nothing.
+ */
+void flowopt_cleanup(struct flowopts *fo)
 {
        struct pre_conn_opt *cur, *next;
 
@@ -412,7 +419,7 @@ static int lookup_address(unsigned l4type, bool passive, const char *host,
  *
  * bind(2) is called on passive sockets, and connect(2) on active sockets. The
  * algorithm tries all possible address combinations until it succeeds. If \a
- * fo is supplied, options are set and cleanup is performed.
+ * fo is supplied, options are set but cleanup must be performed in the caller.
  *
  * \return File descriptor on success, \p E_MAKESOCK on errors.
  *
@@ -422,39 +429,36 @@ 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)
 {
-       int ret = -E_MAKESOCK, on = 1, sockfd = -1;
+       int ret = -E_MAKESOCK, on = 1;
 
        for (; ai; ai = ai->ai_next) {
+               int fd;
                ret = socket(ai->ai_family, sock_type(l4type), l4type);
                if (ret < 0)
                        continue;
-               sockfd = ret;
-               flowopt_setopts(sockfd, fo);
-               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));
-                               return ret;
-                       }
-                       if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
-                               close(sockfd);
-                               continue;
-                       }
-                       return sockfd;
-               } else {
-                       if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
-                               return sockfd;
-                       close(sockfd);
+               fd = ret;
+               flowopt_setopts(fd, fo);
+               if (!passive) {
+                       if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0)
+                               return fd;
+                       close(fd);
+                       continue;
+               }
+               /*
+                * Reuse the address on passive sockets to avoid failure on
+                * restart (protocols using listen()) and when creating
+                * multiple listener instances (UDP multicast).
+                */
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
+                               sizeof(on)) == -1) {
+                       close(fd);
+                       continue;
+               }
+               if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
+                       close(fd);
+                       continue;
                }
+               return fd;
        }
        return -E_MAKESOCK;
 }
@@ -488,7 +492,6 @@ int makesock(unsigned l4type, bool passive, const char *host, uint16_t port_numb
                ret = makesock_addrinfo(l4type, passive, ai, fo);
        if (ai)
                freeaddrinfo(ai);
-       flowopt_cleanup(fo);
        if (ret < 0) {
                PARA_ERROR_LOG("can not create %s socket %s#%d.\n",
                layer4_name(l4type), host? host : (passive?