mirror of
https://github.com/mautrix/telegram.git
synced 2026-05-17 07:25:46 +03:00
131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
package tdesktop
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-faster/errors"
|
|
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
|
|
)
|
|
|
|
// MTPDCOption is a Telegram Desktop storage structure which stores DC info.
|
|
//
|
|
// See https://github.com/telegramdesktop/tdesktop/blob/v2.9.8/Telegram/SourceFiles/mtproto/mtproto_dc_options.h.
|
|
type MTPDCOption struct {
|
|
ID int32
|
|
Flags bin.Fields
|
|
Port int32
|
|
IP string
|
|
Secret []byte
|
|
}
|
|
|
|
// IPv6 denotes that the specified IP is an IPv6 address.
|
|
func (m MTPDCOption) IPv6() bool {
|
|
return m.Flags.Has(0)
|
|
}
|
|
|
|
// MediaOnly denotes that this DC should only be used to download or upload files.
|
|
func (m MTPDCOption) MediaOnly() bool {
|
|
return m.Flags.Has(1)
|
|
}
|
|
|
|
// TCPOOnly denotes that this DC only supports connection with transport obfuscation.
|
|
func (m MTPDCOption) TCPOOnly() bool {
|
|
return m.Flags.Has(2)
|
|
}
|
|
|
|
// CDN denotes that this is a CDN DC.
|
|
func (m MTPDCOption) CDN() bool {
|
|
return m.Flags.Has(3)
|
|
}
|
|
|
|
// Static denotes that this IP should be used when connecting through a proxy.
|
|
func (m MTPDCOption) Static() bool {
|
|
return m.Flags.Has(4)
|
|
}
|
|
|
|
func (m *MTPDCOption) deserialize(r *qtReader, version int32) error {
|
|
id, err := r.readInt32()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read id")
|
|
}
|
|
m.ID = id
|
|
|
|
flags, err := r.readUint32()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read flags")
|
|
}
|
|
m.Flags = bin.Fields(flags)
|
|
|
|
port, err := r.readInt32()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read port")
|
|
}
|
|
m.Port = port
|
|
|
|
const maxIPSize = 45
|
|
ip, err := r.readString()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read ip")
|
|
}
|
|
if l := len(ip); l > maxIPSize {
|
|
return errors.Errorf("too big IP string (%d > %d)", l, maxIPSize)
|
|
}
|
|
m.IP = ip
|
|
|
|
if version > 0 {
|
|
const maxSecretSize = 32
|
|
secret, err := r.readBytes()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read secret")
|
|
}
|
|
if l := len(secret); l > maxSecretSize {
|
|
return errors.Errorf("too big DC secret (%d > %d)", l, maxSecretSize)
|
|
}
|
|
m.Secret = secret
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MTPDCOptions is a Telegram Desktop storage structure which stores DCs info.
|
|
//
|
|
// See https://github.com/telegramdesktop/tdesktop/blob/v2.9.8/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp#L479.
|
|
type MTPDCOptions struct {
|
|
Options []MTPDCOption
|
|
}
|
|
|
|
func (m *MTPDCOptions) deserialize(r *qtReader) error {
|
|
minusVersion, err := r.readInt32()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read version")
|
|
}
|
|
|
|
var version int32
|
|
if minusVersion < 0 {
|
|
version = -minusVersion
|
|
}
|
|
|
|
var count int32
|
|
if version > 0 {
|
|
c, err := r.readInt32()
|
|
if err != nil {
|
|
return errors.Wrap(err, "read count")
|
|
}
|
|
count = c
|
|
} else {
|
|
count = minusVersion
|
|
}
|
|
|
|
for i := 0; i < int(count); i++ {
|
|
var o MTPDCOption
|
|
if err := o.deserialize(r, version); err != nil {
|
|
return fmt.Errorf("read option %d: %w", i, err)
|
|
}
|
|
m.Options = append(m.Options, o)
|
|
}
|
|
|
|
// TODO(tdakkota): Read CDN keys.
|
|
return nil
|
|
}
|