mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-10 19:46:36 +03:00
Add support for local_ip address binding (#1587)
This commit is contained in:
parent
ce71b3293b
commit
d2756cf68f
|
@ -110,6 +110,11 @@ class TelegramBaseClient(abc.ABC):
|
||||||
function parameters for PySocks, like ``(type, 'hostname', port)``.
|
function parameters for PySocks, like ``(type, 'hostname', port)``.
|
||||||
See https://github.com/Anorov/PySocks#usage-1 for more.
|
See https://github.com/Anorov/PySocks#usage-1 for more.
|
||||||
|
|
||||||
|
local_addr (`str`, optional):
|
||||||
|
Local host address used to bind the socket to locally.
|
||||||
|
You only need to use this if you have multiple network cards and
|
||||||
|
want to use a specific one.
|
||||||
|
|
||||||
timeout (`int` | `float`, optional):
|
timeout (`int` | `float`, optional):
|
||||||
The timeout in seconds to be used when connecting.
|
The timeout in seconds to be used when connecting.
|
||||||
This is **not** the timeout to be used when ``await``'ing for
|
This is **not** the timeout to be used when ``await``'ing for
|
||||||
|
@ -215,6 +220,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
connection: 'typing.Type[Connection]' = ConnectionTcpFull,
|
connection: 'typing.Type[Connection]' = ConnectionTcpFull,
|
||||||
use_ipv6: bool = False,
|
use_ipv6: bool = False,
|
||||||
proxy: typing.Union[tuple, dict] = None,
|
proxy: typing.Union[tuple, dict] = None,
|
||||||
|
local_addr=None,
|
||||||
timeout: int = 10,
|
timeout: int = 10,
|
||||||
request_retries: int = 5,
|
request_retries: int = 5,
|
||||||
connection_retries: int =5,
|
connection_retries: int =5,
|
||||||
|
@ -313,12 +319,23 @@ class TelegramBaseClient(abc.ABC):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if local_addr is not None:
|
||||||
|
if use_ipv6 is False and ':' in local_addr:
|
||||||
|
raise TypeError(
|
||||||
|
'A local IPv6 address must only be used with `use_ipv6=True`.'
|
||||||
|
)
|
||||||
|
elif use_ipv6 is True and ':' not in local_addr:
|
||||||
|
raise TypeError(
|
||||||
|
'`use_ipv6=True` must only be used with a local IPv6 address.'
|
||||||
|
)
|
||||||
|
|
||||||
self._raise_last_call_error = raise_last_call_error
|
self._raise_last_call_error = raise_last_call_error
|
||||||
|
|
||||||
self._request_retries = request_retries
|
self._request_retries = request_retries
|
||||||
self._connection_retries = connection_retries
|
self._connection_retries = connection_retries
|
||||||
self._retry_delay = retry_delay or 0
|
self._retry_delay = retry_delay or 0
|
||||||
self._proxy = proxy
|
self._proxy = proxy
|
||||||
|
self._local_addr = local_addr
|
||||||
self._timeout = timeout
|
self._timeout = timeout
|
||||||
self._auto_reconnect = auto_reconnect
|
self._auto_reconnect = auto_reconnect
|
||||||
|
|
||||||
|
@ -501,7 +518,8 @@ class TelegramBaseClient(abc.ABC):
|
||||||
self.session.port,
|
self.session.port,
|
||||||
self.session.dc_id,
|
self.session.dc_id,
|
||||||
loggers=self._log,
|
loggers=self._log,
|
||||||
proxy=self._proxy
|
proxy=self._proxy,
|
||||||
|
local_addr=self._local_addr
|
||||||
)):
|
)):
|
||||||
# We don't want to init or modify anything if we were already connected
|
# We don't want to init or modify anything if we were already connected
|
||||||
return
|
return
|
||||||
|
@ -663,7 +681,8 @@ class TelegramBaseClient(abc.ABC):
|
||||||
dc.port,
|
dc.port,
|
||||||
dc.id,
|
dc.id,
|
||||||
loggers=self._log,
|
loggers=self._log,
|
||||||
proxy=self._proxy
|
proxy=self._proxy,
|
||||||
|
local_addr=self._local_addr
|
||||||
))
|
))
|
||||||
self._log[__name__].info('Exporting auth for new borrowed sender in %s', dc)
|
self._log[__name__].info('Exporting auth for new borrowed sender in %s', dc)
|
||||||
auth = await self(functions.auth.ExportAuthorizationRequest(dc_id))
|
auth = await self(functions.auth.ExportAuthorizationRequest(dc_id))
|
||||||
|
@ -698,7 +717,8 @@ class TelegramBaseClient(abc.ABC):
|
||||||
dc.port,
|
dc.port,
|
||||||
dc.id,
|
dc.id,
|
||||||
loggers=self._log,
|
loggers=self._log,
|
||||||
proxy=self._proxy
|
proxy=self._proxy,
|
||||||
|
local_addr=self._local_addr
|
||||||
))
|
))
|
||||||
|
|
||||||
state.add_borrow()
|
state.add_borrow()
|
||||||
|
|
|
@ -28,12 +28,13 @@ class Connection(abc.ABC):
|
||||||
# should be one of `PacketCodec` implementations
|
# should be one of `PacketCodec` implementations
|
||||||
packet_codec = None
|
packet_codec = None
|
||||||
|
|
||||||
def __init__(self, ip, port, dc_id, *, loggers, proxy=None):
|
def __init__(self, ip, port, dc_id, *, loggers, proxy=None, local_addr=None):
|
||||||
self._ip = ip
|
self._ip = ip
|
||||||
self._port = port
|
self._port = port
|
||||||
self._dc_id = dc_id # only for MTProxy, it's an abstraction leak
|
self._dc_id = dc_id # only for MTProxy, it's an abstraction leak
|
||||||
self._log = loggers[__name__]
|
self._log = loggers[__name__]
|
||||||
self._proxy = proxy
|
self._proxy = proxy
|
||||||
|
self._local_addr = local_addr
|
||||||
self._reader = None
|
self._reader = None
|
||||||
self._writer = None
|
self._writer = None
|
||||||
self._connected = False
|
self._connected = False
|
||||||
|
@ -46,8 +47,13 @@ class Connection(abc.ABC):
|
||||||
|
|
||||||
async def _connect(self, timeout=None, ssl=None):
|
async def _connect(self, timeout=None, ssl=None):
|
||||||
if not self._proxy:
|
if not self._proxy:
|
||||||
|
if self._local_addr is not None:
|
||||||
|
local_addr = (self._local_addr, None)
|
||||||
|
else:
|
||||||
|
local_addr = None
|
||||||
|
|
||||||
self._reader, self._writer = await asyncio.wait_for(
|
self._reader, self._writer = await asyncio.wait_for(
|
||||||
asyncio.open_connection(self._ip, self._port, ssl=ssl),
|
asyncio.open_connection(self._ip, self._port, ssl=ssl, local_addr=local_addr),
|
||||||
timeout=timeout
|
timeout=timeout
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -64,6 +70,8 @@ class Connection(abc.ABC):
|
||||||
s.set_proxy(*self._proxy)
|
s.set_proxy(*self._proxy)
|
||||||
|
|
||||||
s.settimeout(timeout)
|
s.settimeout(timeout)
|
||||||
|
if self._local_addr is not None:
|
||||||
|
s.bind((self._local_addr, None))
|
||||||
await asyncio.wait_for(
|
await asyncio.wait_for(
|
||||||
asyncio.get_event_loop().sock_connect(s, address),
|
asyncio.get_event_loop().sock_connect(s, address),
|
||||||
timeout=timeout
|
timeout=timeout
|
||||||
|
|
Loading…
Reference in New Issue
Block a user