ソースを参照

Merge pull request #37 from 9seconds/default-dcidx

Support of default DC indexes
tags/v0.13^2
Sergey Arkhipov 7年前
コミット
591500de41
コミッターのメールアドレスに関連付けられたアカウントが存在しません

+ 1
- 1
Dockerfile ファイルの表示

1
 ###############################################################################
1
 ###############################################################################
2
 # BUILD STAGE
2
 # BUILD STAGE
3
 
3
 
4
-FROM golang:alpine
4
+FROM golang:1.10-alpine
5
 
5
 
6
 RUN set -x \
6
 RUN set -x \
7
   && apk --no-cache --update add \
7
   && apk --no-cache --update add \

+ 10
- 10
Gopkg.lock ファイルの表示

29
   version = "v0.2.0"
29
   version = "v0.2.0"
30
 
30
 
31
 [[projects]]
31
 [[projects]]
32
-  digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
32
+  digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
33
   name = "github.com/davecgh/go-spew"
33
   name = "github.com/davecgh/go-spew"
34
   packages = ["spew"]
34
   packages = ["spew"]
35
   pruneopts = "UT"
35
   pruneopts = "UT"
36
-  revision = "346938d642f2ec3594ed81d874461961cd0faa76"
37
-  version = "v1.1.0"
36
+  revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
37
+  version = "v1.1.1"
38
 
38
 
39
 [[projects]]
39
 [[projects]]
40
   branch = "master"
40
   branch = "master"
46
 
46
 
47
 [[projects]]
47
 [[projects]]
48
   branch = "master"
48
   branch = "master"
49
-  digest = "1:53bd4347b151fcbedcdda527f7ebf4924f0e21d672131812f857175d8c7a1051"
49
+  digest = "1:1261ccace00babbf02bb702e71c85c8e81f65bad7bdb98c12c7a409c14de1d86"
50
   name = "github.com/juju/errors"
50
   name = "github.com/juju/errors"
51
   packages = ["."]
51
   packages = ["."]
52
   pruneopts = "UT"
52
   pruneopts = "UT"
53
-  revision = "812b06ada1776ad4dd95d575e18ffffe3a9ac34a"
53
+  revision = "22422dad46e14561a0854ad42497a75af9b61909"
54
 
54
 
55
 [[projects]]
55
 [[projects]]
56
   digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
56
   digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
93
   version = "v1.1.0"
93
   version = "v1.1.0"
94
 
94
 
95
 [[projects]]
95
 [[projects]]
96
-  digest = "1:d9a420eae5f76973feeb733fbf58f6a89173255b63b27a7ae4b2124a73dc6c5b"
96
+  digest = "1:c52caf7bd44f92e54627a31b85baf06a68333a196b3d8d241480a774733dcf8b"
97
   name = "go.uber.org/zap"
97
   name = "go.uber.org/zap"
98
   packages = [
98
   packages = [
99
     ".",
99
     ".",
104
     "zapcore",
104
     "zapcore",
105
   ]
105
   ]
106
   pruneopts = "UT"
106
   pruneopts = "UT"
107
-  revision = "4d45f9617f7d90f7a663ff21c7a4321dbe78098b"
108
-  version = "v1.9.0"
107
+  revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982"
108
+  version = "v1.9.1"
109
 
109
 
110
 [[projects]]
110
 [[projects]]
111
   branch = "master"
111
   branch = "master"
112
-  digest = "1:becb2131aece71c64ebca5ddfd38cf631784fbb3a678d73ead3b42107c9f41ce"
112
+  digest = "1:937d8f64b118c494c48b0cc9c990f2163c7483e6c70b5828f20006d81c61412f"
113
   name = "golang.org/x/net"
113
   name = "golang.org/x/net"
114
   packages = [
114
   packages = [
115
     "bpf",
115
     "bpf",
118
     "ipv4",
118
     "ipv4",
119
   ]
119
   ]
120
   pruneopts = "UT"
120
   pruneopts = "UT"
121
-  revision = "3673e40ba22529d22c3fd7c93e97b0ce50fa7bdd"
121
+  revision = "2f5d2388922f370f4355f327fcf4cfe9f5583908"
122
 
122
 
123
 [[projects]]
123
 [[projects]]
124
   digest = "1:c06d9e11d955af78ac3bbb26bd02e01d2f61f689e1a3bce2ef6fb683ef8a7f2d"
124
   digest = "1:c06d9e11d955af78ac3bbb26bd02e01d2f61f689e1a3bce2ef6fb683ef8a7f2d"

+ 2
- 1
Makefile ファイルの表示

6
 CC_BINARIES  := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
6
 CC_BINARIES  := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
7
 APP_DEPS     := version.go $(VENDOR_FILES)
7
 APP_DEPS     := version.go $(VENDOR_FILES)
8
 
8
 
9
-GOLANGCI_LINT_VERSION := v1.9.2
9
+GOLANGCI_LINT_VERSION := v1.10.2
10
 
10
 
11
 COMMON_BUILD_FLAGS := -ldflags="-s -w"
11
 COMMON_BUILD_FLAGS := -ldflags="-s -w"
12
 
12
 
74
 
74
 
75
 .PHONY: prepare
75
 .PHONY: prepare
76
 prepare: install-dep install-lint install-critic
76
 prepare: install-dep install-lint install-critic
77
+	@dep ensure --vendor-only
77
 
78
 
78
 .PHONY: install-dep
79
 .PHONY: install-dep
79
 install-dep:
80
 install-dep:

+ 2
- 2
client/direct.go ファイルの表示

30
 		return nil, nil, errors.Annotate(err, "Cannot set write buffer size of client socket")
