added gnutls backend and moved backend code into new files
[ircu2.10.12-pk.git] / ircd / os_generic.c
index bdcda7c32a6e7bf75ca1e8a0e28c3f3c75f36268..9ddb3c40bd686bb83124e62485cc4a2f3581271a 100644 (file)
@@ -178,13 +178,12 @@ int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, i
 int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd, int family)
 {
     assert(irc != 0);
+    memset(v4, 0, sizeof(*v4));
     v4->sin_family = AF_INET;
     if (irc) {
         assert(!irc->addr.in6_16[0] && !irc->addr.in6_16[1] && !irc->addr.in6_16[2] && !irc->addr.in6_16[3] && !irc->addr.in6_16[4] && (!irc->addr.in6_16[5] || irc->addr.in6_16[5] == 0xffff));
         memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
         v4->sin_port = htons(irc->port);
-    } else{
-        memset(&v4, 0, sizeof(v4));
     }
     (void)compat_fd; (void)family;
     return sizeof(*v4);
@@ -450,9 +449,13 @@ IOResult os_recv_nonb(int fd, char* buf, unsigned int length,
   if (0 < (res = recv(fd, buf, length, 0))) {
     *count_out = (unsigned) res;
     return IO_SUCCESS;
+  } else if (res == 0) {
+    *count_out = 0;
+    errno = 0; /* or ECONNRESET? */
+    return IO_FAILURE;
   } else {
     *count_out = 0;
-    return (res < 0) && is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
+    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
 }
 
@@ -605,8 +608,8 @@ int os_socket(const struct irc_sockaddr* local, int type, const char* port_name,
   }
   if (local) {
 #if defined(IPV6_V6ONLY)
-    int on = 0;
-    if (family == 0 && irc_in_addr_unspec(&local->addr))
+    int on = 1;
+    if (family == AF_INET6 && irc_in_addr_unspec(&local->addr))
       setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
 #endif
     if (bind(fd, (struct sockaddr*)&addr, size)) {