OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_ut_sa.c versions 1.15 and 1.16
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_ut_sa.c 1.15 -> 1.16

--- l2_ut_sa.c   2001/10/10 15:58:27     1.15
+++ l2_ut_sa.c   2001/10/26 10:59:47     1.16
@@ -51,6 +51,24 @@
 /* include own API header */
 #include "l2_ut_sa.h"
 
+/* boolean values */
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE  (!FALSE)
+#endif
+
+/* backward compatibility for AF_LOCAL */
+#if !defined(AF_LOCAL) && defined(AF_UNIX)
+#define AF_LOCAL AF_UNIX
+#endif
+
+/* backward compatibility for ssize_t */
+#if defined(HAVE_CONFIG_H) && !defined(HAVE_SSIZE_T)
+#define ssize_t long
+#endif
+
 /* system call structure declaration macros */
 #define SA_SC_DECLARE_0(rc_t, fn) \
     struct { \
@@ -178,23 +196,10 @@
     socklen_t        slBuf;            /* the length of "struct sockaddr_xx" */
 };
 
-/* boolean values */
-#ifndef FALSE
-#define FALSE (0)
-#endif
-#ifndef TRUE
-#define TRUE  (!FALSE)
-#endif
-
 /* handy struct timeval check */
 #define SA_TVISZERO(tv) \
     ((tv).tv_sec == 0 && (tv).tv_usec == 0)
 
-/* backward compatibility for AF_LOCAL */
-#if !defined(AF_LOCAL) && defined(AF_UNIX)
-#define AF_LOCAL AF_UNIX
-#endif
-
 /* convert Internet address from presentation to network format */
 static int sa_inet_pton(int family, const char *strptr, void *addrptr)
 {
@@ -419,6 +424,7 @@
 #ifdef AF_INET6
     struct sockaddr_in6 sa6;
 #endif
+    int bIPv6;
     struct hostent *he;
     struct servent *se;
     int bNumeric;
@@ -471,7 +477,7 @@
         }
         else
             cp = un.sun_path;
-        memcpy(un.sun_path, cpPath, n+1);
+        memcpy(cp, cpPath, n+1);
         un.sun_family = AF_LOCAL;
 
         /* provide results */
