[or-cvs] o Handle servers with dynamic IP addresses: don"t replace

Roger Dingledine arma at seul.org
Mon Aug 16 11:43:20 UTC 2004


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	config.c connection.c or.h router.c 
Log Message:
o Handle servers with dynamic IP addresses: don't replace
  options->Address with the resolved one at startup.
  o detect our address right before we make a routerinfo each time.
o external IP vs bind-IP. Already done, just use options->Address.
o OutboundBindAddress config option, to bind to a specific
  IP address for outgoing connect()s.


Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.133
retrieving revision 1.134
diff -u -d -r1.133 -r1.134
--- config.c	15 Aug 2004 20:14:44 -0000	1.133
+++ config.c	16 Aug 2004 11:43:18 -0000	1.134
@@ -213,6 +213,11 @@
 
     config_compare(list, "Group",          CONFIG_TYPE_STRING, &options->Group) ||
 
+    config_compare(list, "HiddenServiceDir", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
+    config_compare(list, "HiddenServicePort", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
+    config_compare(list, "HiddenServiceNodes", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
+    config_compare(list, "HiddenServiceExcludeNodes", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
+
     config_compare(list, "IgnoreVersion",  CONFIG_TYPE_BOOL, &options->IgnoreVersion) ||
 
     config_compare(list, "KeepalivePeriod",CONFIG_TYPE_INT, &options->KeepalivePeriod) ||
@@ -230,12 +235,14 @@
 
     config_compare(list, "ORPort",         CONFIG_TYPE_INT, &options->ORPort) ||
     config_compare(list, "ORBindAddress",  CONFIG_TYPE_LINELIST, &options->ORBindAddress) ||
+    config_compare(list, "OutboundBindAddress",CONFIG_TYPE_STRING, &options->OutboundBindAddress) ||
 
     config_compare(list, "PidFile",        CONFIG_TYPE_STRING, &options->PidFile) ||
     config_compare(list, "PathlenCoinWeight",CONFIG_TYPE_DOUBLE, &options->PathlenCoinWeight) ||
 
     config_compare(list, "RouterFile",     CONFIG_TYPE_STRING, &options->RouterFile) ||
     config_compare(list, "RunAsDaemon",    CONFIG_TYPE_BOOL, &options->RunAsDaemon) ||
+    config_compare(list, "RunTesting",     CONFIG_TYPE_BOOL, &options->RunTesting) ||
     config_compare(list, "RecommendedVersions",CONFIG_TYPE_STRING, &options->RecommendedVersions) ||
     config_compare(list, "RendNodes",      CONFIG_TYPE_STRING, &options->RendNodes) ||
     config_compare(list, "RendExcludeNodes",CONFIG_TYPE_STRING, &options->RendExcludeNodes) ||
@@ -246,12 +253,9 @@
 
     config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) ||
 
-    config_compare(list, "User",           CONFIG_TYPE_STRING, &options->User) ||
-    config_compare(list, "RunTesting",     CONFIG_TYPE_BOOL, &options->RunTesting) ||
-    config_compare(list, "HiddenServiceDir", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
-    config_compare(list, "HiddenServicePort", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
-    config_compare(list, "HiddenServiceNodes", CONFIG_TYPE_LINELIST, &options->RendConfigLines)||
-    config_compare(list, "HiddenServiceExcludeNodes", CONFIG_TYPE_LINELIST, &options->RendConfigLines)
+    config_compare(list, "User",           CONFIG_TYPE_STRING, &options->User)
+
+
     ) {
       /* then we're ok. it matched something. */
     } else {
@@ -422,31 +426,34 @@
 /**
  * Adjust <b>options</b> to contain a reasonable value for Address.
  */
-static int resolve_my_address(or_options_t *options) {
+int resolve_my_address(const char *address, uint32_t *addr) {
   struct in_addr in;
   struct hostent *rent;
-  char localhostname[256];
+  char hostname[256];
   int explicit_ip=1;
 
-  if(!options->Address) { /* then we need to guess our address */
+  tor_assert(addr);
+
+  if(address) {
+    strlcpy(hostname,address,sizeof(hostname));
+  } else { /* then we need to guess our address */
     explicit_ip = 0; /* it's implicit */
 
-    if(gethostname(localhostname,sizeof(localhostname)) < 0) {
+    if(gethostname(hostname,sizeof(hostname)) < 0) {
       log_fn(LOG_WARN,"Error obtaining local hostname");
       return -1;
     }
-    options->Address = tor_strdup(localhostname);
-    log_fn(LOG_DEBUG,"Guessed local host name as '%s'",options->Address);
+    log_fn(LOG_DEBUG,"Guessed local host name as '%s'",hostname);
   }
 
-  /* now we know options->Address is set. resolve it and keep only the IP */
+  /* now we know hostname. resolve it and keep only the IP */
 
-  if(tor_inet_aton(options->Address, &in) == 0) {
+  if(tor_inet_aton(hostname, &in) == 0) {
     /* then we have to resolve it */
     explicit_ip = 0;
-    rent = (struct hostent *)gethostbyname(options->Address);
+    rent = (struct hostent *)gethostbyname(hostname);
     if (!rent) {
-      log_fn(LOG_WARN,"Could not resolve Address %s. Failing.", options->Address);
+      log_fn(LOG_WARN,"Could not resolve local Address %s. Failing.", hostname);
       return -1;
     }
     tor_assert(rent->h_length == 4);
@@ -455,12 +462,11 @@
   if(!explicit_ip && is_internal_IP(htonl(in.s_addr))) {
     log_fn(LOG_WARN,"Address '%s' resolves to private IP '%s'. "
            "Please set the Address config option to be the IP you want to use.",
-           options->Address, inet_ntoa(in));
+           hostname, inet_ntoa(in));
     return -1;
   }
-  tor_free(options->Address);
-  options->Address = tor_strdup(inet_ntoa(in));
-  log_fn(LOG_DEBUG,"Resolved Address to %s.", options->Address);
+  log_fn(LOG_DEBUG,"Resolved Address to %s.", inet_ntoa(in));
+  *addr = ntohl(in.s_addr);
   return 0;
 }
 
@@ -513,6 +519,7 @@
   tor_free(options->ExcludeNodes);
   tor_free(options->RendNodes);
   tor_free(options->RendExcludeNodes);
+  tor_free(options->OutboundBindAddress);
   tor_free(options->RecommendedVersions);
   tor_free(options->User);
   tor_free(options->Group);
@@ -540,6 +547,7 @@
   options->SocksBindAddress = NULL;
   options->ORBindAddress = NULL;
   options->DirBindAddress = NULL;
+  options->OutboundBindAddress = NULL;
   options->RecommendedVersions = NULL;
   options->PidFile = NULL; // tor_strdup("tor.pid");
   options->DataDirectory = NULL;
@@ -696,8 +704,10 @@
     }
   }
 
-  if(server_mode()) { /* get an IP for ourselves */
-    if(resolve_my_address(options) < 0)
+  if(server_mode()) {
+    /* confirm that our address isn't broken, so we can complain now */
+    uint32_t tmp;
+    if(resolve_my_address(options->Address, &tmp) < 0)
       result = -1;
   }
 

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.248
retrieving revision 1.249
diff -u -d -r1.248 -r1.249
--- connection.c	15 Aug 2004 05:28:09 -0000	1.248
+++ connection.c	16 Aug 2004 11:43:18 -0000	1.249
@@ -482,6 +482,25 @@
            tor_socket_strerror(tor_socket_errno(-1)));
     return -1;
   }
+
+  if (options.OutboundBindAddress) {
+    struct sockaddr_in ext_addr;
+
+    memset(&ext_addr, 0, sizeof(ext_addr));
+    ext_addr.sin_family = AF_INET;
+    ext_addr.sin_port = 0;
+    if (!tor_inet_aton(options.OutboundBindAddress, &ext_addr.sin_addr)) {
+      log_fn(LOG_WARN,"Outbound bind address '%s' didn't parse. Ignoring.",
+             options.OutboundBindAddress);
+    } else {
+      if(bind(s, (struct sockaddr*)&ext_addr, sizeof(ext_addr) < 0)) {
+        log_fn(LOG_WARN,"Error binding network socket: %s",
+               tor_socket_strerror(tor_socket_errno(s)));
+        return -1;
+      }
+    }
+  }
+
   set_socket_nonblocking(s);
 
   memset(&dest_addr,0,sizeof(dest_addr));

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.404
retrieving revision 1.405
diff -u -d -r1.404 -r1.405
--- or.h	15 Aug 2004 20:14:44 -0000	1.404
+++ or.h	16 Aug 2004 11:43:18 -0000	1.405
@@ -838,12 +838,14 @@
 
   struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */
   struct config_line_t *SocksPolicy; /**< Lists of socks policy components */
+  /** Addresses to bind for listening for SOCKS connections. */
   struct config_line_t *SocksBindAddress;
-  /**< Addresses to bind for listening for SOCKS connections. */
+  /** Addresses to bind for listening for OR connections. */
   struct config_line_t *ORBindAddress;
-  /**< Addresses to bind for listening for OR connections. */
+  /** Addresses to bind for listening for directory connections. */
   struct config_line_t *DirBindAddress;
-  /**< Addresses to bind for listening for directory connections. */
+  /** Local address to bind outbound sockets */
+  char *OutboundBindAddress;
   char *RecommendedVersions; /**< Directory server only: which versions of
                               * Tor should we tell users to run? */
   char *User; /**< Name of user to run Tor as. */
@@ -1021,6 +1023,7 @@
 };
 
 int config_assign_default_dirservers(void);
+int resolve_my_address(const char *address, uint32_t *addr);
 int getconfig(int argc, char **argv, or_options_t *options);
 int config_init_logs(or_options_t *options);
 void config_parse_exit_policy(struct config_line_t *cfg,

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/src/or/router.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- router.c	15 Aug 2004 08:15:12 -0000	1.83
+++ router.c	16 Aug 2004 11:43:18 -0000	1.84
@@ -510,17 +510,20 @@
  */
 int router_rebuild_descriptor(void) {
   routerinfo_t *ri;
-  struct in_addr addr;
+  uint32_t addr;
   char platform[256];
-  if (!tor_inet_aton(options.Address, &addr)) {
-    log_fn(LOG_ERR, "options.Address didn't hold an IP.");
+  struct in_addr in;
+
+  if(resolve_my_address(options.Address, &addr) < 0) {
+    log_fn(LOG_WARN,"options.Address didn't resolve into an IP.");
     return -1;
   }
 
   ri = tor_malloc_zero(sizeof(routerinfo_t));
-  ri->address = tor_strdup(options.Address);
+  in.s_addr = htonl(addr);
+  ri->address = tor_strdup(inet_ntoa(in));
   ri->nickname = tor_strdup(options.Nickname);
-  ri->addr = (uint32_t) ntohl(addr.s_addr);
+  ri->addr = addr;
   ri->or_port = options.ORPort;
   ri->socks_port = options.SocksPort;
   ri->dir_port = options.DirPort;



More information about the tor-commits mailing list