1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-12-31 06:25:32 -05:00

refine socks udp handling

This commit is contained in:
Darien Raymond
2017-01-07 21:57:24 +01:00
parent a150ceb3ea
commit b00ee67369
10 changed files with 94 additions and 725 deletions

View File

@@ -272,3 +272,72 @@ func writeSocks4Response(writer io.Writer, errCode byte, address v2net.Address,
_, err := writer.Write(buffer.Bytes())
return err
}
func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
if len(packet) < 5 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
}
request := &protocol.RequestHeader{
Version: socks5Version,
Command: protocol.RequestCommandUDP,
}
// packet[0] and packet[1] are reserved
if packet[2] != 0 /* fragments */ {
return nil, nil, errors.New("Socks|UDP: Fragmented payload.")
}
addrType := packet[3]
var dataBegin int
switch addrType {
case addrTypeIPv4:
if len(packet) < 10 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
}
ip := packet[4:8]
request.Port = v2net.PortFromBytes(packet[8:10])
request.Address = v2net.IPAddress(ip)
dataBegin = 10
case addrTypeIPv6:
if len(packet) < 22 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
}
ip := packet[4:20]
request.Port = v2net.PortFromBytes(packet[20:22])
request.Address = v2net.IPAddress(ip)
dataBegin = 22
case addrTypeDomain:
domainLength := int(packet[4])
if len(packet) < 5+domainLength+2 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
}
domain := string(packet[5 : 5+domainLength])
request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
request.Address = v2net.ParseAddress(domain)
dataBegin = 5 + domainLength + 2
default:
return nil, nil, errors.New("Socks|UDP: Unknown address type ", addrType)
}
return request, packet[dataBegin:], nil
}
func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) *buf.Buffer {
b := buf.NewSmall()
b.AppendBytes(0, 0, 0 /* Fragment */)
switch request.Address.Family() {
case v2net.AddressFamilyIPv4:
b.AppendBytes(addrTypeIPv4)
b.Append(request.Address.IP())
case v2net.AddressFamilyIPv6:
b.AppendBytes(addrTypeIPv6)
b.Append(request.Address.IP())
case v2net.AddressFamilyDomain:
b.AppendBytes(addrTypeDomain, byte(len(request.Address.Domain())))
b.AppendSupplier(serial.WriteString(request.Address.Domain()))
}
b.AppendSupplier(serial.WriteUint16(request.Port.Value()))
b.Append(data)
return b
}