Bug 1544089 - Allow the configuration of the ssltunnel listening address, r=mayhemer.
authorBob Clary <bclary@bclary.com>
Wed, 17 Apr 2019 14:37:28 +0000
changeset 469885 1f13810ca79e630b96812c10331b8f03691fe728
parent 469884 67d59eccba20c9a96f3e0a06a8e947dc06918ecc
child 469886 a3f2c83b52150662f28e3efa5f48a6b3854cdf89
push id35884
push userapavel@mozilla.com
push dateThu, 18 Apr 2019 21:35:00 +0000
treeherdermozilla-central@74dc09642c22 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1544089
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1544089 - Allow the configuration of the ssltunnel listening address, r=mayhemer. Differential Revision: https://phabricator.services.mozilla.com/D27722
testing/mochitest/ssltunnel/ssltunnel.cpp
--- a/testing/mochitest/ssltunnel/ssltunnel.cpp
+++ b/testing/mochitest/ssltunnel/ssltunnel.cpp
@@ -206,16 +206,17 @@ PRNetAddr remote_addr;
 PRNetAddr websocket_server;
 PRThreadPool* threads = nullptr;
 PRLock* shutdown_lock = nullptr;
 PRCondVar* shutdown_condvar = nullptr;
 // Not really used, unless something fails to start
 bool shutdown_server = false;
 bool do_http_proxy = false;
 bool any_host_spec_config = false;
+bool listen_public = false;
 
 int ClientAuthValueComparator(const void* v1, const void* v2) {
   int a = *static_cast<const client_auth_option*>(v1) -
           *static_cast<const client_auth_option*>(v2);
   if (a == 0) return 0;
   if (a > 0) return 1;
   // (a < 0)
   return -1;
@@ -884,20 +885,25 @@ void StartServer(void* data) {
 
   // In case the socket is still open in the TIME_WAIT state from a previous
   // instance of ssltunnel we ask to reuse the port.
   PRSocketOptionData socket_option;
   socket_option.option = PR_SockOpt_Reuseaddr;
   socket_option.value.reuse_addr = true;
   PR_SetSocketOption(listen_socket.get(), &socket_option);
 
-  // Explicitly listen on loopback to avoid users getting errors from their
-  // firewalls about ssltunnel needing permission.
   PRNetAddr server_addr;
-  PR_InitializeNetAddr(PR_IpAddrLoopback, si->listen_port, &server_addr);
+  PRNetAddrValue listen_addr;
+  if (listen_public) {
+    listen_addr = PR_IpAddrAny;
+  } else {
+    listen_addr = PR_IpAddrLoopback;
+  }
+  PR_InitializeNetAddr(listen_addr, si->listen_port, &server_addr);
+
   if (PR_Bind(listen_socket.get(), &server_addr) != PR_SUCCESS) {
     LOG_ERROR(("failed to bind socket on port %d: error %d\n", si->listen_port,
                PR_GetError()));
     SignalShutdown();
     return;
   }
 
   if (PR_Listen(listen_socket.get(), 1) != PR_SUCCESS) {
@@ -1048,35 +1054,48 @@ int processConfigLine(char* configLine) 
       LOG_ERROR(("Invalid remote port: %s\n", serverportstring));
       return 1;
     }
     remote_addr.inet.port = PR_htons(port);
 
     return 0;
   }
 
-  // Configure all listen sockets and port+certificate bindings
+  // Configure all listen sockets and port+certificate bindings.
+  // Listen on the public address if "*" was specified as the listen
+  // address or listen on the loopback address if "127.0.0.1" was
+  // specified. Using loopback will prevent users getting errors from
+  // their firewalls about ssltunnel needing permission. A public
+  // address is required when proxying ssl traffic from a physical or
+  // emulated Android device since it has a different ip address from
+  // the host.
   if (!strcmp(keyword, "listen")) {
     char* hostname = strtok2(_caret, ":", &_caret);
     char* hostportstring = nullptr;
-    if (strcmp(hostname, "*")) {
+    if (!strcmp(hostname, "*")) {
+      listen_public = true;
+    } else if (strcmp(hostname, "127.0.0.1")) {
       any_host_spec_config = true;
       hostportstring = strtok2(_caret, ":", &_caret);
     }
 
     char* serverportstring = strtok2(_caret, ":", &_caret);
     char* certnick = strtok2(_caret, ":", &_caret);
 
     int port = atoi(serverportstring);
     if (port <= 0) {
       LOG_ERROR(("Invalid port specified: %s\n", serverportstring));
       return 1;
     }
 
     if (server_info_t* existingServer = findServerInfo(port)) {
+      if (!hostportstring) {
+        LOG_ERROR(("Null hostportstring specified for hostname %s\n", hostname));
+        return 1;
+      }
       char* certnick_copy = new char[strlen(certnick) + 1];
       char* hostname_copy =
           new char[strlen(hostname) + strlen(hostportstring) + 2];
 
       strcpy(hostname_copy, hostname);
       strcat(hostname_copy, ":");
       strcat(hostname_copy, hostportstring);
       strcpy(certnick_copy, certnick);