github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/internal/socks/dial_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package socks_test 6 7 import ( 8 "context" 9 "io" 10 "math/rand" 11 "net" 12 "os" 13 "testing" 14 "time" 15 16 "github.com/Andyfoo/golang/x/net/internal/socks" 17 "github.com/Andyfoo/golang/x/net/internal/sockstest" 18 ) 19 20 func TestDial(t *testing.T) { 21 t.Run("Connect", func(t *testing.T) { 22 ss, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired) 23 if err != nil { 24 t.Fatal(err) 25 } 26 defer ss.Close() 27 d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String()) 28 d.AuthMethods = []socks.AuthMethod{ 29 socks.AuthMethodNotRequired, 30 socks.AuthMethodUsernamePassword, 31 } 32 d.Authenticate = (&socks.UsernamePassword{ 33 Username: "username", 34 Password: "password", 35 }).Authenticate 36 c, err := d.DialContext(context.Background(), ss.TargetAddr().Network(), ss.TargetAddr().String()) 37 if err != nil { 38 t.Fatal(err) 39 } 40 c.(*socks.Conn).BoundAddr() 41 c.Close() 42 }) 43 t.Run("ConnectWithConn", func(t *testing.T) { 44 ss, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired) 45 if err != nil { 46 t.Fatal(err) 47 } 48 defer ss.Close() 49 c, err := net.Dial(ss.Addr().Network(), ss.Addr().String()) 50 if err != nil { 51 t.Fatal(err) 52 } 53 defer c.Close() 54 d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String()) 55 d.AuthMethods = []socks.AuthMethod{ 56 socks.AuthMethodNotRequired, 57 socks.AuthMethodUsernamePassword, 58 } 59 d.Authenticate = (&socks.UsernamePassword{ 60 Username: "username", 61 Password: "password", 62 }).Authenticate 63 a, err := d.DialWithConn(context.Background(), c, ss.TargetAddr().Network(), ss.TargetAddr().String()) 64 if err != nil { 65 t.Fatal(err) 66 } 67 if _, ok := a.(*socks.Addr); !ok { 68 t.Fatalf("got %+v; want socks.Addr", a) 69 } 70 }) 71 t.Run("Cancel", func(t *testing.T) { 72 ss, err := sockstest.NewServer(sockstest.NoAuthRequired, blackholeCmdFunc) 73 if err != nil { 74 t.Fatal(err) 75 } 76 defer ss.Close() 77 d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String()) 78 ctx, cancel := context.WithCancel(context.Background()) 79 defer cancel() 80 dialErr := make(chan error) 81 go func() { 82 c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String()) 83 if err == nil { 84 c.Close() 85 } 86 dialErr <- err 87 }() 88 time.Sleep(100 * time.Millisecond) 89 cancel() 90 err = <-dialErr 91 if perr, nerr := parseDialError(err); perr != context.Canceled && nerr == nil { 92 t.Fatalf("got %v; want context.Canceled or equivalent", err) 93 } 94 }) 95 t.Run("Deadline", func(t *testing.T) { 96 ss, err := sockstest.NewServer(sockstest.NoAuthRequired, blackholeCmdFunc) 97 if err != nil { 98 t.Fatal(err) 99 } 100 defer ss.Close() 101 d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String()) 102 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(100*time.Millisecond)) 103 defer cancel() 104 c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String()) 105 if err == nil { 106 c.Close() 107 } 108 if perr, nerr := parseDialError(err); perr != context.DeadlineExceeded && nerr == nil { 109 t.Fatalf("got %v; want context.DeadlineExceeded or equivalent", err) 110 } 111 }) 112 t.Run("WithRogueServer", func(t *testing.T) { 113 ss, err := sockstest.NewServer(sockstest.NoAuthRequired, rogueCmdFunc) 114 if err != nil { 115 t.Fatal(err) 116 } 117 defer ss.Close() 118 d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String()) 119 for i := 0; i < 2*len(rogueCmdList); i++ { 120 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(100*time.Millisecond)) 121 defer cancel() 122 c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String()) 123 if err == nil { 124 t.Log(c.(*socks.Conn).BoundAddr()) 125 c.Close() 126 t.Error("should fail") 127 } 128 } 129 }) 130 } 131 132 func blackholeCmdFunc(rw io.ReadWriter, b []byte) error { 133 if _, err := sockstest.ParseCmdRequest(b); err != nil { 134 return err 135 } 136 var bb [1]byte 137 for { 138 if _, err := rw.Read(bb[:]); err != nil { 139 return err 140 } 141 } 142 } 143 144 func rogueCmdFunc(rw io.ReadWriter, b []byte) error { 145 if _, err := sockstest.ParseCmdRequest(b); err != nil { 146 return err 147 } 148 rw.Write(rogueCmdList[rand.Intn(len(rogueCmdList))]) 149 return nil 150 } 151 152 var rogueCmdList = [][]byte{ 153 {0x05}, 154 {0x06, 0x00, 0x00, 0x01, 192, 0, 2, 1, 0x17, 0x4b}, 155 {0x05, 0x00, 0xff, 0x01, 192, 0, 2, 2, 0x17, 0x4b}, 156 {0x05, 0x00, 0x00, 0x01, 192, 0, 2, 3}, 157 {0x05, 0x00, 0x00, 0x03, 0x04, 'F', 'Q', 'D', 'N'}, 158 } 159 160 func parseDialError(err error) (perr, nerr error) { 161 if e, ok := err.(*net.OpError); ok { 162 err = e.Err 163 nerr = e 164 } 165 if e, ok := err.(*os.SyscallError); ok { 166 err = e.Err 167 } 168 perr = err 169 return 170 }