package shadow import ( "crypto/tls" "fmt" "io" "net" "time" ) type Client struct { ListenAddress string ServerAddress string FakeAddressSNI string } func NewClient(listenAddress string, serverAddress string, fakeAddressSNI string) *Client { client := &Client{ ListenAddress: listenAddress, ServerAddress: serverAddress, FakeAddressSNI: fakeAddressSNI, } return client } func (c *Client) Start() { listen, err := net.Listen("tcp", c.ListenAddress) if err != nil { fmt.Printf("[Client] Start client error: %v\n", err) return } defer listen.Close() fmt.Printf("[Client] Listening at:%v\n", c.ListenAddress) for { conn, err := listen.Accept() if err != nil { fmt.Printf("[Client] accept error: %v\n", err) continue } go handlerClient(conn, c.ServerAddress, c.FakeAddressSNI) } } func handlerClient(conn net.Conn, serverAddress string, fakeAddressSNI string) { dial, err := tls.DialWithDialer(&net.Dialer{ Timeout: time.Second * 5, }, "tcp", serverAddress, &tls.Config{ ServerName: fakeAddressSNI, }) if err != nil { fmt.Printf("[Client] Dial server error: %v\n", err) return } err = dial.Handshake() if err != nil { fmt.Printf("[Client] Handshake error: %v\n", err) return } dial.NetConn().SetDeadline(time.Now()) dial.NetConn().SetDeadline(time.Time{}) p := &PackAppData{Conn: dial.NetConn()} go io.Copy(conn, p) go io.Copy(p, conn) } func MyCopy(src io.ReadWriteCloser, dst io.ReadWriteCloser) { buf := make([]byte, 32*1024) for { nr, er := src.Read(buf) if nr > 0 { nw, ew := dst.Write(buf[0:nr]) if nw < 0 || nr < nw { nw = 0 if ew == nil { fmt.Printf("err1:\n") } } if ew != nil { fmt.Printf("err2:%v\n", ew) break } if nr != nw { fmt.Printf("nr != nw \n") break } } if er != nil { if er != io.EOF { fmt.Printf("err3:%v\n", er) } else { fmt.Println("EOF") } break } } }