[git] ADNS-g10 - branch, justus/tor, created. adns-1.4-g10-6-8-g54f3128

by Werner Koch cvs at cvs.gnupg.org
Tue Jan 26 12:00:25 CET 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "ADNS migrated to autotools/libtool".

The branch, justus/tor has been created
        at  54f312816e32ccd6519171940f381ccdce6822d8 (commit)

- Log -----------------------------------------------------------------
commit 54f312816e32ccd6519171940f381ccdce6822d8
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Nov 20 13:15:40 2015 +0100

    Also try port 9150 in Tor mode.
    
    * src/w32support.c (ECONNREFUSED):  Define if missing.
    (adns__sock_wsa2errno): Map WSAECONNREFUSED.
    * src/event.c (socks_connect): Try port 9150.
    --
    
    The Tor browser uses this port.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/event.c b/src/event.c
index 064fbd9..5f4c8c1 100644
--- a/src/event.c
+++ b/src/event.c
@@ -164,6 +164,12 @@ socks_connect (adns_state ads, int fd,
   proxyaddr = (struct sockaddr *)&proxyaddr_in;
   proxyaddrlen = sizeof proxyaddr_in;
   ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen);
+  if (ret && errno == ECONNREFUSED)
+    {
+      /* Assume the Tor browser is used.  */
+      proxyaddr_in.sin_port = htons (9150);
+      ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen);
+    }
   if (ret)
     return ret;
 
diff --git a/src/w32support.c b/src/w32support.c
index fcf86aa..67b6b83 100644
--- a/src/w32support.c
+++ b/src/w32support.c
@@ -41,6 +41,12 @@
 
 static int wsa_startup_failed;
 
+/* Define missing error codes for older Windows compilers.  */
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 107
+#endif
+
+
 
 int WINAPI
 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
@@ -81,6 +87,8 @@ adns__sock_wsa2errno (int err)
       return ENOBUFS;
     case WSAEMSGSIZE:
       return EMSGSIZE;
+    case WSAECONNREFUSED:
+      return ECONNREFUSED;
     default:
       return EIO;
     }

commit e59d05b8d440e9efdc4a4b328781b55306a91d2c
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Nov 9 18:10:27 2015 +0100

    Allow SOCKS5 authentication with username/password.
    
    * src/event.c (socks_connect): Implemedn authentication method 2.
    --
    
    The credentials are given by the new config option adns_sockscred.
    Changing the credentials is an indication to Tor to use a new circuit.
    Tor ignore the actual values.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/event.c b/src/event.c
