]> git.meshlink.io Git - catta/blobdiff - src/socket.c
Fix compilation error caused by ACX_THREAD
[catta] / src / socket.c
index 1914316716861442ae149dcac1e6a2866ced1632..31adcf81a99e5080ccd7ea7af3e80be8c0bee1f4 100644 (file)
@@ -21,6 +21,8 @@
 #include <config.h>
 #endif
 
+#define __APPLE_USE_RFC_2292
+
 #include <inttypes.h>
 #include <errno.h>
 #include <string.h>
@@ -50,6 +52,7 @@
 #include "fdutil.h"
 #include "socket.h"
 #include "addr-util.h"
+#include "internal.h"
 
 /* this is a portability hack */
 #ifndef IPV6_ADD_MEMBERSHIP
@@ -104,7 +107,7 @@ static void ipv6_address_to_sockaddr(struct sockaddr_in6 *ret_sa, const CattaIPv
     memcpy(&ret_sa->sin6_addr, a, sizeof(CattaIPv6Address));
 }
 
-int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, int idx, int join) {
+int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, CattaIfIndex idx, int join) {
 #ifdef HAVE_STRUCT_IP_MREQN
     struct ip_mreqn mreq;
 #else
@@ -130,17 +133,17 @@ int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, int idx, int j
      * mcast groups when the iface is down, but don't allow rejoining
      * when it comes back up. This is an ugly workaround */
     if (join)
-        setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+        setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq));
 
-    if (setsockopt(fd, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
-        catta_log_warn("%s failed: %s", join ? "IP_ADD_MEMBERSHIP" : "IP_DROP_MEMBERSHIP", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
+        catta_log_warn("%s failed: %s", join ? "IP_ADD_MEMBERSHIP" : "IP_DROP_MEMBERSHIP", errnostrsocket());
         return -1;
     }
 
     return 0;
 }
 
-int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, int idx, int join) {
+int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, CattaIfIndex idx, int join) {
     struct ipv6_mreq mreq6;
     struct sockaddr_in6 sa6;
 
@@ -154,10 +157,10 @@ int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, int idx, int j
     mreq6.ipv6mr_interface = idx;
 
     if (join)
-        setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
+        setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (void *)&mreq6, sizeof(mreq6));
 