30
 		return nil, nil, errors.Annotate(err, "Cannot set write buffer size of client socket")
31
 	}
31
 	}
32
 
32
 
33
-	socket.SetReadDeadline(time.Now().Add(handshakeTimeout)) // nolint: errcheck
33
+	socket.SetReadDeadline(time.Now().Add(handshakeTimeout)) // nolint: errcheck, gosec
34
 	frame, err := obfuscated2.ExtractFrame(socket)
34
 	frame, err := obfuscated2.ExtractFrame(socket)
35
 	if err != nil {
35
 	if err != nil {
36
 		return nil, nil, errors.Annotate(err, "Cannot extract frame")
36
 		return nil, nil, errors.Annotate(err, "Cannot extract frame")
37
 	}
37
 	}
38
-	socket.SetReadDeadline(time.Time{}) // nolint: errcheck
38
+	socket.SetReadDeadline(time.Time{}) // nolint: errcheck, gosec
39
 
39
 
40
 	conn := wrappers.NewConn(ctx, cancel, socket, connID, wrappers.ConnPurposeClient, conf.PublicIPv4, conf.PublicIPv6)
40
 	conn := wrappers.NewConn(ctx, cancel, socket, connID, wrappers.ConnPurposeClient, conf.PublicIPv4, conf.PublicIPv6)
41
 	obfs2, connOpts, err := obfuscated2.ParseObfuscated2ClientFrame(conf.Secret, frame)
41
 	obfs2, connOpts, err := obfuscated2.ParseObfuscated2ClientFrame(conf.Secret, frame)

+ 1
- 1
main.go ファイルの表示

227
 }
227
 }
228
 
228
 
229
 func usage(msg string) {
229
 func usage(msg string) {
230
-	io.WriteString(os.Stderr, msg+"\n") // nolint: errcheck
230
+	io.WriteString(os.Stderr, msg+"\n") // nolint: errcheck, gosec
231
 	os.Exit(1)
231
 	os.Exit(1)
232
 }
232
 }

+ 4
- 4
mtproto/rpc/handshake_request.go ファイルの表示

12
 	buf := &bytes.Buffer{}
12
 	buf := &bytes.Buffer{}
13
 	buf.Grow(len(TagHandshake) + len(HandshakeFlags) + len(HandshakeSenderPID) + len(HandshakePeerPID))
13
 	buf.Grow(len(TagHandshake) + len(HandshakeFlags) + len(HandshakeSenderPID) + len(HandshakePeerPID))
14
 
14
 
15
-	buf.Write(TagHandshake)
16
-	buf.Write(HandshakeFlags)
17
-	buf.Write(HandshakeSenderPID)
18
-	buf.Write(HandshakePeerPID)
15
+	buf.Write(TagHandshake)       // nolint: gosec
16
+	buf.Write(HandshakeFlags)     // nolint: gosec
17
+	buf.Write(HandshakeSenderPID) // nolint: gosec
18
+	buf.Write(HandshakePeerPID)   // nolint: gosec
19
 
19
 
20
 	return buf.Bytes()
20
 	return buf.Bytes()
21
 }
21
 }

+ 4
- 4
mtproto/rpc/handshake_response.go ファイルの表示

19
 func (r *HandshakeResponse) Bytes() []byte {
19
 func (r *HandshakeResponse) Bytes() []byte {
20
 	buf := &bytes.Buffer{}
20
 	buf := &bytes.Buffer{}
21
 
21
 
22
-	buf.Write(r.Type)
23
-	buf.Write(r.Flags)
24
-	buf.Write(r.SenderPID)
25
-	buf.Write(r.PeerPID)
22
+	buf.Write(r.Type)      // nolint: gosec
23
+	buf.Write(r.Flags)     // nolint: gosec
24
+	buf.Write(r.SenderPID) // nolint: gosec
25
+	buf.Write(r.PeerPID)   // nolint: gosec
26
 
26
 
27
 	return buf.Bytes()
27
 	return buf.Bytes()
28
 }
28
 }

+ 5
- 5
mtproto/rpc/nonce_request.go ファイルの表示

21
 func (r *NonceRequest) Bytes() []byte {
21
 func (r *NonceRequest) Bytes() []byte {
22
 	buf := &bytes.Buffer{}
22
 	buf := &bytes.Buffer{}
23
 
23
 
24
-	buf.Write(TagNonce)
25
-	buf.Write(r.KeySelector)
26
-	buf.Write(NonceCryptoAES)
27
-	buf.Write(r.CryptoTS)
28
-	buf.Write(r.Nonce)
24
+	buf.Write(TagNonce)       // nolint: gosec
25
+	buf.Write(r.KeySelector)  // nolint: gosec
26
+	buf.Write(NonceCryptoAES) // nolint: gosec
27
+	buf.Write(r.CryptoTS)     // nolint: gosec
28
+	buf.Write(r.Nonce)        // nolint: gosec
29
 
29
 
30
 	return buf.Bytes()
30
 	return buf.Bytes()
31
 }
31
 }

+ 5
- 5
mtproto/rpc/nonce_response.go ファイルの表示

18
 func (r *NonceResponse) Bytes() []byte {
18
 func (r *NonceResponse) Bytes() []byte {
19
 	buf := &bytes.Buffer{}
19
 	buf := &bytes.Buffer{}
20
 
20
 
21
-	buf.Write(r.Type)
22
-	buf.Write(r.KeySelector)
23
-	buf.Write(r.Crypto)
24
-	buf.Write(r.CryptoTS)
25
-	buf.Write(r.Nonce)
21
+	buf.Write(r.Type)        // nolint: gosec
22
+	buf.Write(r.KeySelector) // nolint: gosec
23
+	buf.Write(r.Crypto)      // nolint: gosec
24
+	buf.Write(r.CryptoTS)    // nolint: gosec
25
+	buf.Write(r.Nonce)       // nolint: gosec
26
 
26
 
27
 	return buf.Bytes()
27
 	return buf.Bytes()
28
 }
28
 }

+ 10
- 10
mtproto/rpc/proxy_request.go ファイルの表示

49
 		flags |= proxyRequestFlagsEncrypted
49
 		flags |= proxyRequestFlagsEncrypted
50
 	}
50
 	}
51
 
51
 
52
-	buf.Write(TagProxyRequest)
53
-	buf.Write(flags.Bytes())
54
-	buf.Write(r.ConnectionID)
55
-	buf.Write(r.ClientIPPort)
56
-	buf.Write(r.OurIPPort)
57
-	buf.Write(ProxyRequestExtraSize)
58
-	buf.Write(ProxyRequestProxyTag)
59
-	buf.WriteByte(byte(len(r.ADTag)))
60
-	buf.Write(r.ADTag)
61
-	buf.Write(make([]byte, (4-buf.Len()%4)%4))
52
+	buf.Write(TagProxyRequest)                 // nolint: gosec
53
+	buf.Write(flags.Bytes())                   // nolint: gosec
54
+	buf.Write(r.ConnectionID)                  // nolint: gosec
55
+	buf.Write(r.ClientIPPort)                  // nolint: gosec
56
+	buf.Write(r.OurIPPort)                     // nolint: gosec
57
+	buf.Write(ProxyRequestExtraSize)           // nolint: gosec
58
+	buf.Write(ProxyRequestProxyTag)            // nolint: gosec
59
+	buf.WriteByte(byte(len(r.ADTag)))          // nolint: gosec
60
+	buf.Write(r.ADTag)                         // nolint: gosec
61
+	buf.Write(make([]byte, (4-buf.Len()%4)%4)) // nolint: gosec
62
 
62
 
63
 	return buf, flags
63
 	return buf, flags
64
 }
64
 }

+ 1
- 1
obfuscated2/frame.go ファイルの表示

113
 		}
113
 		}
114
 
114
 
115
 		// error has to be checked before calling this function
115
 		// error has to be checked before calling this function
116
-		tag, _ := connectionType.Tag() // nolint: errcheck
116
+		tag, _ := connectionType.Tag() // nolint: errcheck, gosec
117
 		copy(frame.Magic(), tag)
117
 		copy(frame.Magic(), tag)
118
 
118
 
119
 		return frame
119
 		return frame

+ 5
- 5
obfuscated2/obfuscated2.go ファイルの表示

23
 // Beware, link above is in russian.
23
 // Beware, link above is in russian.
24
 func ParseObfuscated2ClientFrame(secret []byte, frame Frame) (*Obfuscated2, *mtproto.ConnectionOpts, error) {
24
 func ParseObfuscated2ClientFrame(secret []byte, frame Frame) (*Obfuscated2, *mtproto.ConnectionOpts, error) {
25
 	decHasher := sha256.New()
25
 	decHasher := sha256.New()
26
-	decHasher.Write(frame.Key()) // nolint: errcheck
27
-	decHasher.Write(secret)      // nolint: errcheck
26
+	decHasher.Write(frame.Key()) // nolint: errcheck, gosec
27
+	decHasher.Write(secret)      // nolint: errcheck, gosec
28
 	decryptor := makeStreamCipher(decHasher.Sum(nil), frame.IV())
28
 	decryptor := makeStreamCipher(decHasher.Sum(nil), frame.IV())
29
 
29
 
30
 	invertedFrame := frame.Invert()
30
 	invertedFrame := frame.Invert()
31
 	encHasher := sha256.New()
31
 	encHasher := sha256.New()
32
-	encHasher.Write(invertedFrame.Key()) // nolint: errcheck
33
-	encHasher.Write(secret)              // nolint: errcheck
32
+	encHasher.Write(invertedFrame.Key()) // nolint: errcheck, gosec
33
+	encHasher.Write(secret)              // nolint: errcheck, gosec
34
 	encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
34
 	encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
35
 
35
 
36
 	decryptedFrame := make(Frame, FrameLen)
36
 	decryptedFrame := make(Frame, FrameLen)
76
 }
76
 }
77
 
77
 
78
 func makeStreamCipher(key, iv []byte) cipher.Stream {
78
 func makeStreamCipher(key, iv []byte) cipher.Stream {
79
-	block, _ := aes.NewCipher(key)
79
+	block, _ := aes.NewCipher(key) // nolint: gosec
80
 	return cipher.NewCTR(block, iv)
80
 	return cipher.NewCTR(block, iv)
81
 }
81
 }

+ 4
- 4
obfuscated2/obfuscated2_test.go ファイルの表示

47
 
47
 
48
 	clientFrame := generateFrame(mtproto.ConnectionTypeIntermediate)
48
 	clientFrame := generateFrame(mtproto.ConnectionTypeIntermediate)
49
 	clientHasher := sha256.New()
49
 	clientHasher := sha256.New()
50
-	clientHasher.Write(clientFrame.Key()) // nolint: errcheck
51
-	clientHasher.Write(secret)            // nolint: errcheck
50
+	clientHasher.Write(clientFrame.Key()) // nolint: errcheck, gosec
51
+	clientHasher.Write(secret)            // nolint: errcheck, gosec
52
 	clientKey := clientHasher.Sum(nil)
52
 	clientKey := clientHasher.Sum(nil)
53
 
53
 
54
 	encryptor := makeStreamCipher(clientKey, clientFrame.IV())
54
 	encryptor := makeStreamCipher(clientKey, clientFrame.IV())
58
 
58
 
59
 	invertedClientFrame := clientFrame.Invert()
59
 	invertedClientFrame := clientFrame.Invert()
60
 	clientHasher = sha256.New()
60
 	clientHasher = sha256.New()
61
-	clientHasher.Write(invertedClientFrame.Key()) // nolint: errcheck
62
-	clientHasher.Write(secret)                    // nolint: errcheck
61
+	clientHasher.Write(invertedClientFrame.Key()) // nolint: errcheck, gosec
62
+	clientHasher.Write(secret)                    // nolint: errcheck, gosec
63
 	invertedClientKey := clientHasher.Sum(nil)
63
 	invertedClientKey := clientHasher.Sum(nil)
64
 	clientDecryptor := makeStreamCipher(invertedClientKey, invertedClientFrame.IV())
64
 	clientDecryptor := makeStreamCipher(invertedClientKey, invertedClientFrame.IV())
65
 
65
 

+ 7
- 7
proxy/proxy.go ファイルの表示

48
 
48
 
49
 	defer func() {
49
 	defer func() {
50
 		cancel()
50
 		cancel()
51
-		conn.Close() // nolint: errcheck
51
+		conn.Close() // nolint: errcheck, gosec
52
 
52
 
53
 		if err := recover(); err != nil {
53
 		if err := recover(); err != nil {
54
 			stats.NewCrash()
54
 			stats.NewCrash()
77
 
77
 
78
 	go func() {
78
 	go func() {
79
 		<-ctx.Done()
79
 		<-ctx.Done()
80
-		serverConn.(io.Closer).Close()
81
-		clientConn.(io.Closer).Close()
80
+		serverConn.(io.Closer).Close() // nolint: gosec
81
+		clientConn.(io.Closer).Close() // nolint: gosec
82
 	}()
82
 	}()
83
 
83
 
84
 	wait := &sync.WaitGroup{}
84
 	wait := &sync.WaitGroup{}
119
 func (p *Proxy) middlePipe(src wrappers.PacketReadCloser, dst io.WriteCloser,
119
 func (p *Proxy) middlePipe(src wrappers.PacketReadCloser, dst io.WriteCloser,
120
 	wait *sync.WaitGroup, hacks *mtproto.Hacks) {
120
 	wait *sync.WaitGroup, hacks *mtproto.Hacks) {
121
 	defer func() {
121
 	defer func() {
122
-		src.Close() // nolint: errcheck
123
-		dst.Close() // nolint: errcheck
122
+		src.Close() // nolint: errcheck, gosec
123
+		dst.Close() // nolint: errcheck, gosec
124
 		wait.Done()
124
 		wait.Done()
125
 	}()
125
 	}()
126
 
126
 
143
 func (p *Proxy) directPipe(src wrappers.StreamReadCloser, dst io.WriteCloser,
143
 func (p *Proxy) directPipe(src wrappers.StreamReadCloser, dst io.WriteCloser,
144
 	wait *sync.WaitGroup, bufferSize int) {
144
 	wait *sync.WaitGroup, bufferSize int) {
145
 	defer func() {
145
 	defer func() {
146
-		src.Close() // nolint: errcheck
147
-		dst.Close() // nolint: errcheck
146
+		src.Close() // nolint: errcheck, gosec
147
+		dst.Close() // nolint: errcheck, gosec
148
 		wait.Done()
148
 		wait.Done()
149
 	}()
149
 	}()
150
 
150
 

+ 1
- 1
stats/server.go ファイルの表示

49
 		}
49
 		}
50
 
50
 
51
 		interm := map[string]interface{}{}
51
 		interm := map[string]interface{}{}
52
-		json.Unmarshal(first, &interm) // nolint: errcheck
52
+		json.Unmarshal(first, &interm) // nolint: errcheck, gosec
53
 
53
 
54
 		encoder := json.NewEncoder(w)
54
 		encoder := json.NewEncoder(w)
55
 		encoder.SetEscapeHTML(false)
55
 		encoder.SetEscapeHTML(false)

+ 9
- 2
telegram/direct.go ファイルの表示

12
 	"github.com/9seconds/mtg/wrappers"
12
 	"github.com/9seconds/mtg/wrappers"
13
 )
13
 )
14
 
14
 
15
+const (
16
+	directV4DefaultIdx = 1
17
+	directV6DefaultIdx = 1
18
+)
19
+
15
 var (
20
 var (
16
 	directV4Addresses = map[int16][]string{
21
 	directV4Addresses = map[int16][]string{
17
 		0: {"149.154.175.50:443"},
22
 		0: {"149.154.175.50:443"},
65
 				Dialer: net.Dialer{Timeout: telegramDialTimeout},
70
 				Dialer: net.Dialer{Timeout: telegramDialTimeout},
66
 				conf:   conf,
71
 				conf:   conf,
67
 			},
72
 			},
68
-			v4Addresses: directV4Addresses,
69
-			v6Addresses: directV6Addresses,
73
+			v4DefaultIdx: directV4DefaultIdx,
74
+			v6DefaultIdx: directV6DefaultIdx,
75
+			v4Addresses:  directV4Addresses,
76
+			v6Addresses:  directV6Addresses,
70
 		},
77
 		},
71
 	}
78
 	}
72
 }
79
 }

+ 64
- 27
telegram/middle_caller.go ファイルの表示

65
 		return errors.Annotate(err, "Cannot get proxy secret")
65
 		return errors.Annotate(err, "Cannot get proxy secret")
66
 	}
66
 	}
67
 
67
 
68
-	v4Addresses, err := t.getTelegramAddresses(tgAddrProxyV4)
68
+	v4Addresses, v4DefaultIdx, err := t.getTelegramAddresses(tgAddrProxyV4)
69
 	if err != nil {
69
 	if err != nil {
70
 		return errors.Annotate(err, "Cannot get ipv4 addresses")
70
 		return errors.Annotate(err, "Cannot get ipv4 addresses")
71
 	}
71
 	}
72
 
72
 
73
-	v6Addresses, err := t.getTelegramAddresses(tgAddrProxyV6)
73
+	v6Addresses, v6DefaultIdx, err := t.getTelegramAddresses(tgAddrProxyV6)
74
 	if err != nil {
74
 	if err != nil {
75
 		return errors.Annotate(err, "Cannot get ipv6 addresses")
75
 		return errors.Annotate(err, "Cannot get ipv6 addresses")
76
 	}
76
 	}
77
 
77
 
78
 	t.dialerMutex.Lock()
78
 	t.dialerMutex.Lock()
79
 	t.proxySecret = secret
79
 	t.proxySecret = secret
80
+	t.v4DefaultIdx = v4DefaultIdx
81
+	t.v6DefaultIdx = v6DefaultIdx
80
 	t.v4Addresses = v4Addresses
82
 	t.v4Addresses = v4Addresses
81
 	t.v6Addresses = v6Addresses
83
 	t.v6Addresses = v6Addresses
82
 	t.dialerMutex.Unlock()
84
 	t.dialerMutex.Unlock()
101
 	return secret, nil
103
 	return secret, nil
102
 }
104
 }
103
 
105
 
104
-func (t *middleTelegramCaller) getTelegramAddresses(url string) (map[int16][]string, error) {
106
+func (t *middleTelegramCaller) getTelegramAddresses(url string) (map[int16][]string, int16, error) { // nolint: gocyclo
105
 	resp, err := t.call(url)
107
 	resp, err := t.call(url)
106
 	if err != nil {
108
 	if err != nil {
107
-		return nil, errors.Annotate(err, "Cannot access telegram server")
109
+		return nil, 0, errors.Annotate(err, "Cannot access telegram server")
108
 	}
110
 	}
109
 	defer resp.Body.Close() // nolint: errcheck
111
 	defer resp.Body.Close() // nolint: errcheck
110
 
112
 
111
 	scanner := bufio.NewScanner(resp.Body)
113
 	scanner := bufio.NewScanner(resp.Body)
112
 	data := map[int16][]string{}
114
 	data := map[int16][]string{}
115
+
116
+	var defaultIdx int16 = 1
113
 	for scanner.Scan() {
117
 	for scanner.Scan() {
114
 		text := strings.TrimSpace(scanner.Text())
118
 		text := strings.TrimSpace(scanner.Text())
115
-		if strings.HasPrefix(text, "#") {
119
+		switch {
120
+		case strings.HasPrefix(text, "#"):
116
 			continue
121
 			continue
122
+		case strings.HasPrefix(text, "proxy_for"):
123
+			addr, idx, err2 := t.parseProxyFor(text)
124
+			if err2 != nil {
125
+				return nil, 0, errors.Annotate(err2, "Cannot parse 'proxy_for' section")
126
+			}
127
+			if addresses, ok := data[idx]; ok {
128
+				data[idx] = append(addresses, addr)
129
+			} else {
130
+				data[idx] = []string{addr}
131
+			}
132
+		case strings.HasPrefix(text, "default"):
133
+			idx, err2 := t.parseDefault(text)
134
+			if err2 != nil {
135
+				return nil, 0, errors.Annotate(err2, "Cannot parse 'default' section")
136
+			}
137
+			defaultIdx = idx
138
+		default:
139
+			return nil, 0, errors.Errorf("Unknown config string '%s'", text)
117
 		}
140
 		}
141
+	}
118
 
142
 
119
-		chunks := middleTelegramProxyConfigSplitter.Split(text, 3)
120
-		if len(chunks) != 3 || chunks[0] != "proxy_for" {
121
-			return nil, errors.Errorf("Incorrect config '%s'", text)
122
-		}
123
-		dcIdx64, err2 := strconv.ParseInt(chunks[1], 10, 16)
124
-		if err2 != nil {
125
-			return nil, errors.Errorf("Incorrect config '%s'", text)
126
-		}
127
-		dcIdx := int16(dcIdx64)
143
+	err = scanner.Err()
144
+	if err != nil {
145
+		return nil, 0, errors.Annotate(err, "Cannot read response from the telegram")
146
+	}
128
 
147
 
129
-		addr := strings.TrimRight(chunks[2], ";")
130
-		if _, _, err2 = net.SplitHostPort(addr); err != nil {
131
-			return nil, errors.Annotatef(err2, "Incorrect config '%s'", text)
132
-		}
148
+	return data, defaultIdx, nil
149
+}
133
 
150
 
134
-		if addresses, ok := data[dcIdx]; ok {
135
-			data[dcIdx] = append(addresses, addr)
136
-		} else {
137
-			data[dcIdx] = []string{addr}
138
-		}
151
+func (t *middleTelegramCaller) parseProxyFor(text string) (string, int16, error) {
152
+	chunks := middleTelegramProxyConfigSplitter.Split(text, 3)
153
+	if len(chunks) != 3 || chunks[0] != "proxy_for" {
154
+		return "", 0, errors.Errorf("Incorrect config '%s'", text)
139
 	}
155
 	}
140
-	err = scanner.Err()
156
+
157
+	dcIdx, err := strconv.ParseInt(chunks[1], 10, 16)
158
+	if err != nil {
159
+		return "", 0, errors.Annotatef(err, "Incorrect config '%s'", text)
160
+	}
161
+
162
+	addr := strings.TrimRight(chunks[2], ";")
163
+	if _, _, err = net.SplitHostPort(addr); err != nil {
164
+		return "", 0, errors.Annotatef(err, "Incorrect config '%s'", text)
165
+	}
166
+
167
+	return addr, int16(dcIdx), nil
168
+}
169
+
170
+func (t *middleTelegramCaller) parseDefault(text string) (int16, error) {
171
+	chunks := middleTelegramProxyConfigSplitter.Split(text, 2)
172
+	if len(chunks) != 2 || chunks[0] != "default" {
173
+		return 0, errors.Errorf("Incorrect config '%s'", text)
174
+	}
175
+
176
+	dcIdxString := strings.TrimRight(chunks[1], ";")
177
+	dcIdx, err := strconv.ParseInt(dcIdxString, 10, 16)
141
 	if err != nil {
178
 	if err != nil {
142
-		return nil, errors.Annotate(err, "Cannot read response from the telegram")
179
+		return 0, errors.Annotatef(err, "Incorrect config '%s'", text)
143
 	}
180
 	}
144
 
181
 
145
-	return data, nil
182
+	return int16(dcIdx), nil
146
 }
183
 }
147
 
184
 
148
 func (t *middleTelegramCaller) call(url string) (*http.Response, error) {
185
 func (t *middleTelegramCaller) call(url string) (*http.Response, error) {
149
-	req, _ := http.NewRequest("GET", url, nil)
186
+	req, _ := http.NewRequest("GET", url, nil) // nolint: gosec
150
 	req.Header.Set("Accept", "text/plain")
187
 	req.Header.Set("Accept", "text/plain")
151
 	req.Header.Set("User-Agent", tgUserAgent)
188
 	req.Header.Set("User-Agent", tgUserAgent)
152
 
189
 

+ 26
- 6
telegram/telegram.go ファイルの表示

19
 type baseTelegram struct {
19
 type baseTelegram struct {
20
 	dialer tgDialer
20
 	dialer tgDialer
21
 
21
 
22
-	v4Addresses map[int16][]string
23
-	v6Addresses map[int16][]string
22
+	v4DefaultIdx int16
23
+	v6DefaultIdx int16
24
+	v4Addresses  map[int16][]string
25
+	v6Addresses  map[int16][]string
24
 }
26
 }
25
 
27
 
26
 func (b *baseTelegram) dial(ctx context.Context, cancel context.CancelFunc, dcIdx int16, connID string,
28
 func (b *baseTelegram) dial(ctx context.Context, cancel context.CancelFunc, dcIdx int16, connID string,
28
 	addrs := make([]string, 2)
30
 	addrs := make([]string, 2)
29
 
31
 
30
 	if proto&mtproto.ConnectionProtocolIPv6 != 0 {
32
 	if proto&mtproto.ConnectionProtocolIPv6 != 0 {
31
-		if addr, ok := b.v6Addresses[dcIdx]; ok && len(addr) > 0 {
32
-			addrs = append(addrs, addr[rand.Intn(len(addr))])
33
+		if addr := b.chooseAddress(b.v6Addresses, dcIdx, b.v6DefaultIdx); addr != "" {
34
+			addrs = append(addrs, addr)
33
 		}
35
 		}
34
 	}
36
 	}
35
 	if proto&mtproto.ConnectionProtocolIPv4 != 0 {
37
 	if proto&mtproto.ConnectionProtocolIPv4 != 0 {
36
-		if addr, ok := b.v4Addresses[dcIdx]; ok && len(addr) > 0 {
37
-			addrs = append(addrs, addr[rand.Intn(len(addr))])
38
+		if addr := b.chooseAddress(b.v4Addresses, dcIdx, b.v4DefaultIdx); addr != "" {
39
+			addrs = append(addrs, addr)
38
 		}
40
 		}
39
 	}
41
 	}
40
 
42
 
46
 
48
 
47
 	return nil, errors.New("Cannot connect to Telegram")
49
 	return nil, errors.New("Cannot connect to Telegram")
48
 }
50
 }
51
+
52
+func (b *baseTelegram) chooseAddress(addresses map[int16][]string, idx, defaultIdx int16) string {
53
+	if addr, ok := addresses[idx]; ok {
54
+		return b.chooseRandomAddress(addr)
55
+	} else if addr, ok := addresses[defaultIdx]; ok {
56
+		return b.chooseRandomAddress(addr)
57
+	}
58
+
59
+	return ""
60
+}
61
+
62
+func (b *baseTelegram) chooseRandomAddress(addresses []string) string {
63
+	if len(addresses) > 0 {
64
+		return addresses[rand.Intn(len(addresses))]
65
+	}
66
+
67
+	return ""
68
+}

+ 1
- 1
wrappers/blockcipher.go ファイルの表示

40
 	}
40
 	}
41
 
41
 
42
 	b.decryptor.CryptBlocks(buf, buf)
42
 	b.decryptor.CryptBlocks(buf, buf)
43
-	b.buf.Write(buf)
43
+	b.buf.Write(buf) // nolint: gosec
44
 
44
 
45
 	return b.flush(p)
45
 	return b.flush(p)
46
 }
46
 }

+ 3
- 3
wrappers/conn.go ファイルの表示

99
 	case res := <-resChan:
99
 	case res := <-resChan:
100
 		timer.Stop()
100
 		timer.Stop()
101
 		if res.err != nil {
101
 		if res.err != nil {
102
-			c.Close()
102
+			c.Close() // nolint: gosec
103
 		}
103
 		}
