1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-20 16:26:23 -05:00

Basic implementation of socks udp listener.

This commit is contained in:
V2Ray 2015-09-22 23:50:05 +02:00
parent dc5fbf8e60
commit 019d8266bc
2 changed files with 62 additions and 10 deletions

View File

@ -13,18 +13,18 @@ var (
)
type Socks5UDPRequest struct {
fragment byte
address v2net.Address
data []byte
Fragment byte
Address v2net.Address
Data []byte
}
func (request *Socks5UDPRequest) Destination() v2net.Destination {
return v2net.NewUDPDestination(request.address)
return v2net.NewUDPDestination(request.Address)
}
func ReadUDPRequest(packet []byte) (request Socks5UDPRequest, err error) {
// packet[0] and packet[1] are reserved
request.fragment = packet[2]
request.Fragment = packet[2]
addrType := packet[3]
var dataBegin int
@ -33,18 +33,18 @@ func ReadUDPRequest(packet []byte) (request Socks5UDPRequest, err error) {
case AddrTypeIPv4:
ip := packet[4:8]
port := binary.BigEndian.Uint16(packet[8:10])
request.address = v2net.IPAddress(ip, port)
request.Address = v2net.IPAddress(ip, port)
dataBegin = 10
case AddrTypeIPv6:
ip := packet[4:20]
port := binary.BigEndian.Uint16(packet[20:22])
request.address = v2net.IPAddress(ip, port)
request.Address = v2net.IPAddress(ip, port)
dataBegin = 22
case AddrTypeDomain:
domainLength := int(packet[4])
domain := string(packet[5 : 5+domainLength])
port := binary.BigEndian.Uint16(packet[5+domainLength : 5+domainLength+2])
request.address = v2net.DomainAddress(domain, port)
request.Address = v2net.DomainAddress(domain, port)
dataBegin = 5 + domainLength + 2
default:
log.Warning("Unknown address type %d", addrType)
@ -52,8 +52,8 @@ func ReadUDPRequest(packet []byte) (request Socks5UDPRequest, err error) {
return
}
request.data = make([]byte, len(packet)-dataBegin)
copy(request.data, packet[dataBegin:])
request.Data = make([]byte, len(packet)-dataBegin)
copy(request.Data, packet[dataBegin:])
return
}

52
proxy/socks/udp.go Normal file
View File

@ -0,0 +1,52 @@
package socks
import (
"net"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy/socks/protocol"
)
const (
bufferSize = 2 * 1024
)
func (server *SocksServer) ListenUDP(port uint16) error {
addr := &net.UDPAddr{
IP: net.IP{0, 0, 0, 0},
Port: int(port),
Zone: "",
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
log.Error("Socks failed to listen UDP on port %d: %v", port, err)
return err
}
go server.AcceptPackets(conn)
return nil
}
func (server *SocksServer) AcceptPackets(conn *net.UDPConn) error {
for {
buffer := make([]byte, 0, bufferSize)
nBytes, _, err := conn.ReadFromUDP(buffer)
if err != nil {
log.Error("Socks failed to read UDP packets: %v", err)
return err
}
request, err := protocol.ReadUDPRequest(buffer[:nBytes])
if err != nil {
log.Error("Socks failed to parse UDP request: %v", err)
return err
}
if request.Fragment != 0 {
// TODO handle fragments
continue
}
udpPacket := v2net.NewUDPPacket(request.Destination(), request.Data)
server.vPoint.DispatchToOutbound(udpPacket)
}
}