@@ -480,12 +486,36 @@
         sf = AF_LOCAL;
     }
     else if (strncmp(uri, "inet://", 7) == 0) {
-        /* parse URI */
+        /* parse URI into host, port and protocol parts */
         cpHost = (char *)(uri+7);
-        if ((cp = strrchr(cpHost, ':')) == NULL)
+        bIPv6 = FALSE;
+        if (cpHost[0] == '[') {
+            /* IPv6 address (see RFC2732) */
+#ifndef AF_INET6
             return SA_ERR_ARG;
-        *cp++ = '\0';
+#else
+            bIPv6 = TRUE;
+            cpHost++;
+            if ((cp = strchr(cpHost, ']')) == NULL)
+                return SA_ERR_ARG;
+            *cp++ = '\0';
+            if (*cp != ':')
+                return SA_ERR_ARG;
+            cp++;
+#endif
+        }
+        else {
+            /* IPv4 address or hostname */
+            if ((cp = strrchr(cpHost, ':')) == NULL)
+                return SA_ERR_ARG;
+            *cp++ = '\0';
+        }
         cpPort = cp;
+        cpProto = "tcp";
+        if ((cp = strchr(cpPort, '#')) != NULL) {
+            *cp++ = '\0';
+            cpProto = cp;
+        }
 
         /* resolve port */
         nPort = 0;
@@ -499,11 +529,6 @@
         if (bNumeric)
             nPort = atoi(cpPort);
         else {
-            cpProto = "tcp";
-            if ((cp = strchr(cpPort, '#')) != NULL) {
-                *cp++ = '\0';
-                cpProto = cp;
-            }
             if ((se = getservbyname(cpPort, cpProto)) == NULL)
                 return SA_ERR_SYS;
             nPort = ntohs(se->s_port);
@@ -515,9 +540,9 @@
         memset(&sa6, 0, sizeof(sa6));
 #endif
 
-        /* resolve host by trying to parse it as either directly a IPv4 or
-           IPv6 address or by resolving it to either a IPv4 or IPv6 address */
-        if (sa_inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
+        /* resolve host by trying to parse it as either directly an IPv4 or
+           IPv6 address or by resolving it to either an IPv4 or IPv6 address */
+        if (!bIPv6 && sa_inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
             sa4.sin_family = AF_INET;
             sa4.sin_port = htons(nPort);
             sa = (struct sockaddr *)&sa4;
@@ -525,7 +550,7 @@
             sf = AF_INET;
         }
 #ifdef AF_INET6
-        else if (sa_inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
+        else if (bIPv6 && sa_inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
             sa6.sin6_family = AF_INET6;
             sa6.sin6_port = htons(nPort);
             sa = (struct sockaddr *)&sa6;
@@ -578,13 +603,6 @@
 /* import "struct sockaddr" into address object */
 sa_rc_t sa_addr_s2a(sa_addr_t *saa, const struct sockaddr *sabuf, socklen_t salen)
 {
-    struct sockaddr_un *un;
-    struct sockaddr_in *sa4;
-#ifdef AF_INET6
-    struct sockaddr_in6 *sa6;
-#endif
-    int sf;
-
     /* argument sanity check(s) */
     if (saa == NULL || sabuf == NULL || salen == 0)
         return SA_ERR_ARG;
@@ -597,28 +615,8 @@
     memcpy(saa->saBuf, sabuf, salen);
     saa->slBuf = salen;
 
-    /* resolve family */
-    sf = 0;
-    if (sizeof(struct sockaddr_un) == salen) {
-        un = (struct sockaddr_un *)((void *)sabuf);
-        if (un->sun_family == AF_LOCAL)
-            sf = AF_LOCAL;
-    }
-    if (sf == 0 && sizeof(struct sockaddr_in) == salen) {
-        sa4 = (struct sockaddr_in *)((void *)sabuf);
-        if (sa4->sin_family == AF_INET)
-            sf = AF_INET;
-    }
-#ifdef AF_INET6
-    if (sf == 0 && sizeof(struct sockaddr_in6) == salen) {
-        sa6 = (struct sockaddr_in6 *)((void *)sabuf);
-        if (sa6->sin6_family == AF_INET6)
-            sf = AF_INET6;
-    }
-#endif
-    if (sf == 0)
-        return SA_ERR_ARG;
-    saa->nFamily = sf;
+    /* remember family */
+    saa->nFamily = sabuf->sa_family;
 
     return SA_OK;
 }
@@ -642,27 +640,31 @@
     /* export object contents */
     if (saa->nFamily == AF_LOCAL) {
         un = (struct sockaddr_un *)((void *)saa->saBuf);
-        sa_msnprintf(uribuf, sizeof(uribuf), "unix:%s", un->sun_path);
+        if (   (   saa->slBuf >= (socklen_t)(&(((struct sockaddr_un *)0)->sun_path[0]))
+                && un->sun_path[0] == '\0')
+            || saa->slBuf < sizeof(struct sockaddr_un))
+            /* in case the remote side of a Unix Domain socket was not
+               bound, a "struct sockaddr_un" can occur with a length less
+               than the expected one. Then there is actually no path at all. 
+               This has been verified under FreeBSD, Linux and Solaris. */
+            sa_msnprintf(uribuf, sizeof(uribuf), "unix:/NOT-BOUND");
+        else
+            sa_msnprintf(uribuf, sizeof(uribuf), "unix:%s", un->sun_path);
     }
-#ifdef AF_INET6
-    else if (saa->nFamily == AF_INET || saa->nFamily == AF_INET6) {
-#else
     else if (saa->nFamily == AF_INET) {
-#endif
-        if (saa->nFamily == AF_INET) {
-            sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
-            sa_inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
-            nPort = ntohs(sa4->sin_port);
-        }
-#ifdef AF_INET6
-        else {
-            sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
-            sa_inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
-            nPort = ntohs(sa6->sin6_port);
-        }
-#endif
+        sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
+        sa_inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
+        nPort = ntohs(sa4->sin_port);
         sa_msnprintf(uribuf, sizeof(uribuf), "inet://%s:%d", caHost, nPort);
     }
+#ifdef AF_INET6
+    else if (saa->nFamily == AF_INET6) {
+        sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
+        sa_inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
+        nPort = ntohs(sa6->sin6_port);
+        sa_msnprintf(uribuf, sizeof(uribuf), "inet://[%s]:%d", caHost, nPort);
+    }
+#endif
     else
         return SA_ERR_INT;
 
@@ -693,21 +695,23 @@
     const unsigned char *ucp1, *ucp2;
     unsigned int uc1, uc2, mask;
     size_t l1, l2;
-    int nFamily;
     int nBytes;
     int nBits;
+#ifdef AF_INET6
+    int i;
+    const unsigned char *ucp0;
+#endif
 
     /* argument sanity check(s) */
     if (saa1 == NULL || saa2 == NULL || prefixlen < -1)
         return SA_ERR_ARG;
 
-    /* match short circuiting */
-    if (saa1->nFamily != saa2->nFamily)
-        return SA_ERR_MTC;
+    /* short circuiting for wildcard matching */
+    if (prefixlen == 0)
+        return SA_OK;
 
     /* determine address representation pointer and size */
-    nFamily = saa1->nFamily;
-    if (nFamily == AF_LOCAL) {
+    if (saa1->nFamily == AF_LOCAL) {
         ucp1 = (const unsigned char *)(((struct sockaddr_un *)saa1->saBuf)->sun_path);
         ucp2 = (const unsigned char *)(((struct sockaddr_un *)saa2->saBuf)->sun_path);
         l1 = strlen(((struct sockaddr_un *)saa1->saBuf)->sun_path) * 8;
@@ -723,13 +727,38 @@
             nBits = prefixlen;
         }
     }
-    else if (nFamily == AF_INET) {
+#ifdef AF_INET6
+    else if (   (saa1->nFamily == AF_INET  && saa2->nFamily == AF_INET6)
+             || (saa1->nFamily == AF_INET6 && saa2->nFamily == AF_INET )) {
+        /* special case of comparing a regular IPv4 address (1.2.3.4) with an 
+           "IPv4-mapped IPv6 address" (::ffff:1.2.3.4). For details see RFC 2373. */
+        if (saa1->nFamily == AF_INET6) {
+            ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr);
+            ucp2 = (const unsigned char *)&(((struct sockaddr_in  *)saa2->saBuf)->sin_addr);
+            ucp0 = ucp1;
+            ucp1 += 12;
+        }
+        else {
+            ucp1 = (const unsigned char *)&(((struct sockaddr_in  *)saa1->saBuf)->sin_addr);
+            ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr);
+            ucp0 = ucp2;
+            ucp2 += 12;
+        }
+        for (i = 0; i < 10; i++)
+            if (ucp0[i] != 0x00)
+                return SA_ERR_MTC;
+        if (!(ucp0[10] == 0xFF && ucp0[11] == 0xFF))
+            return SA_ERR_MTC;
+        nBits = 32;
+    }
+#endif
+    else if (saa1->nFamily == AF_INET) {
         ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr);
         ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr);
         nBits = 32;
     }
 #ifdef AF_INET6
-    else if (nFamily == AF_INET6) {
+    else if (saa1->nFamily == AF_INET6) {
         ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr);
         ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr);
         nBits = 128;
@@ -1141,6 +1170,7 @@
         }
         else if (n == 0) {
             close(sa->fdSocket); /* stop TCP three-way handshake */
+            sa->fdSocket = -1;
             rv = SA_ERR_TMT;
             goto done;
         }
@@ -1158,6 +1188,7 @@
         /* optionally set errno */
         if (error != 0) {
             close(sa->fdSocket); /* just in case */
+            sa->fdSocket = -1;
             errno = error;
             rv = SA_ERR_SYS;
         }
@@ -1194,6 +1225,7 @@
     int n;
     fd_set fds;
     union {
+        struct sockaddr_un un;
         struct sockaddr_in sa4;
 #ifdef AF_INET6
         struct sockaddr_in6 sa6;
@@ -1502,6 +1534,7 @@
     char c;
     size_t n;
     size_t res;
+    sa_rc_t rv;
 
     /* argument sanity check(s) */
     if (sa == NULL || cpBuf == NULL || nBufReq == 0)
@@ -1519,9 +1552,12 @@
        buffers are enabled, this is not as stupid as it looks at the first
        hand and if buffers are disabled, there is no better solution
        anyway. */
+    rv = SA_OK;
     res = 0;
     while (res < (nBufReq-1)) {
-        sa_read(sa, &c, 1, &n);
+        rv = sa_read(sa, &c, 1, &n);
+        if (rv != SA_OK)
+            break;
         if (n <= 0)
             break;
         cpBuf[res++] = c;
@@ -1534,7 +1570,7 @@
     if (nBufRes != NULL)
         *nBufRes = res;
 
-    return SA_OK;
+    return rv;
 }
 
 /* internal raw write operation */

CVSTrac 2.0.1