mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-26 11:23:46 +03:00
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:
parent
21e5f0b547
commit
ab07f0220a
|
@ -39,6 +39,7 @@ from .update_state import UpdateState
|
||||||
from .utils import get_appropriated_part_size
|
from .utils import get_appropriated_part_size
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_DC_ID = 4
|
||||||
DEFAULT_IPV4_IP = '149.154.167.51'
|
DEFAULT_IPV4_IP = '149.154.167.51'
|
||||||
DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]'
|
DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]'
|
||||||
DEFAULT_PORT = 443
|
DEFAULT_PORT = 443
|
||||||
|
@ -101,9 +102,11 @@ class TelegramBareClient:
|
||||||
# ':' in session.server_address is True if it's an IPv6 address
|
# ':' in session.server_address is True if it's an IPv6 address
|
||||||
if (not session.server_address or
|
if (not session.server_address or
|
||||||
(':' in session.server_address) != use_ipv6):
|
(':' in session.server_address) != use_ipv6):
|
||||||
session.port = DEFAULT_PORT
|
session.set_dc(
|
||||||
session.server_address = \
|
DEFAULT_DC_ID,
|
||||||
DEFAULT_IPV6_IP if self._use_ipv6 else DEFAULT_IPV4_IP
|
DEFAULT_IPV6_IP if self._use_ipv6 else DEFAULT_IPV4_IP,
|
||||||
|
DEFAULT_PORT
|
||||||
|
)
|
||||||
|
|
||||||
self.session = session
|
self.session = session
|
||||||
self.api_id = int(api_id)
|
self.api_id = int(api_id)
|
||||||
|
@ -294,8 +297,7 @@ class TelegramBareClient:
|
||||||
dc = self._get_dc(new_dc)
|
dc = self._get_dc(new_dc)
|
||||||
__log__.info('Reconnecting to new data center %s', dc)
|
__log__.info('Reconnecting to new data center %s', dc)
|
||||||
|
|
||||||
self.session.server_address = dc.ip_address
|
self.session.set_dc(dc.id, dc.ip_address, dc.port)
|
||||||
self.session.port = dc.port
|
|
||||||
# auth_key's are associated with a server, which has now changed
|
# 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.
|
# so it's not valid anymore. Set to None to force recreating it.
|
||||||
self.session.auth_key = None
|
self.session.auth_key = None
|
||||||
|
@ -363,8 +365,7 @@ class TelegramBareClient:
|
||||||
# Construct this session with the connection parameters
|
# Construct this session with the connection parameters
|
||||||
# (system version, device model...) from the current one.
|
# (system version, device model...) from the current one.
|
||||||
session = Session(self.session)
|
session = Session(self.session)
|
||||||
session.server_address = dc.ip_address
|
session.set_dc(dc.id, dc.ip_address, dc.port)
|
||||||
session.port = dc.port
|
|
||||||
self._exported_sessions[dc_id] = session
|
self._exported_sessions[dc_id] = session
|
||||||
|
|
||||||
__log__.info('Creating exported new client')
|
__log__.info('Creating exported new client')
|
||||||
|
@ -390,8 +391,7 @@ class TelegramBareClient:
|
||||||
if not session:
|
if not session:
|
||||||
dc = self._get_dc(cdn_redirect.dc_id, cdn=True)
|
dc = self._get_dc(cdn_redirect.dc_id, cdn=True)
|
||||||
session = Session(self.session)
|
session = Session(self.session)
|
||||||
session.server_address = dc.ip_address
|
session.set_dc(dc.id, dc.ip_address, dc.port)
|
||||||
session.port = dc.port
|
|
||||||
self._exported_sessions[cdn_redirect.dc_id] = session
|
self._exported_sessions[cdn_redirect.dc_id] = session
|
||||||
|
|
||||||
__log__.info('Creating new CDN client')
|
__log__.info('Creating new CDN client')
|
||||||
|
@ -494,7 +494,7 @@ class TelegramBareClient:
|
||||||
def _invoke(self, sender, call_receive, update_state, *requests):
|
def _invoke(self, sender, call_receive, update_state, *requests):
|
||||||
# We need to specify the new layer (by initializing a new
|
# We need to specify the new layer (by initializing a new
|
||||||
# connection) if it has changed from the latest known one.
|
# connection) if it has changed from the latest known one.
|
||||||
init_connection = self.session.layer != LAYER
|
init_connection = False # TODO Only first call
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Ensure that we start with no previous errors (i.e. resending)
|
# 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.
|
# User never called .connect(), so raise this error.
|
||||||
raise
|
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:
|
try:
|
||||||
raise next(x.rpc_error for x in requests if x.rpc_error)
|
raise next(x.rpc_error for x in requests if x.rpc_error)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|
|
@ -67,6 +67,7 @@ class Session:
|
||||||
self._sequence = 0
|
self._sequence = 0
|
||||||
self.time_offset = 0
|
self.time_offset = 0
|
||||||
self._last_msg_id = 0 # Long
|
self._last_msg_id = 0 # Long
|
||||||
|
self.salt = 0 # Long
|
||||||
|
|
||||||
# Cross-thread safety
|
# Cross-thread safety
|
||||||
self._seq_no_lock = Lock()
|
self._seq_no_lock = Lock()
|
||||||
|
@ -74,11 +75,10 @@ class Session:
|
||||||
self._db_lock = Lock()
|
self._db_lock = Lock()
|
||||||
|
|
||||||
# These values will be saved
|
# These values will be saved
|
||||||
|
self._dc_id = 0
|
||||||
self._server_address = None
|
self._server_address = None
|
||||||
self._port = None
|
self._port = None
|
||||||
self._auth_key = None
|
self._auth_key = None
|
||||||
self._layer = 0
|
|
||||||
self._salt = 0 # Signed long
|
|
||||||
|
|
||||||
# Migrating from .json -> SQL
|
# Migrating from .json -> SQL
|
||||||
entities = self._check_migrate_json()
|
entities = self._check_migrate_json()
|
||||||
|
@ -97,8 +97,7 @@ class Session:
|
||||||
|
|
||||||
# These values will be saved
|
# These values will be saved
|
||||||
c.execute('select * from sessions')
|
c.execute('select * from sessions')
|
||||||
self._server_address, self._port, key, \
|
self._dc_id, self._server_address, self._port, key, = c.fetchone()
|
||||||
self._layer, self._salt = c.fetchone()
|
|
||||||
|
|
||||||
from ..crypto import AuthKey
|
from ..crypto import AuthKey
|
||||||
self._auth_key = AuthKey(data=key)
|
self._auth_key = AuthKey(data=key)
|
||||||
|
@ -108,12 +107,11 @@ class Session:
|
||||||
c.execute("create table version (version integer)")
|
c.execute("create table version (version integer)")
|
||||||
c.execute(
|
c.execute(
|
||||||
"""create table sessions (
|
"""create table sessions (
|
||||||
|
dc_id integer primary key,
|
||||||
server_address text,
|
server_address text,
|
||||||
port integer,
|
port integer,
|
||||||
auth_key blob,
|
auth_key blob
|
||||||
layer integer,
|
) without rowid"""
|
||||||
salt integer
|
|
||||||
)"""
|
|
||||||
)
|
)
|
||||||
c.execute(
|
c.execute(
|
||||||
"""create table entities (
|
"""create table entities (
|
||||||
|
@ -142,13 +140,6 @@ class Session:
|
||||||
self.delete() # Delete JSON file to create database
|
self.delete() # Delete JSON file to create database
|
||||||
|
|
||||||
self._port = data.get('port', self._port)
|
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 = \
|
self._server_address = \
|
||||||
data.get('server_address', self._server_address)
|
data.get('server_address', self._server_address)
|
||||||
|
|
||||||
|
@ -169,24 +160,20 @@ class Session:
|
||||||
|
|
||||||
# Data from sessions should be kept as properties
|
# Data from sessions should be kept as properties
|
||||||
# not to fetch the database every time we need it
|
# 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
|
@property
|
||||||
def server_address(self):
|
def server_address(self):
|
||||||
return self._server_address
|
return self._server_address
|
||||||
|
|
||||||
@server_address.setter
|
|
||||||
def server_address(self, value):
|
|
||||||
self._server_address = value
|
|
||||||
self._update_session_table()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port(self):
|
def port(self):
|
||||||
return self._port
|
return self._port
|
||||||
|
|
||||||
@port.setter
|
|
||||||
def port(self, value):
|
|
||||||
self._port = value
|
|
||||||
self._update_session_table()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auth_key(self):
|
def auth_key(self):
|
||||||
return self._auth_key
|
return self._auth_key
|
||||||
|
@ -196,34 +183,15 @@ class Session:
|
||||||
self._auth_key = value
|
self._auth_key = value
|
||||||
self._update_session_table()
|
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):
|
def _update_session_table(self):
|
||||||
with self._db_lock:
|
with self._db_lock:
|
||||||
c = self._conn.cursor()
|
c = self._conn.cursor()
|
||||||
c.execute('delete from sessions')
|
c.execute('delete from sessions')
|
||||||
c.execute('insert into sessions values (?,?,?,?,?)', (
|
c.execute('insert into sessions values (?,?,?,?)', (
|
||||||
|
self._dc_id,
|
||||||
self._server_address,
|
self._server_address,
|
||||||
self._port,
|
self._port,
|
||||||
self._auth_key.key if self._auth_key else b'',
|
self._auth_key.key if self._auth_key else b''
|
||||||
self._layer,
|
|
||||||
self._salt
|
|
||||||
))
|
))
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class HigherLevelTests(unittest.TestCase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def test_cdn_download():
|
def test_cdn_download():
|
||||||
client = TelegramClient(None, api_id, api_hash)
|
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()
|
assert client.connect()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user