tls_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. package scenarios
  2. import (
  3. "crypto/rand"
  4. "crypto/x509"
  5. "runtime"
  6. "sync"
  7. "testing"
  8. "time"
  9. "v2ray.com/core"
  10. "v2ray.com/core/app/proxyman"
  11. "v2ray.com/core/common"
  12. "v2ray.com/core/common/net"
  13. "v2ray.com/core/common/protocol"
  14. "v2ray.com/core/common/protocol/tls/cert"
  15. "v2ray.com/core/common/serial"
  16. "v2ray.com/core/common/uuid"
  17. "v2ray.com/core/proxy/dokodemo"
  18. "v2ray.com/core/proxy/freedom"
  19. "v2ray.com/core/proxy/vmess"
  20. "v2ray.com/core/proxy/vmess/inbound"
  21. "v2ray.com/core/proxy/vmess/outbound"
  22. "v2ray.com/core/testing/servers/tcp"
  23. "v2ray.com/core/testing/servers/udp"
  24. "v2ray.com/core/transport/internet"
  25. "v2ray.com/core/transport/internet/http"
  26. "v2ray.com/core/transport/internet/tls"
  27. "v2ray.com/core/transport/internet/websocket"
  28. . "v2ray.com/ext/assert"
  29. )
  30. func TestSimpleTLSConnection(t *testing.T) {
  31. assert := With(t)
  32. tcpServer := tcp.Server{
  33. MsgProcessor: xor,
  34. }
  35. dest, err := tcpServer.Start()
  36. common.Must(err)
  37. defer tcpServer.Close()
  38. userID := protocol.NewID(uuid.New())
  39. serverPort := tcp.PickPort()
  40. serverConfig := &core.Config{
  41. Inbound: []*core.InboundHandlerConfig{
  42. {
  43. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  44. PortRange: net.SinglePortRange(serverPort),
  45. Listen: net.NewIPOrDomain(net.LocalHostIP),
  46. StreamSettings: &internet.StreamConfig{
  47. SecurityType: serial.GetMessageType(&tls.Config{}),
  48. SecuritySettings: []*serial.TypedMessage{
  49. serial.ToTypedMessage(&tls.Config{
  50. Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
  51. }),
  52. },
  53. },
  54. }),
  55. ProxySettings: serial.ToTypedMessage(&inbound.Config{
  56. User: []*protocol.User{
  57. {
  58. Account: serial.ToTypedMessage(&vmess.Account{
  59. Id: userID.String(),
  60. }),
  61. },
  62. },
  63. }),
  64. },
  65. },
  66. Outbound: []*core.OutboundHandlerConfig{
  67. {
  68. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  69. },
  70. },
  71. }
  72. clientPort := tcp.PickPort()
  73. clientConfig := &core.Config{
  74. Inbound: []*core.InboundHandlerConfig{
  75. {
  76. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  77. PortRange: net.SinglePortRange(clientPort),
  78. Listen: net.NewIPOrDomain(net.LocalHostIP),
  79. }),
  80. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  81. Address: net.NewIPOrDomain(dest.Address),
  82. Port: uint32(dest.Port),
  83. NetworkList: &net.NetworkList{
  84. Network: []net.Network{net.Network_TCP},
  85. },
  86. }),
  87. },
  88. },
  89. Outbound: []*core.OutboundHandlerConfig{
  90. {
  91. ProxySettings: serial.ToTypedMessage(&outbound.Config{
  92. Receiver: []*protocol.ServerEndpoint{
  93. {
  94. Address: net.NewIPOrDomain(net.LocalHostIP),
  95. Port: uint32(serverPort),
  96. User: []*protocol.User{
  97. {
  98. Account: serial.ToTypedMessage(&vmess.Account{
  99. Id: userID.String(),
  100. }),
  101. },
  102. },
  103. },
  104. },
  105. }),
  106. SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
  107. StreamSettings: &internet.StreamConfig{
  108. SecurityType: serial.GetMessageType(&tls.Config{}),
  109. SecuritySettings: []*serial.TypedMessage{
  110. serial.ToTypedMessage(&tls.Config{
  111. AllowInsecure: true,
  112. }),
  113. },
  114. },
  115. }),
  116. },
  117. },
  118. }
  119. servers, err := InitializeServerConfigs(serverConfig, clientConfig)
  120. common.Must(err)
  121. defer CloseAllServers(servers)
  122. {
  123. conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
  124. IP: []byte{127, 0, 0, 1},
  125. Port: int(clientPort),
  126. })
  127. assert(err, IsNil)
  128. payload := "dokodemo request."
  129. nBytes, err := conn.Write([]byte(payload))
  130. assert(err, IsNil)
  131. assert(nBytes, Equals, len(payload))
  132. response := readFrom(conn, time.Second*2, len(payload))
  133. assert(response, Equals, xor([]byte(payload)))
  134. assert(conn.Close(), IsNil)
  135. }
  136. }
  137. func TestAutoIssuingCertificate(t *testing.T) {
  138. if runtime.GOOS == "windows" {
  139. // Not supported on Windows yet.
  140. return
  141. }
  142. if runtime.GOARCH == "arm64" {
  143. return
  144. }
  145. assert := With(t)
  146. tcpServer := tcp.Server{
  147. MsgProcessor: xor,
  148. }
  149. dest, err := tcpServer.Start()
  150. assert(err, IsNil)
  151. defer tcpServer.Close()
  152. caCert, err := cert.Generate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment|x509.KeyUsageCertSign))
  153. assert(err, IsNil)
  154. certPEM, keyPEM := caCert.ToPEM()
  155. userID := protocol.NewID(uuid.New())
  156. serverPort := tcp.PickPort()
  157. serverConfig := &core.Config{
  158. Inbound: []*core.InboundHandlerConfig{
  159. {
  160. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  161. PortRange: net.SinglePortRange(serverPort),
  162. Listen: net.NewIPOrDomain(net.LocalHostIP),
  163. StreamSettings: &internet.StreamConfig{
  164. SecurityType: serial.GetMessageType(&tls.Config{}),
  165. SecuritySettings: []*serial.TypedMessage{
  166. serial.ToTypedMessage(&tls.Config{
  167. Certificate: []*tls.Certificate{{
  168. Certificate: certPEM,
  169. Key: keyPEM,
  170. Usage: tls.Certificate_AUTHORITY_ISSUE,
  171. }},
  172. }),
  173. },
  174. },
  175. }),
  176. ProxySettings: serial.ToTypedMessage(&inbound.Config{
  177. User: []*protocol.User{
  178. {
  179. Account: serial.ToTypedMessage(&vmess.Account{
  180. Id: userID.String(),
  181. }),
  182. },
  183. },
  184. }),
  185. },
  186. },
  187. Outbound: []*core.OutboundHandlerConfig{
  188. {
  189. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  190. },
  191. },
  192. }
  193. clientPort := tcp.PickPort()
  194. clientConfig := &core.Config{
  195. Inbound: []*core.InboundHandlerConfig{
  196. {
  197. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  198. PortRange: net.SinglePortRange(clientPort),
  199. Listen: net.NewIPOrDomain(net.LocalHostIP),
  200. }),
  201. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  202. Address: net.NewIPOrDomain(dest.Address),
  203. Port: uint32(dest.Port),
  204. NetworkList: &net.NetworkList{
  205. Network: []net.Network{net.Network_TCP},
  206. },
  207. }),
  208. },
  209. },
  210. Outbound: []*core.OutboundHandlerConfig{
  211. {
  212. ProxySettings: serial.ToTypedMessage(&outbound.Config{
  213. Receiver: []*protocol.ServerEndpoint{
  214. {
  215. Address: net.NewIPOrDomain(net.LocalHostIP),
  216. Port: uint32(serverPort),
  217. User: []*protocol.User{
  218. {
  219. Account: serial.ToTypedMessage(&vmess.Account{
  220. Id: userID.String(),
  221. }),
  222. },
  223. },
  224. },
  225. },
  226. }),
  227. SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
  228. StreamSettings: &internet.StreamConfig{
  229. SecurityType: serial.GetMessageType(&tls.Config{}),
  230. SecuritySettings: []*serial.TypedMessage{
  231. serial.ToTypedMessage(&tls.Config{
  232. ServerName: "v2ray.com",
  233. Certificate: []*tls.Certificate{{
  234. Certificate: certPEM,
  235. Usage: tls.Certificate_AUTHORITY_VERIFY,
  236. }},
  237. }),
  238. },
  239. },
  240. }),
  241. },
  242. },
  243. }
  244. servers, err := InitializeServerConfigs(serverConfig, clientConfig)
  245. assert(err, IsNil)
  246. for i := 0; i < 10; i++ {
  247. conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
  248. IP: []byte{127, 0, 0, 1},
  249. Port: int(clientPort),
  250. })
  251. assert(err, IsNil)
  252. payload := "dokodemo request."
  253. nBytes, err := conn.Write([]byte(payload))
  254. assert(err, IsNil)
  255. assert(nBytes, Equals, len(payload))
  256. response := readFrom(conn, time.Second*2, len(payload))
  257. assert(response, Equals, xor([]byte(payload)))
  258. assert(conn.Close(), IsNil)
  259. }
  260. CloseAllServers(servers)
  261. }
  262. func TestTLSOverKCP(t *testing.T) {
  263. assert := With(t)
  264. tcpServer := tcp.Server{
  265. MsgProcessor: xor,
  266. }
  267. dest, err := tcpServer.Start()
  268. assert(err, IsNil)
  269. defer tcpServer.Close()
  270. userID := protocol.NewID(uuid.New())
  271. serverPort := udp.PickPort()
  272. serverConfig := &core.Config{
  273. Inbound: []*core.InboundHandlerConfig{
  274. {
  275. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  276. PortRange: net.SinglePortRange(serverPort),
  277. Listen: net.NewIPOrDomain(net.LocalHostIP),
  278. StreamSettings: &internet.StreamConfig{
  279. Protocol: internet.TransportProtocol_MKCP,
  280. SecurityType: serial.GetMessageType(&tls.Config{}),
  281. SecuritySettings: []*serial.TypedMessage{
  282. serial.ToTypedMessage(&tls.Config{
  283. Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
  284. }),
  285. },
  286. },
  287. }),
  288. ProxySettings: serial.ToTypedMessage(&inbound.Config{
  289. User: []*protocol.User{
  290. {
  291. Account: serial.ToTypedMessage(&vmess.Account{
  292. Id: userID.String(),
  293. }),
  294. },
  295. },
  296. }),
  297. },
  298. },
  299. Outbound: []*core.OutboundHandlerConfig{
  300. {
  301. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  302. },
  303. },
  304. }
  305. clientPort := tcp.PickPort()
  306. clientConfig := &core.Config{
  307. Inbound: []*core.InboundHandlerConfig{
  308. {
  309. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  310. PortRange: net.SinglePortRange(clientPort),
  311. Listen: net.NewIPOrDomain(net.LocalHostIP),
  312. }),
  313. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  314. Address: net.NewIPOrDomain(dest.Address),
  315. Port: uint32(dest.Port),
  316. NetworkList: &net.NetworkList{
  317. Network: []net.Network{net.Network_TCP},
  318. },
  319. }),
  320. },
  321. },
  322. Outbound: []*core.OutboundHandlerConfig{
  323. {
  324. ProxySettings: serial.ToTypedMessage(&outbound.Config{
  325. Receiver: []*protocol.ServerEndpoint{
  326. {
  327. Address: net.NewIPOrDomain(net.LocalHostIP),
  328. Port: uint32(serverPort),
  329. User: []*protocol.User{
  330. {
  331. Account: serial.ToTypedMessage(&vmess.Account{
  332. Id: userID.String(),
  333. }),
  334. },
  335. },
  336. },
  337. },
  338. }),
  339. SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
  340. StreamSettings: &internet.StreamConfig{
  341. Protocol: internet.TransportProtocol_MKCP,
  342. SecurityType: serial.GetMessageType(&tls.Config{}),
  343. SecuritySettings: []*serial.TypedMessage{
  344. serial.ToTypedMessage(&tls.Config{
  345. AllowInsecure: true,
  346. }),
  347. },
  348. },
  349. }),
  350. },
  351. },
  352. }
  353. servers, err := InitializeServerConfigs(serverConfig, clientConfig)
  354. assert(err, IsNil)
  355. conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
  356. IP: []byte{127, 0, 0, 1},
  357. Port: int(clientPort),
  358. })
  359. assert(err, IsNil)
  360. payload := "dokodemo request."
  361. nBytes, err := conn.Write([]byte(payload))
  362. assert(err, IsNil)
  363. assert(nBytes, Equals, len(payload))
  364. response := readFrom(conn, time.Second*2, len(payload))
  365. assert(response, Equals, xor([]byte(payload)))
  366. assert(conn.Close(), IsNil)
  367. CloseAllServers(servers)
  368. }
  369. func TestTLSOverWebSocket(t *testing.T) {
  370. assert := With(t)
  371. tcpServer := tcp.Server{
  372. MsgProcessor: xor,
  373. }
  374. dest, err := tcpServer.Start()
  375. assert(err, IsNil)
  376. defer tcpServer.Close()
  377. userID := protocol.NewID(uuid.New())
  378. serverPort := tcp.PickPort()
  379. serverConfig := &core.Config{
  380. Inbound: []*core.InboundHandlerConfig{
  381. {
  382. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  383. PortRange: net.SinglePortRange(serverPort),
  384. Listen: net.NewIPOrDomain(net.LocalHostIP),
  385. StreamSettings: &internet.StreamConfig{
  386. Protocol: internet.TransportProtocol_WebSocket,
  387. SecurityType: serial.GetMessageType(&tls.Config{}),
  388. SecuritySettings: []*serial.TypedMessage{
  389. serial.ToTypedMessage(&tls.Config{
  390. Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
  391. }),
  392. },
  393. },
  394. }),
  395. ProxySettings: serial.ToTypedMessage(&inbound.Config{
  396. User: []*protocol.User{
  397. {
  398. Account: serial.ToTypedMessage(&vmess.Account{
  399. Id: userID.String(),
  400. }),
  401. },
  402. },
  403. }),
  404. },
  405. },
  406. Outbound: []*core.OutboundHandlerConfig{
  407. {
  408. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  409. },
  410. },
  411. }
  412. clientPort := tcp.PickPort()
  413. clientConfig := &core.Config{
  414. Inbound: []*core.InboundHandlerConfig{
  415. {
  416. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  417. PortRange: net.SinglePortRange(clientPort),
  418. Listen: net.NewIPOrDomain(net.LocalHostIP),
  419. }),
  420. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  421. Address: net.NewIPOrDomain(dest.Address),
  422. Port: uint32(dest.Port),
  423. NetworkList: &net.NetworkList{
  424. Network: []net.Network{net.Network_TCP},
  425. },
  426. }),
  427. },
  428. },
  429. Outbound: []*core.OutboundHandlerConfig{
  430. {
  431. ProxySettings: serial.ToTypedMessage(&outbound.Config{
  432. Receiver: []*protocol.ServerEndpoint{
  433. {
  434. Address: net.NewIPOrDomain(net.LocalHostIP),
  435. Port: uint32(serverPort),
  436. User: []*protocol.User{
  437. {
  438. Account: serial.ToTypedMessage(&vmess.Account{
  439. Id: userID.String(),
  440. }),
  441. },
  442. },
  443. },
  444. },
  445. }),
  446. SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
  447. StreamSettings: &internet.StreamConfig{
  448. Protocol: internet.TransportProtocol_WebSocket,
  449. TransportSettings: []*internet.TransportConfig{
  450. {
  451. Protocol: internet.TransportProtocol_WebSocket,
  452. Settings: serial.ToTypedMessage(&websocket.Config{}),
  453. },
  454. },
  455. SecurityType: serial.GetMessageType(&tls.Config{}),
  456. SecuritySettings: []*serial.TypedMessage{
  457. serial.ToTypedMessage(&tls.Config{
  458. AllowInsecure: true,
  459. }),
  460. },
  461. },
  462. }),
  463. },
  464. },
  465. }
  466. servers, err := InitializeServerConfigs(serverConfig, clientConfig)
  467. common.Must(err)
  468. defer CloseAllServers(servers)
  469. var wg sync.WaitGroup
  470. for i := 0; i < 10; i++ {
  471. wg.Add(1)
  472. go func() {
  473. defer wg.Done()
  474. conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
  475. IP: []byte{127, 0, 0, 1},
  476. Port: int(clientPort),
  477. })
  478. common.Must(err)
  479. payload := make([]byte, 10240*1024)
  480. rand.Read(payload)
  481. nBytes, err := conn.Write([]byte(payload))
  482. assert(err, IsNil)
  483. assert(nBytes, Equals, len(payload))
  484. response := readFrom(conn, time.Second*20, len(payload))
  485. assert(response, Equals, xor([]byte(payload)))
  486. assert(conn.Close(), IsNil)
  487. }()
  488. }
  489. wg.Wait()
  490. }
  491. func TestHTTP2(t *testing.T) {
  492. assert := With(t)
  493. tcpServer := tcp.Server{
  494. MsgProcessor: xor,
  495. }
  496. dest, err := tcpServer.Start()
  497. assert(err, IsNil)
  498. defer tcpServer.Close()
  499. userID := protocol.NewID(uuid.New())
  500. serverPort := tcp.PickPort()
  501. serverConfig := &core.Config{
  502. Inbound: []*core.InboundHandlerConfig{
  503. {
  504. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  505. PortRange: net.SinglePortRange(serverPort),
  506. Listen: net.NewIPOrDomain(net.LocalHostIP),
  507. StreamSettings: &internet.StreamConfig{
  508. Protocol: internet.TransportProtocol_HTTP,
  509. TransportSettings: []*internet.TransportConfig{
  510. {
  511. Protocol: internet.TransportProtocol_HTTP,
  512. Settings: serial.ToTypedMessage(&http.Config{
  513. Host: []string{"v2ray.com"},
  514. Path: "/testpath",
  515. }),
  516. },
  517. },
  518. SecurityType: serial.GetMessageType(&tls.Config{}),
  519. SecuritySettings: []*serial.TypedMessage{
  520. serial.ToTypedMessage(&tls.Config{
  521. Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
  522. }),
  523. },
  524. },
  525. }),
  526. ProxySettings: serial.ToTypedMessage(&inbound.Config{
  527. User: []*protocol.User{
  528. {
  529. Account: serial.ToTypedMessage(&vmess.Account{
  530. Id: userID.String(),
  531. }),
  532. },
  533. },
  534. }),
  535. },
  536. },
  537. Outbound: []*core.OutboundHandlerConfig{
  538. {
  539. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  540. },
  541. },
  542. }
  543. clientPort := tcp.PickPort()
  544. clientConfig := &core.Config{
  545. Inbound: []*core.InboundHandlerConfig{
  546. {
  547. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  548. PortRange: net.SinglePortRange(clientPort),
  549. Listen: net.NewIPOrDomain(net.LocalHostIP),
  550. }),
  551. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  552. Address: net.NewIPOrDomain(dest.Address),
  553. Port: uint32(dest.Port),
  554. NetworkList: &net.NetworkList{
  555. Network: []net.Network{net.Network_TCP},
  556. },
  557. }),
  558. },
  559. },
  560. Outbound: []*core.OutboundHandlerConfig{
  561. {
  562. ProxySettings: serial.ToTypedMessage(&outbound.Config{
  563. Receiver: []*protocol.ServerEndpoint{
  564. {
  565. Address: net.NewIPOrDomain(net.LocalHostIP),
  566. Port: uint32(serverPort),
  567. User: []*protocol.User{
  568. {
  569. Account: serial.ToTypedMessage(&vmess.Account{
  570. Id: userID.String(),
  571. }),
  572. },
  573. },
  574. },
  575. },
  576. }),
  577. SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
  578. StreamSettings: &internet.StreamConfig{
  579. Protocol: internet.TransportProtocol_HTTP,
  580. TransportSettings: []*internet.TransportConfig{
  581. {
  582. Protocol: internet.TransportProtocol_HTTP,
  583. Settings: serial.ToTypedMessage(&http.Config{
  584. Host: []string{"v2ray.com"},
  585. Path: "/testpath",
  586. }),
  587. },
  588. },
  589. SecurityType: serial.GetMessageType(&tls.Config{}),
  590. SecuritySettings: []*serial.TypedMessage{
  591. serial.ToTypedMessage(&tls.Config{
  592. AllowInsecure: true,
  593. }),
  594. },
  595. },
  596. }),
  597. },
  598. },
  599. }
  600. servers, err := InitializeServerConfigs(serverConfig, clientConfig)
  601. assert(err, IsNil)
  602. var wg sync.WaitGroup
  603. for i := 0; i < 10; i++ {
  604. wg.Add(1)
  605. go func() {
  606. defer wg.Done()
  607. conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
  608. IP: []byte{127, 0, 0, 1},
  609. Port: int(clientPort),
  610. })
  611. assert(err, IsNil)
  612. payload := make([]byte, 10240*1024)
  613. rand.Read(payload)
  614. nBytes, err := conn.Write([]byte(payload))
  615. assert(err, IsNil)
  616. assert(nBytes, Equals, len(payload))
  617. response := readFrom(conn, time.Second*20, len(payload))
  618. assert(response, Equals, xor([]byte(payload)))
  619. assert(conn.Close(), IsNil)
  620. }()
  621. }
  622. wg.Wait()
  623. CloseAllServers(servers)
  624. }