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

check for conflicting *Port directives



if someone does something like:

ORPort 9031
SocksPort 9031

this will tell them where they've screwed up, rather than attempting to bind 
to the port and fail for the second of the two options.

possibly a case of sledgehammer meets walnut (it's a large patch for what it's 
fixing). If the idea is right it will need some cleaning to be up to 
standard, but hopefully this will be less than the time required to write 
from scratch.


-- 

Browse Anonymously Anywhere	- http://anonymityanywhere.com
TorK	- KDE Anonymity Manager	- http://tork.sf.net
KlamAV	- KDE Anti-Virus 	- http://www.klamav.net

Index: src/or/config.c
===================================================================
--- src/or/config.c	(revision 10664)
+++ src/or/config.c	(working copy)
@@ -47,6 +47,24 @@
   int warn;
 } config_abbrev_t;
 
+/** Port Option Name and Configured Port. */
+typedef struct option_port_t {
+  char *name;
+  int value;
+} option_port_t;
+
+/** An array of all configured port opton names and values. */
+typedef struct ports_used_t {
+  int nports;
+  struct port_t **portandname;
+} ports_used_t;
+
+/** Used by ports_used_t. */
+typedef struct port_t {
+  int port;
+  const char *name;
+} port_t;
+
 /* Handy macro for declaring "In the config file or on the command line,
  * you can abbreviate <b>tok</b>s as <b>tok</b>". */
 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
@@ -651,6 +669,45 @@
 };
 
 /*
+ * Helper functions for verifying that *Port options do not conflict.
+ */
+
+static port_t *
+port_new(const char *name, int port)
+{
+  port_t *b;
+  b = tor_malloc_zero(sizeof(port_t) + strlen(name));
+  b->name = tor_strdup(name);
+  b->port = port;
+  return b;
+}
+
+int
+port_add(struct ports_used_t *array, struct port_t *new)
+{
+  int i;
+  for (i = 0; i < array->nports; ++i) {
+    if (new->port == array->portandname[i]->port)
+        return i;
+  }
+  return -1;
+}
+
+void
+ports_free(struct ports_used_t *ports_used_array)
+{
+  int i;
+  if (ports_used_array) {
+      if (ports_used_array->portandname) {
+          for (i = 0; i < ports_used_array->nports; ++i)
+              tor_free(ports_used_array->portandname[i]);
+          tor_free(ports_used_array->portandname);
+      }
+      tor_free(ports_used_array);
+  }
+}
+
+/*
  * Functions to read and write the global options pointer.
  */
 
@@ -2415,9 +2472,13 @@
                  int from_setconf, char **msg)
 {
   int i, r;
+  int opt;
   config_line_t *cl;
   const char *uname = get_uname();
   char buf[1024];
+  struct ports_used_t *ports_used_array = NULL;
+  struct port_t *p;
+
 #define REJECT(arg) \
   STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
@@ -2438,6 +2499,46 @@
         "for details.", uname);
   }
 
+  option_port_t option_ports[] = {
+  { "DirPort", options->DirPort},
+  { "ORPort", options->ORPort},
+  { "ControlPort", options->ControlPort},
+  { "DNSPort", options->DNSPort},
+  { "TransPort", options->TransPort},
+  { "NatdPort", options->NatdPort},
+  { "SocksPort", options->SocksPort},
+  { NULL, 0},
+  };
+
+  ports_used_array = tor_malloc(sizeof(struct ports_used_t));
+  ports_used_array->nports = 0;
+
+  for (i=0; option_ports[i].name; i++){}
+  ports_used_array->portandname = tor_malloc(sizeof(struct port_t *) * i);
+
+
+  for (i=0; option_ports[i].name; i++){
+    if (option_ports[i].value != 0) {
+        p = port_new(option_ports[i].name, option_ports[i].value);
+        opt = port_add(ports_used_array,p);
+        if (opt < 0)
+            ports_used_array->portandname[ports_used_array->nports++] = p;
+        else{
+            char *resp;
+            int len = 256 + sizeof(p->port)
+                        + strlen(option_ports[i].name)
+                        + strlen(ports_used_array->portandname[opt]->name);
+            resp = tor_malloc(len);
+            tor_snprintf(resp,len,"Cannot assign port %i to %s because you have also assigned it to %s. ",
+                p->port, option_ports[i].name,
+                ports_used_array->portandname[opt]->name);
+            ports_free(ports_used_array);
+            REJECT(resp);
+        }
+    }
+  }
+  ports_free(ports_used_array);
+
   if (options->ORPort == 0 && options->ORListenAddress != NULL)
     REJECT("ORPort must be defined if ORListenAddress is defined.");
 
@@ -2456,6 +2557,7 @@
   if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
     REJECT("NatdPort must be defined if NatdListenAddress is defined.");
 
+
   /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
    * configuration does this. */