connections_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright (C) 2016 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package connections
  7. import (
  8. "context"
  9. "errors"
  10. "net/url"
  11. "testing"
  12. "github.com/syncthing/syncthing/lib/config"
  13. "github.com/syncthing/syncthing/lib/protocol"
  14. )
  15. func TestFixupPort(t *testing.T) {
  16. cases := [][2]string{
  17. {"tcp://1.2.3.4:5", "tcp://1.2.3.4:5"},
  18. {"tcp://1.2.3.4:", "tcp://1.2.3.4:22000"},
  19. {"tcp://1.2.3.4", "tcp://1.2.3.4:22000"},
  20. {"tcp://[fe80::1]", "tcp://[fe80::1]:22000"},
  21. {"tcp://[fe80::1]:", "tcp://[fe80::1]:22000"},
  22. {"tcp://[fe80::1]:22000", "tcp://[fe80::1]:22000"},
  23. {"tcp://[fe80::1]:22000", "tcp://[fe80::1]:22000"},
  24. {"tcp://[fe80::1%25abc]", "tcp://[fe80::1%25abc]:22000"},
  25. {"tcp://[fe80::1%25abc]:", "tcp://[fe80::1%25abc]:22000"},
  26. {"tcp://[fe80::1%25abc]:22000", "tcp://[fe80::1%25abc]:22000"},
  27. {"tcp://[fe80::1%25abc]:22000", "tcp://[fe80::1%25abc]:22000"},
  28. }
  29. for _, tc := range cases {
  30. u0, err := url.Parse(tc[0])
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. u1 := fixupPort(u0, 22000).String()
  35. if u1 != tc[1] {
  36. t.Errorf("fixupPort(%q, 22000) => %q, expected %q", tc[0], u1, tc[1])
  37. }
  38. }
  39. }
  40. func TestAllowedNetworks(t *testing.T) {
  41. cases := []struct {
  42. host string
  43. allowed []string
  44. ok bool
  45. }{
  46. {
  47. "192.168.0.1",
  48. nil,
  49. false,
  50. },
  51. {
  52. "192.168.0.1",
  53. []string{},
  54. false,
  55. },
  56. {
  57. "fe80::1",
  58. nil,
  59. false,
  60. },
  61. {
  62. "fe80::1",
  63. []string{},
  64. false,
  65. },
  66. {
  67. "192.168.0.1",
  68. []string{"fe80::/48", "192.168.0.0/24"},
  69. true,
  70. },
  71. {
  72. "fe80::1",
  73. []string{"192.168.0.0/24", "fe80::/48"},
  74. true,
  75. },
  76. {
  77. "192.168.0.1",
  78. []string{"192.168.1.0/24", "fe80::/48"},
  79. false,
  80. },
  81. {
  82. "fe80::1",
  83. []string{"fe82::/48", "192.168.1.0/24"},
  84. false,
  85. },
  86. {
  87. "192.168.0.1:4242",
  88. []string{"fe80::/48", "192.168.0.0/24"},
  89. true,
  90. },
  91. {
  92. "[fe80::1]:4242",
  93. []string{"192.168.0.0/24", "fe80::/48"},
  94. true,
  95. },
  96. {
  97. "10.20.30.40",
  98. []string{"!10.20.30.0/24", "10.0.0.0/8"},
  99. false,
  100. },
  101. {
  102. "10.20.30.40",
  103. []string{"10.0.0.0/8", "!10.20.30.0/24"},
  104. true,
  105. },
  106. {
  107. "[fe80::1]:4242",
  108. []string{"192.168.0.0/24", "!fe00::/8", "fe80::/48"},
  109. false,
  110. },
  111. }
  112. for _, tc := range cases {
  113. res := IsAllowedNetwork(tc.host, tc.allowed)
  114. if res != tc.ok {
  115. t.Errorf("allowedNetwork(%q, %q) == %v, want %v", tc.host, tc.allowed, res, tc.ok)
  116. }
  117. }
  118. }
  119. func TestGetDialer(t *testing.T) {
  120. mustParseURI := func(v string) *url.URL {
  121. uri, err := url.Parse(v)
  122. if err != nil {
  123. panic(err)
  124. }
  125. return uri
  126. }
  127. cases := []struct {
  128. uri *url.URL
  129. ok bool
  130. disabled bool
  131. deprecated bool
  132. }{
  133. {mustParseURI("tcp://1.2.3.4:5678"), true, false, false}, // ok
  134. {mustParseURI("tcp4://1.2.3.4:5678"), true, false, false}, // ok
  135. {mustParseURI("kcp://1.2.3.4:5678"), false, false, true}, // deprecated
  136. {mustParseURI("relay://1.2.3.4:5678"), false, true, false}, // disabled
  137. {mustParseURI("http://1.2.3.4:5678"), false, false, false}, // generally bad
  138. {mustParseURI("bananas!"), false, false, false}, // wat
  139. }
  140. cfg := config.New(protocol.LocalDeviceID)
  141. cfg.Options.RelaysEnabled = false
  142. for _, tc := range cases {
  143. df, err := getDialerFactory(cfg, tc.uri)
  144. if tc.ok && err != nil {
  145. t.Errorf("getDialerFactory(%q) => %v, expected nil err", tc.uri, err)
  146. }
  147. if tc.ok && df == nil {
  148. t.Errorf("getDialerFactory(%q) => nil factory, expected non-nil", tc.uri)
  149. }
  150. if tc.deprecated && err != errDeprecated {
  151. t.Errorf("getDialerFactory(%q) => %v, expected %v", tc.uri, err, errDeprecated)
  152. }
  153. if tc.disabled && err != errDisabled {
  154. t.Errorf("getDialerFactory(%q) => %v, expected %v", tc.uri, err, errDisabled)
  155. }
  156. lf, err := getListenerFactory(cfg, tc.uri)
  157. if tc.ok && err != nil {
  158. t.Errorf("getListenerFactory(%q) => %v, expected nil err", tc.uri, err)
  159. }
  160. if tc.ok && lf == nil {
  161. t.Errorf("getListenerFactory(%q) => nil factory, expected non-nil", tc.uri)
  162. }
  163. if tc.deprecated && err != errDeprecated {
  164. t.Errorf("getListenerFactory(%q) => %v, expected %v", tc.uri, err, errDeprecated)
  165. }
  166. if tc.disabled && err != errDisabled {
  167. t.Errorf("getListenerFactory(%q) => %v, expected %v", tc.uri, err, errDisabled)
  168. }
  169. }
  170. }
  171. func TestConnectionStatus(t *testing.T) {
  172. s := newConnectionStatusHandler()
  173. addr := "testAddr"
  174. testErr := errors.New("testErr")
  175. if stats := s.ConnectionStatus(); len(stats) != 0 {
  176. t.Fatal("newly created connectionStatusHandler isn't empty:", len(stats))
  177. }
  178. check := func(in, out error) {
  179. t.Helper()
  180. s.setConnectionStatus(addr, in)
  181. switch stat, ok := s.ConnectionStatus()[addr]; {
  182. case !ok:
  183. t.Fatal("entry missing")
  184. case out == nil:
  185. if stat.Error != nil {
  186. t.Fatal("expected nil error, got", stat.Error)
  187. }
  188. case *stat.Error != out.Error():
  189. t.Fatalf("expected %v error, got %v", out.Error(), *stat.Error)
  190. }
  191. }
  192. check(nil, nil)
  193. check(context.Canceled, nil)
  194. check(testErr, testErr)
  195. check(context.Canceled, testErr)
  196. check(nil, nil)
  197. }