| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package tuic
- import (
- "bytes"
- "context"
- "io"
- "net"
- "testing"
- "time"
- )
- func TestAudit3CloseMustInterruptIdleTCPRelay(t *testing.T) {
- listener, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatal(err)
- }
- defer listener.Close()
- release := make(chan struct{})
- defer close(release)
- peerFIN := make(chan struct{})
- ready := make(chan struct{})
- go func() {
- c, err := listener.Accept()
- if err != nil {
- return
- }
- defer c.Close()
- var greeting [4]byte
- if _, err := io.ReadFull(c, greeting[:]); err != nil {
- return
- }
- c.Write([]byte{5, 0})
- var req [10]byte
- if _, err := io.ReadFull(c, req[:]); err != nil {
- return
- }
- c.Write([]byte{5, 0, 0, 1, 127, 0, 0, 1, 0, 0})
- var payload [1]byte
- if _, err := io.ReadFull(c, payload[:]); err != nil {
- return
- }
- c.Write(payload[:])
- close(ready)
- io.Copy(io.Discard, c)
- close(peerFIN)
- <-release
- }()
- server, conn, _, _ := startLifecycleTestServer(t, listener.Addr().String(), "close-idle@audit3")
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- stream, err := conn.OpenStreamSync(ctx)
- if err != nil {
- t.Fatal(err)
- }
- var cmd bytes.Buffer
- cmd.Write([]byte{ProtocolVersion, CmdConnect})
- WriteAddress(&cmd, &Address{Type: AddrTypeIPv4, IP: net.ParseIP("1.1.1.1"), Port: 443})
- cmd.WriteByte('x')
- if _, err := stream.Write(cmd.Bytes()); err != nil {
- t.Fatal(err)
- }
- var echo [1]byte
- if _, err := io.ReadFull(stream, echo[:]); err != nil {
- t.Fatal(err)
- }
- <-ready
- closed := make(chan error, 1)
- started := time.Now()
- go func() { closed <- server.Close() }()
- select {
- case err := <-closed:
- if err != nil {
- t.Fatal(err)
- }
- case <-time.After(time.Second):
- t.Fatalf("Server.Close waited for idle TCP peer after %s", time.Since(started))
- }
- select {
- case <-peerFIN:
- case <-time.After(time.Second):
- t.Fatal("upstream socket did not close")
- }
- _, _, deltas := server.CollectAllTraffic()
- if len(deltas) != 1 || deltas[0].Up != 1 || deltas[0].Down != 1 {
- t.Fatalf("final traffic: %+v", deltas)
- }
- }
|