104
 		return res.n, res.err
104
 		return res.n, res.err
105
 	case <-c.ctx.Done():
105
 	case <-c.ctx.Done():
106
 		timer.Stop()
106
 		timer.Stop()
107
-		c.Close()
107
+		c.Close() // nolint: gosec
108
 		return 0, errors.Annotate(c.ctx.Err(), "Cannot do IO because context is closed")
108
 		return 0, errors.Annotate(c.ctx.Err(), "Cannot do IO because context is closed")
109
 	case <-timer.C:
109
 	case <-timer.C:
110
-		c.Close()
110
+		c.Close() // nolint: gosec
111
 		return 0, errors.Annotate(c.ctx.Err(), "Timeout on IO operation")
111
 		return 0, errors.Annotate(c.ctx.Err(), "Timeout on IO operation")
112
 	}
112
 	}
113
 }
113
 }

+ 3
- 3
wrappers/mtproto_abridged.go ファイルの表示

119
 		buf := &bytes.Buffer{}
119
 		buf := &bytes.Buffer{}
120
 		buf.Grow(1 + 3 + len(p))
120
 		buf.Grow(1 + 3 + len(p))
121
 
121
 
122
-		buf.WriteByte(byte(mtprotoAbridgedSmallPacketLength))
123
-		buf.Write(length24[:])
124
-		buf.Write(p)
122
+		buf.WriteByte(byte(mtprotoAbridgedSmallPacketLength)) // nolint: gosec
123
+		buf.Write(length24[:])                                // nolint: gosec
124
+		buf.Write(p)                                          // nolint: gosec
125
 
125
 
126
 		return m.conn.Write(buf.Bytes())
126
 		return m.conn.Write(buf.Bytes())
127
 	}
127
 	}

+ 17
- 17
wrappers/mtproto_cipher.go ファイルの表示

4
 	"bytes"
4
 	"bytes"
5
 	"crypto/aes"
5
 	"crypto/aes"
6
 	"crypto/cipher"
6
 	"crypto/cipher"
7
-	"crypto/md5" // nolint: gas
8
-	"crypto/sha1"
7
+	"crypto/md5"  // nolint: gas
8
+	"crypto/sha1" // nolint: gosec
9
 	"encoding/binary"
9
 	"encoding/binary"
10
 	"net"
10
 	"net"
11
 
11
 
41
 func deriveKeys(purpose cipherPurpose, req *rpc.NonceRequest, resp *rpc.NonceResponse,
41
 func deriveKeys(purpose cipherPurpose, req *rpc.NonceRequest, resp *rpc.NonceResponse,
42
 	client, remote *net.TCPAddr, secret []byte) ([]byte, []byte) {
42
 	client, remote *net.TCPAddr, secret []byte) ([]byte, []byte) {
43
 	message := bytes.Buffer{}
43
 	message := bytes.Buffer{}
44
-	message.Write(resp.Nonce)
45
-	message.Write(req.Nonce)
46
-	message.Write(req.CryptoTS)
44
+	message.Write(resp.Nonce)   // nolint: gosec
45
+	message.Write(req.Nonce)    // nolint: gosec
46
+	message.Write(req.CryptoTS) // nolint: gosec
47
 
47
 
48
 	clientIPv4 := emptyIP[:]
48
 	clientIPv4 := emptyIP[:]
49
 	serverIPv4 := emptyIP[:]
49
 	serverIPv4 := emptyIP[:]
51
 		clientIPv4 = utils.ReverseBytes(client.IP.To4())
51
 		clientIPv4 = utils.ReverseBytes(client.IP.To4())
52
 		serverIPv4 = utils.ReverseBytes(remote.IP.To4())
52
 		serverIPv4 = utils.ReverseBytes(remote.IP.To4())
53
 	}
53
 	}
54
-	message.Write(serverIPv4)
54
+	message.Write(serverIPv4) // nolint: gosec
55
 
55
 
56
 	var port [2]byte
56
 	var port [2]byte
57
 	binary.LittleEndian.PutUint16(port[:], uint16(client.Port))
57
 	binary.LittleEndian.PutUint16(port[:], uint16(client.Port))
58
-	message.Write(port[:])
58
+	message.Write(port[:]) // nolint: gosec
59
 
59
 
60
 	switch purpose {
60
 	switch purpose {
61
 	case cipherPurposeClient:
61
 	case cipherPurposeClient:
62
-		message.WriteString("CLIENT")
62
+		message.WriteString("CLIENT") // nolint: gosec
63
 	case cipherPurposeServer:
63
 	case cipherPurposeServer:
64
-		message.WriteString("SERVER")
64
+		message.WriteString("SERVER") // nolint: gosec
65
 	default:
65
 	default:
66
 		panic("Unexpected cipher purpose")
66
 		panic("Unexpected cipher purpose")
67
 	}
67
 	}
68
 
68
 
69
-	message.Write(clientIPv4)
69
+	message.Write(clientIPv4) // nolint: gosec
70
 	binary.LittleEndian.PutUint16(port[:], uint16(remote.Port))
70
 	binary.LittleEndian.PutUint16(port[:], uint16(remote.Port))
71
-	message.Write(port[:])
72
-	message.Write(secret)
73
-	message.Write(resp.Nonce)
71
+	message.Write(port[:])    // nolint: gosec
72
+	message.Write(secret)     // nolint: gosec
73
+	message.Write(resp.Nonce) // nolint: gosec
74
 
74
 
