]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Move bindin into _create_stream
authorMircea Ulinic <mirucha@cloudflare.com>
Wed, 1 Feb 2017 11:31:30 +0000 (11:31 +0000)
committerMircea Ulinic <mirucha@cloudflare.com>
Wed, 1 Feb 2017 11:31:30 +0000 (11:31 +0000)
tornado/iostream.py
tornado/tcpclient.py

index 458a6e1189774348cb0fe69f3efa5fab8709ff9d..bcf444148c0ff2b639571ccb8796d569d8c7bf53 100644 (file)
@@ -1023,8 +1023,7 @@ class IOStream(BaseIOStream):
     def write_to_fd(self, data):
         return self.socket.send(data)
 
-    def connect(self, address, callback=None, server_hostname=None,
-                source_ip=None):
+    def connect(self, address, callback=None, server_hostname=None):
         """Connects the socket to a remote address without blocking.
 
         May only be called if the socket passed to the constructor was
@@ -1048,9 +1047,6 @@ class IOStream(BaseIOStream):
         ``ssl_options``) and SNI (if supported; requires Python
         2.7.9+).
 
-        If ``source_ip`` is specified, will try to use a certain source
-        IP address to establish the connection.
-
         Note that it is safe to call `IOStream.write
         <BaseIOStream.write>` while the connection is pending, in
         which case the data will be written as soon as the connection
@@ -1072,17 +1068,6 @@ class IOStream(BaseIOStream):
             future = None
         else:
             future = self._connect_future = TracebackFuture()
-        if source_ip:
-            try:
-                self.socket.bind((source_ip, 0))
-                # port = 0, will not bind to a specific port
-            except socket.error as e:
-                gen_log.error("Unable to use the source IP %s",
-                                    source_ip)
-                gen_log.error("%s: %s", self.socket.fileno(), e)
-                # log the error and move on
-                # will try to connect using the loopback
-                gen_log.warning("Using the loopback IP address as source.")
         try:
             self.socket.connect(address)
         except socket.error as e:
@@ -1361,9 +1346,7 @@ class SSLIOStream(IOStream):
             return
         super(SSLIOStream, self)._handle_write()
 
-    def connect(self, address, callback=None, server_hostname=None,
-                source_ip=None):
-        # source_ip not used here
+    def connect(self, address, callback=None, server_hostname=None):
         self._server_hostname = server_hostname
         # Pass a dummy callback to super.connect(), which is slightly
         # more efficient than letting it return a Future we ignore.
index 0b94da23deaecce3d0d2718e8468030c07fc0740..e238bdd21d1d4b53da392d42d569f87761799140 100644 (file)
@@ -162,17 +162,18 @@ class TCPClient(object):
         Asynchronously returns an `.IOStream` (or `.SSLIOStream` if
         ``ssl_options`` is not None).
 
-        source_ip
-            Specify the source IP address to use when establishing
-            the connection. In case the user needs to resolve and
-            use a specific interface, it has to be handled outside
-            of Tornado as this depneds very much on the platform.
+        Using the `source_ip` kwarg, one can specify the source
+        IP address to use when establishing the connection.
+        In case the user needs to resolve and
+        use a specific interface, it has to be handled outside
+        of Tornado as this depends very much on the platform.
         """
         addrinfo = yield self.resolver.resolve(host, port, af)
         connector = _Connector(
             addrinfo, self.io_loop,
-            functools.partial(self._create_stream, max_buffer_size),
-            source_ip=source_ip)
+            functools.partial(self._create_stream, max_buffer_size,
+                              source_ip=source_ip)
+        )
         af, addr, stream = yield connector.start()
         # TODO: For better performance we could cache the (af, addr)
         # information here and re-use it on subsequent connections to
@@ -185,6 +186,12 @@ class TCPClient(object):
     def _create_stream(self, max_buffer_size, af, addr, source_ip=None):
         # Always connect in plaintext; we'll convert to ssl if necessary
         # after one connection has completed.
+        if source_ip:
+            # If source_ip is needed, will try binding.
+            # If it fails, will exit loudly.
+            self.socket.bind((source_ip, 0))
+            # Does not bind try binding to a specific port,
+            # so the port argument is set to 0.
         try:
             stream = IOStream(socket.socket(af),
                               io_loop=self.io_loop,