| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- 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 > 5 {
- return nil, fmt.Errorf("do not know how to dial to %d", dc)
- }
-
- 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 {
- case preferIPPreferIPv4:
- addresses = append(addresses, v6Addresses[dc-1])
- case preferIPPreferIPv6:
- addresses = append([]tgAddr{v6Addresses[dc-1]}, 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 New(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
- }
|