fix(core): use existing auth_key from storage

This commit is contained in:
teidesu 2022-11-08 06:50:49 +03:00 committed by Alina Sireneva
parent a23197df91
commit bd5130c77b
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
4 changed files with 73 additions and 32 deletions

View file

@ -334,6 +334,7 @@ export class BaseTelegramClient extends EventEmitter {
storage: this.storage,
testMode: this._testMode,
transport: opts.transport,
_emitError: this._emitError.bind(this),
...(opts.network ?? {}),
}, this._config)
@ -881,9 +882,8 @@ export class BaseTelegramClient extends EventEmitter {
}
}
await this.storage.updatePeers(parsedPeers)
if (count > 0) {
await this.storage.updatePeers(parsedPeers)
this.log.debug('cached %d peers', count)
}

View file

@ -10,7 +10,7 @@ import { MtprotoSession } from './mtproto-session'
export class MultiSessionConnection extends EventEmitter {
private _log: Logger
private _sessions: MtprotoSession[]
readonly _sessions: MtprotoSession[]
constructor(
readonly params: SessionConnectionParams,
@ -88,6 +88,7 @@ export class MultiSessionConnection extends EventEmitter {
if (this._connections.length > this._count) {
// destroy extra connections
for (let i = this._connections.length - 1; i >= this._count; i--) {
this._connections[i].removeAllListeners()
this._connections[i].destroy()
}
@ -97,10 +98,17 @@ export class MultiSessionConnection extends EventEmitter {
// create new connections
for (let i = this._connections.length; i < this._count; i++) {
const session = this.params.isMainConnection ? this._sessions[i] : this._sessions[0]
const session = this.params.isMainConnection
? this._sessions[i]
: this._sessions[0]
const conn = new SessionConnection(this.params, session)
conn.on('update', (update) => this.emit('update', update))
conn.on('error', (err) => this.emit('error', err, conn))
conn.on('key-change', (key) => this.emit('key-change', i, key))
conn.on('tmp-key-change', (key, expires) =>
this.emit('tmp-key-change', i, key, expires)
)
this._connections.push(conn)
}
@ -128,7 +136,9 @@ export class MultiSessionConnection extends EventEmitter {
let minIdx = 0
for (let i = 0; i < this._connections.length; i++) {
const conn = this._connections[i]
const total = conn._session.queuedRpc.length + conn._session.pendingMessages.size()
const total =
conn._session.queuedRpc.length +
conn._session.pendingMessages.size()
if (total < min) {
min = total
@ -157,4 +167,10 @@ export class MultiSessionConnection extends EventEmitter {
conn.connect()
}
}
async setAuthKey(authKey: Buffer | null, temp = false, idx = 0): Promise<void> {
const session = this._sessions[idx]
const key = temp ? session._authKeyTemp : session._authKey
await key.setup(authKey)
}
}

View file

@ -10,16 +10,10 @@ import {
import { PersistentConnectionParams } from './persistent-connection'
import { ConfigManager } from './config-manager'
import { MultiSessionConnection } from './multi-session-connection'
import { SessionConnectionParams } from './session-connection'
import { SessionConnection, SessionConnectionParams } from "./session-connection";
import { ITelegramStorage } from '../storage'
export class DcConnectionManager {
constructor(
readonly manager: NetworkManager,
readonly dcId: number,
private _dc: tl.RawDcOption
) {}
private __baseConnectionParams = (): SessionConnectionParams => ({
crypto: this.manager.params.crypto,
initConnection: this.manager._initConnectionParams,
@ -43,6 +37,38 @@ export class DcConnectionManager {
1,
this.manager._log
)
constructor(
readonly manager: NetworkManager,
readonly dcId: number,
private _dc: tl.RawDcOption
) {
this._setupStorageHandlers(this.mainConnection)
}
private _setupStorageHandlers(connection: MultiSessionConnection): void {
connection.on('key-change', (idx, key) => {
this.manager._log.debug('key change for dc %d from connection %d', this.dcId, idx)
this.manager._storage.setAuthKeyFor(this.dcId, key)
})
connection.on('tmp-key-change', (idx, key, expires) => {
this.manager._log.debug('temp key change for dc %d from connection %d', this.dcId, idx)
this.manager._storage.setTempAuthKeyFor(this.dcId, idx, key, expires * 1000)
})
}
async loadKeys(): Promise<void> {
const permanent = await this.manager._storage.getAuthKeyFor(this.dcId)
await this.mainConnection.setAuthKey(permanent)
if (this.manager.params.usePfs) {
for (let i = 0; i < this.mainConnection._sessions.length; i++) {
const temp = await this.manager._storage.getAuthKeyFor(this.dcId, i)
await this.mainConnection.setAuthKey(temp, true, i)
}
}
}
}
/**
@ -66,6 +92,7 @@ export interface NetworkManagerParams {
layer: number
readerMap: TlReaderMap
writerMap: TlWriterMap
_emitError: (err: Error, connection?: SessionConnection) => void
}
/**
@ -82,6 +109,7 @@ export interface NetworkManagerExtraParams {
export class NetworkManager {
readonly _log = this.params.log.create('network')
readonly _storage = this.params.storage
readonly _initConnectionParams: tl.RawInitConnectionRequest
readonly _transportFactory: TransportFactory
@ -92,6 +120,8 @@ export class NetworkManager {
private _keepAliveInterval?: NodeJS.Timeout
private _keepAliveAction = this._defaultKeepAliveAction.bind(this)
private _lastUpdateTime = 0
private _updateHandler: (upd: tl.TypeUpdates) => void = () => {}
private _defaultKeepAliveAction(): void {
if (this._keepAliveInterval) return
@ -160,9 +190,7 @@ export class NetworkManager {
this._primaryDc = dc
// todo add handlers
/*
this.primaryConnection.on('usable', () => {
dc.mainConnection.on('usable', () => {
this._lastUpdateTime = Date.now()
if (this._keepAliveInterval) clearInterval(this._keepAliveInterval)
@ -173,22 +201,19 @@ export class NetworkManager {
}
}, 60_000)
})
this.primaryConnection.on('update', (update) => {
dc.mainConnection.on('update', (update) => {
this._lastUpdateTime = Date.now()
this._handleUpdate(update)
this._updateHandler(update)
})
this.primaryConnection.on('wait', () =>
this._cleanupPrimaryConnection()
// dc.mainConnection.on('wait', () =>
// this._cleanupPrimaryConnection()
// )
dc.mainConnection.on('error', (err, conn) =>
this.params._emitError(err, conn)
)
this.primaryConnection.on('key-change', async (key) => {
this.storage.setAuthKeyFor(this._defaultDc.id, key)
await this._saveStorage()
})
this.primaryConnection.on('error', (err) =>
this._emitError(err, this.primaryConnection)
)
*/
dc.mainConnection.connect()
dc.loadKeys()
.catch((e) => this.params._emitError(e))
.then(() => dc.mainConnection.connect())
}
/**

View file

@ -41,7 +41,7 @@ import {
import { TransportError } from './transports'
import { createAesIgeForMessageOld } from '../utils/crypto/mtproto'
const TEMP_AUTH_KEY_EXPIRY = 300 // 86400 fixme
const TEMP_AUTH_KEY_EXPIRY = 86400
export interface SessionConnectionParams extends PersistentConnectionParams {
initConnection: tl.RawInitConnectionRequest
@ -57,7 +57,7 @@ export interface SessionConnectionParams extends PersistentConnectionParams {
}
// destroy_auth_key#d1435160 = DestroyAuthKeyRes;
const DESTROY_AUTH_KEY = Buffer.from('605134d1', 'hex')
// const DESTROY_AUTH_KEY = Buffer.from('605134d1', 'hex')
function makeNiceStack(
error: tl.errors.RpcError,
@ -160,7 +160,7 @@ export class SessionConnection extends PersistentConnection {
this._authorize()
// todo: if we use pfs, we can also start temp key exchange here
} else if (this.params.usePfs && !this._session._authKeyTemp.ready) {
this.log.info('no perm auth key but using pfs, authorizing')
this.log.info('no temp auth key but using pfs, authorizing')
this._authorizePfs()
} else {
this.log.info('auth keys are already available')
@ -234,7 +234,7 @@ export class SessionConnection extends PersistentConnection {
}
}
this.emit('err', error)
this.emit('error', error)
}
protected onConnectionUsable() {