]> jfr.im git - solanum.git/blobdiff - librb/src/commio.c
remove RB_IPV6
[solanum.git] / librb / src / commio.c
index 21bc226ec68a37891e4e27dac06efaa2d54b5b1a..a131b7eb91202a383146fbeae217333596d0a51c 100644 (file)
@@ -21,8 +21,8 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
  *  USA
  *
- *  $Id: commio.c 26254 2008-12-10 04:04:38Z androsyn $
  */
+
 #include <librb_config.h>
 #include <rb_lib.h>
 #include <commio-int.h>
@@ -69,9 +69,7 @@ int rb_maxconnections = 0;
 
 static PF rb_connect_timeout;
 static PF rb_connect_tryconnect;
-#ifdef RB_IPV6
 static void mangle_mapped_sockaddr(struct sockaddr *in);
-#endif
 
 #ifndef HAVE_SOCKETPAIR
 static int rb_inet_socketpair(int d, int type, int protocol, rb_platform_fd_t sv[2]);
@@ -110,6 +108,16 @@ free_fds(void)
        RB_DLINK_FOREACH_SAFE(ptr, next, closed_list.head)
        {
                F = ptr->data;
+
+               number_fd--;
+
+#ifdef _WIN32
+               if(F->type & (RB_FD_SOCKET | RB_FD_PIPE))
+                       closesocket(F->fd);
+               else
+#endif
+                       close(F->fd);
+
                rb_dlinkDelete(ptr, &closed_list);
                rb_bh_free(fd_heap, F);
        }
