dialParameters_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * Copyright (c) 2023, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package inproxy
  20. import (
  21. "context"
  22. "encoding/json"
  23. "fmt"
  24. "net"
  25. "sync"
  26. "sync/atomic"
  27. "time"
  28. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  29. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  30. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/stacktrace"
  31. )
  32. type testDialParameters struct {
  33. mutex sync.Mutex
  34. commonCompartmentIDs []ID
  35. personalCompartmentIDs []ID
  36. networkID string
  37. networkType NetworkType
  38. brokerClientPrivateKey SessionPrivateKey
  39. brokerPublicKey SessionPublicKey
  40. brokerRootObfuscationSecret ObfuscationSecret
  41. brokerClientRoundTripper RoundTripper
  42. brokerClientRoundTripperSucceeded func(RoundTripper)
  43. brokerClientRoundTripperFailed func(RoundTripper)
  44. clientRootObfuscationSecret ObfuscationSecret
  45. doDTLSRandomization bool
  46. stunServerAddress string
  47. stunServerAddressRFC5780 string
  48. stunServerAddressSucceeded func(RFC5780 bool, address string)
  49. stunServerAddressFailed func(RFC5780 bool, address string)
  50. discoverNAT bool
  51. disableSTUN bool
  52. disablePortMapping bool
  53. disableInboundForMobleNetworks bool
  54. natType NATType
  55. setNATType func(NATType)
  56. portMappingTypes PortMappingTypes
  57. setPortMappingTypes func(PortMappingTypes)
  58. bindToDevice func(int) error
  59. discoverNATTimeout time.Duration
  60. offerRequestTimeout time.Duration
  61. offerRetryDelay time.Duration
  62. offerRetryJitter float64
  63. announceRequestTimeout time.Duration
  64. announceRetryDelay time.Duration
  65. announceRetryJitter float64
  66. webRTCAnswerTimeout time.Duration
  67. answerRequestTimeout time.Duration
  68. proxyClientConnectTimeout time.Duration
  69. proxyDestinationDialTimeout time.Duration
  70. }
  71. func (t *testDialParameters) CommonCompartmentIDs() []ID {
  72. t.mutex.Lock()
  73. defer t.mutex.Unlock()
  74. return t.commonCompartmentIDs
  75. }
  76. func (t *testDialParameters) PersonalCompartmentIDs() []ID {
  77. t.mutex.Lock()
  78. defer t.mutex.Unlock()
  79. return t.personalCompartmentIDs
  80. }
  81. func (t *testDialParameters) NetworkID() string {
  82. t.mutex.Lock()
  83. defer t.mutex.Unlock()
  84. return t.networkID
  85. }
  86. func (t *testDialParameters) NetworkType() NetworkType {
  87. t.mutex.Lock()
  88. defer t.mutex.Unlock()
  89. return t.networkType
  90. }
  91. func (t *testDialParameters) BrokerClientPrivateKey() SessionPrivateKey {
  92. t.mutex.Lock()
  93. defer t.mutex.Unlock()
  94. return t.brokerClientPrivateKey
  95. }
  96. func (t *testDialParameters) BrokerPublicKey() SessionPublicKey {
  97. t.mutex.Lock()
  98. defer t.mutex.Unlock()
  99. return t.brokerPublicKey
  100. }
  101. func (t *testDialParameters) BrokerRootObfuscationSecret() ObfuscationSecret {
  102. t.mutex.Lock()
  103. defer t.mutex.Unlock()
  104. return t.brokerRootObfuscationSecret
  105. }
  106. func (t *testDialParameters) BrokerClientRoundTripper() (RoundTripper, error) {
  107. t.mutex.Lock()
  108. defer t.mutex.Unlock()
  109. return t.brokerClientRoundTripper, nil
  110. }
  111. func (t *testDialParameters) BrokerClientRoundTripperSucceeded(roundTripper RoundTripper) {
  112. t.mutex.Lock()
  113. defer t.mutex.Unlock()
  114. t.brokerClientRoundTripperSucceeded(roundTripper)
  115. }
  116. func (t *testDialParameters) BrokerClientRoundTripperFailed(roundTripper RoundTripper) {
  117. t.mutex.Lock()
  118. defer t.mutex.Unlock()
  119. t.brokerClientRoundTripperFailed(roundTripper)
  120. }
  121. func (t *testDialParameters) ClientRootObfuscationSecret() ObfuscationSecret {
  122. t.mutex.Lock()
  123. defer t.mutex.Unlock()
  124. return t.clientRootObfuscationSecret
  125. }
  126. func (t *testDialParameters) DoDTLSRandomization() bool {
  127. t.mutex.Lock()
  128. defer t.mutex.Unlock()
  129. return t.doDTLSRandomization
  130. }
  131. func (t *testDialParameters) STUNServerAddress(RFC5780 bool) string {
  132. t.mutex.Lock()
  133. defer t.mutex.Unlock()
  134. if RFC5780 {
  135. return t.stunServerAddressRFC5780
  136. }
  137. return t.stunServerAddress
  138. }
  139. func (t *testDialParameters) STUNServerAddressSucceeded(RFC5780 bool, address string) {
  140. t.mutex.Lock()
  141. defer t.mutex.Unlock()
  142. t.stunServerAddressSucceeded(RFC5780, address)
  143. }
  144. func (t *testDialParameters) STUNServerAddressFailed(RFC5780 bool, address string) {
  145. t.mutex.Lock()
  146. defer t.mutex.Unlock()
  147. t.stunServerAddressFailed(RFC5780, address)
  148. }
  149. func (t *testDialParameters) DiscoverNAT() bool {
  150. t.mutex.Lock()
  151. defer t.mutex.Unlock()
  152. return t.discoverNAT
  153. }
  154. func (t *testDialParameters) DisableSTUN() bool {
  155. t.mutex.Lock()
  156. defer t.mutex.Unlock()
  157. return t.disableSTUN
  158. }
  159. func (t *testDialParameters) DisablePortMapping() bool {
  160. t.mutex.Lock()
  161. defer t.mutex.Unlock()
  162. return t.disablePortMapping
  163. }
  164. func (t *testDialParameters) DisableInboundForMobleNetworks() bool {
  165. t.mutex.Lock()
  166. defer t.mutex.Unlock()
  167. return t.disableInboundForMobleNetworks
  168. }
  169. func (t *testDialParameters) NATType() NATType {
  170. t.mutex.Lock()
  171. defer t.mutex.Unlock()
  172. return t.natType
  173. }
  174. func (t *testDialParameters) SetNATType(natType NATType) {
  175. t.mutex.Lock()
  176. defer t.mutex.Unlock()
  177. t.natType = natType
  178. t.setNATType(natType)
  179. }
  180. func (t *testDialParameters) PortMappingTypes() PortMappingTypes {
  181. t.mutex.Lock()
  182. defer t.mutex.Unlock()
  183. return t.portMappingTypes
  184. }
  185. func (t *testDialParameters) SetPortMappingTypes(portMappingTypes PortMappingTypes) {
  186. t.mutex.Lock()
  187. defer t.mutex.Unlock()
  188. t.portMappingTypes = append(PortMappingTypes{}, portMappingTypes...)
  189. t.setPortMappingTypes(portMappingTypes)
  190. }
  191. func (t *testDialParameters) ResolveAddress(ctx context.Context, address string) (string, error) {
  192. // No hostnames are resolved in the test.
  193. return address, nil
  194. }
  195. func (t *testDialParameters) UDPListen() (net.PacketConn, error) {
  196. t.mutex.Lock()
  197. defer t.mutex.Unlock()
  198. conn, err := net.ListenUDP("udp", nil)
  199. return conn, errors.Trace(err)
  200. }
  201. func (t *testDialParameters) BindToDevice(fileDescriptor int) error {
  202. t.mutex.Lock()
  203. defer t.mutex.Unlock()
  204. return errors.Trace(t.bindToDevice(fileDescriptor))
  205. }
  206. func (t *testDialParameters) DiscoverNATTimeout() time.Duration {
  207. t.mutex.Lock()
  208. defer t.mutex.Unlock()
  209. return t.discoverNATTimeout
  210. }
  211. func (t *testDialParameters) OfferRequestTimeout() time.Duration {
  212. t.mutex.Lock()
  213. defer t.mutex.Unlock()
  214. return t.offerRequestTimeout
  215. }
  216. func (t *testDialParameters) OfferRetryDelay() time.Duration {
  217. t.mutex.Lock()
  218. defer t.mutex.Unlock()
  219. return t.offerRetryDelay
  220. }
  221. func (t *testDialParameters) OfferRetryJitter() float64 {
  222. t.mutex.Lock()
  223. defer t.mutex.Unlock()
  224. return t.offerRetryJitter
  225. }
  226. func (t *testDialParameters) AnnounceRequestTimeout() time.Duration {
  227. t.mutex.Lock()
  228. defer t.mutex.Unlock()
  229. return t.announceRequestTimeout
  230. }
  231. func (t *testDialParameters) AnnounceRetryDelay() time.Duration {
  232. t.mutex.Lock()
  233. defer t.mutex.Unlock()
  234. return t.announceRetryDelay
  235. }
  236. func (t *testDialParameters) AnnounceRetryJitter() float64 {
  237. t.mutex.Lock()
  238. defer t.mutex.Unlock()
  239. return t.announceRetryJitter
  240. }
  241. func (t *testDialParameters) WebRTCAnswerTimeout() time.Duration {
  242. t.mutex.Lock()
  243. defer t.mutex.Unlock()
  244. return t.webRTCAnswerTimeout
  245. }
  246. func (t *testDialParameters) AnswerRequestTimeout() time.Duration {
  247. t.mutex.Lock()
  248. defer t.mutex.Unlock()
  249. return t.answerRequestTimeout
  250. }
  251. func (t *testDialParameters) ProxyClientConnectTimeout() time.Duration {
  252. t.mutex.Lock()
  253. defer t.mutex.Unlock()
  254. return t.proxyClientConnectTimeout
  255. }
  256. func (t *testDialParameters) ProxyDestinationDialTimeout() time.Duration {
  257. t.mutex.Lock()
  258. defer t.mutex.Unlock()
  259. return t.proxyDestinationDialTimeout
  260. }
  261. type testLogger struct {
  262. logLevelDebug int32
  263. }
  264. func newTestLogger() *testLogger {
  265. return &testLogger{logLevelDebug: 1}
  266. }
  267. func (logger *testLogger) WithTrace() common.LogTrace {
  268. return &testLoggerTrace{
  269. logger: logger,
  270. trace: stacktrace.GetParentFunctionName(),
  271. }
  272. }
  273. func (logger *testLogger) WithTraceFields(fields common.LogFields) common.LogTrace {
  274. return &testLoggerTrace{
  275. logger: logger,
  276. trace: stacktrace.GetParentFunctionName(),
  277. fields: fields,
  278. }
  279. }
  280. func (logger *testLogger) LogMetric(metric string, fields common.LogFields) {
  281. jsonFields, _ := json.Marshal(fields)
  282. fmt.Printf(
  283. "[%s] METRIC: %s: %s\n",
  284. time.Now().UTC().Format(time.RFC3339),
  285. metric,
  286. string(jsonFields))
  287. }
  288. func (logger *testLogger) IsLogLevelDebug() bool {
  289. return atomic.LoadInt32(&logger.logLevelDebug) == 1
  290. }
  291. func (logger *testLogger) SetLogLevelDebug(logLevelDebug bool) {
  292. value := int32(0)
  293. if logLevelDebug {
  294. value = 1
  295. }
  296. atomic.StoreInt32(&logger.logLevelDebug, value)
  297. }
  298. type testLoggerTrace struct {
  299. logger *testLogger
  300. trace string
  301. fields common.LogFields
  302. }
  303. func (logger *testLoggerTrace) log(priority, message string) {
  304. now := time.Now().UTC().Format(time.RFC3339)
  305. if len(logger.fields) == 0 {
  306. fmt.Printf(
  307. "[%s] %s: %s: %s\n",
  308. now, priority, logger.trace, message)
  309. } else {
  310. fields := common.LogFields{}
  311. for k, v := range logger.fields {
  312. switch v := v.(type) {
  313. case error:
  314. // Workaround for Go issue 5161: error types marshal to "{}"
  315. fields[k] = v.Error()
  316. default:
  317. fields[k] = v
  318. }
  319. }
  320. jsonFields, _ := json.Marshal(fields)
  321. fmt.Printf(
  322. "[%s] %s: %s: %s %s\n",
  323. now, priority, logger.trace, message, string(jsonFields))
  324. }
  325. }
  326. func (logger *testLoggerTrace) Debug(args ...interface{}) {
  327. if !logger.logger.IsLogLevelDebug() {
  328. return
  329. }
  330. logger.log("DEBUG", fmt.Sprint(args...))
  331. }
  332. func (logger *testLoggerTrace) Info(args ...interface{}) {
  333. logger.log("INFO", fmt.Sprint(args...))
  334. }
  335. func (logger *testLoggerTrace) Warning(args ...interface{}) {
  336. logger.log("WARNING", fmt.Sprint(args...))
  337. }
  338. func (logger *testLoggerTrace) Error(args ...interface{}) {
  339. logger.log("ERROR", fmt.Sprint(args...))
  340. }