From ab07f0220a6646379fa27d840d8129d41b0248cb Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 28 Dec 2017 01:04:11 +0100 Subject: [PATCH] Save dc_id instead layer and salt in the session file Server salts change every 30 minutes after all, so keeping them in the long-term storage session file doesn't make much sense. Saving the layer doesn't make sense either, as it was only used to know whether to init connection or not, but it should be done always. --- telethon/telegram_bare_client.py | 26 +++++------- telethon/tl/session.py | 62 +++++++---------------------- telethon_tests/higher_level_test.py | 2 +- 3 files changed, 26 insertions(+), 64 deletions(-) diff --git a/telethon/telegram_bare_client.py b/telethon/telegram_bare_client.py index d4f19b8d..d8cc498e 100644 --- a/telethon/telegram_bare_client.py +++ b/telethon/telegram_bare_client.py @@ -39,6 +39,7 @@ from .update_state import UpdateState from .utils import get_appropriated_part_size +DEFAULT_DC_ID = 4 DEFAULT_IPV4_IP = '149.154.167.51' DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]' DEFAULT_PORT = 443 @@ -101,9 +102,11 @@ class TelegramBareClient: # ':' in session.server_address is True if it's an IPv6 address if (not session.server_address or (':' in session.server_address) != use_ipv6): - session.port = DEFAULT_PORT - session.server_address = \ - DEFAULT_IPV6_IP if self._use_ipv6 else DEFAULT_IPV4_IP + session.set_dc( + DEFAULT_DC_ID, + DEFAULT_IPV6_IP if self._use_ipv6 else DEFAULT_IPV4_IP, + DEFAULT_PORT + ) self.session = session self.api_id = int(api_id) @@ -294,8 +297,7 @@ class TelegramBareClient: dc = self._get_dc(new_dc) __log__.info('Reconnecting to new data center %s', dc) - self.session.server_address = dc.ip_address - self.session.port = dc.port + self.session.set_dc(dc.id, dc.ip_address, dc.port) # auth_key's are associated with a server, which has now changed # so it's not valid anymore. Set to None to force recreating it. self.session.auth_key = None @@ -363,8 +365,7 @@ class TelegramBareClient: # Construct this session with the connection parameters # (system version, device model...) from the current one. session = Session(self.session) - session.server_address = dc.ip_address - session.port = dc.port + session.set_dc(dc.id, dc.ip_address, dc.port) self._exported_sessions[dc_id] = session __log__.info('Creating exported new client') @@ -390,8 +391,7 @@ class TelegramBareClient: if not session: dc = self._get_dc(cdn_redirect.dc_id, cdn=True) session = Session(self.session) - session.server_address = dc.ip_address - session.port = dc.port + session.set_dc(dc.id, dc.ip_address, dc.port) self._exported_sessions[cdn_redirect.dc_id] = session __log__.info('Creating new CDN client') @@ -494,7 +494,7 @@ class TelegramBareClient: def _invoke(self, sender, call_receive, update_state, *requests): # We need to specify the new layer (by initializing a new # connection) if it has changed from the latest known one. - init_connection = self.session.layer != LAYER + init_connection = False # TODO Only first call try: # Ensure that we start with no previous errors (i.e. resending) @@ -553,12 +553,6 @@ class TelegramBareClient: # User never called .connect(), so raise this error. raise - if init_connection: - # We initialized the connection successfully, even if - # a request had an RPC error we have invoked it fine. - self.session.layer = LAYER - self.session.save() - try: raise next(x.rpc_error for x in requests if x.rpc_error) except StopIteration: diff --git a/telethon/tl/session.py b/telethon/tl/session.py index 3dfba1d9..030b4e13 100644 --- a/telethon/tl/session.py +++ b/telethon/tl/session.py @@ -67,6 +67,7 @@ class Session: self._sequence = 0 self.time_offset = 0 self._last_msg_id = 0 # Long + self.salt = 0 # Long # Cross-thread safety self._seq_no_lock = Lock() @@ -74,11 +75,10 @@ class Session: self._db_lock = Lock() # These values will be saved + self._dc_id = 0 self._server_address = None self._port = None self._auth_key = None - self._layer = 0 - self._salt = 0 # Signed long # Migrating from .json -> SQL entities = self._check_migrate_json() @@ -97,8 +97,7 @@ class Session: # These values will be saved c.execute('select * from sessions') - self._server_address, self._port, key, \ - self._layer, self._salt = c.fetchone() + self._dc_id, self._server_address, self._port, key, = c.fetchone() from ..crypto import AuthKey self._auth_key = AuthKey(data=key) @@ -108,12 +107,11 @@ class Session: c.execute("create table version (version integer)") c.execute( """create table sessions ( + dc_id integer primary key, server_address text, port integer, - auth_key blob, - layer integer, - salt integer - )""" + auth_key blob + ) without rowid""" ) c.execute( """create table entities ( @@ -142,13 +140,6 @@ class Session: self.delete() # Delete JSON file to create database self._port = data.get('port', self._port) - self._salt = data.get('salt', self._salt) - # Keep while migrating from unsigned to signed salt - if self._salt > 0: - self._salt = struct.unpack( - 'q', struct.pack('Q', self._salt))[0] - - self._layer = data.get('layer', self._layer) self._server_address = \ data.get('server_address', self._server_address) @@ -169,24 +160,20 @@ class Session: # Data from sessions should be kept as properties # not to fetch the database every time we need it + def set_dc(self, dc_id, server_address, port): + self._dc_id = dc_id + self._server_address = server_address + self._port = port + self._update_session_table() + @property def server_address(self): return self._server_address - @server_address.setter - def server_address(self, value): - self._server_address = value - self._update_session_table() - @property def port(self): return self._port - @port.setter - def port(self, value): - self._port = value - self._update_session_table() - @property def auth_key(self): return self._auth_key @@ -196,34 +183,15 @@ class Session: self._auth_key = value self._update_session_table() - @property - def layer(self): - return self._layer - - @layer.setter - def layer(self, value): - self._layer = value - self._update_session_table() - - @property - def salt(self): - return self._salt - - @salt.setter - def salt(self, value): - self._salt = value - self._update_session_table() - def _update_session_table(self): with self._db_lock: c = self._conn.cursor() c.execute('delete from sessions') - c.execute('insert into sessions values (?,?,?,?,?)', ( + c.execute('insert into sessions values (?,?,?,?)', ( + self._dc_id, self._server_address, self._port, - self._auth_key.key if self._auth_key else b'', - self._layer, - self._salt + self._auth_key.key if self._auth_key else b'' )) c.close() diff --git a/telethon_tests/higher_level_test.py b/telethon_tests/higher_level_test.py index 7bd4b181..7433fac9 100644 --- a/telethon_tests/higher_level_test.py +++ b/telethon_tests/higher_level_test.py @@ -18,7 +18,7 @@ class HigherLevelTests(unittest.TestCase): @staticmethod def test_cdn_download(): client = TelegramClient(None, api_id, api_hash) - client.session.server_address = '149.154.167.40' + client.session.set_dc(0, '149.154.167.40', 80) assert client.connect() try: