egress_port_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package amneziawgnet
  2. import (
  3. "encoding/json"
  4. "net"
  5. "strconv"
  6. "testing"
  7. )
  8. // holdEgressBasePort occupies EgressBasePort the way another service would; a
  9. // port the OS already refuses, such as a Windows reservation, needs no holder.
  10. func holdEgressBasePort(t *testing.T) {
  11. t.Helper()
  12. ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(EgressBasePort)))
  13. if err != nil {
  14. return
  15. }
  16. t.Cleanup(func() { ln.Close() })
  17. }
  18. // bridgePort is the port a socks bridge generated right now dials.
  19. func bridgePort(t *testing.T) int {
  20. t.Helper()
  21. out, ok := BuildSocksBridge([]byte(`{"protocol":"amneziawg","tag":"awg-hop","settings":{}}`))
  22. if !ok {
  23. t.Fatal("bridge rejected")
  24. }
  25. var got struct {
  26. Settings struct {
  27. Port int `json:"port"`
  28. } `json:"settings"`
  29. }
  30. if err := json.Unmarshal(out, &got); err != nil {
  31. t.Fatal(err)
  32. }
  33. return got.Settings.Port
  34. }
  35. // Windows can reserve a port range covering EgressBasePort, and any host can run
  36. // another service on it; the egress must still come up and report where.
  37. func TestEgressListenFallsBackWhenBasePortIsTaken(t *testing.T) {
  38. srv := GetEgressServer()
  39. srv.Close()
  40. t.Cleanup(srv.Close)
  41. holdEgressBasePort(t)
  42. if err := srv.Listen(); err != nil {
  43. t.Fatalf("Listen with EgressBasePort taken: %v", err)
  44. }
  45. port := srv.Port()
  46. if port == EgressBasePort {
  47. t.Fatalf("Port() = %d, the taken EgressBasePort", port)
  48. }
  49. conn, err := net.Dial("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
  50. if err != nil {
  51. t.Fatalf("egress not accepting on Port() %d: %v", port, err)
  52. }
  53. conn.Close()
  54. }
  55. // Xray's bridges are generated apart from the listener, so a listener that came
  56. // up elsewhere must be reported until the bridges are regenerated for it.
  57. func TestBridgesStaleUntilRegeneratedForTheBoundPort(t *testing.T) {
  58. srv := GetEgressServer()
  59. srv.Close()
  60. t.Cleanup(srv.Close)
  61. holdEgressBasePort(t)
  62. if got := bridgePort(t); got != EgressBasePort {
  63. t.Fatalf("bridge generated before Listen dials %d, want %d", got, EgressBasePort)
  64. }
  65. if err := srv.Listen(); err != nil {
  66. t.Fatal(err)
  67. }
  68. if !BridgesStale() {
  69. t.Fatalf("bridges dial %d while the egress listens on %d, but BridgesStale() = false", EgressBasePort, srv.Port())
  70. }
  71. if got := bridgePort(t); got != srv.Port() || BridgesStale() {
  72. t.Fatalf("regenerated bridge dials %d with BridgesStale() = %v, want %d and false", got, BridgesStale(), srv.Port())
  73. }
  74. }