[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r10326: First bare stubs of ipv6 work: commit some (untested, hence (in tor/trunk: . doc src/common)



Author: nickm
Date: 2007-05-25 14:22:37 -0400 (Fri, 25 May 2007)
New Revision: 10326

Modified:
   tor/trunk/
   tor/trunk/configure.in
   tor/trunk/doc/TODO
   tor/trunk/src/common/compat.c
   tor/trunk/src/common/compat.h
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
Log:
 r12955@catbus:  nickm | 2007-05-25 13:17:30 -0400
 First bare stubs of ipv6 work: commit some (untested, hence doublessly broken) implementations of inet_ntop/pton for systems that lack them.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12955] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/configure.in
===================================================================
--- tor/trunk/configure.in	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/configure.in	2007-05-25 18:22:37 UTC (rev 10326)
@@ -152,7 +152,7 @@
 dnl Check for functions before libevent, since libevent-1.2 apparently
 dnl exports strlcpy without defining it in a header.
 
-AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit strlcat strlcpy strtoull ftello getaddrinfo localtime_r gmtime_r memmem strtok_r)
+AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit strlcat strlcpy strtoull ftello getaddrinfo localtime_r gmtime_r memmem strtok_r inet_pton inet_ntop)
 
 if test $enable_threads = "yes"; then
   AC_CHECK_HEADERS(pthread.h)

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/doc/TODO	2007-05-25 18:22:37 UTC (rev 10326)
@@ -238,6 +238,12 @@
     - Let controller set router flags for authority to transmit, and for
       client to use.
     - Support relaying streams to ipv6.
+      - Internal code support for ipv6:
+        o Clone ipv6 functions (inet_ntop, inet_pton) where they don't exist.
+        - Most address variables need to become sockaddrs.
+        - Teach resolving code how to handle ipv6.
+        - Teach exit policies about ipv6 (consider ipv4/ipv6 interaction!)
+        - ...
     - Let servers decide to support BEGIN_DIR but not DirPort.
     - Tor should bind its ports before dropping privs, so users don't
       have to do the ipchains dance.

Modified: tor/trunk/src/common/compat.c
===================================================================
--- tor/trunk/src/common/compat.c	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/src/common/compat.c	2007-05-25 18:22:37 UTC (rev 10326)
@@ -807,6 +807,167 @@
 #endif
 }
 
+/** DOCDOC */
+const char *
+tor_inet_ntop(int af, const void *src, char *dst, size_t len)
+{
+#ifdef HAVE_INET_NTOP
+  return inet_ntop(af,src,dst,(socklen_t)len);
+#else
+  /* XXXX needs testing. !!!! */
+  if (af == AF_INET) {
+    if (tor_inet_ntoa(src, dst, len) < 0)
+      return NULL;
+    else
+      return dst;
+  } else if (af == AF_INET6) {
+    const struct in6_addr *addr = src;
+    char buf[64], *cp;
+    int longestGapLen = 0, longestGapPos = -1, i,
+      curGapPos = -1, curGapLen = 0;
+    uint16_t words[8];
+    for (i = 0; i < 8; ++i) {
+      words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
+    }
+    if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
+        words[4] == 0 && (words[5] == 0 || words[5] == 0xffff) && words[6]) {
+      /* This is an IPv4 address. */
+      tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
+                   addr->s6_addr[12], addr->s6_addr[13],
+                   addr->s6_addr[14], addr->s6_addr[15]);
+      if (strlen(buf) > len)
+        return NULL;
+      strlcpy(dst, buf, len);
+      return dst;
+    }
+    i = 0;
+    while (i < 8) {
+      if (words[i] == 0) {
+        curGapPos = i++;
+        curGapLen = 1;
+        while (i<8 && words[i] == 0) {
+          ++i; ++curGapLen;
+        }
+        if (curGapLen > longestGapLen) {
+          longestGapPos = curGapPos;
+          longestGapLen = curGapLen;
+        }
+      } else {
+        ++i;
+      }
+    }
+    cp = buf;
+    for (i = 0; i < 8; ++i) {
+      if (words[i] == 0 && longestGapPos == i) {
+        *cp++ = ':';
+        *cp++ = ':';
+        while (i < 8 && words[i] == 0)
+          ++i;
+        --i; /* to compensate for loop increment. */
+      } else {
+        tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
+        cp += strlen(cp);
+        if (i != 7)
+          *cp++ = ':';
+      }
+    }
+    if (strlen(buf) > len)
+      return NULL;
+    strlcpy(dst, buf, len);
+    return dst;
+  } else {
+    return NULL;
+  }
+#endif
+}
+
+/** DOCDOC */
+int
+tor_inet_pton(int af, const char *src, void *dst)
+{
+#ifdef HAVE_INET_PTON
+  return inet_pton(af, src, dst);
+#else
+  /* XXXX needs testing. !!!! */
+  if (af == AF_INET) {
+    return tor_inet_aton(src, dst);
+  } else if (af == AF_INET6) {
+    struct in6_addr *out = dst;
+    uint16_t words[8];
+    struct in_addr in;
+    int gapPos = -1, i, setWords=0;
+    const char *dot = strchr(src, '.');
+    const char *eow; /* end of words. */
+    if (dot == src)
+      return 0;
+    else if (!dot)
+      eow = src+strlen(src);
+    else {
+      uint32_t a;
+      for (eow = dot-1; eow >= src && TOR_ISDIGIT(*eow); --eow)
+        ;
+      ++eow;
+
+      if (inet_aton(eow, &in) != 1)
+        return 0;
+      a = ntohl(in.s_addr);
+      words[6] = a >> 16;
+      words[7] = a & 0xFFFF;
+      setWords += 2;
+    }
+
+    i = 0;
+    while (src < eow) {
+      if (i > 7)
+        return 0;
+      if (TOR_ISXDIGIT(*src)) {
+        char *next;
+        int r = strtol(src, &next, 16);
+        if (next > 4+src)
+          return 0;
+        if (next == src)
+          return 0;
+        if (r<0 || r>65536)
+          return 0;
+
+        words[i++] = (uint16_t)r;
+        setWords++;
+        src = next;
+        if (*src != ':')
+          return 0;
+        ++src;
+      } else if (*src == ':' && i > 0 && gapPos==-1) {
+        gapPos = i;
+        ++src;
+      } else if (*src == ':' && i == 0 && src[1] == ':') {
+        gapPos = i;
+        src += 2;
+      } else {
+        return 0;
+      }
+    }
+
+    if (setWords > 8 || (setWords < 8 && gapPos == -1))
+      return 0;
+
+    if (gapPos >= 0) {
+      int gapLen = 8 - setWords;
+      memmove(&words[gapPos+gapLen], &words[gapPos],
+              sizeof(uint16_t)*(8-gapPos));
+    }
+    for (i = 0; i < 8; ++i) {
+      out->s6_addr[2*i  ] = words[i] >> 8;
+      out->s6_addr[2*i+1] = words[i] & 0xff;
+    }
+
+    return 1;
+  } else {
+    return -1;
+  }
+#endif
+}
+
+
 /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
  * *addr to the proper IP address, in network byte order.  Returns 0
  * on success, -1 on failure; 1 on transient failure.

Modified: tor/trunk/src/common/compat.h
===================================================================
--- tor/trunk/src/common/compat.h	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/src/common/compat.h	2007-05-25 18:22:37 UTC (rev 10326)
@@ -32,6 +32,9 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
 #include <stdarg.h>
 
 #ifndef NULL_REP_IS_ZERO_BYTES
@@ -241,8 +244,17 @@
 typedef int socklen_t;
 #endif
 
+#ifndef HAVE_STRUCT_IN6_ADDR
+struct in6_addr
+{
+  uint8_t s6_addr[16];
+};
+#endif
+
 struct in_addr;
 int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
+const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
+int tor_inet_pton(int af, const char *src, void *dst);
 int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
 void set_socket_nonblocking(int socket);
 int tor_socketpair(int family, int type, int protocol, int fd[2]);

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/src/common/util.c	2007-05-25 18:22:37 UTC (rev 10326)
@@ -1952,7 +1952,7 @@
  * <b>buf</b>.
  */
 int
-tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len)
+tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
 {
   uint32_t a = ntohl(in->s_addr);
   return tor_snprintf(buf, buf_len, "%d.%d.%d.%d",

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2007-05-25 16:05:47 UTC (rev 10325)
+++ tor/trunk/src/common/util.h	2007-05-25 18:22:37 UTC (rev 10326)
@@ -250,7 +250,7 @@
                               uint16_t *port_max_out);
 int addr_mask_get_bits(uint32_t mask);
 #define INET_NTOA_BUF_LEN 16
-int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len);
+int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
 char *tor_dup_addr(uint32_t addr) ATTR_MALLOC;
 int get_interface_address(int severity, uint32_t *addr);