diff --git a/src/or/config.c b/src/or/config.c
index 7f789c4..6a748de 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -695,17 +695,17 @@ static int options_act_reversible(const or_options_t *old_options, char **msg);
 static int options_transition_allowed(const or_options_t *old,
                                       const or_options_t *new,
                                       char **msg);
 static int options_transition_affects_workers(
       const or_options_t *old_options, const or_options_t *new_options);
 static int options_transition_affects_descriptor(
       const or_options_t *old_options, const or_options_t *new_options);
 static int check_nickname_list(char **lst, const char *name, char **msg);
-static char *get_bindaddr_from_transport_listen_line(const char *line,
+static smartlist_t *get_bindaddr_from_transport_listen_line(const char *line,
                                                      const char *transport);
 static int parse_ports(or_options_t *options, int validate_only,
                               char **msg_out, int *n_ports_out,
                               int *world_writable_control_socket);
 static int check_server_ports(const smartlist_t *ports,
                               const or_options_t *options,
                               int *num_low_ports_out);
 
@@ -3944,20 +3944,21 @@ options_validate(or_options_t *old_options, or_options_t *options,
                "line will be ignored.",
                escaped(options->ServerTransportPlugin->value));
   }
 
   for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
     /** If get_bindaddr_from_transport_listen_line() fails with
         'transport' being NULL, it means that something went wrong
         while parsing the ServerTransportListenAddr line. */
-    char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
-    if (!bindaddr)
+    smartlist_t *bindaddr_list = get_bindaddr_from_transport_listen_line(cl->value, NULL);
+    if (!bindaddr_list)
       REJECT("ServerTransportListenAddr did not parse. See logs for details.");
-    tor_free(bindaddr);
+    SMARTLIST_FOREACH(bindaddr_list, char*, s, tor_free(s));
+    smartlist_free(bindaddr_list);
   }
 
   if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
     log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
                "specify a transport listen address. The "
                "ServerTransportListenAddr line will be ignored.");
   }
 
@@ -5854,59 +5855,70 @@ parse_transport_line(const or_options_t *options,
  *  <address:port> string. Return NULL if the line was not
  *  well-formed.
  *
  *  If <b>transport</b> is set, return NULL if the line is not
  *  referring to <b>transport</b>.
  *
  *  The returned string is allocated on the heap and it's the
  *  responsibility of the caller to free it. */
-static char *
+static smartlist_t *
 get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
 {
   smartlist_t *items = NULL;
+  smartlist_t *bindaddr_list = NULL;
   const char *parsed_transport = NULL;
   char *addrport = NULL;
   tor_addr_t addr;
   uint16_t port = 0;
+  int ap;
 
   items = smartlist_new();
   smartlist_split_string(items, line, NULL,
                          SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
 
   if (smartlist_len(items) < 2) {
     log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
     goto err;
   }
 
   parsed_transport = smartlist_get(items, 0);
-  addrport = tor_strdup(smartlist_get(items, 1));
-
   /* If 'transport' is given, check if it matches the one on the line */
   if (transport && strcmp(transport, parsed_transport))
     goto err;
 
-  /* Validate addrport */
-  if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
-    log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
-             "address '%s'", addrport);
-    goto err;
+  bindaddr_list = smartlist_new();
+  for (ap = 1; ap < smartlist_len(items); ++ap) {
+    addrport = tor_strdup(smartlist_get(items, ap));
+    /* Validate addrport */
+    if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
+      log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
+               "address '%s'", addrport);
+      SMARTLIST_FOREACH(bindaddr_list, char*, s, tor_free(s));
+      smartlist_free(bindaddr_list);
+      bindaddr_list = NULL;
+      goto err;
+    }
+    smartlist_add_strdup(bindaddr_list, addrport);
+    tor_free(addrport);
+    addrport = NULL;
   }
 
   goto done;
 
  err:
-  tor_free(addrport);
+  if (addrport)
+    tor_free(addrport);
   addrport = NULL;
 
  done:
   SMARTLIST_FOREACH(items, char*, s, tor_free(s));
   smartlist_free(items);
 
-  return addrport;
+  return bindaddr_list;
 }
 
 /** Given a ServerTransportOptions <b>line</b>, return a smartlist
  *  with the options. Return NULL if the line was not well-formed.
  *
  *  If <b>transport</b> is set, return NULL if the line is not
  *  referring to <b>transport</b>.
  *
@@ -5960,27 +5972,27 @@ get_options_from_transport_options_line(const char *line,const char *transport)
 
   return options;
 }
 
 /** Given the name of a pluggable transport in <b>transport</b>, check
  *  the configuration file to see if the user has explicitly asked for
  *  it to listen on a specific port. Return a <address:port> string if
  *  so, otherwise NULL. */
-char *
+smartlist_t *
 get_transport_bindaddr_from_config(const char *transport)
 {
   config_line_t *cl;
   const or_options_t *options = get_options();
 
   for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
-    char *bindaddr =
+    smartlist_t *bindaddr_list =
       get_bindaddr_from_transport_listen_line(cl->value, transport);
-    if (bindaddr)
-      return bindaddr;
+    if (bindaddr_list)
+      return bindaddr_list;
   }
 
   return NULL;
 }
 
 /** Given the name of a pluggable transport in <b>transport</b>, check
  *  the configuration file to see if the user has asked us to pass any
  *  parameters to the pluggable transport. Return a smartlist
diff --git a/src/or/config.h b/src/or/config.h
index 6645532..b574080 100644
--- a/src/or/config.h
+++ b/src/or/config.h
@@ -107,17 +107,17 @@ smartlist_t *get_list_of_ports_to_forward(void);
 
 int getinfo_helper_config(control_connection_t *conn,
                           const char *question, char **answer,
                           const char **errmsg);
 
 uint32_t get_effective_bwrate(const or_options_t *options);
 uint32_t get_effective_bwburst(const or_options_t *options);
 
-char *get_transport_bindaddr_from_config(const char *transport);
+smartlist_t *get_transport_bindaddr_from_config(const char *transport);
 
 int init_cookie_authentication(const char *fname, const char *header,
                                int cookie_len, int group_readable,
                                uint8_t **cookie_out, int *cookie_is_set_out);
 
 or_options_t *options_new(void);
 
 int config_parse_commandline(int argc, char **argv, int ignore_errors,
diff --git a/src/or/statefile.c b/src/or/statefile.c
index a95ba85..e2db29a 100644
--- a/src/or/statefile.c
+++ b/src/or/statefile.c
@@ -174,17 +174,17 @@ state_transport_line_is_valid(const char *line)
   tor_addr_t addr;
   uint16_t port = 0;
   int r;
 
   items = smartlist_new();
   smartlist_split_string(items, line, NULL,
                          SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
 
-  if (smartlist_len(items) != 2) {
+  if (smartlist_len(items) < 2) {
     log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
     goto err;
   }
 
   addrport = smartlist_get(items, 1);
   if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
     log_warn(LD_CONFIG, "state: Could not parse addrport.");
     goto err;
@@ -519,17 +519,17 @@ get_transport_in_state_by_name(const char *transport)
   smartlist_t *items = NULL;
 
   for (line = or_state->TransportProxies ; line ; line = line->next) {
     tor_assert(!strcmp(line->key, "TransportProxy"));
 
     items = smartlist_new();
     smartlist_split_string(items, line->value, NULL,
                            SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
-    if (smartlist_len(items) != 2) /* broken state */
+    if (smartlist_len(items) < 2) /* broken state */
       goto done;
 
     if (!strcmp(smartlist_get(items, 0), transport)) {
       ret = line;
       goto done;
     }
 
     SMARTLIST_FOREACH(items, char*, s, tor_free(s));
@@ -569,108 +569,113 @@ get_transport_bindaddr(const char *line, const char *transport)
  broken_state:
   tor_free(line_tmp);
   return NULL;
 }
 
 /** Return a string containing the address:port that a proxy transport
  *  should bind on. The string is stored on the heap and must be freed
  *  by the caller of this function. */
-char *
+smartlist_t *
 get_stored_bindaddr_for_server_transport(const char *transport)
 {
   char *default_addrport = NULL;
   const char *stored_bindaddr = NULL;
   config_line_t *line = NULL;
+  smartlist_t *ret = NULL;
 
   {
     /* See if the user explicitly asked for a specific listening
        address for this transport. */
-    char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
-    if (conf_bindaddr)
-      return conf_bindaddr;
+    smartlist_t *conf_binaddr_list = get_transport_bindaddr_from_config(transport);
+    if (conf_binaddr_list)
+      return conf_binaddr_list;
   }
 
   line = get_transport_in_state_by_name(transport);
   if (!line) /* Found no references in state for this transport. */
     goto no_bindaddr_found;
 
   stored_bindaddr = get_transport_bindaddr(line->value, transport);
-  if (stored_bindaddr) /* found stored bindaddr in state file. */
-    return tor_strdup(stored_bindaddr);
+  if (stored_bindaddr) { /* found stored bindaddr in state file. */
+    ret = smartlist_new();
+    smartlist_split_string(ret, stored_bindaddr, NULL,
+                           SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+    return ret;
+  }
 
  no_bindaddr_found:
   /** If we didn't find references for this pluggable transport in the
       state file, we should instruct the pluggable transport proxy to
       listen on INADDR_ANY on a random ephemeral port. */
+  ret = smartlist_new();
   tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
-  return default_addrport;
+  smartlist_add(ret, default_addrport);
+  return ret;
 }
 
 /** Save <b>transport</b> listening on <b>addr</b>:<b>port</b> to
     state */
 void
 save_transport_to_state(const char *transport,
-                        const tor_addr_t *addr, uint16_t port)
+                        /*const tor_addr_t *addr, uint16_t port*/
+                        const char *bind_addresses)
 {
   or_state_t *state = get_or_state();
 
-  char *transport_addrport=NULL;
-
   /** find where to write on the state */
   config_line_t **next, *line;
 
   /* see if this transport is already stored in state */
   config_line_t *transport_line =
     get_transport_in_state_by_name(transport);
 
   if (transport_line) { /* if transport already exists in state... */
     const char *prev_bindaddr = /* get its addrport... */
       get_transport_bindaddr(transport_line->value, transport);
-    transport_addrport = tor_strdup(fmt_addrport(addr, port));
 
     /* if transport in state has the same address as this one, life is good */
-    if (!strcmp(prev_bindaddr, transport_addrport)) {
+    if (!strcmp(prev_bindaddr, bind_addresses)) {
       log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
                "address:port.");
       goto done;
     } else { /* if addrport in state is different than the one we got */
       log_info(LD_CONFIG, "Transport seems to have spawned on different "
                "address:port. Let's update the state file with the new "
                "address:port");
       tor_free(transport_line->value); /* free the old line */
       /* replace old addrport line with new line */
       tor_asprintf(&transport_line->value, "%s %s", transport,
-                   fmt_addrport(addr, port));
+                   bind_addresses);
     }
   } else { /* never seen this one before; save it in state for next time */
     log_info(LD_CONFIG, "It's the first time we see this transport. "
              "Let's save its address:port");
     next = &state->TransportProxies;
     /* find the last TransportProxy line in the state and point 'next'
        right after it  */
     line = state->TransportProxies;
     while (line) {
       next = &(line->next);
       line = line->next;
     }
 
     /* allocate space for the new line and fill it in */
     *next = line = tor_malloc_zero(sizeof(config_line_t));
     line->key = tor_strdup("TransportProxy");
-    tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
+    tor_asprintf(&line->value, "%s %s", transport, bind_addresses);
 
     next = &(line->next);
   }
 
   if (!get_options()->AvoidDiskWrites)
     or_state_mark_dirty(state, 0);
 
  done:
-  tor_free(transport_addrport);
+  return;
 }
 
 STATIC void
 or_state_free(or_state_t *state)
 {
   if (!state)
     return;
 
diff --git a/src/or/statefile.h b/src/or/statefile.h
index b137434..f4a9e03 100644
--- a/src/or/statefile.h
+++ b/src/or/statefile.h
@@ -7,18 +7,19 @@
 #ifndef TOR_STATEFILE_H
 #define TOR_STATEFILE_H
 
 MOCK_DECL(or_state_t *,get_or_state,(void));
 int did_last_state_file_write_fail(void);
 int or_state_save(time_t now);
 
 void save_transport_to_state(const char *transport_name,
-                             const tor_addr_t *addr, uint16_t port);
-char *get_stored_bindaddr_for_server_transport(const char *transport);
+                             /*const tor_addr_t *addr, uint16_t port*/
+                             const char *bind_addresses);
+smartlist_t *get_stored_bindaddr_for_server_transport(const char *transport);
 int or_state_load(void);
 int or_state_loaded(void);
 void or_state_free_all(void);
 
 #ifdef STATEFILE_PRIVATE
 STATIC config_line_t *get_transport_in_state_by_name(const char *transport);
 STATIC void or_state_free(or_state_t *state);
 STATIC or_state_t *or_state_new(void);
