package telegram
import (
"context"
"fmt"
"github.com/go-faster/errors"
"go.uber.org/zap"
"github.com/gotd/td/internal/crypto"
"github.com/gotd/td/internal/mtproto"
"github.com/gotd/td/internal/pool"
"github.com/gotd/td/session"
"github.com/gotd/td/tg"
)
func (c *Client ) restoreConnection (ctx context .Context ) error {
if c .storage == nil {
return nil
}
data , err := c .storage .Load (ctx )
if errors .Is (err , session .ErrNotFound ) {
return nil
}
if err != nil {
return errors .Wrap (err , "load" )
}
prev := c .session .Load ()
if data .DC == 0 {
data .DC = prev .DC
}
var key crypto .AuthKey
copy (key .Value [:], data .AuthKey )
copy (key .ID [:], data .AuthKeyID )
if key .Value .ID () != key .ID {
return errors .New ("corrupted key" )
}
c .log .Info ("Connection restored from state" ,
zap .String ("addr" , data .Addr ),
zap .String ("key_id" , fmt .Sprintf ("%x" , data .AuthKeyID )),
)
c .connMux .Lock ()
c .session .Store (pool .Session {
DC : data .DC ,
AuthKey : key ,
Salt : data .Salt ,
})
c .conn = c .createPrimaryConn (nil )
c .connMux .Unlock ()
return nil
}
func (c *Client ) saveSession (cfg tg .Config , s mtproto .Session ) error {
if c .storage == nil {
return nil
}
data , err := c .storage .Load (c .ctx )
if errors .Is (err , session .ErrNotFound ) {
err = nil
data = &session .Data {}
}
if err != nil {
return errors .Wrap (err , "load" )
}
data .Config = session .ConfigFromTG (cfg )
data .AuthKey = s .Key .Value [:]
data .AuthKeyID = s .Key .ID [:]
data .DC = cfg .ThisDC
data .Salt = s .Salt
if err := c .storage .Save (c .ctx , data ); err != nil {
return errors .Wrap (err , "save" )
}
c .log .Debug ("Data saved" ,
zap .String ("key_id" , fmt .Sprintf ("%x" , data .AuthKeyID )),
)
return nil
}
func (c *Client ) onSession (cfg tg .Config , s mtproto .Session ) error {
c .sessionsMux .Lock ()
c .sessions [cfg .ThisDC ] = pool .NewSyncSession (pool .Session {
DC : cfg .ThisDC ,
Salt : s .Salt ,
AuthKey : s .Key ,
})
c .sessionsMux .Unlock ()
primaryDC := c .session .Load ().DC
if cfg .ThisDC != 0 && primaryDC != 0 && primaryDC != cfg .ThisDC {
return nil
}
c .connMux .Lock ()
c .session .Store (pool .Session {
DC : cfg .ThisDC ,
Salt : s .Salt ,
AuthKey : s .Key ,
})
c .cfg .Store (cfg )
c .onReady ()
c .connMux .Unlock ()
if err := c .saveSession (cfg , s ); err != nil {
return errors .Wrap (err , "save" )
}
return nil
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .