mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 17:54:01 +03:00
Add implementation of telegram dialer
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type preferIP uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
preferIPOnlyIPv4 preferIP = iota
|
||||||
|
preferIPOnlyIPv6
|
||||||
|
preferIPPreferIPv4
|
||||||
|
preferIPPreferIPv6
|
||||||
|
)
|
||||||
|
|
||||||
|
type tgAddr struct {
|
||||||
|
network string
|
||||||
|
address string
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp#L30
|
||||||
|
var (
|
||||||
|
v4Addresses = [5][]tgAddr{
|
||||||
|
{
|
||||||
|
{network: "tcp4", address: "149.154.175.50:443"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{network: "tcp4", address: "149.154.167.51:443"},
|
||||||
|
{network: "tcp4", address: "95.161.76.100:443"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{network: "tcp4", address: "149.154.175.100:443"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{network: "tcp4", address: "149.154.167.91:443"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{network: "tcp4", address: "149.154.171.5"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
v6Addresses = [5]tgAddr{
|
||||||
|
{network: "tcp6", address: "[2001:b28:f23d:f001::a]:443"},
|
||||||
|
{network: "tcp6", address: "[2001:67c:04e8:f002::a]:443"},
|
||||||
|
{network: "tcp6", address: "[2001:b28:f23d:f003::a]:443"},
|
||||||
|
{network: "tcp6", address: "[2001:67c:04e8:f004::a]:443"},
|
||||||
|
{network: "tcp6", address: "[2001:b28:f23f:f005::a]:443"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dialer interface {
|
||||||
|
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Telegram struct {
|
||||||
|
dialer Dialer
|
||||||
|
preferIP preferIP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Telegram) Dial(ctx context.Context, dc int) (net.Conn, error) {
|
||||||
|
if dc < 0 || dc > 4 {
|
||||||
|
return nil, fmt.Errorf("do not know how to dial to %d", dc)
|
||||||
|
}
|
||||||
|
|
||||||
|
var addresses []tgAddr
|
||||||
|
|
||||||
|
if t.preferIP == preferIPOnlyIPv6 {
|
||||||
|
addresses = []tgAddr{v6Addresses[dc]}
|
||||||
|
} else {
|
||||||
|
addresses = append(addresses, v4Addresses[dc]...)
|
||||||
|
rand.Shuffle(len(addresses), func(i, j int) {
|
||||||
|
addresses[i], addresses[j] = addresses[j], addresses[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t.preferIP {
|
||||||
|
case preferIPPreferIPv4:
|
||||||
|
addresses = append(addresses, v6Addresses[dc])
|
||||||
|
case preferIPPreferIPv6:
|
||||||
|
addresses = append([]tgAddr{v6Addresses[dc]}, addresses...)
|
||||||
|
case preferIPOnlyIPv4, preferIPOnlyIPv6:
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
conn net.Conn
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, v := range addresses {
|
||||||
|
conn, err = t.dialer.DialContext(ctx, v.network, v.address)
|
||||||
|
if err == nil {
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("cannot dial to %d dc: %w", dc, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTelegramDialer(dialer Dialer, ipPreference string) (*Telegram, error) {
|
||||||
|
var pref preferIP
|
||||||
|
|
||||||
|
switch strings.ToLower(ipPreference) {
|
||||||
|
case "prefer-ipv4":
|
||||||
|
pref = preferIPPreferIPv4
|
||||||
|
case "prefer-ipv6":
|
||||||
|
pref = preferIPPreferIPv6
|
||||||
|
case "only-ipv4":
|
||||||
|
pref = preferIPOnlyIPv4
|
||||||
|
case "only-ipv6":
|
||||||
|
pref = preferIPOnlyIPv6
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown ip preference %s", ipPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Telegram{
|
||||||
|
dialer: dialer,
|
||||||
|
preferIP: pref,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
+3
-5
@@ -43,11 +43,9 @@ func (n *network) DialContext(ctx context.Context, protocol, address string) (ne
|
|||||||
return nil, fmt.Errorf("cannot resolve dns names: %w", err)
|
return nil, fmt.Errorf("cannot resolve dns names: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ips) > 1 {
|
rand.Shuffle(len(ips), func(i, j int) {
|
||||||
rand.Shuffle(len(ips), func(i, j int) {
|
ips[i], ips[j] = ips[j], ips[i]
|
||||||
ips[i], ips[j] = ips[j], ips[i]
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
for _, v := range ips {
|
for _, v := range ips {
|
||||||
|
|||||||
Reference in New Issue
Block a user