-    if (setsockopt(fd, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
-        catta_log_warn("%s failed: %s", join ? "IPV6_ADD_MEMBERSHIP" : "IPV6_DROP_MEMBERSHIP", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, (void *)&mreq6, sizeof(mreq6)) < 0) {
+        catta_log_warn("%s failed: %s", join ? "IPV6_ADD_MEMBERSHIP" : "IPV6_DROP_MEMBERSHIP", errnostrsocket());
         return -1;
     }
 
@@ -168,15 +171,15 @@ static int reuseaddr(int fd) {
     int yes;
 
     yes = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("SO_REUSEADDR failed: %s", strerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("SO_REUSEADDR failed: %s", errnostrsocket());
         return -1;
     }
 
 #ifdef SO_REUSEPORT
     yes = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("SO_REUSEPORT failed: %s", strerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("SO_REUSEPORT failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -190,10 +193,20 @@ static int bind_with_warn(int fd, const struct sockaddr *sa, socklen_t l) {
     assert(sa);
     assert(l > 0);
 
+#ifdef _WIN32
+    // Windows does not allow address reuse when SO_REUSEADDR was set after
+    // bind() on the first socket, so we must set it before.
+    // Note that this spoils the detection trickery below and the warning will
+    // not be logged.
+
+    if (reuseaddr(fd) < 0)
+        return -1;
+#endif
+
     if (bind(fd, sa, l) < 0) {
 
         if (errno != EADDRINUSE) {
-            catta_log_warn("bind() failed: %s", strerror(errno));
+            catta_log_warn("bind() failed: %s", errnostrsocket());
             return -1;
         }
 
@@ -205,7 +218,7 @@ static int bind_with_warn(int fd, const struct sockaddr *sa, socklen_t l) {
             return -1;
 
         if (bind(fd, sa, l) < 0) {
-            catta_log_warn("bind() failed: %s", strerror(errno));
+            catta_log_warn("bind() failed: %s", errnostrsocket());
             return -1;
         }
     } else {
@@ -226,30 +239,30 @@ static int ipv4_pktinfo(int fd) {
 
 #ifdef IP_PKTINFO
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_PKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_PKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #else
 
 #ifdef IP_RECVINTERFACE
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVINTERFACE failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVINTERFACE failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IP_RECVIF)
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVIF failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVIF failed: %s", errnostrsocket());
         return -1;
     }
 #endif
 
 #ifdef IP_RECVDSTADDR
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVDSTADDR failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVDSTADDR failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -258,8 +271,8 @@ static int ipv4_pktinfo(int fd) {
 
 #ifdef IP_RECVTTL
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVTTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVTTL failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -272,34 +285,34 @@ static int ipv6_pktinfo(int fd) {
 
 #ifdef IPV6_RECVPKTINFO
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVPKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVPKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_PKTINFO)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_PKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_PKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #endif
 
 #ifdef IPV6_RECVHOPS
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPS, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVHOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPS, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVHOPS failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_RECVHOPLIMIT)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVHOPLIMIT failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVHOPLIMIT failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_HOPLIMIT)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_HOPLIMIT failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_HOPLIMIT failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -313,25 +326,25 @@ int catta_open_socket_ipv4(int no_reuse) {
     uint8_t ttl, cyes;
 
     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IP_MULTICAST_TTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IP_MULTICAST_TTL failed: %s", errnostrsocket());
         goto fail;
     }
 
     ittl = 255;
-    if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) < 0) {
-        catta_log_warn("IP_TTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_TTL, (void *)&ittl, sizeof(ittl)) < 0) {
+        catta_log_warn("IP_TTL failed: %s", errnostrsocket());
         goto fail;
     }
 
     cyes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &cyes, sizeof(cyes)) < 0) {
-        catta_log_warn("IP_MULTICAST_LOOP failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&cyes, sizeof(cyes)) < 0) {
+        catta_log_warn("IP_MULTICAST_LOOP failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -351,12 +364,12 @@ int catta_open_socket_ipv4(int no_reuse) {
          goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -377,31 +390,31 @@ int catta_open_socket_ipv6(int no_reuse) {
     mdns_mcast_group_ipv6(&sa);
 
     if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IPV6_MULTICAST_HOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IPV6_MULTICAST_HOPS failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IPV6_UNICAST_HOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IPV6_UNICAST_HOPS failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_V6ONLY failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_V6ONLY failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_MULTICAST_LOOP failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_MULTICAST_LOOP failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -421,12 +434,12 @@ int catta_open_socket_ipv6(int no_reuse) {
         goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -451,12 +464,15 @@ static int sendmsg_loop(int fd, struct msghdr *msg, int flags) {
         if (errno == EINTR)
             continue;
 
-        if (errno != EAGAIN) {
+        if (errno != EAGAIN && errno != EWOULDBLOCK) {
             char where[64];
-            struct sockaddr_in *sin = msg->msg_name;
+            struct sockaddr *sa = msg->msg_name;
 
-            inet_ntop(sin->sin_family, &sin->sin_addr, where, sizeof(where));
-            catta_log_debug("sendmsg() to %s failed: %s", where, strerror(errno));
+            if(sa->sa_family == AF_INET)
+                inet_ntop(sa->sa_family, &((struct sockaddr_in *)sa)->sin_addr, where, sizeof(where));
+            else
+                inet_ntop(sa->sa_family, &((struct sockaddr_in6 *)sa)->sin6_addr, where, sizeof(where));
+            catta_log_debug("sendmsg() to %s failed: %s", where, errnostrsocket());
             return -1;
         }
 
@@ -530,13 +546,16 @@ int catta_send_dns_packet_ipv4(
 #ifdef HAVE_IPI_SPEC_DST
         if (src_address)
             pkti->ipi_spec_dst.s_addr = src_address->address;
+#else
+        if (src_address)
+            pkti->ipi_addr.s_addr = src_address->address;
 #endif
     }
 #elif defined(IP_MULTICAST_IF)
     if (src_address) {
         struct in_addr any = { INADDR_ANY };
-        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, src_address ? &src_address->address : &any, sizeof(struct in_addr)) < 0) {
-            catta_log_warn("IP_MULTICAST_IF failed: %s", strerror(errno));
+        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)(src_address ? &src_address->address : &any), sizeof(struct in_addr)) < 0) {
+            catta_log_warn("IP_MULTICAST_IF failed: %s", errnostrsocket());
             return -1;
         }
     }
@@ -598,6 +617,11 @@ int catta_send_dns_packet_ipv6(
     msg.msg_iovlen = 1;
     msg.msg_flags = 0;
 
+// TODO: don't ask me why, but Win8.1 64bit WSASendMsg() fails with an InvalidArgument error 10022 when IPv6 source address is specified ( everHannes / hannes.ahrens@everbase.net )
+#ifdef _WIN32
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+#else    
     if (iface > 0 || src_address) {
         struct in6_pktinfo *pkti;
 
@@ -621,6 +645,7 @@ int catta_send_dns_packet_ipv6(
         msg.msg_control = NULL;
         msg.msg_controllen = 0;
     }
+#endif
 
     return sendmsg_loop(fd, &msg, 0);
 }
@@ -646,7 +671,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv4(
     assert(fd >= 0);
 
     if (ioctl(fd, FIONREAD, &ms) < 0) {
-        catta_log_warn("ioctl(): %s", strerror(errno));
+        catta_log_warn("ioctl(): %s", errnostrsocket());
         goto fail;
     }
 
@@ -676,7 +701,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv4(
         links. (See #60) */
 
         if (errno != EAGAIN)
-            catta_log_warn("recvmsg(): %s", strerror(errno));
+            catta_log_warn("recvmsg(): %s", errnostrsocket());
 
         goto fail;
     }
@@ -807,7 +832,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv6(
     assert(fd >= 0);
 
     if (ioctl(fd, FIONREAD, &ms) < 0) {
-        catta_log_warn("ioctl(): %s", strerror(errno));
+        catta_log_warn("ioctl(): %s", errnostrsocket());
         goto fail;
     }
 
@@ -838,7 +863,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv6(
         links. (See #60) */
 
         if (errno != EAGAIN)
-            catta_log_warn("recvmsg(): %s", strerror(errno));
+            catta_log_warn("recvmsg(): %s", errnostrsocket());
 
         goto fail;
     }
@@ -914,7 +939,7 @@ int catta_open_unicast_socket_ipv4(void) {
     int fd = -1;
 
     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -922,7 +947,7 @@ int catta_open_unicast_socket_ipv4(void) {
     local.sin_family = AF_INET;
 
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
-        catta_log_warn("bind() failed: %s", strerror(errno));
+        catta_log_warn("bind() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -931,12 +956,12 @@ int catta_open_unicast_socket_ipv4(void) {
     }
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -954,13 +979,13 @@ int catta_open_unicast_socket_ipv6(void) {
     int fd = -1, yes;
 
     if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_V6ONLY failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_V6ONLY failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -968,7 +993,7 @@ int catta_open_unicast_socket_ipv6(void) {
     local.sin6_family = AF_INET6;
 
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
-        catta_log_warn("bind() failed: %s", strerror(errno));
+        catta_log_warn("bind() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -976,12 +1001,12 @@ int catta_open_unicast_socket_ipv6(void) {
         goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }