Merge pull request #183 from 9seconds/test-stage

Add option to use telegram test dcs
This commit is contained in:
Sergey Arkhipov
2021-04-09 17:14:08 +03:00
committed by GitHub
6 changed files with 118 additions and 43 deletions
+33
View File
@@ -0,0 +1,33 @@
package telegram
import "math/rand"
type addressPool struct {
v4 [][]tgAddr
v6 [][]tgAddr
}
func (a addressPool) getV4(dc int) []tgAddr {
return a.get(a.v4, dc-1)
}
func (a addressPool) getV6(dc int) []tgAddr {
return a.get(a.v6, dc-1)
}
func (a addressPool) get(addresses [][]tgAddr, dc int) []tgAddr {
if dc < 0 || dc >= len(addresses) {
return nil
}
rv := make([]tgAddr, len(addresses[dc]))
copy(rv, addresses[dc])
if len(rv) > 1 {
rand.Shuffle(len(rv), func(i, j int) {
rv[i], rv[j] = rv[j], rv[i]
})
}
return rv
}
+40 -7
View File
@@ -21,30 +21,63 @@ type tgAddr struct {
// https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp#L30 // https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp#L30
var ( var (
v4Addresses = [5][]tgAddr{ productionV4Addresses = [][]tgAddr{
{ { // dc1
{network: "tcp4", address: "149.154.175.50:443"}, {network: "tcp4", address: "149.154.175.50:443"},
}, },
{ { // dc2
{network: "tcp4", address: "149.154.167.51:443"}, {network: "tcp4", address: "149.154.167.51:443"},
{network: "tcp4", address: "95.161.76.100:443"}, {network: "tcp4", address: "95.161.76.100:443"},
}, },
{ { // dc3
{network: "tcp4", address: "149.154.175.100:443"}, {network: "tcp4", address: "149.154.175.100:443"},
}, },
{ { // dc4
{network: "tcp4", address: "149.154.167.91:443"}, {network: "tcp4", address: "149.154.167.91:443"},
}, },
{ { // dc5
{network: "tcp4", address: "149.154.171.5:443"}, {network: "tcp4", address: "149.154.171.5:443"},
}, },
} }
v6Addresses = [5]tgAddr{ productionV6Addresses = [][]tgAddr{
{ // dc1
{network: "tcp6", address: "[2001:b28:f23d:f001::a]:443"}, {network: "tcp6", address: "[2001:b28:f23d:f001::a]:443"},
},
{ // dc2
{network: "tcp6", address: "[2001:67c:04e8:f002::a]:443"}, {network: "tcp6", address: "[2001:67c:04e8:f002::a]:443"},
},
{ // dc3
{network: "tcp6", address: "[2001:b28:f23d:f003::a]:443"}, {network: "tcp6", address: "[2001:b28:f23d:f003::a]:443"},
},
{ // dc4
{network: "tcp6", address: "[2001:67c:04e8:f004::a]:443"}, {network: "tcp6", address: "[2001:67c:04e8:f004::a]:443"},
},
{ // dc5
{network: "tcp6", address: "[2001:b28:f23f:f005::a]:443"}, {network: "tcp6", address: "[2001:b28:f23f:f005::a]:443"},
},
}
testV4Addresses = [][]tgAddr{
{ // dc1
{network: "tcp4", address: "149.154.175.10:443"},
},
{ // dc2
{network: "tcp4", address: "149.154.167.40:443"},
},
{ // dc3
{network: "tcp4", address: "149.154.175.117:443"},
},
}
testV6Addresses = [][]tgAddr{
{ // dc1
{network: "tcp6", address: "[2001:b28:f23d:f001::e]:443"},
},
{ // dc2
{network: "tcp6", address: "[2001:67c:04e8:f002::e]:443"},
},
{ // dc3
{network: "tcp6", address: "[2001:b28:f23d:f003::e]:443"},
},
} }
) )
+18 -18
View File
@@ -3,7 +3,6 @@ package telegram
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand"
"net" "net"
"strings" "strings"
) )
@@ -11,30 +10,21 @@ import (
type Telegram struct { type Telegram struct {
dialer Dialer dialer Dialer
preferIP preferIP preferIP preferIP
pool addressPool
} }
func (t Telegram) Dial(ctx context.Context, dc int) (net.Conn, error) { func (t Telegram) Dial(ctx context.Context, dc int) (net.Conn, error) {
if dc <= 0 || dc > 5 {
return nil, fmt.Errorf("do not know how to dial to %d", dc)
}
var addresses []tgAddr var addresses []tgAddr
if t.preferIP == preferIPOnlyIPv6 {
addresses = []tgAddr{v6Addresses[dc-1]}
} else {
addresses = append(addresses, v4Addresses[dc-1]...)
rand.Shuffle(len(addresses), func(i, j int) {
addresses[i], addresses[j] = addresses[j], addresses[i]
})
}
switch t.preferIP { switch t.preferIP {
case preferIPOnlyIPv4:
addresses = t.pool.getV4(dc)
case preferIPOnlyIPv6:
addresses = t.pool.getV6(dc)
case preferIPPreferIPv4: case preferIPPreferIPv4:
addresses = append(addresses, v6Addresses[dc-1]) addresses = append(t.pool.getV4(dc), t.pool.getV6(dc)...)
case preferIPPreferIPv6: case preferIPPreferIPv6:
addresses = append([]tgAddr{v6Addresses[dc-1]}, addresses...) addresses = append(t.pool.getV6(dc), t.pool.getV4(dc)...)
case preferIPOnlyIPv4, preferIPOnlyIPv6:
} }
var ( var (
@@ -52,7 +42,7 @@ func (t Telegram) Dial(ctx context.Context, dc int) (net.Conn, error) {
return nil, fmt.Errorf("cannot dial to %d dc: %w", dc, err) return nil, fmt.Errorf("cannot dial to %d dc: %w", dc, err)
} }
func New(dialer Dialer, ipPreference string) (*Telegram, error) { func New(dialer Dialer, ipPreference string, useTestDCs bool) (*Telegram, error) {
var pref preferIP var pref preferIP
switch strings.ToLower(ipPreference) { switch strings.ToLower(ipPreference) {
@@ -68,8 +58,18 @@ func New(dialer Dialer, ipPreference string) (*Telegram, error) {
return nil, fmt.Errorf("unknown ip preference %s", ipPreference) return nil, fmt.Errorf("unknown ip preference %s", ipPreference)
} }
pool := addressPool{
v4: productionV4Addresses,
v6: productionV6Addresses,
}
if useTestDCs {
pool.v4 = testV4Addresses
pool.v6 = testV6Addresses
}
return &Telegram{ return &Telegram{
dialer: dialer, dialer: dialer,
preferIP: pref, preferIP: pref,
pool: pool,
}, nil }, nil
} }
@@ -23,7 +23,7 @@ type TelegramTestSuite struct {
func (suite *TelegramTestSuite) SetupTest() { func (suite *TelegramTestSuite) SetupTest() {
suite.dialerMock = &testlib.MtglibNetworkMock{} suite.dialerMock = &testlib.MtglibNetworkMock{}
suite.t, _ = New(suite.dialerMock, "prefer-ipv4") suite.t, _ = New(suite.dialerMock, "prefer-ipv4", false)
} }
func (suite *TelegramTestSuite) TearDownTest() { func (suite *TelegramTestSuite) TearDownTest() {
@@ -53,8 +53,8 @@ func (suite *TelegramTestSuite) TestDialToCorrectIPs() {
for i := 1; i <= 5; i++ { for i := 1; i <= 5; i++ {
testData[i] = []tgAddr{} testData[i] = []tgAddr{}
testData[i] = append(testData[i], v4Addresses[i-1]...) testData[i] = append(testData[i], productionV4Addresses[i-1]...)
testData[i] = append(testData[i], v6Addresses[i-1]) testData[i] = append(testData[i], productionV6Addresses[i-1]...)
} }
for i, v := range testData { for i, v := range testData {
@@ -77,10 +77,10 @@ func (suite *TelegramTestSuite) TestDialToCorrectIPs() {
func (suite *TelegramTestSuite) TestDialPreferIPRange() { func (suite *TelegramTestSuite) TestDialPreferIPRange() {
testData := map[string][]tgAddr{ testData := map[string][]tgAddr{
"prefer-ipv4": {v4Addresses[0][0], v6Addresses[0]}, "prefer-ipv4": {testV4Addresses[0][0], testV6Addresses[0][0]},
"prefer-ipv6": {v6Addresses[0], v4Addresses[0][0]}, "prefer-ipv6": {testV6Addresses[0][0], testV4Addresses[0][0]},
"only-ipv4": {v4Addresses[0][0]}, "only-ipv4": {testV4Addresses[0][0]},
"only-ipv6": {v6Addresses[0]}, "only-ipv6": {testV6Addresses[0][0]},
} }
for k, v := range testData { for k, v := range testData {
@@ -95,7 +95,7 @@ func (suite *TelegramTestSuite) TestDialPreferIPRange() {
Return((*net.TCPConn)(nil), io.EOF) Return((*net.TCPConn)(nil), io.EOF)
} }
tg, _ := New(suite.dialerMock, name) tg, _ := New(suite.dialerMock, name, true)
_, err := tg.Dial(context.Background(), 1) _, err := tg.Dial(context.Background(), 1)
assert.True(t, errors.Is(err, io.EOF)) assert.True(t, errors.Is(err, io.EOF))
@@ -105,8 +105,8 @@ func (suite *TelegramTestSuite) TestDialPreferIPRange() {
func (suite *TelegramTestSuite) TestDialPreferIPPriority() { func (suite *TelegramTestSuite) TestDialPreferIPPriority() {
testData := map[string]tgAddr{ testData := map[string]tgAddr{
"prefer-ipv4": v4Addresses[0][0], "prefer-ipv4": productionV4Addresses[0][0],
"prefer-ipv6": v6Addresses[0], "prefer-ipv6": productionV6Addresses[0][0],
} }
for k, v := range testData { for k, v := range testData {
@@ -121,7 +121,7 @@ func (suite *TelegramTestSuite) TestDialPreferIPPriority() {
Once(). Once().
Return(conn, nil) Return(conn, nil)
tg, _ := New(suite.dialerMock, name) tg, _ := New(suite.dialerMock, name, false)
res, err := tg.Dial(context.Background(), 1) res, err := tg.Dial(context.Background(), 1)
assert.NoError(t, err) assert.NoError(t, err)
@@ -131,7 +131,7 @@ func (suite *TelegramTestSuite) TestDialPreferIPPriority() {
} }
func (suite *TelegramTestSuite) TestUnknownPreferIP() { func (suite *TelegramTestSuite) TestUnknownPreferIP() {
_, err := New(suite.dialerMock, "xxx") _, err := New(suite.dialerMock, "xxx", false)
suite.Error(err) suite.Error(err)
} }
+1 -1
View File
@@ -270,7 +270,7 @@ func NewProxy(opts ProxyOpts) (*Proxy, error) {
return nil, fmt.Errorf("invalid settings: %w", err) return nil, fmt.Errorf("invalid settings: %w", err)
} }
tg, err := telegram.New(opts.Network, opts.getPreferIP()) tg, err := telegram.New(opts.Network, opts.getPreferIP(), opts.UseTestDCs)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot build telegram dialer: %w", err) return nil, fmt.Errorf("cannot build telegram dialer: %w", err)
} }
+9
View File
@@ -89,6 +89,15 @@ type ProxyOpts struct {
// //
// This is an optional setting. // This is an optional setting.
PreferIP string PreferIP string
// UseTestDCs defines if we have to connect to production or to staging
// DCs of Telegram.
//
// This is required if you use mtglib as an integration library for
// your Telegram-related projects.
//
// This is an optional setting.
UseTestDCs bool
} }
func (p ProxyOpts) valid() error { func (p ProxyOpts) valid() error {