net: fix broken dccp_available_ccids()
[paraslash.git] / net.c
diff --git a/net.c b/net.c
index b9729b6988f894a3e346a591b477ed0fb9012149..f34ab8522eaf7b36b1bc5996c226cc5cd8b0bcb0 100644 (file)
--- a/net.c
+++ b/net.c
@@ -436,6 +436,7 @@ int makesock(unsigned l4type, bool passive,
                if (passive && setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
                                                  &on, sizeof(on)) == -1) {
                        rc = errno;
+                       close(sockfd);
                        PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
                                       strerror(rc));
                        return -ERRNO_TO_PARA_ERROR(rc);
@@ -775,30 +776,35 @@ int para_accept(int fd, void *addr, socklen_t size)
 }
 
 /**
- * Probe the list of DCCP CCIDs supported locally by the host.
- * \param ccids Array to be filled in.
- * \param nccids Length of \a ccids.
- * \return Pointer to \a ccids, NULL on failure.
+ * Probe the list of DCCP CCIDs configured on this host.
+ * \param ccid_array Pointer to return statically allocated array in.
+ * \return Number of elements returned in \a ccid_array or error.
  *
  * NB: This feature is only available on Linux > 2.6.30; on older kernels
  * ENOPROTOOPT ("Protocol not available") will be returned.
  */
-const uint8_t *dccp_available_ccids(uint8_t *ccids, uint8_t *nccids)
+int dccp_available_ccids(uint8_t **ccid_array)
 {
-       int fd = makesock(IPPROTO_DCCP, 1, NULL, 0, NULL);
+       static uint8_t ccids[DCCP_MAX_HOST_CCIDS];
+       socklen_t nccids = sizeof(ccids);
+       int ret, fd;
 
-       if (fd < 0)
-               return NULL;
+       ret = fd = makesock(IPPROTO_DCCP, 1, NULL, 0, NULL);
+       if (ret < 0)
+               return ret;
 
        if (getsockopt(fd, SOL_DCCP, DCCP_SOCKOPT_AVAILABLE_CCIDS,
-                                       ccids, (socklen_t *)nccids) < 0) {
+                                               ccids, &nccids) < 0) {
+               ret = errno;
+               close(fd);
                PARA_ERROR_LOG("No DCCP_SOCKOPT_AVAILABLE_CCIDS: %s\n",
-                               strerror(errno));
-               *nccids = 0;
+                               strerror(ret));
+               return -ERRNO_TO_PARA_ERROR(ret);
        }
-       close(fd);
 
-       return *nccids ? ccids : NULL;
+       close(fd);
+       *ccid_array = ccids;
+       return nccids;
 }
 
 /**