(addr *net.UDPAddr, b, p []byte, w func([]byte) (int, error), timeout int)
| 44 | } |
| 45 | |
| 46 | func (f *PacketServerConnFactory) Handle(addr *net.UDPAddr, b, p []byte, w func([]byte) (int, error), timeout int) (net.Conn, []byte, error) { |
| 47 | if len(b) < 12+4+16 { |
| 48 | return nil, nil, errors.New("data too small") |
| 49 | } |
| 50 | ck := x.BP32.Get().([]byte) |
| 51 | if _, err := io.ReadFull(hkdf.New(sha256.New, p, b[:12], ClientHKDFInfo), ck); err != nil { |
| 52 | x.BP32.Put(ck) |
| 53 | return nil, nil, err |
| 54 | } |
| 55 | |
| 56 | cb, err := aes.NewCipher(ck) |
| 57 | if err != nil { |
| 58 | x.BP32.Put(ck) |
| 59 | return nil, nil, err |
| 60 | } |
| 61 | x.BP32.Put(ck) |
| 62 | ca, err := cipher.NewGCM(cb) |
| 63 | if err != nil { |
| 64 | return nil, nil, err |
| 65 | } |
| 66 | if _, err := ca.Open(b[:12], b[:12], b[12:], nil); err != nil { |
| 67 | return nil, nil, err |
| 68 | } |
| 69 | i := int64(binary.BigEndian.Uint32(b[12 : 12+4])) |
| 70 | if time.Now().Unix()-i > 60 { |
| 71 | return nil, nil, errors.New("Expired request") |
| 72 | } |
| 73 | a, h, p, err := socks5.ParseBytesAddress(b[12+4:]) |
| 74 | if err != nil { |
| 75 | return nil, nil, err |
| 76 | } |
| 77 | if 12+4+1+len(h)+2 >= len(b)-16 { |
| 78 | return nil, nil, errors.New(fmt.Sprintf("invalid packet. length: %d address: %#x %#x %#x", len(b), a, h, p)) |
| 79 | } |
| 80 | dst := socks5.ToAddress(a, h, p) |
| 81 | f.Lock.Lock() |
| 82 | c, ok := f.Conns[addr.String()+dst] |
| 83 | f.Lock.Unlock() |
| 84 | if ok { |
| 85 | _ = c.In(b[12+4+1+len(h)+2 : len(b)-16]) |
| 86 | return nil, nil, nil |
| 87 | } |
| 88 | f.Lock.Lock() |
| 89 | c = NewPacketConn(b[12+4+1+len(h)+2:len(b)-16], w, timeout, func() { |
| 90 | f.Lock.Lock() |
| 91 | delete(f.Conns, addr.String()+dst) |
| 92 | f.Lock.Unlock() |
| 93 | }) |
| 94 | f.Conns[addr.String()+dst] = c |
| 95 | f.Lock.Unlock() |
| 96 | return c, b[12+4 : 12+4+1+len(h)+2], nil |
| 97 | } |
no test coverage detected