diff --git a/src/or/transports.c b/src/or/transports.c
index feeff6e..afee05e 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -667,24 +667,53 @@ configure_proxy(managed_proxy_t *mp)
 
   return configuration_finished;
 }
 
 /** Register server managed proxy <b>mp</b> transports to state */
 static void
 register_server_proxy(const managed_proxy_t *mp)
 {
+  char *ap; /* ap means address:port */
+  smartlist_t *ap_list;
+  strmap_t *transport_to_ap_list = strmap_new();
+
   tor_assert(mp->conf_state != PT_PROTO_COMPLETED);
 
   SMARTLIST_FOREACH_BEGIN(mp->transports, transport_t *, t) {
-    save_transport_to_state(t->name, &t->addr, t->port);
     log_notice(LD_GENERAL, "Registered server transport '%s' at '%s'",
                t->name, fmt_addrport(&t->addr, t->port));
     control_event_transport_launched("server", t->name, &t->addr, t->port);
+
+    ap = tor_strdup(fmt_addrport(&t->addr, t->port));
+
+    ap_list = strmap_get(transport_to_ap_list, t->name);
+    if (!ap_list) {
+      ap_list = smartlist_new();
+      strmap_set(transport_to_ap_list, t->name, ap_list);
+    }
+    smartlist_add(ap_list, ap);
   } SMARTLIST_FOREACH_END(t);
+
+  STRMAP_FOREACH(transport_to_ap_list, t_name, smartlist_t *, t_ap_list) {
+    char *all_ap;
+
+    tor_assert(smartlist_len(t_ap_list) != 0);
+    smartlist_sort_strings(t_ap_list);
+    all_ap = smartlist_join_strings(t_ap_list, " ", 0, NULL);
+
+    save_transport_to_state(t_name, all_ap);
+    tor_free(all_ap);
+    all_ap = NULL;
+
+    SMARTLIST_FOREACH(t_ap_list, char*, s, tor_free(s));
+    smartlist_free(t_ap_list);
+  } STRMAP_FOREACH_END;
+
+  strmap_free(transport_to_ap_list, NULL);
 }
 
 /** Register all the transports supported by client managed proxy
  *  <b>mp</b> to the bridge subsystem. */
 static void
 register_client_proxy(const managed_proxy_t *mp)
 {
   int r;
@@ -1271,25 +1300,27 @@ get_transport_options_for_server_proxy(const managed_proxy_t *mp)
 /** Return the string that tor should place in TOR_PT_SERVER_BINDADDR
  *  while configuring the server managed proxy in <b>mp</b>. The
  *  string is stored in the heap, and it's the responsibility of
  *  the caller to deallocate it after its use. */
 static char *
 get_bindaddr_for_server_proxy(const managed_proxy_t *mp)
 {
   char *bindaddr_result = NULL;
-  char *bindaddr_tmp = NULL;
+  smartlist_t *bindaddr_tmp = NULL;
   smartlist_t *string_tmp = smartlist_new();
 
   tor_assert(mp->is_server);
 
   SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, char *, t) {
     bindaddr_tmp = get_stored_bindaddr_for_server_transport(t);
 
-    smartlist_add_asprintf(string_tmp, "%s-%s", t, bindaddr_tmp);
+    SMARTLIST_FOREACH_BEGIN(bindaddr_tmp, char *, a_addrport) {
+      smartlist_add_asprintf(string_tmp, "%s-%s", t, a_addrport);
+    } SMARTLIST_FOREACH_END(a_addrport);
 
     tor_free(bindaddr_tmp);
   } SMARTLIST_FOREACH_END(t);
 
   bindaddr_result = smartlist_join_strings(string_tmp, ",", 0, NULL);
 
   SMARTLIST_FOREACH(string_tmp, char *, t, tor_free(t));
   smartlist_free(string_tmp);