index 925617d..064fbd9 100644
--- a/src/event.c
+++ b/src/event.c
@@ -149,8 +149,10 @@ socks_connect (adns_state ads, int fd,
   size_t proxyaddrlen;
   struct sockaddr_in6 *addr_in6;
   struct sockaddr_in  *addr_in;
-  unsigned char buffer[22];
+  unsigned char buffer[22+512]; /* The extra 512 bytes is used as
+                                   space for username:password.  */
   size_t buflen;
+  int method;
 
   memset (&proxyaddr_in, 0, sizeof proxyaddr_in);
 
@@ -168,7 +170,11 @@ socks_connect (adns_state ads, int fd,
   /* Negotiate method.  */
   buffer[0] = 5; /* RFC-1928 VER field.  */
   buffer[1] = 1; /* NMETHODS */
-  buffer[2] = 0; /* Method: No authentication required. */
+  if (ads->sockscred)
+    method = 2;  /* Method: username/password authentication. */
+  else
+    method = 0;  /* Method: No authentication required. */
+  buffer[2] = method;
   adns__sigpipe_protect(ads);
   ret = adns__sock_write(fd, buffer, 3);
   adns__sigpipe_unprotect(ads);
@@ -181,7 +187,7 @@ socks_connect (adns_state ads, int fd,
   ret = adns__sock_read(fd, buffer, 2);
   if (ret < 0)
     return ret;
-  if (ret != 2 || buffer[0] != 5 || buffer[1] != 0 )
+  if (ret != 2 || buffer[0] != 5 || buffer[1] != method )
     {
       /* Socks server returned wrong version or does not support our
          requested method.  */
@@ -189,6 +195,66 @@ socks_connect (adns_state ads, int fd,
       return -1;
     }
 
+  if (ads->sockscred)
+    {
+      /* Username/Password sub-negotiation.  */
+      const char *password;
+      int ulen, plen;
+
+      password = strchr (ads->sockscred, ':');
+      if (!password)
+        {
+          errno = EINVAL; /* No password given.  */
+          return -1;
+        }
+      ulen = password - ads->sockscred;
+      password++;
+      plen = strlen (password);
+      if (!ulen || ulen > 255 || !plen || plen > 255)
+        {
+          errno = EINVAL; /* Credentials too long or too short.  */
+          return -1;
+        }
+
+      buffer[0] = 1; /* VER of the sub-negotiation. */
+      buffer[1] = ulen;
+      buflen = 2;
+      memcpy (buffer+buflen, ads->sockscred, ulen);
+      buflen += ulen;
+      buffer[buflen++] = plen;
+      memcpy (buffer+buflen, password, plen);
+      buflen += plen;
+      adns__sigpipe_protect(ads);
+      ret = adns__sock_write(fd, buffer, buflen);
+      adns__sigpipe_unprotect(ads);
+      WIPEMEMORY (buffer, buflen);
+      if (ret != buflen)
+        {
+          if (ret >= 0)
+            errno = EIO;
+          return -1;
+        }
+      ret = adns__sock_read(fd, buffer, 2);
+      if (ret != 2)
+        {
+          if (ret >= 0)
+            errno = EIO;
+          return -1;
+        }
+      if (buffer[0] != 1)
+        {
+          /* SOCKS server returned wrong version.  */
+          errno = EPROTO;
+          return -1;
+        }
+      if (buffer[1])
+        {
+          /* SOCKS server denied access.  */
+          errno = EACCES;
+          return -1;
+        }
+    }
+
   /* Send request details (rfc-1928, 4).  */
   buffer[0] = 5; /* VER  */
   buffer[1] = 1; /* CMD = CONNECT  */

commit fd4837e72b5bca662b9153003c4921e077aad18b
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Nov 9 18:01:43 2015 +0100

    Add macro to safely clear memory.
    
    * src/internal.h (WIPEMEMORY): New.
    --
    
    This kind of platform neutral code has been in use by GnuPG and
    Libgcrypt for ages.  I am still waiting for some C committee f^D
    experts to figure that this makes use of undefined behaviour for
    volatile and they tell their optimizing-for-the-flat-world compiler
    to remove such code and thereby unveil passwords in memory (which
    actually happened for the standard memset).
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/internal.h b/src/internal.h
index acd6148..927284d 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -769,6 +769,14 @@ static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; }
 		      )
 
 
+/* To avoid that a compiler optimizes certain memset calls away, this
+   macro may be used instead.  */
+#define WIPEMEMORY(_ptr,_len) do {                          \
+              volatile char *_vptr=(volatile char *)(_ptr); \
+              size_t _vlen=(_len);                          \
+              while(_vlen) { *_vptr=0; _vptr++; _vlen--; }  \
+              } while(0)
+
 
 
 #endif

commit a3fea30602d2aaea175ba1fc7abaa87fdf561ebe
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Nov 9 18:08:03 2015 +0100

    Make handling of returned SOCKS bound address more robust.
    
    * src/event.c (socks_connect): Allow proxy to return a v6 address
    instead of the provided v4 and vice versa.
    --
    
    The specs say nothing about this but doing it this way is likely more
    robust that assuming the same family will be returned.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/event.c b/src/event.c
index 8aae3af..925617d 100644
--- a/src/event.c
+++ b/src/event.c
@@ -220,7 +220,7 @@ socks_connect (adns_state ads, int fd,
         errno = EIO;
       return -1;
     }
-  ret = adns__sock_read(fd, buffer, buflen);
+  ret = adns__sock_read(fd, buffer, 10 /*(v4 length)*/);
   if (ret < 0)
     return ret;
   if (ret != buflen || buffer[0] != 5 || buffer[2] != 0 )
@@ -258,9 +258,23 @@ socks_connect (adns_state ads, int fd,
         case 0x07: /* Command not supported */
         default:
           errno = ENOTSUP; /* Fixme: Is there a better errno? */
+          break;
         }
       return -1;
     }
+  if (buffer[3] == 4)
+    {
+      /* ATYP indicates a v6 address.  We need to read the remaining
+         12 bytes to finialize the SOCKS5 intro.  */
+      ret = adns__sock_read(fd, buffer, 12 /*(v6-v4 length)*/);
+      if (ret != 12)
+        {
+          if (ret >= 0)
+            errno = EIO;
+          return -1;
+        }
+    }
+
   /* FIXME: We have not way to store the actual address used by the
      server.  */
 

