123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- package kcp
- import (
- "crypto/sha1"
- "fmt"
- "io"
- "log"
- "net"
- "net/http"
- _ "net/http/pprof"
- "sync"
- "testing"
- "time"
- "golang.org/x/crypto/pbkdf2"
- )
- const portEcho = "127.0.0.1:9999"
- const portSink = "127.0.0.1:19999"
- const portTinyBufferEcho = "127.0.0.1:29999"
- const portListerner = "127.0.0.1:9998"
- const salt = "kcptest"
- var key = []byte("testkey")
- var fec = 4
- var pass = pbkdf2.Key(key, []byte(portSink), 4096, 32, sha1.New)
- func init() {
- go func() {
- log.Println(http.ListenAndServe("localhost:6060", nil))
- }()
- go echoServer()
- go sinkServer()
- go tinyBufferEchoServer()
- println("beginning tests, encryption:salsa20, fec:10/3")
- }
- func dialEcho() (*UDPSession, error) {
- //block, _ := NewNoneBlockCrypt(pass)
- //block, _ := NewSimpleXORBlockCrypt(pass)
- //block, _ := NewTEABlockCrypt(pass[:16])
- //block, _ := NewAESBlockCrypt(pass)
- block, _ := NewSalsa20BlockCrypt(pass)
- sess, err := DialWithOptions(portEcho, block, 10, 3)
- if err != nil {
- panic(err)
- }
- sess.SetStreamMode(true)
- sess.SetStreamMode(false)
- sess.SetStreamMode(true)
- sess.SetWindowSize(4096, 4096)
- sess.SetReadBuffer(4 * 1024 * 1024)
- sess.SetWriteBuffer(4 * 1024 * 1024)
- sess.SetStreamMode(true)
- sess.SetNoDelay(1, 10, 2, 1)
- sess.SetMtu(1400)
- sess.SetMtu(1600)
- sess.SetMtu(1400)
- sess.SetACKNoDelay(true)
- sess.SetDeadline(time.Now().Add(time.Minute))
- return sess, err
- }
- func dialSink() (*UDPSession, error) {
- sess, err := DialWithOptions(portSink, nil, 0, 0)
- if err != nil {
- panic(err)
- }
- sess.SetStreamMode(true)
- sess.SetWindowSize(4096, 4096)
- sess.SetReadBuffer(4 * 1024 * 1024)
- sess.SetWriteBuffer(4 * 1024 * 1024)
- sess.SetStreamMode(true)
- sess.SetNoDelay(1, 10, 2, 1)
- sess.SetMtu(1400)
- sess.SetACKNoDelay(true)
- sess.SetDeadline(time.Now().Add(time.Minute))
- return sess, err
- }
- func dialTinyBufferEcho() (*UDPSession, error) {
- //block, _ := NewNoneBlockCrypt(pass)
- //block, _ := NewSimpleXORBlockCrypt(pass)
- //block, _ := NewTEABlockCrypt(pass[:16])
- //block, _ := NewAESBlockCrypt(pass)
- block, _ := NewSalsa20BlockCrypt(pass)
- sess, err := DialWithOptions(portTinyBufferEcho, block, 10, 3)
- if err != nil {
- panic(err)
- }
- return sess, err
- }
- //////////////////////////
- func listenEcho() (net.Listener, error) {
- //block, _ := NewNoneBlockCrypt(pass)
- //block, _ := NewSimpleXORBlockCrypt(pass)
- //block, _ := NewTEABlockCrypt(pass[:16])
- //block, _ := NewAESBlockCrypt(pass)
- block, _ := NewSalsa20BlockCrypt(pass)
- return ListenWithOptions(portEcho, block, 10, 3)
- }
- func listenTinyBufferEcho() (net.Listener, error) {
- //block, _ := NewNoneBlockCrypt(pass)
- //block, _ := NewSimpleXORBlockCrypt(pass)
- //block, _ := NewTEABlockCrypt(pass[:16])
- //block, _ := NewAESBlockCrypt(pass)
- block, _ := NewSalsa20BlockCrypt(pass)
- return ListenWithOptions(portTinyBufferEcho, block, 10, 3)
- }
- func listenSink() (net.Listener, error) {
- return ListenWithOptions(portSink, nil, 0, 0)
- }
- func echoServer() {
- l, err := listenEcho()
- if err != nil {
- panic(err)
- }
- go func() {
- kcplistener := l.(*Listener)
- kcplistener.SetReadBuffer(4 * 1024 * 1024)
- kcplistener.SetWriteBuffer(4 * 1024 * 1024)
- kcplistener.SetDSCP(46)
- for {
- s, err := l.Accept()
- if err != nil {
- return
- }
- // coverage test
- s.(*UDPSession).SetReadBuffer(4 * 1024 * 1024)
- s.(*UDPSession).SetWriteBuffer(4 * 1024 * 1024)
- go handleEcho(s.(*UDPSession))
- }
- }()
- }
- func sinkServer() {
- l, err := listenSink()
- if err != nil {
- panic(err)
- }
- go func() {
- kcplistener := l.(*Listener)
- kcplistener.SetReadBuffer(4 * 1024 * 1024)
- kcplistener.SetWriteBuffer(4 * 1024 * 1024)
- kcplistener.SetDSCP(46)
- for {
- s, err := l.Accept()
- if err != nil {
- return
- }
- go handleSink(s.(*UDPSession))
- }
- }()
- }
- func tinyBufferEchoServer() {
- l, err := listenTinyBufferEcho()
- if err != nil {
- panic(err)
- }
- go func() {
- for {
- s, err := l.Accept()
- if err != nil {
- return
- }
- go handleTinyBufferEcho(s.(*UDPSession))
- }
- }()
- }
- ///////////////////////////
- func handleEcho(conn *UDPSession) {
- conn.SetStreamMode(true)
- conn.SetWindowSize(4096, 4096)
- conn.SetNoDelay(1, 10, 2, 1)
- conn.SetDSCP(46)
- conn.SetMtu(1400)
- conn.SetACKNoDelay(false)
- conn.SetReadDeadline(time.Now().Add(time.Hour))
- conn.SetWriteDeadline(time.Now().Add(time.Hour))
- buf := make([]byte, 65536)
- for {
- n, err := conn.Read(buf)
- if err != nil {
- panic(err)
- }
- conn.Write(buf[:n])
- }
- }
- func handleSink(conn *UDPSession) {
- conn.SetStreamMode(true)
- conn.SetWindowSize(4096, 4096)
- conn.SetNoDelay(1, 10, 2, 1)
- conn.SetDSCP(46)
- conn.SetMtu(1400)
- conn.SetACKNoDelay(false)
- conn.SetReadDeadline(time.Now().Add(time.Hour))
- conn.SetWriteDeadline(time.Now().Add(time.Hour))
- buf := make([]byte, 65536)
- for {
- _, err := conn.Read(buf)
- if err != nil {
- panic(err)
- }
- }
- }
- func handleTinyBufferEcho(conn *UDPSession) {
- conn.SetStreamMode(true)
- buf := make([]byte, 2)
- for {
- n, err := conn.Read(buf)
- if err != nil {
- panic(err)
- }
- conn.Write(buf[:n])
- }
- }
- ///////////////////////////
- func TestTimeout(t *testing.T) {
- cli, err := dialEcho()
- if err != nil {
- panic(err)
- }
- buf := make([]byte, 10)
- //timeout
- cli.SetDeadline(time.Now().Add(time.Second))
- <-time.After(2 * time.Second)
- n, err := cli.Read(buf)
- if n != 0 || err == nil {
- t.Fail()
- }
- cli.Close()
- }
- func TestSendRecv(t *testing.T) {
- cli, err := dialEcho()
- if err != nil {
- panic(err)
- }
- cli.SetWriteDelay(true)
- cli.SetDUP(1)
- const N = 100
- buf := make([]byte, 10)
- for i := 0; i < N; i++ {
- msg := fmt.Sprintf("hello%v", i)
- cli.Write([]byte(msg))
- if n, err := cli.Read(buf); err == nil {
- if string(buf[:n]) != msg {
- t.Fail()
- }
- } else {
- panic(err)
- }
- }
- cli.Close()
- }
- func TestTinyBufferReceiver(t *testing.T) {
- cli, err := dialTinyBufferEcho()
- if err != nil {
- panic(err)
- }
- const N = 100
- snd := byte(0)
- fillBuffer := func(buf []byte) {
- for i := 0; i < len(buf); i++ {
- buf[i] = snd
- snd++
- }
- }
- rcv := byte(0)
- check := func(buf []byte) bool {
- for i := 0; i < len(buf); i++ {
- if buf[i] != rcv {
- return false
- }
- rcv++
- }
- return true
- }
- sndbuf := make([]byte, 7)
- rcvbuf := make([]byte, 7)
- for i := 0; i < N; i++ {
- fillBuffer(sndbuf)
- cli.Write(sndbuf)
- if n, err := io.ReadFull(cli, rcvbuf); err == nil {
- if !check(rcvbuf[:n]) {
- t.Fail()
- }
- } else {
- panic(err)
- }
- }
- cli.Close()
- }
- func TestClose(t *testing.T) {
- cli, err := dialEcho()
- if err != nil {
- panic(err)
- }
- buf := make([]byte, 10)
- cli.Close()
- if cli.Close() == nil {
- t.Fail()
- }
- n, err := cli.Write(buf)
- if n != 0 || err == nil {
- t.Fail()
- }
- n, err = cli.Read(buf)
- if n != 0 || err == nil {
- t.Fail()
- }
- cli.Close()
- }
- func TestParallel1024CLIENT_64BMSG_64CNT(t *testing.T) {
- var wg sync.WaitGroup
- wg.Add(1024)
- for i := 0; i < 1024; i++ {
- go parallel_client(&wg)
- }
- wg.Wait()
- }
- func parallel_client(wg *sync.WaitGroup) (err error) {
- cli, err := dialEcho()
- if err != nil {
- panic(err)
- }
- err = echo_tester(cli, 64, 64)
- wg.Done()
- return
- }
- func BenchmarkEchoSpeed4K(b *testing.B) {
- speedclient(b, 4096)
- }
- func BenchmarkEchoSpeed64K(b *testing.B) {
- speedclient(b, 65536)
- }
- func BenchmarkEchoSpeed512K(b *testing.B) {
- speedclient(b, 524288)
- }
- func BenchmarkEchoSpeed1M(b *testing.B) {
- speedclient(b, 1048576)
- }
- func speedclient(b *testing.B, nbytes int) {
- b.ReportAllocs()
- cli, err := dialEcho()
- if err != nil {
- panic(err)
- }
- if err := echo_tester(cli, nbytes, b.N); err != nil {
- b.Fail()
- }
- b.SetBytes(int64(nbytes))
- }
- func BenchmarkSinkSpeed4K(b *testing.B) {
- sinkclient(b, 4096)
- }
- func BenchmarkSinkSpeed64K(b *testing.B) {
- sinkclient(b, 65536)
- }
- func BenchmarkSinkSpeed256K(b *testing.B) {
- sinkclient(b, 524288)
- }
- func BenchmarkSinkSpeed1M(b *testing.B) {
- sinkclient(b, 1048576)
- }
- func sinkclient(b *testing.B, nbytes int) {
- b.ReportAllocs()
- cli, err := dialSink()
- if err != nil {
- panic(err)
- }
- sink_tester(cli, nbytes, b.N)
- b.SetBytes(int64(nbytes))
- }
- func echo_tester(cli net.Conn, msglen, msgcount int) error {
- buf := make([]byte, msglen)
- for i := 0; i < msgcount; i++ {
- // send packet
- if _, err := cli.Write(buf); err != nil {
- return err
- }
- // receive packet
- nrecv := 0
- for {
- n, err := cli.Read(buf)
- if err != nil {
- return err
- } else {
- nrecv += n
- if nrecv == msglen {
- break
- }
- }
- }
- }
- return nil
- }
- func sink_tester(cli *UDPSession, msglen, msgcount int) error {
- // sender
- buf := make([]byte, msglen)
- for i := 0; i < msgcount; i++ {
- if _, err := cli.Write(buf); err != nil {
- return err
- }
- }
- return nil
- }
- func TestSNMP(t *testing.T) {
- t.Log(DefaultSnmp.Copy())
- t.Log(DefaultSnmp.Header())
- t.Log(DefaultSnmp.ToSlice())
- DefaultSnmp.Reset()
- t.Log(DefaultSnmp.ToSlice())
- }
- func TestListenerClose(t *testing.T) {
- l, err := ListenWithOptions(portListerner, nil, 10, 3)
- if err != nil {
- t.Fail()
- }
- l.SetReadDeadline(time.Now().Add(time.Second))
- l.SetWriteDeadline(time.Now().Add(time.Second))
- l.SetDeadline(time.Now().Add(time.Second))
- time.Sleep(2 * time.Second)
- if _, err := l.Accept(); err == nil {
- t.Fail()
- }
- l.Close()
- fakeaddr, _ := net.ResolveUDPAddr("udp6", "127.0.0.1:1111")
- if l.closeSession(fakeaddr) {
- t.Fail()
- }
- }
|