From: Mircea Ulinic Date: Wed, 1 Feb 2017 11:31:30 +0000 (+0000) Subject: Move bindin into _create_stream X-Git-Tag: v4.5.0~39^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6eb51a0b9828b62905d2b549c0724fd038a1bcb0;p=thirdparty%2Ftornado.git Move bindin into _create_stream --- diff --git a/tornado/iostream.py b/tornado/iostream.py index 458a6e118..bcf444148 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -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 ` 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. diff --git a/tornado/tcpclient.py b/tornado/tcpclient.py index 0b94da23d..e238bdd21 100644 --- a/tornado/tcpclient.py +++ b/tornado/tcpclient.py @@ -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,