@@ -336,11 +344,14 @@ rb_accept_tryaccept(rb_fde_t *F, void *data)
 {
        struct rb_sockaddr_storage st;
        rb_fde_t *new_F;
-       rb_socklen_t addrlen = sizeof(st);
+       rb_socklen_t addrlen;
        int new_fd;
 
        while(1)
        {
+               memset(&st, 0, sizeof(st));
+               addrlen = sizeof(st);
+
                new_fd = accept(F->fd, (struct sockaddr *)&st, &addrlen);
                rb_get_errno();
                if(new_fd < 0)
@@ -369,9 +380,7 @@ rb_accept_tryaccept(rb_fde_t *F, void *data)
                        rb_close(new_F);
                }
 
-#ifdef RB_IPV6
                mangle_mapped_sockaddr((struct sockaddr *)&st);
-#endif
 
                if(F->accept->precb != NULL)
                {
@@ -410,10 +419,10 @@ rb_accept_tcp(rb_fde_t *F, ACPRE * precb, ACCB * callback, void *data)
 
 /*
  * void rb_connect_tcp(rb_platform_fd_t fd, struct sockaddr *dest,
- *                       struct sockaddr *clocal, int socklen,
+ *                       struct sockaddr *clocal,
  *                       CNCB *callback, void *data, int timeout)
  * Input: An fd to connect with, a host and port to connect to,
- *        a local sockaddr to connect from + length(or NULL to use the
+ *        a local sockaddr to connect from (or NULL to use the
  *        default), a callback, the data to pass into the callback, the
  *        address family.
  * Output: None.
@@ -423,7 +432,7 @@ rb_accept_tcp(rb_fde_t *F, ACPRE * precb, ACCB * callback, void *data)
  */
 void
 rb_connect_tcp(rb_fde_t *F, struct sockaddr *dest,
-              struct sockaddr *clocal, int socklen, CNCB * callback, void *data, int timeout)
+              struct sockaddr *clocal, CNCB * callback, void *data, int timeout)
 {
        if(F == NULL)
                return;
@@ -442,7 +451,7 @@ rb_connect_tcp(rb_fde_t *F, struct sockaddr *dest,
         * virtual host IP, for completeness.
         *   -- adrian
         */
-       if((clocal != NULL) && (bind(F->fd, clocal, socklen) < 0))
+       if((clocal != NULL) && (bind(F->fd, clocal, GET_SS_LEN(clocal)) < 0))
        {
                /* Failure, call the callback with RB_ERR_BIND */
                rb_connect_callback(F, RB_ERR_BIND);
@@ -695,7 +704,6 @@ rb_socket(int family, int sock_type, int proto, const char *note)
        if(rb_unlikely(fd < 0))
                return NULL;    /* errno will be passed through, yay.. */
 
-#if defined(RB_IPV6) && defined(IPV6_V6ONLY)
        /*
         * Make sure we can take both IPv4 and IPv6 connections
         * on an AF_INET6 socket
@@ -703,7 +711,7 @@ rb_socket(int family, int sock_type, int proto, const char *note)
        if(family == AF_INET6)
        {
                int off = 1;
-               if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)) == -1)
+               if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &off, sizeof(off)) == -1)
                {
                        rb_lib_log("rb_socket: Could not set IPV6_V6ONLY option to 1 on FD %d: %s",
                                   fd, strerror(errno));
@@ -711,7 +719,6 @@ rb_socket(int family, int sock_type, int proto, const char *note)
                        return NULL;
                }
        }
-#endif
 
        F = rb_open(fd, RB_FD_SOCKET, note);
        if(F == NULL)
@@ -736,15 +743,11 @@ rb_socket(int family, int sock_type, int proto, const char *note)
  * If a sockaddr_storage is AF_INET6 but is a mapped IPv4
  * socket manged the sockaddr.
  */
-#ifdef RB_IPV6
 static void
 mangle_mapped_sockaddr(struct sockaddr *in)
 {
        struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
 
-       if(in->sa_family == AF_INET)
-               return;
-
        if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr))
        {
                struct sockaddr_in in4;
@@ -754,9 +757,7 @@ mangle_mapped_sockaddr(struct sockaddr *in)
                in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3];
                memcpy(in, &in4, sizeof(struct sockaddr_in));
        }
-       return;
 }
-#endif
 
 /*
  * rb_listen() - listen on a port
@@ -886,17 +887,8 @@ rb_close(rb_fde_t *F)
                ClearFDOpen(F);
        }
 
-       number_fd--;
-
-#ifdef _WIN32
-       if(type & (RB_FD_SOCKET | RB_FD_PIPE))
-       {
-               closesocket(fd);
-               return;
-       }
-       else
-#endif
-               close(fd);
+       if(type & RB_FD_LISTEN)
+               shutdown(fd, SHUT_RDWR);
 }
 
 
@@ -970,7 +962,7 @@ rb_fd_ssl(rb_fde_t *F)
        return 0;
 }
 
-int
+rb_platform_fd_t
 rb_get_fd(rb_fde_t *F)
 {
        if(F == NULL)
@@ -1180,9 +1172,7 @@ inetntoa(const char *in)
  */
 
 static const char *inet_ntop4(const unsigned char *src, char *dst, unsigned int size);
-#ifdef RB_IPV6
 static const char *inet_ntop6(const unsigned char *src, char *dst, unsigned int size);
-#endif
 
 /* const char *
  * inet_ntop4(src, dst, size)
@@ -1209,7 +1199,6 @@ inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
  * author:
  *     Paul Vixie, 1996.
  */
-#ifdef RB_IPV6
 static const char *
 inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
 {
@@ -1314,27 +1303,24 @@ inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
        }
        return memcpy(dst, tmp, tp - tmp);
 }
-#endif
 
 int
 rb_inet_pton_sock(const char *src, struct sockaddr *dst)
 {
        if(rb_inet_pton(AF_INET, src, &((struct sockaddr_in *)dst)->sin_addr))
        {
-               ((struct sockaddr_in *)dst)->sin_port = 0;
-               ((struct sockaddr_in *)dst)->sin_family = AF_INET;
+               SET_SS_FAMILY(dst, AF_INET);
+               SET_SS_PORT(dst, 0);
                SET_SS_LEN(dst, sizeof(struct sockaddr_in));
                return 1;
        }
-#ifdef RB_IPV6
        else if(rb_inet_pton(AF_INET6, src, &((struct sockaddr_in6 *)dst)->sin6_addr))
        {
-               ((struct sockaddr_in6 *)dst)->sin6_port = 0;
-               ((struct sockaddr_in6 *)dst)->sin6_family = AF_INET6;
+               SET_SS_FAMILY(dst, AF_INET6);
+               SET_SS_PORT(dst, 0);
                SET_SS_LEN(dst, sizeof(struct sockaddr_in6));
                return 1;
        }
-#endif
        return 0;
 }
 
@@ -1345,16 +1331,11 @@ rb_inet_ntop_sock(struct sockaddr *src, char *dst, unsigned int size)
        {
        case AF_INET:
                return (rb_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr, dst, size));
