github.com/ipfans/trojan-go@v0.11.0/tunnel/simplesocks/client.go (about) 1 package simplesocks 2 3 import ( 4 "context" 5 6 "github.com/ipfans/trojan-go/common" 7 "github.com/ipfans/trojan-go/log" 8 "github.com/ipfans/trojan-go/tunnel" 9 "github.com/ipfans/trojan-go/tunnel/trojan" 10 ) 11 12 const ( 13 Connect tunnel.Command = 1 14 Associate tunnel.Command = 3 15 ) 16 17 type Client struct { 18 underlay tunnel.Client 19 } 20 21 func (c *Client) DialConn(addr *tunnel.Address, t tunnel.Tunnel) (tunnel.Conn, error) { 22 conn, err := c.underlay.DialConn(nil, &Tunnel{}) 23 if err != nil { 24 return nil, common.NewError("simplesocks failed to dial using underlying tunnel").Base(err) 25 } 26 return &Conn{ 27 Conn: conn, 28 isOutbound: true, 29 metadata: &tunnel.Metadata{ 30 Command: Connect, 31 Address: addr, 32 }, 33 }, nil 34 } 35 36 func (c *Client) DialPacket(t tunnel.Tunnel) (tunnel.PacketConn, error) { 37 conn, err := c.underlay.DialConn(nil, &Tunnel{}) 38 if err != nil { 39 return nil, common.NewError("simplesocks failed to dial using underlying tunnel").Base(err) 40 } 41 metadata := &tunnel.Metadata{ 42 Command: Associate, 43 Address: &tunnel.Address{ 44 DomainName: "UDP_CONN", 45 AddressType: tunnel.DomainName, 46 }, 47 } 48 if err := metadata.WriteTo(conn); err != nil { 49 return nil, common.NewError("simplesocks failed to write udp associate").Base(err) 50 } 51 return &PacketConn{ 52 PacketConn: trojan.PacketConn{ 53 Conn: conn, 54 }, 55 }, nil 56 } 57 58 func (c *Client) Close() error { 59 return c.underlay.Close() 60 } 61 62 func NewClient(ctx context.Context, underlay tunnel.Client) (*Client, error) { 63 log.Debug("simplesocks client created") 64 return &Client{ 65 underlay: underlay, 66 }, nil 67 }