| 36 | } |
| 37 | |
| 38 | func NewSimpleStreamClient(network string, password []byte, src string, server net.Conn, timeout int, dst []byte) (Exchanger, error) { |
| 39 | c := &SimpleStreamClient{network: network, Server: server, Timeout: timeout, src: src, dst: socks5.ToAddress(dst[0], dst[1:len(dst)-2], dst[len(dst)-2:])} |
| 40 | if len(dst) > 2048-32-2-4 { |
| 41 | return nil, errors.New("dst too long") |
| 42 | } |
| 43 | b := x.BP2048.Get().([]byte) |
| 44 | binary.BigEndian.PutUint16(b[32:32+2], uint16(4+len(dst))) |
| 45 | i := time.Now().Unix() |
| 46 | if c.network == "tcp" && i%2 != 0 { |
| 47 | i += 1 |
| 48 | } |
| 49 | if c.network == "udp" && i%2 != 1 { |
| 50 | i += 1 |
| 51 | } |
| 52 | binary.BigEndian.PutUint32(b[32+2:32+2+4], uint32(i)) |
| 53 | copy(b[:32], password) |
| 54 | copy(b[32+2+4:], dst) |
| 55 | if _, err := server.Write(b[:32+2+4+len(dst)]); err != nil { |
| 56 | x.BP2048.Put(b) |
| 57 | return nil, err |
| 58 | } |
| 59 | if c.network == "tcp" { |
| 60 | c.RB = b |
| 61 | c.WB = x.BP2048.Get().([]byte) |
| 62 | } |
| 63 | if c.network == "udp" { |
| 64 | x.BP2048.Put(b) |
| 65 | c.RB = x.BP65507.Get().([]byte) |
| 66 | c.WB = x.BP65507.Get().([]byte) |
| 67 | } |
| 68 | return ClientGate(c) |
| 69 | } |
| 70 | |
| 71 | func (c *SimpleStreamClient) Exchange(local net.Conn) error { |
| 72 | go func() { |