75
 	if client.IP.To4() == nil {
75
 	if client.IP.To4() == nil {
76
-		message.Write(client.IP.To16())
77
-		message.Write(remote.IP.To16())
76
+		message.Write(client.IP.To16()) // nolint: gosec
77
+		message.Write(remote.IP.To16()) // nolint: gosec
78
 	}
78
 	}
79
-	message.Write(req.Nonce)
79
+	message.Write(req.Nonce) // nolint: gosec
80
 
80
 
81
 	data := message.Bytes()
81
 	data := message.Bytes()
82
 	md5sum := md5.Sum(data[1:]) // nolint: gas
82
 	md5sum := md5.Sum(data[1:]) // nolint: gas
83
-	sha1sum := sha1.Sum(data)
83
+	sha1sum := sha1.Sum(data)   // nolint: gosec
84
 
84
 
85
 	key := append(md5sum[:12], sha1sum[:]...)
85
 	key := append(md5sum[:12], sha1sum[:]...)
86
 	iv := md5.Sum(data[2:]) // nolint: gas
86
 	iv := md5.Sum(data[2:]) // nolint: gas

+ 7
- 7
wrappers/mtproto_frame.go ファイルの表示

73
 	}
73
 	}
74
 
74
 
75
 	var seqNo int32
75
 	var seqNo int32
76
-	binary.Read(buf, binary.LittleEndian, &seqNo) // nolint: errcheck
76
+	binary.Read(buf, binary.LittleEndian, &seqNo) // nolint: errcheck, gosec
77
 	if seqNo != m.readSeqNo {
77
 	if seqNo != m.readSeqNo {
78
 		return nil, errors.Errorf("Unexpected sequence number %d (wait for %d)", seqNo, m.readSeqNo)
78
 		return nil, errors.Errorf("Unexpected sequence number %d (wait for %d)", seqNo, m.readSeqNo)
79
 	}
79
 	}
80
 
80
 
81
-	data, _ := ioutil.ReadAll(buf)
81
+	data, _ := ioutil.ReadAll(buf) // nolint: gosec
82
 	buf.Reset()
82
 	buf.Reset()
83
 	// write to buf, not to writer. This is because we are going to fetch
83
 	// write to buf, not to writer. This is because we are going to fetch
84
 	// crc32 checksum.
84
 	// crc32 checksum.
109
 	buf := &bytes.Buffer{}
109
 	buf := &bytes.Buffer{}
110
 	buf.Grow(messageLength + paddingLength)
110
 	buf.Grow(messageLength + paddingLength)
111
 
111
 
112
-	binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
113
-	binary.Write(buf, binary.LittleEndian, m.writeSeqNo)          // nolint: errcheck
114
-	buf.Write(p)
112
+	binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck, gosec
113
+	binary.Write(buf, binary.LittleEndian, m.writeSeqNo)          // nolint: errcheck, gosec
114
+	buf.Write(p)                                                  // nolint: gosec
115
 
115
 
116
 	checksum := crc32.ChecksumIEEE(buf.Bytes())
116
 	checksum := crc32.ChecksumIEEE(buf.Bytes())
117
-	binary.Write(buf, binary.LittleEndian, checksum) // nolint: errcheck
118
-	buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4))
117
+	binary.Write(buf, binary.LittleEndian, checksum)              // nolint: errcheck, gosec
118
+	buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4)) // nolint: gosec
119
 
119
 
120
 	m.logger.Debugw("Write MTProto frame",
120
 	m.logger.Debugw("Write MTProto frame",
121
 		"length", len(p),
121
 		"length", len(p),

+ 3
- 3
wrappers/mtproto_intermediate_secure.go ファイルの表示

44
 	paddingLength := rand.Intn(4)
44
 	paddingLength := rand.Intn(4)
45
 	buf.Grow(4 + len(p) + paddingLength)
45
 	buf.Grow(4 + len(p) + paddingLength)
46
 
46
 
47
-	binary.Write(buf, binary.LittleEndian, uint32(len(p)+paddingLength)) // nolint: errcheck
48
-	buf.Write(p)
49
-	buf.Write(make([]byte, paddingLength))
47
+	binary.Write(buf, binary.LittleEndian, uint32(len(p)+paddingLength)) // nolint: errcheck, gosec
48
+	buf.Write(p)                                                         // nolint: gosec
49
+	buf.Write(make([]byte, paddingLength))                               // nolint: gosec
50
 
50
 
51
 	m.logger.Debugw("Write packet with padding",
51
 	m.logger.Debugw("Write packet with padding",
52
 		"simple_ack", m.opts.WriteHacks.SimpleAck,
52
 		"simple_ack", m.opts.WriteHacks.SimpleAck,

+ 1
- 1
wrappers/mtproto_proxy.go ファイルの表示

120
 			zap.Stringer("flags", flags),
120
 			zap.Stringer("flags", flags),
121
 		)
121
 		)
122
 	}
122
 	}
123
-	header.Write(p)
123
+	header.Write(p) // nolint: gosec
124
 
124
 
125
 	if _, err := m.conn.Write(header.Bytes()); err != nil {
125
 	if _, err := m.conn.Write(header.Bytes()); err != nil {
126
 		return 0, err
126
 		return 0, err

+ 1
- 1
wrappers/streamcipher.go ファイルの表示

34
 
34
 
35
 	buf.Reset()
35
 	buf.Reset()
36
 	buf.Grow(len(p))
36
 	buf.Grow(len(p))
37
-	buf.Write(p)
37
+	buf.Write(p) // nolint: gosec
38
 
38
 
39
 	data := buf.Bytes()
39
 	data := buf.Bytes()
40
 	s.encryptor.XORKeyStream(data, data)
40
 	s.encryptor.XORKeyStream(data, data)

読み込み中…
キャンセル
保存