-               break;
-#ifdef RB_IPV6
        case AF_INET6:
                return (rb_inet_ntop
                        (AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr, dst, size));
-               break;
-#endif
        default:
                return NULL;
-               break;
        }
 }
 
@@ -1373,7 +1354,6 @@ rb_inet_ntop(int af, const void *src, char *dst, unsigned int size)
        {
        case AF_INET:
                return (inet_ntop4(src, dst, size));
-#ifdef RB_IPV6
        case AF_INET6:
                if(IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src) ||
                   IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src))
@@ -1382,9 +1362,6 @@ rb_inet_ntop(int af, const void *src, char *dst, unsigned int size)
                                 s6_addr[12], dst, size));
                else
                        return (inet_ntop6(src, dst, size));
-
-
-#endif
        default:
                return (NULL);
        }
@@ -1460,7 +1437,6 @@ inet_pton4(const char *src, unsigned char *dst)
        return (1);
 }
 
-#ifdef RB_IPV6
 /* int
  * inet_pton6(src, dst)
  *     convert presentation level address to network order binary form.
@@ -1573,7 +1549,7 @@ inet_pton6(const char *src, unsigned char *dst)
        memcpy(dst, tmp, IN6ADDRSZ);
        return (1);
 }
-#endif
+
 int
 rb_inet_pton(int af, const char *src, void *dst)
 {
@@ -1581,7 +1557,6 @@ rb_inet_pton(int af, const char *src, void *dst)
        {
        case AF_INET:
                return (inet_pton4(src, dst));
-#ifdef RB_IPV6
        case AF_INET6:
                /* Somebody might have passed as an IPv4 address this is sick but it works */
                if(inet_pton4(src, dst))
@@ -1592,7 +1567,6 @@ rb_inet_pton(int af, const char *src, void *dst)
                }
                else
                        return (inet_pton6(src, dst));
-#endif
        default:
                return (-1);
        }
@@ -2096,7 +2070,6 @@ rb_setup_fd(rb_fde_t *F)
 }
 
 
-
 int
 rb_ignore_errno(int error)
 {
@@ -2223,6 +2196,7 @@ rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasiz
 
        if(count > 0)
        {
+               size_t ucount = (size_t)count;
                int len = CMSG_SPACE(sizeof(int) * count);
                char buf[len];
 
@@ -2233,7 +2207,7 @@ rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasiz
                cmsg->cmsg_type = SCM_RIGHTS;
                cmsg->cmsg_len = CMSG_LEN(sizeof(int) * count);
 
-               for(unsigned int i = 0; i < count; i++)
+               for(size_t i = 0; i < ucount; i++)
                {
                        ((int *)CMSG_DATA(cmsg))[i] = rb_get_fd(F[i]);
                }
@@ -2242,7 +2216,7 @@ rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasiz
        }
        return sendmsg(rb_get_fd(xF), &msg, MSG_NOSIGNAL);
 }
-#else
+#else /* defined(HAVE_SENDMSG) && !defined(WIN32) */
 #ifndef _WIN32
 int
 rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int nfds)
@@ -2257,5 +2231,30 @@ rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasiz
        errno = ENOSYS;
        return -1;
 }
-#endif
-#endif
+#endif /* _WIN32 */
+#endif /* defined(HAVE_SENDMSG) && !defined(WIN32) */
+
+int
+rb_ipv4_from_ipv6(const struct sockaddr_in6 *restrict ip6, struct sockaddr_in *restrict ip4)
+{
+       int i;
+
+       if (!memcmp(ip6->sin6_addr.s6_addr, "\x20\x02", 2))
+       {
+               /* 6to4 and similar */
+               memcpy(&ip4->sin_addr, ip6->sin6_addr.s6_addr + 2, 4);
+       }
+       else if (!memcmp(ip6->sin6_addr.s6_addr, "\x20\x01\x00\x00", 4))
+       {
+               /* Teredo */
+               for (i = 0; i < 4; i++)
+                       ((uint8_t *)&ip4->sin_addr)[i] = 0xFF ^
+                               ip6->sin6_addr.s6_addr[12 + i];
+       }
+       else
+               return 0;
+       SET_SS_LEN(ip4, sizeof(struct sockaddr_in));
+       ip4->sin_family = AF_INET;
+       ip4->sin_port = 0;
+       return 1;
+}