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
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

probe_test.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package dcprobe_test
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. "net"
  7. "os"
  8. "testing"
  9. "time"
  10. "github.com/9seconds/mtg/v2/mtglib/dcprobe"
  11. )
  12. // TestProbeAgainstTelegramDCs makes outbound TCP connections to public
  13. // Telegram DCs. Skipped by default; opt-in with MTG_PROBE_NETWORK=1.
  14. func TestProbeAgainstTelegramDCs(t *testing.T) {
  15. if os.Getenv("MTG_PROBE_NETWORK") != "1" {
  16. t.Skip("skipping network probe (set MTG_PROBE_NETWORK=1 to enable)")
  17. }
  18. cases := []struct {
  19. dc int
  20. addr string
  21. }{
  22. {1, "149.154.175.50:443"},
  23. {2, "149.154.167.51:443"},
  24. {2, "95.161.76.100:443"},
  25. {3, "149.154.175.100:443"},
  26. {4, "149.154.167.91:443"},
  27. {5, "149.154.171.5:443"},
  28. {1, "[2001:b28:f23d:f001::a]:443"},
  29. {2, "[2001:67c:04e8:f002::a]:443"},
  30. }
  31. for _, tc := range cases {
  32. t.Run(tc.addr, func(t *testing.T) {
  33. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  34. defer cancel()
  35. conn, err := (&net.Dialer{}).DialContext(ctx, "tcp", tc.addr)
  36. if err != nil {
  37. t.Fatalf("dial: %v", err)
  38. }
  39. t.Cleanup(func() { _ = conn.Close() })
  40. rtt, err := dcprobe.Probe(ctx, conn, tc.dc)
  41. if err != nil {
  42. t.Fatalf("probe DC %d: %v", tc.dc, err)
  43. }
  44. t.Logf("DC %d (%s): rtt=%s", tc.dc, tc.addr, rtt)
  45. })
  46. }
  47. }
  48. // TestProbeRejectsMisbehavingPeer connects to an in-process listener that
  49. // accepts the obfs2 handshake, then writes back arbitrary bytes. With
  50. // overwhelming probability the decrypted reply fails one of: frame-length
  51. // bounds, resPQ constructor, or nonce echo. All three paths wrap
  52. // ErrNotTelegram, so we assert errors.Is.
  53. func TestProbeRejectsMisbehavingPeer(t *testing.T) {
  54. ln, err := net.Listen("tcp", "127.0.0.1:0")
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. t.Cleanup(func() { _ = ln.Close() })
  59. go func() {
  60. c, err := ln.Accept()
  61. if err != nil {
  62. return
  63. }
  64. defer c.Close() //nolint: errcheck
  65. // Discard the 64-byte obfs2 handshake the client sends.
  66. var hs [64]byte
  67. if _, err := io.ReadFull(c, hs[:]); err != nil {
  68. return
  69. }
  70. // Write enough garbage to satisfy any plausible respLen the client
  71. // might decode (we cap at maxResPQFrame=256 in probe.go). Whatever
  72. // the client decrypts will fail constructor or nonce verification.
  73. junk := make([]byte, 512)
  74. for i := range junk {
  75. junk[i] = byte(i)
  76. }
  77. _, _ = c.Write(junk)
  78. // Keep the conn open until the client closes it (avoids racing the
  79. // client's read against our close).
  80. _, _ = io.Copy(io.Discard, c)
  81. }()
  82. ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
  83. defer cancel()
  84. conn, err := (&net.Dialer{}).DialContext(ctx, "tcp", ln.Addr().String())
  85. if err != nil {
  86. t.Fatal(err)
  87. }
  88. t.Cleanup(func() { _ = conn.Close() })
  89. _, err = dcprobe.Probe(ctx, conn, 2)
  90. if err == nil {
  91. t.Fatal("expected ErrNotTelegram, got nil")
  92. }
  93. if !errors.Is(err, dcprobe.ErrNotTelegram) {
  94. t.Fatalf("expected errors.Is(err, ErrNotTelegram) to be true, got: %v", err)
  95. }
  96. t.Logf("rejected: %v", err)
  97. }