Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

network.go 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package network
  2. import (
  3. "context"
  4. "fmt"
  5. "math/rand"
  6. "net"
  7. "net/http"
  8. "time"
  9. doh "github.com/babolivier/go-doh-client"
  10. )
  11. type Network struct {
  12. HTTP http.Client
  13. DNS doh.Resolver
  14. dialer Dialer
  15. }
  16. func (d *Network) Dial(network, address string) (net.Conn, error) {
  17. return d.DialContext(context.Background(), network, address)
  18. }
  19. func (d *Network) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
  20. host, port, _ := net.SplitHostPort(address)
  21. ips, err := d.resolveIPs(network, host)
  22. if err != nil {
  23. return nil, fmt.Errorf("cannot resolve dns names: %w", err)
  24. }
  25. rand.Shuffle(len(ips), func(i, j int) {
  26. ips[i], ips[j] = ips[j], ips[i]
  27. })
  28. for _, v := range ips {
  29. if conn, err := d.dialer.DialContext(ctx, network, net.JoinHostPort(v, port)); err == nil {
  30. return conn, nil
  31. }
  32. }
  33. return nil, fmt.Errorf("cannot dial to %s:%s", network, address)
  34. }
  35. func (d *Network) resolveIPs(network, address string) ([]string, error) {
  36. if net.ParseIP(address) != nil {
  37. return []string{address}, nil
  38. }
  39. var ips []string
  40. switch network {
  41. case "tcp", "tcp4":
  42. if recs, _, err := d.DNS.LookupA(address); err == nil {
  43. for _, v := range recs {
  44. ips = append(ips, v.IP4)
  45. }
  46. }
  47. }
  48. switch network {
  49. case "tcp", "tcp6":
  50. if recs, _, err := d.DNS.LookupAAAA(address); err == nil {
  51. for _, v := range recs {
  52. ips = append(ips, v.IP6)
  53. }
  54. }
  55. }
  56. if len(ips) == 0 {
  57. return nil, fmt.Errorf("cannot find any ips for %s:%s", network, address)
  58. }
  59. return ips, nil
  60. }
  61. func NewNetwork(dialer Dialer, dohHostname string, httpTimeout time.Duration) (*Network, error) {
  62. switch {
  63. case httpTimeout < 0:
  64. return nil, fmt.Errorf("timeout should be positive number %v", httpTimeout)
  65. case httpTimeout == 0:
  66. httpTimeout = DefaultHTTPTimeout
  67. }
  68. if net.ParseIP(dohHostname) == nil {
  69. return nil, fmt.Errorf("hostname %s should be IP address", dohHostname)
  70. }
  71. dohHTTPClient := &http.Client{
  72. Timeout: httpTimeout,
  73. Transport: &http.Transport{
  74. DialContext: dialer.DialContext,
  75. },
  76. }
  77. network := &Network{
  78. dialer: dialer,
  79. DNS: doh.Resolver{
  80. Host: dohHostname,
  81. Class: doh.IN,
  82. HTTPClient: dohHTTPClient,
  83. },
  84. }
  85. network.HTTP = http.Client{
  86. Timeout: httpTimeout,
  87. Transport: &http.Transport{
  88. DialContext: network.DialContext,
  89. },
  90. }
  91. return network, nil
  92. }