-
-
Notifications
You must be signed in to change notification settings - Fork 126
/
mtp_dcoptions.go
128 lines (108 loc) · 2.8 KB
/
mtp_dcoptions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package tdesktop
import (
"github.com/go-faster/errors"
"github.com/gotd/td/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 errors.Errorf("read option %d: %w", i, err)
}
m.Options = append(m.Options, o)
}
// TODO(tdakkota): Read CDN keys.
return nil
}