tls_test.go 17 KB

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