udpproxy_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. //go:build !wasm
  2. // +build !wasm
  3. package vnet
  4. import (
  5. "context"
  6. "errors"
  7. "flag"
  8. "fmt"
  9. "net"
  10. "os"
  11. "sync"
  12. "testing"
  13. "time"
  14. "github.com/pion/logging"
  15. )
  16. type MockUDPEchoServer struct {
  17. realServerAddr *net.UDPAddr
  18. realServerReady context.Context
  19. realServerReadyCancel context.CancelFunc
  20. }
  21. func NewMockUDPEchoServer() *MockUDPEchoServer {
  22. v := &MockUDPEchoServer{}
  23. v.realServerReady, v.realServerReadyCancel = context.WithCancel(context.Background())
  24. return v
  25. }
  26. func (v *MockUDPEchoServer) doMockUDPServer(ctx context.Context) error {
  27. // Listen to a random port.
  28. laddr, err := net.ResolveUDPAddr("udp4", "127.0.0.1:0")
  29. if err != nil {
  30. return err
  31. }
  32. conn, err := net.ListenUDP("udp4", laddr)
  33. if err != nil {
  34. return err
  35. }
  36. v.realServerAddr = conn.LocalAddr().(*net.UDPAddr)
  37. v.realServerReadyCancel()
  38. // When system quit, interrupt client.
  39. selfKill, selfKillCancel := context.WithCancel(context.Background())
  40. go func() {
  41. <-ctx.Done()
  42. selfKillCancel()
  43. _ = conn.Close()
  44. }()
  45. // Note that if they has the same ID, the address should not changed.
  46. addrs := make(map[string]net.Addr)
  47. // Start an echo UDP server.
  48. buf := make([]byte, 1500)
  49. for ctx.Err() == nil {
  50. n, addr, err := conn.ReadFrom(buf)
  51. if err != nil {
  52. if errors.Is(selfKill.Err(), context.Canceled) {
  53. return nil
  54. }
  55. return err
  56. } else if n == 0 || addr == nil {
  57. return fmt.Errorf("n=%v, addr=%v", n, addr) // nolint:goerr113
  58. } else if nn, err := conn.WriteTo(buf[:n], addr); err != nil {
  59. return err
  60. } else if nn != n {
  61. return fmt.Errorf("nn=%v, n=%v", nn, n) // nolint:goerr113
  62. }
  63. // Check the address, shold not change, use content as ID.
  64. clientID := string(buf[:n])
  65. if oldAddr, ok := addrs[clientID]; ok && oldAddr.String() != addr.String() {
  66. return fmt.Errorf("address change %v to %v", oldAddr.String(), addr.String()) // nolint:goerr113
  67. }
  68. addrs[clientID] = addr
  69. }
  70. return nil
  71. }
  72. var testTimeout = flag.Int("timeout", 5000, "For each case, the timeout in ms") // nolint:gochecknoglobals
  73. func TestMain(m *testing.M) {
  74. flag.Parse()
  75. os.Exit(m.Run())
  76. }
  77. // vnet client:
  78. //
  79. // 10.0.0.11:5787
  80. //
  81. // proxy to real server:
  82. //
  83. // 192.168.1.10:8000
  84. func TestUDPProxyOne2One(t *testing.T) {
  85. ctx, cancel := context.WithCancel(context.Background())
  86. var r0, r1, r2 error
  87. defer func() {
  88. if r0 != nil || r1 != nil || r2 != nil {
  89. t.Errorf("fail for ctx=%v, r0=%v, r1=%v, r2=%v", ctx.Err(), r0, r1, r2)
  90. }
  91. }()
  92. var wg sync.WaitGroup
  93. defer wg.Wait()
  94. // Timeout, fail
  95. wg.Add(1)
  96. go func() {
  97. defer wg.Done()
  98. defer cancel()
  99. select {
  100. case <-ctx.Done():
  101. case <-time.After(time.Duration(*testTimeout) * time.Millisecond):
  102. r2 = fmt.Errorf("timeout") // nolint:goerr113
  103. }
  104. }()
  105. // For utest, we always proxy vnet packets to the random port we listen to.
  106. mockServer := NewMockUDPEchoServer()
  107. wg.Add(1)
  108. go func() {
  109. defer wg.Done()
  110. defer cancel()
  111. if err := mockServer.doMockUDPServer(ctx); err != nil {
  112. r0 = err
  113. }
  114. }()
  115. // Create a vent and proxy.
  116. wg.Add(1)
  117. go func() {
  118. defer wg.Done()
  119. defer cancel()
  120. // When real server is ready, start the vnet test.
  121. select {
  122. case <-ctx.Done():
  123. return
  124. case <-mockServer.realServerReady.Done():
  125. }
  126. doVnetProxy := func() error {
  127. router, err := NewRouter(&RouterConfig{
  128. CIDR: "0.0.0.0/0",
  129. LoggerFactory: logging.NewDefaultLoggerFactory(),
  130. })
  131. if err != nil {
  132. return err
  133. }
  134. clientNetwork := NewNet(&NetConfig{
  135. StaticIP: "10.0.0.11",
  136. })
  137. if err = router.AddNet(clientNetwork); err != nil {
  138. return err
  139. }
  140. if err = router.Start(); err != nil {
  141. return err
  142. }
  143. defer router.Stop() // nolint:errcheck
  144. proxy, err := NewProxy(router)
  145. if err != nil {
  146. return err
  147. }
  148. defer proxy.Close() // nolint:errcheck
  149. // For utest, mock the target real server.
  150. proxy.mockRealServerAddr = mockServer.realServerAddr
  151. // The real server address to proxy to.
  152. // Note that for utest, we will proxy to a local address.
  153. serverAddr, err := net.ResolveUDPAddr("udp4", "192.168.1.10:8000")
  154. if err != nil {
  155. return err
  156. }
  157. if err = proxy.Proxy(clientNetwork, serverAddr); err != nil {
  158. return err
  159. }
  160. // Now, all packets from client, will be proxy to real server, vice versa.
  161. client, err := clientNetwork.ListenPacket("udp4", "10.0.0.11:5787")
  162. if err != nil {
  163. return err
  164. }
  165. // When system quit, interrupt client.
  166. selfKill, selfKillCancel := context.WithCancel(context.Background())
  167. go func() {
  168. <-ctx.Done()
  169. selfKillCancel()
  170. _ = client.Close() // nolint:errcheck
  171. }()
  172. for i := 0; i < 10; i++ {
  173. if _, err = client.WriteTo([]byte("Hello"), serverAddr); err != nil {
  174. return err
  175. }
  176. var n int
  177. var addr net.Addr
  178. buf := make([]byte, 1500)
  179. if n, addr, err = client.ReadFrom(buf); err != nil { // nolint:gocritic
  180. if errors.Is(selfKill.Err(), context.Canceled) {
  181. return nil
  182. }
  183. return err
  184. } else if n != 5 || addr == nil {
  185. return fmt.Errorf("n=%v, addr=%v", n, addr) // nolint:goerr113
  186. } else if string(buf[:n]) != "Hello" {
  187. return fmt.Errorf("data %v", buf[:n]) // nolint:goerr113
  188. }
  189. // Wait for awhile for each UDP packet, to simulate real network.
  190. select {
  191. case <-ctx.Done():
  192. return nil
  193. case <-time.After(30 * time.Millisecond):
  194. }
  195. }
  196. return err
  197. }
  198. if err := doVnetProxy(); err != nil {
  199. r1 = err
  200. }
  201. }()
  202. }
  203. // vnet client:
  204. //
  205. // 10.0.0.11:5787
  206. // 10.0.0.11:5788
  207. //
  208. // proxy to real server:
  209. //
  210. // 192.168.1.10:8000
  211. func TestUDPProxyTwo2One(t *testing.T) {
  212. ctx, cancel := context.WithCancel(context.Background())
  213. var r0, r1, r2, r3 error
  214. defer func() {
  215. if r0 != nil || r1 != nil || r2 != nil || r3 != nil {
  216. t.Errorf("fail for ctx=%v, r0=%v, r1=%v, r2=%v, r3=%v", ctx.Err(), r0, r1, r2, r3)
  217. }
  218. }()
  219. var wg sync.WaitGroup
  220. defer wg.Wait()
  221. // Timeout, fail
  222. wg.Add(1)
  223. go func() {
  224. defer wg.Done()
  225. defer cancel()
  226. select {
  227. case <-ctx.Done():
  228. case <-time.After(time.Duration(*testTimeout) * time.Millisecond):
  229. r2 = fmt.Errorf("timeout") // nolint:goerr113
  230. }
  231. }()
  232. // For utest, we always proxy vnet packets to the random port we listen to.
  233. mockServer := NewMockUDPEchoServer()
  234. wg.Add(1)
  235. go func() {
  236. defer wg.Done()
  237. defer cancel()
  238. if err := mockServer.doMockUDPServer(ctx); err != nil {
  239. r0 = err
  240. }
  241. }()
  242. // Create a vent and proxy.
  243. wg.Add(1)
  244. go func() {
  245. defer wg.Done()
  246. defer cancel()
  247. // When real server is ready, start the vnet test.
  248. select {
  249. case <-ctx.Done():
  250. return
  251. case <-mockServer.realServerReady.Done():
  252. }
  253. doVnetProxy := func() error {
  254. router, err := NewRouter(&RouterConfig{
  255. CIDR: "0.0.0.0/0",
  256. LoggerFactory: logging.NewDefaultLoggerFactory(),
  257. })
  258. if err != nil {
  259. return err
  260. }
  261. clientNetwork := NewNet(&NetConfig{
  262. StaticIP: "10.0.0.11",
  263. })
  264. if err = router.AddNet(clientNetwork); err != nil {
  265. return err
  266. }
  267. if err = router.Start(); err != nil {
  268. return err
  269. }
  270. defer router.Stop() // nolint:errcheck
  271. proxy, err := NewProxy(router)
  272. if err != nil {
  273. return err
  274. }
  275. defer proxy.Close() // nolint:errcheck
  276. // For utest, mock the target real server.
  277. proxy.mockRealServerAddr = mockServer.realServerAddr
  278. // The real server address to proxy to.
  279. // Note that for utest, we will proxy to a local address.
  280. serverAddr, err := net.ResolveUDPAddr("udp4", "192.168.1.10:8000")
  281. if err != nil {
  282. return err
  283. }
  284. if err = proxy.Proxy(clientNetwork, serverAddr); err != nil {
  285. return err
  286. }
  287. handClient := func(address, echoData string) error {
  288. // Now, all packets from client, will be proxy to real server, vice versa.
  289. client, err := clientNetwork.ListenPacket("udp4", address) // nolint:govet
  290. if err != nil {
  291. return err
  292. }
  293. // When system quit, interrupt client.
  294. selfKill, selfKillCancel := context.WithCancel(context.Background())
  295. go func() {
  296. <-ctx.Done()
  297. selfKillCancel()
  298. _ = client.Close()
  299. }()
  300. for i := 0; i < 10; i++ {
  301. if _, err := client.WriteTo([]byte(echoData), serverAddr); err != nil { // nolint:govet
  302. return err
  303. }
  304. var n int
  305. var addr net.Addr
  306. buf := make([]byte, 1400)
  307. if n, addr, err = client.ReadFrom(buf); err != nil { // nolint:gocritic
  308. if errors.Is(selfKill.Err(), context.Canceled) {
  309. return nil
  310. }
  311. return err
  312. } else if n != len(echoData) || addr == nil {
  313. return fmt.Errorf("n=%v, addr=%v", n, addr) // nolint:goerr113
  314. } else if string(buf[:n]) != echoData {
  315. return fmt.Errorf("check data %v", buf[:n]) // nolint:goerr113
  316. }
  317. // Wait for awhile for each UDP packet, to simulate real network.
  318. select {
  319. case <-ctx.Done():
  320. return nil
  321. case <-time.After(30 * time.Millisecond):
  322. }
  323. }
  324. return nil
  325. }
  326. client0, client0Cancel := context.WithCancel(context.Background())
  327. go func() {
  328. defer client0Cancel()
  329. address := "10.0.0.11:5787"
  330. if err := handClient(address, "Hello"); err != nil { // nolint:govet
  331. r3 = fmt.Errorf("client %v err %v", address, err) // nolint:goerr113
  332. }
  333. }()
  334. client1, client1Cancel := context.WithCancel(context.Background())
  335. go func() {
  336. defer client1Cancel()
  337. address := "10.0.0.11:5788"
  338. if err := handClient(address, "World"); err != nil { // nolint:govet
  339. r3 = fmt.Errorf("client %v err %v", address, err) // nolint:goerr113
  340. }
  341. }()
  342. select {
  343. case <-ctx.Done():
  344. case <-client0.Done():
  345. case <-client1.Done():
  346. }
  347. return err
  348. }
  349. if err := doVnetProxy(); err != nil {
  350. r1 = err
  351. }
  352. }()
  353. }
  354. // vnet client:
  355. //
  356. // 10.0.0.11:5787
  357. //
  358. // proxy to real server:
  359. //
  360. // 192.168.1.10:8000
  361. //
  362. // vnet client:
  363. //
  364. // 10.0.0.11:5788
  365. //
  366. // proxy to real server:
  367. //
  368. // 192.168.1.10:8000
  369. func TestUDPProxyProxyTwice(t *testing.T) {
  370. ctx, cancel := context.WithCancel(context.Background())
  371. var r0, r1, r2, r3 error
  372. defer func() {
  373. if r0 != nil || r1 != nil || r2 != nil || r3 != nil {
  374. t.Errorf("fail for ctx=%v, r0=%v, r1=%v, r2=%v, r3=%v", ctx.Err(), r0, r1, r2, r3)
  375. }
  376. }()
  377. var wg sync.WaitGroup
  378. defer wg.Wait()
  379. // Timeout, fail
  380. wg.Add(1)
  381. go func() {
  382. defer wg.Done()
  383. defer cancel()
  384. select {
  385. case <-ctx.Done():
  386. case <-time.After(time.Duration(*testTimeout) * time.Millisecond):
  387. r2 = fmt.Errorf("timeout") // nolint:goerr113
  388. }
  389. }()
  390. // For utest, we always proxy vnet packets to the random port we listen to.
  391. mockServer := NewMockUDPEchoServer()
  392. wg.Add(1)
  393. go func() {
  394. defer wg.Done()
  395. defer cancel()
  396. if err := mockServer.doMockUDPServer(ctx); err != nil {
  397. r0 = err
  398. }
  399. }()
  400. // Create a vent and proxy.
  401. wg.Add(1)
  402. go func() {
  403. defer wg.Done()
  404. defer cancel()
  405. // When real server is ready, start the vnet test.
  406. select {
  407. case <-ctx.Done():
  408. return
  409. case <-mockServer.realServerReady.Done():
  410. }
  411. doVnetProxy := func() error {
  412. router, err := NewRouter(&RouterConfig{
  413. CIDR: "0.0.0.0/0",
  414. LoggerFactory: logging.NewDefaultLoggerFactory(),
  415. })
  416. if err != nil {
  417. return err
  418. }
  419. clientNetwork := NewNet(&NetConfig{
  420. StaticIP: "10.0.0.11",
  421. })
  422. if err = router.AddNet(clientNetwork); err != nil {
  423. return err
  424. }
  425. if err = router.Start(); err != nil {
  426. return err
  427. }
  428. defer router.Stop() // nolint:errcheck
  429. proxy, err := NewProxy(router)
  430. if err != nil {
  431. return err
  432. }
  433. defer proxy.Close() // nolint:errcheck
  434. // For utest, mock the target real server.
  435. proxy.mockRealServerAddr = mockServer.realServerAddr
  436. // The real server address to proxy to.
  437. // Note that for utest, we will proxy to a local address.
  438. serverAddr, err := net.ResolveUDPAddr("udp4", "192.168.1.10:8000")
  439. if err != nil {
  440. return err
  441. }
  442. handClient := func(address, echoData string) error {
  443. // We proxy multiple times, for example, in publisher and player, both call
  444. // the proxy when got answer.
  445. if err := proxy.Proxy(clientNetwork, serverAddr); err != nil { // nolint:govet
  446. return err
  447. }
  448. // Now, all packets from client, will be proxy to real server, vice versa.
  449. client, err := clientNetwork.ListenPacket("udp4", address) // nolint:govet
  450. if err != nil {
  451. return err
  452. }
  453. // When system quit, interrupt client.
  454. selfKill, selfKillCancel := context.WithCancel(context.Background())
  455. go func() {
  456. <-ctx.Done()
  457. selfKillCancel()
  458. _ = client.Close() // nolint:errcheck
  459. }()
  460. for i := 0; i < 10; i++ {
  461. if _, err = client.WriteTo([]byte(echoData), serverAddr); err != nil {
  462. return err
  463. }
  464. buf := make([]byte, 1500)
  465. if n, addr, err := client.ReadFrom(buf); err != nil { // nolint:gocritic,govet
  466. if errors.Is(selfKill.Err(), context.Canceled) {
  467. return nil
  468. }
  469. return err
  470. } else if n != len(echoData) || addr == nil {
  471. return fmt.Errorf("n=%v, addr=%v", n, addr) // nolint:goerr113
  472. } else if string(buf[:n]) != echoData {
  473. return fmt.Errorf("verify data %v", buf[:n]) // nolint:goerr113
  474. }
  475. // Wait for awhile for each UDP packet, to simulate real network.
  476. select {
  477. case <-ctx.Done():
  478. return nil
  479. case <-time.After(30 * time.Millisecond):
  480. }
  481. }
  482. return nil
  483. }
  484. client0, client0Cancel := context.WithCancel(context.Background())
  485. go func() {
  486. defer client0Cancel()
  487. address := "10.0.0.11:5787"
  488. if err = handClient(address, "Hello"); err != nil {
  489. r3 = fmt.Errorf("client %v err %v", address, err) // nolint:goerr113
  490. }
  491. }()
  492. client1, client1Cancel := context.WithCancel(context.Background())
  493. go func() {
  494. defer client1Cancel()
  495. // Slower than client0, 60ms.
  496. // To simulate the real player or publisher, might not start at the same time.
  497. select {
  498. case <-ctx.Done():
  499. return
  500. case <-time.After(150 * time.Millisecond):
  501. }
  502. address := "10.0.0.11:5788"
  503. if err = handClient(address, "World"); err != nil {
  504. r3 = fmt.Errorf("client %v err %v", address, err) // nolint:goerr113
  505. }
  506. }()
  507. select {
  508. case <-ctx.Done():
  509. case <-client0.Done():
  510. case <-client1.Done():
  511. }
  512. return err
  513. }
  514. if err := doVnetProxy(); err != nil {
  515. r1 = err
  516. }
  517. }()
  518. }