commit 6d71a6f7f327c9d6763ae3021e609a4e6da4a00a
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Nov 8 18:57:56 2015 +0100

    Add config options adns_tormode and adns_sockscred.
    
    * src/internal.h (struct adns__state): Add field "sockscred".
    * src/setup.c (init_begin): Clear SOCKSCRED.
    (init_finish): Free SOCKSCRED.
    (ccf_options): Implement new options.
    * src/adns.h: Describe options.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/adns.h b/src/adns.h
index 6ed9a97..9fe9a9a 100644
--- a/src/adns.h
+++ b/src/adns.h
@@ -515,6 +515,14 @@ int adns_init_logfn(adns_state *newstate_r, adns_initflags flags,
  *   setting of adns_if_check_entex, adns_if_check_freq, or neither,
  *   in the flags passed to adns_init.
  *
+ *  adns_tormode
+ *   Forces the use of virtual circuits over a SOCKS5 proxy running at
+ *   port 9050.  No UDP based communication is done.
+ *
+ *  adns_sockscred:username:password
+ *   Use username and password for SOCKS5 authentication.  Default is
+ *   no authentication.
+ *
  * There are a number of environment variables which can modify the
  * behaviour of adns.  They take effect only if adns_init is used, and
  * the caller of adns_init can disable them using adns_if_noenv.  In
diff --git a/src/internal.h b/src/internal.h
index 6bc0702..acd6148 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -347,6 +347,7 @@ struct adns__state {
   } sortlist[MAXSORTLIST];
   char **searchlist;
   unsigned short rand48xsubi[3];
+  char *sockscred; /* Malloced string with the SOCKS5 credentials or NULL.  */
 };
 
 /* From setup.c: */
diff --git a/src/setup.c b/src/setup.c
index 6b0172c..c33e2c5 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -269,6 +269,21 @@ static void ccf_options(adns_state ads, const char *fn,
       }
       continue;
     }
+    if (l==12 && !memcmp(word,"adns_tormode",12)) {
+      ads->iflags |= adns_if_tormode;
+      continue;
+    }
+    if (l>=15 && !memcmp(word,"adns_sockscred:",15)) {
+      l -= 15;
+      ads->sockscred = malloc (l + 1);
+      if (!ads->sockscred) {
+        saveerr(ads,errno);
+        continue;
+      }
+      memcpy (ads->sockscred, word+15, l);
+      ads->sockscred[l] = 0;
+      continue;
+    }
     adns__diag(ads,-1,0,"%s:%d: unknown option `%.*s'", fn,lno, l,word);
   }
 }
@@ -557,6 +572,8 @@ static int init_begin(adns_state *ads_r, adns_initflags flags,
   ads->rand48xsubi[1]= (unsigned long)pid >> 16;
   ads->rand48xsubi[2]= pid ^ ((unsigned long)pid >> 16);
 
+  ads->sockscred = NULL;
+
   *ads_r= ads;
   return 0;
 }
@@ -585,6 +602,8 @@ static int init_finish(adns_state ads) {
  x_closeudp:
   close(ads->udpsocket);
  x_free:
+  if (ads->sockscred)
+    free (ads->sockscred);
   free(ads);
   return r;
 }

commit ebc35be0fb258e14614e1312ab3a9e3f4884c2ce
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Oct 20 14:48:23 2015 +0200

    Add flag adns_if_tormode to provide a basic TOR mode.
    
    * src/adns.h (adns_if_tormode): New.
    * src/query.c (adns_submit): For a VC in tormode.
    (adns_submit_reverse_any): Ditto.
    (adns_synchronous): Ditto.
    * src/event.c (use_socks_p, socks_connect): New.  Based on code from
    Libassuan.
    (adns__tcp_tryconnect): Move setnonblock after the init of ADDR.  Call
    socks_connect if needed.
    * client/adh-opts.c (global_options): Add "--use-tor"
    (ov_tormode): New.
    * client/adnshost.h (ov_tormode): New declaration.
    * client/adh-query.c (ensure_adns_init): Enable TOR mode uf OV_TORMODE
    is set.
    --
    
    This patch has the problem that connecting to the TOR server and more
    important establishing the TOR connection will block.  Changing this
    would require quite some report of the TCP code in ADNS.
    
    In fact it has always been the case that when falling back to TCP mode
    and the connect would have blocked the connection won't be established
    but times outs.  There is no retry code for if connect returns with
    EWOULDBLOCK or EINPROGRESS.
    
    To test the code this command can be used.
    
      adnshost --config 'nameserver 8.8.8.8' --use-tor NAME
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/client/adh-opts.c b/client/adh-opts.c
index 5bb7273..5797b6c 100644
--- a/client/adh-opts.c
+++ b/client/adh-opts.c
@@ -27,7 +27,7 @@
 
 #include "adnshost.h"
 
