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.
This commit is contained in:
Lonami Exo 2017-12-28 01:04:11 +01:00
parent 21e5f0b547
commit ab07f0220a
3 changed files with 26 additions and 64 deletions

View File

@ -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:

View File

@ -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()

View File

@ -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: