sess_test.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. package kcp
  2. import (
  3. "crypto/sha1"
  4. "fmt"
  5. "io"
  6. "log"
  7. "net"
  8. "net/http"
  9. _ "net/http/pprof"
  10. "sync"
  11. "testing"
  12. "time"
  13. "golang.org/x/crypto/pbkdf2"
  14. )
  15. const portEcho = "127.0.0.1:9999"
  16. const portSink = "127.0.0.1:19999"
  17. const portTinyBufferEcho = "127.0.0.1:29999"
  18. const portListerner = "127.0.0.1:9998"
  19. var key = []byte("testkey")
  20. var pass = pbkdf2.Key(key, []byte(portSink), 4096, 32, sha1.New)
  21. func init() {
  22. go func() {
  23. log.Println(http.ListenAndServe("localhost:6060", nil))
  24. }()
  25. go echoServer()
  26. go sinkServer()
  27. go tinyBufferEchoServer()
  28. println("beginning tests, encryption:salsa20, fec:10/3")
  29. }
  30. func dialEcho() (*UDPSession, error) {
  31. //block, _ := NewNoneBlockCrypt(pass)
  32. //block, _ := NewSimpleXORBlockCrypt(pass)
  33. //block, _ := NewTEABlockCrypt(pass[:16])
  34. //block, _ := NewAESBlockCrypt(pass)
  35. block, _ := NewSalsa20BlockCrypt(pass)
  36. sess, err := DialWithOptions(portEcho, block, 10, 3)
  37. if err != nil {
  38. panic(err)
  39. }
  40. sess.SetStreamMode(true)
  41. sess.SetStreamMode(false)
  42. sess.SetStreamMode(true)
  43. sess.SetWindowSize(1024, 1024)
  44. sess.SetReadBuffer(16 * 1024 * 1024)
  45. sess.SetWriteBuffer(16 * 1024 * 1024)
  46. sess.SetStreamMode(true)
  47. sess.SetNoDelay(1, 10, 2, 1)
  48. sess.SetMtu(1400)
  49. sess.SetMtu(1600)
  50. sess.SetMtu(1400)
  51. sess.SetACKNoDelay(true)
  52. sess.SetACKNoDelay(false)
  53. sess.SetDeadline(time.Now().Add(time.Minute))
  54. return sess, err
  55. }
  56. func dialSink() (*UDPSession, error) {
  57. sess, err := DialWithOptions(portSink, nil, 0, 0)
  58. if err != nil {
  59. panic(err)
  60. }
  61. sess.SetStreamMode(true)
  62. sess.SetWindowSize(1024, 1024)
  63. sess.SetReadBuffer(16 * 1024 * 1024)
  64. sess.SetWriteBuffer(16 * 1024 * 1024)
  65. sess.SetStreamMode(true)
  66. sess.SetNoDelay(1, 10, 2, 1)
  67. sess.SetMtu(1400)
  68. sess.SetACKNoDelay(false)
  69. sess.SetDeadline(time.Now().Add(time.Minute))
  70. return sess, err
  71. }
  72. func dialTinyBufferEcho() (*UDPSession, error) {
  73. //block, _ := NewNoneBlockCrypt(pass)
  74. //block, _ := NewSimpleXORBlockCrypt(pass)
  75. //block, _ := NewTEABlockCrypt(pass[:16])
  76. //block, _ := NewAESBlockCrypt(pass)
  77. block, _ := NewSalsa20BlockCrypt(pass)
  78. sess, err := DialWithOptions(portTinyBufferEcho, block, 10, 3)
  79. if err != nil {
  80. panic(err)
  81. }
  82. return sess, err
  83. }
  84. //////////////////////////
  85. func listenEcho() (net.Listener, error) {
  86. //block, _ := NewNoneBlockCrypt(pass)
  87. //block, _ := NewSimpleXORBlockCrypt(pass)
  88. //block, _ := NewTEABlockCrypt(pass[:16])
  89. //block, _ := NewAESBlockCrypt(pass)
  90. block, _ := NewSalsa20BlockCrypt(pass)
  91. return ListenWithOptions(portEcho, block, 10, 3)
  92. }
  93. func listenTinyBufferEcho() (net.Listener, error) {
  94. //block, _ := NewNoneBlockCrypt(pass)
  95. //block, _ := NewSimpleXORBlockCrypt(pass)
  96. //block, _ := NewTEABlockCrypt(pass[:16])
  97. //block, _ := NewAESBlockCrypt(pass)
  98. block, _ := NewSalsa20BlockCrypt(pass)
  99. return ListenWithOptions(portTinyBufferEcho, block, 10, 3)
  100. }
  101. func listenSink() (net.Listener, error) {
  102. return ListenWithOptions(portSink, nil, 0, 0)
  103. }
  104. func echoServer() {
  105. l, err := listenEcho()
  106. if err != nil {
  107. panic(err)
  108. }
  109. go func() {
  110. kcplistener := l.(*Listener)
  111. kcplistener.SetReadBuffer(4 * 1024 * 1024)
  112. kcplistener.SetWriteBuffer(4 * 1024 * 1024)
  113. kcplistener.SetDSCP(46)
  114. for {
  115. s, err := l.Accept()
  116. if err != nil {
  117. return
  118. }
  119. // coverage test
  120. s.(*UDPSession).SetReadBuffer(4 * 1024 * 1024)
  121. s.(*UDPSession).SetWriteBuffer(4 * 1024 * 1024)
  122. go handleEcho(s.(*UDPSession))
  123. }
  124. }()
  125. }
  126. func sinkServer() {
  127. l, err := listenSink()
  128. if err != nil {
  129. panic(err)
  130. }
  131. go func() {
  132. kcplistener := l.(*Listener)
  133. kcplistener.SetReadBuffer(4 * 1024 * 1024)
  134. kcplistener.SetWriteBuffer(4 * 1024 * 1024)
  135. kcplistener.SetDSCP(46)
  136. for {
  137. s, err := l.Accept()
  138. if err != nil {
  139. return
  140. }
  141. go handleSink(s.(*UDPSession))
  142. }
  143. }()
  144. }
  145. func tinyBufferEchoServer() {
  146. l, err := listenTinyBufferEcho()
  147. if err != nil {
  148. panic(err)
  149. }
  150. go func() {
  151. for {
  152. s, err := l.Accept()
  153. if err != nil {
  154. return
  155. }
  156. go handleTinyBufferEcho(s.(*UDPSession))
  157. }
  158. }()
  159. }
  160. ///////////////////////////
  161. func handleEcho(conn *UDPSession) {
  162. conn.SetStreamMode(true)
  163. conn.SetWindowSize(4096, 4096)
  164. conn.SetNoDelay(1, 10, 2, 1)
  165. conn.SetDSCP(46)
  166. conn.SetMtu(1400)
  167. conn.SetACKNoDelay(false)
  168. conn.SetReadDeadline(time.Now().Add(time.Hour))
  169. conn.SetWriteDeadline(time.Now().Add(time.Hour))
  170. buf := make([]byte, 65536)
  171. for {
  172. n, err := conn.Read(buf)
  173. if err != nil {
  174. panic(err)
  175. }
  176. conn.Write(buf[:n])
  177. }
  178. }
  179. func handleSink(conn *UDPSession) {
  180. conn.SetStreamMode(true)
  181. conn.SetWindowSize(4096, 4096)
  182. conn.SetNoDelay(1, 10, 2, 1)
  183. conn.SetDSCP(46)
  184. conn.SetMtu(1400)
  185. conn.SetACKNoDelay(false)
  186. conn.SetReadDeadline(time.Now().Add(time.Hour))
  187. conn.SetWriteDeadline(time.Now().Add(time.Hour))
  188. buf := make([]byte, 65536)
  189. for {
  190. _, err := conn.Read(buf)
  191. if err != nil {
  192. panic(err)
  193. }
  194. }
  195. }
  196. func handleTinyBufferEcho(conn *UDPSession) {
  197. conn.SetStreamMode(true)
  198. buf := make([]byte, 2)
  199. for {
  200. n, err := conn.Read(buf)
  201. if err != nil {
  202. panic(err)
  203. }
  204. conn.Write(buf[:n])
  205. }
  206. }
  207. ///////////////////////////
  208. func TestTimeout(t *testing.T) {
  209. cli, err := dialEcho()
  210. if err != nil {
  211. panic(err)
  212. }
  213. buf := make([]byte, 10)
  214. //timeout
  215. cli.SetDeadline(time.Now().Add(time.Second))
  216. <-time.After(2 * time.Second)
  217. n, err := cli.Read(buf)
  218. if n != 0 || err == nil {
  219. t.Fail()
  220. }
  221. cli.Close()
  222. }
  223. func TestSendRecv(t *testing.T) {
  224. cli, err := dialEcho()
  225. if err != nil {
  226. panic(err)
  227. }
  228. cli.SetWriteDelay(true)
  229. cli.SetDUP(1)
  230. const N = 100
  231. buf := make([]byte, 10)
  232. for i := 0; i < N; i++ {
  233. msg := fmt.Sprintf("hello%v", i)
  234. cli.Write([]byte(msg))
  235. if n, err := cli.Read(buf); err == nil {
  236. if string(buf[:n]) != msg {
  237. t.Fail()
  238. }
  239. } else {
  240. panic(err)
  241. }
  242. }
  243. cli.Close()
  244. }
  245. func TestTinyBufferReceiver(t *testing.T) {
  246. cli, err := dialTinyBufferEcho()
  247. if err != nil {
  248. panic(err)
  249. }
  250. const N = 100
  251. snd := byte(0)
  252. fillBuffer := func(buf []byte) {
  253. for i := 0; i < len(buf); i++ {
  254. buf[i] = snd
  255. snd++
  256. }
  257. }
  258. rcv := byte(0)
  259. check := func(buf []byte) bool {
  260. for i := 0; i < len(buf); i++ {
  261. if buf[i] != rcv {
  262. return false
  263. }
  264. rcv++
  265. }
  266. return true
  267. }
  268. sndbuf := make([]byte, 7)
  269. rcvbuf := make([]byte, 7)
  270. for i := 0; i < N; i++ {
  271. fillBuffer(sndbuf)
  272. cli.Write(sndbuf)
  273. if n, err := io.ReadFull(cli, rcvbuf); err == nil {
  274. if !check(rcvbuf[:n]) {
  275. t.Fail()
  276. }
  277. } else {
  278. panic(err)
  279. }
  280. }
  281. cli.Close()
  282. }
  283. func TestClose(t *testing.T) {
  284. cli, err := dialEcho()
  285. if err != nil {
  286. panic(err)
  287. }
  288. buf := make([]byte, 10)
  289. cli.Close()
  290. if cli.Close() == nil {
  291. t.Fail()
  292. }
  293. n, err := cli.Write(buf)
  294. if n != 0 || err == nil {
  295. t.Fail()
  296. }
  297. n, err = cli.Read(buf)
  298. if n != 0 || err == nil {
  299. t.Fail()
  300. }
  301. cli.Close()
  302. }
  303. func TestParallel1024CLIENT_64BMSG_64CNT(t *testing.T) {
  304. var wg sync.WaitGroup
  305. wg.Add(1024)
  306. for i := 0; i < 1024; i++ {
  307. go parallel_client(&wg)
  308. }
  309. wg.Wait()
  310. }
  311. func parallel_client(wg *sync.WaitGroup) (err error) {
  312. cli, err := dialEcho()
  313. if err != nil {
  314. panic(err)
  315. }
  316. err = echo_tester(cli, 64, 64)
  317. wg.Done()
  318. return
  319. }
  320. func BenchmarkEchoSpeed4K(b *testing.B) {
  321. speedclient(b, 4096)
  322. }
  323. func BenchmarkEchoSpeed64K(b *testing.B) {
  324. speedclient(b, 65536)
  325. }
  326. func BenchmarkEchoSpeed512K(b *testing.B) {
  327. speedclient(b, 524288)
  328. }
  329. func BenchmarkEchoSpeed1M(b *testing.B) {
  330. speedclient(b, 1048576)
  331. }
  332. func speedclient(b *testing.B, nbytes int) {
  333. b.ReportAllocs()
  334. cli, err := dialEcho()
  335. if err != nil {
  336. panic(err)
  337. }
  338. if err := echo_tester(cli, nbytes, b.N); err != nil {
  339. b.Fail()
  340. }
  341. b.SetBytes(int64(nbytes))
  342. }
  343. func BenchmarkSinkSpeed4K(b *testing.B) {
  344. sinkclient(b, 4096)
  345. }
  346. func BenchmarkSinkSpeed64K(b *testing.B) {
  347. sinkclient(b, 65536)
  348. }
  349. func BenchmarkSinkSpeed256K(b *testing.B) {
  350. sinkclient(b, 524288)
  351. }
  352. func BenchmarkSinkSpeed1M(b *testing.B) {
  353. sinkclient(b, 1048576)
  354. }
  355. func sinkclient(b *testing.B, nbytes int) {
  356. b.ReportAllocs()
  357. cli, err := dialSink()
  358. if err != nil {
  359. panic(err)
  360. }
  361. sink_tester(cli, nbytes, b.N)
  362. b.SetBytes(int64(nbytes))
  363. }
  364. func echo_tester(cli net.Conn, msglen, msgcount int) error {
  365. buf := make([]byte, msglen)
  366. for i := 0; i < msgcount; i++ {
  367. // send packet
  368. if _, err := cli.Write(buf); err != nil {
  369. return err
  370. }
  371. // receive packet
  372. nrecv := 0
  373. for {
  374. n, err := cli.Read(buf)
  375. if err != nil {
  376. return err
  377. } else {
  378. nrecv += n
  379. if nrecv == msglen {
  380. break
  381. }
  382. }
  383. }
  384. }
  385. return nil
  386. }
  387. func sink_tester(cli *UDPSession, msglen, msgcount int) error {
  388. // sender
  389. buf := make([]byte, msglen)
  390. for i := 0; i < msgcount; i++ {
  391. if _, err := cli.Write(buf); err != nil {
  392. return err
  393. }
  394. }
  395. return nil
  396. }
  397. func TestSNMP(t *testing.T) {
  398. t.Log(DefaultSnmp.Copy())
  399. t.Log(DefaultSnmp.Header())
  400. t.Log(DefaultSnmp.ToSlice())
  401. DefaultSnmp.Reset()
  402. t.Log(DefaultSnmp.ToSlice())
  403. }
  404. func TestListenerClose(t *testing.T) {
  405. l, err := ListenWithOptions(portListerner, nil, 10, 3)
  406. if err != nil {
  407. t.Fail()
  408. }
  409. l.SetReadDeadline(time.Now().Add(time.Second))
  410. l.SetWriteDeadline(time.Now().Add(time.Second))
  411. l.SetDeadline(time.Now().Add(time.Second))
  412. time.Sleep(2 * time.Second)
  413. if _, err := l.Accept(); err == nil {
  414. t.Fail()
  415. }
  416. l.Close()
  417. fakeaddr, _ := net.ResolveUDPAddr("udp6", "127.0.0.1:1111")
  418. if l.closeSession(fakeaddr) {
  419. t.Fail()
  420. }
  421. }