-int ov_env=1, ov_pipe=0, ov_asynch=0;
+int ov_env=1, ov_pipe=0, ov_asynch=0, ov_tormode = 0;
 int ov_verbose= 0;
 adns_rrtype ov_type= adns_r_none;
 int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1;
@@ -43,6 +43,8 @@ static const struct optioninfo global_options[]= {
     "f", "pipe",           &ov_pipe, 1 },
   { ot_flag,             "Allow answers to be reordered",
     "a", "asynch",         &ov_asynch, 1 },
+  { ot_flag,             "Run over TOR",
+    0, "use-tor",          &ov_tormode, 1 },
 
   { ot_desconly, "answer/error output format and destination (see below):" },
   { ot_value,            "Answers to stdout, errors as messages to stderr (default)",
diff --git a/client/adh-query.c b/client/adh-query.c
index b5cfad7..d74dbda 100644
--- a/client/adh-query.c
+++ b/client/adh-query.c
@@ -70,6 +70,7 @@ void ensure_adns_init(void) {
 
   initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose;
   if (!ov_env) initflags |= adns_if_noenv;
+  if (ov_tormode) initflags |= adns_if_tormode;
 
   if (config_text) {
     r= adns_init_strcfg(&ads, initflags, stderr, config_text);
diff --git a/client/adnshost.h b/client/adnshost.h
index 876b021..fab3ac0 100644
--- a/client/adnshost.h
+++ b/client/adnshost.h
@@ -78,7 +78,7 @@ struct perqueryflags_remember {
   int ttl;
 };
 
-extern int ov_env, ov_pipe, ov_asynch;
+extern int ov_env, ov_pipe, ov_asynch, ov_tormode;
 extern int ov_verbose;
 extern adns_rrtype ov_type;
 extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname;
diff --git a/src/adns.h b/src/adns.h
index feb7cb1..6ed9a97 100644
--- a/src/adns.h
+++ b/src/adns.h
@@ -92,7 +92,8 @@ typedef enum { /* In general, or together the desired flags: */
  adns_if_eintr=       0x0020,/* allow _wait and _synchronous to return EINTR */
  adns_if_nosigpipe=   0x0040,/* applic has SIGPIPE ignored, do not protect */
  adns_if_checkc_entex=0x0100,/* consistency checks on entry/exit to adns fns */
- adns_if_checkc_freq= 0x0300 /* consistency checks very frequently (slow!) */
+ adns_if_checkc_freq= 0x0300,/* consistency checks very frequently (slow!) */
+ adns_if_tormode=     0x1000 /* route all trafic via TOR.  */
 } adns_initflags;
 
 typedef enum { /* In general, or together the desired flags: */
diff --git a/src/event.c b/src/event.c
index 6a88f98..8aae3af 100644
--- a/src/event.c
+++ b/src/event.c
@@ -9,6 +9,7 @@
  *    Copyright (C) 1997-2000,2003,2006  Ian Jackson
  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
  *    Copyright (C) 1991 Massachusetts Institute of Technology
+ *    Copyright (C) 2015 g10 Code GmbH
  *  (See the file INSTALL for full details.)
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -96,6 +97,177 @@ static void tcp_broken_events(adns_state ads) {
   ads->tcpstate= server_disconnected;
 }
 
+
+/* Return true if SOCKS shall be used.  This is the case if
+   adns_if_tormode is set and the desired address is not the loopback
+   address.  */
+static int
+use_socks_p (adns_state ads, const struct sockaddr *addr)
+{
+  if (!(ads->iflags & adns_if_tormode))
+    return 0;
+  else if (addr->sa_family == AF_INET6)
+    {
+      const struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
+      const unsigned char *s;
+      int i;
+
+      s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
+      if (s[15] != 1)
+        return 1;   /* Last octet is not 1 - not the loopback address.  */
+      for (i=0; i < 15; i++, s++)
+        if (*s)
+          return 1; /* Non-zero octet found - not the loopback address.  */
+
+      return 0; /* This is the loopback address.  */
+    }
+  else if (addr->sa_family == AF_INET)
+    {
+      const struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+
+      if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
+        return 0; /* Loopback (127.0.0.0/8) */
+
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
+/* Connect to TOR using the SOCKS5 protocol.  We assume that the
+   connection to the SOCKS proxy (TOR server) does not block; if it
+   would block we return and the the usual retry logic of the caller
+   kicks in.  */
+static int
+socks_connect (adns_state ads, int fd,
+               const struct sockaddr *addr, socklen_t length)
+{
+  int ret;
+  struct sockaddr_in  proxyaddr_in;
+  struct sockaddr *proxyaddr;
+  size_t proxyaddrlen;
+  struct sockaddr_in6 *addr_in6;
+  struct sockaddr_in  *addr_in;
+  unsigned char buffer[22];
+  size_t buflen;
+
+  memset (&proxyaddr_in, 0, sizeof proxyaddr_in);
+
+  /* Connect to local host.  */
+  /* Fixme: First try to use IPv6.  */
+  proxyaddr_in.sin_family = AF_INET;
+  proxyaddr_in.sin_port = htons (9050);
+  proxyaddr_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+  proxyaddr = (struct sockaddr *)&proxyaddr_in;
+  proxyaddrlen = sizeof proxyaddr_in;
+  ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen);
+  if (ret)
+    return ret;
+
+  /* Negotiate method.  */
+  buffer[0] = 5; /* RFC-1928 VER field.  */
+  buffer[1] = 1; /* NMETHODS */
+  buffer[2] = 0; /* Method: No authentication required. */
+  adns__sigpipe_protect(ads);
+  ret = adns__sock_write(fd, buffer, 3);
+  adns__sigpipe_unprotect(ads);
+  if (ret != 3)
+    {
+      if (ret >= 0)
+        errno = EIO;
+      return -1;
+    }
+  ret = adns__sock_read(fd, buffer, 2);
+  if (ret < 0)
+    return ret;
+  if (ret != 2 || buffer[0] != 5 || buffer[1] != 0 )
+    {
+      /* Socks server returned wrong version or does not support our
+         requested method.  */
+      errno = ENOTSUP; /* Fixme: Is there a better errno? */
+      return -1;
+    }
+
+  /* Send request details (rfc-1928, 4).  */
+  buffer[0] = 5; /* VER  */
+  buffer[1] = 1; /* CMD = CONNECT  */
+  buffer[2] = 0; /* RSV  */
+  if (addr->sa_family == AF_INET6)
+    {
+      addr_in6 = (struct sockaddr_in6 *)addr;
+
+      buffer[3] = 4; /* ATYP = IPv6 */
+      memcpy (buffer+ 4, &addr_in6->sin6_addr.s6_addr, 16); /* DST.ADDR */
+      memcpy (buffer+20, &addr_in6->sin6_port, 2);          /* DST.PORT */
+      buflen = 22;
+    }
+  else
+    {
+      addr_in = (struct sockaddr_in *)addr;
+
+      buffer[3] = 1; /* ATYP = IPv4 */
+      memcpy (buffer+4, &addr_in->sin_addr.s_addr, 4); /* DST.ADDR */
+      memcpy (buffer+8, &addr_in->sin_port, 2);        /* DST.PORT */
+      buflen = 10;
+    }
+  adns__sigpipe_protect(ads);
+  ret = adns__sock_write(fd, buffer, buflen);
+  adns__sigpipe_unprotect(ads);
+  if (ret != buflen)
+    {
+      if (ret >= 0)
+        errno = EIO;
+      return -1;
+    }
+  ret = adns__sock_read(fd, buffer, buflen);
+  if (ret < 0)
+    return ret;
+  if (ret != buflen || buffer[0] != 5 || buffer[2] != 0 )
+    {
+      /* Socks server returned wrong version or the reserved field is
+         not zero.  */
+      errno = EPROTO;
+      return -1;
+    }
+  if (buffer[1])
+    {
+      switch (buffer[1])
+        {
+        case 0x01: /* general SOCKS server failure.  */
+          errno = ENETDOWN;
+          break;
+        case 0x02: /* connection not allowed by ruleset.  */
+          errno = EACCES;
+          break;
+        case 0x03: /* Network unreachable */
+          errno = ENETUNREACH;
+          break;
+        case 0x04: /* Host unreachable */
+          errno = EHOSTUNREACH;
+          break;
+        case 0x05: /* Connection refused */
+          errno = ECONNREFUSED;
+          break;
+        case 0x06: /* TTL expired */
+          errno = ETIMEDOUT;
+          break;
+        case 0x08: /* Address type not supported */
+          errno = EPROTONOSUPPORT;
+          break;
+        case 0x07: /* Command not supported */
+        default:
+          errno = ENOTSUP; /* Fixme: Is there a better errno? */
+        }
+      return -1;
+    }
+  /* FIXME: We have not way to store the actual address used by the
+     server.  */
+
+  return 0;
+}
+
+
 void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
   int r, fd, tries;
   struct sockaddr_in addr;
@@ -127,21 +299,41 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
       adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno));
       return;
     }
-    r= adns__setnonblock(ads,fd);
-    if (r) {
-      adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:"
-		 " %s",strerror(r));
-      adns__sock_close(fd);
-      return;
-    }
     memset(&addr,0,sizeof(addr));
     addr.sin_family= AF_INET;
     addr.sin_port= htons(DNS_PORT);
     addr.sin_addr= ads->servers[ads->tcpserver].addr;
-    r= adns__sock_connect(fd,(const struct sockaddr*)&addr,sizeof(addr));
+    if (use_socks_p(ads, (const struct sockaddr*)&addr))
+      {
+        r= socks_connect(ads, fd,(const struct sockaddr*)&addr,sizeof(addr));
+        if (!r)
+          {
+            r= adns__setnonblock(ads,fd);
+            if (r) {
+              adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:"
+                         " %s",strerror(r));
+              adns__sock_close(fd);
+              return;
+            }
+          }
+      }
+    else
+      {
+        r= adns__setnonblock(ads,fd);
+        if (r) {
+          adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:"
+                     " %s",strerror(r));
+          adns__sock_close(fd);
+          return;
+        }
+        r= adns__sock_connect(fd,(const struct sockaddr*)&addr,sizeof(addr));
+      }
     ads->tcpsocket= fd;
     ads->tcpstate= server_connecting;
-    if (r==0) { tcp_connected(ads,now); return; }
+    if (r==0) {
+      tcp_connected(ads,now);
+      return;
+    }
     if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
       ads->tcptimeout= now;
       timevaladd(&ads->tcptimeout,TCPCONNMS);
diff --git a/src/internal.h b/src/internal.h
index c3aa213..6bc0702 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -277,7 +277,7 @@ struct adns__query {
    *        too big for UDP /             UDP timeout  \  \ send via UDP
    *        send via TCP   /              more retries  \  \
    *        when conn'd   /                  desired     \  \
-   *                     |     	       	       	       	  |  |
+   *        or TOR-mode  |     	       	       	       	  |  |
    *                     v				  |  v
    *              +-----------+         	    	+-------------+
    *              | tcpw/tcpw | ________                | tosend/udpw |
diff --git a/src/query.c b/src/query.c
index 948b5d3..5c8c2cc 100644
--- a/src/query.c
+++ b/src/query.c
@@ -222,6 +222,9 @@ int adns_submit(adns_state ads,
 
   adns__consistency(ads,0,cc_entex);
 
+  if ((ads->iflags & adns_if_tormode))
+    flags |= adns_qf_usevc;
+
   typei= adns__findtype(type);
   if (!typei) return ENOSYS;
 
@@ -287,6 +290,8 @@ int adns_submit_reverse_any(adns_state ads,
   int r, lreq;
 
   flags &= ~adns_qf_search;
+  if ((ads->iflags & adns_if_tormode))
+    flags |= adns_qf_usevc;
 
   if (addr->sa_family != AF_INET) return ENOSYS;
   iaddr= (const unsigned char*)
@@ -315,6 +320,10 @@ int adns_submit_reverse(adns_state ads,
 			void *context,
 			adns_query *query_r) {
   if (type != adns_r_ptr && type != adns_r_ptr_raw) return EINVAL;
+
+  if ((ads->iflags & adns_if_tormode))
+    flags |= adns_qf_usevc;
+
   return adns_submit_reverse_any(ads,addr,"in-addr.arpa",
 				 type,flags,context,query_r);
 }
@@ -326,7 +335,10 @@ int adns_synchronous(adns_state ads,
 		     adns_answer **answer_r) {
   adns_query qu;
   int r;
-  
+
+  if ((ads->iflags & adns_if_tormode))
+    flags |= adns_qf_usevc;
+
   r= adns_submit(ads,owner,type,flags,0,&qu);
   if (r) return r;
 

-----------------------------------------------------------------------


hooks/post-receive
-- 
ADNS migrated to autotools/libtool
http://git.gnupg.org




More information about the Gnupg-commits mailing list