From 820da78f92c53758b4b4c6f0c145cdc9fc6789b8 Mon Sep 17 00:00:00 2001 From: V2Ray Date: Fri, 2 Oct 2015 16:08:01 +0200 Subject: [PATCH] UDP handler in VMess in. --- proxy/vmess/protocol/udp.go | 5 ++++ proxy/vmess/vmessin_udp.go | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 proxy/vmess/vmessin_udp.go diff --git a/proxy/vmess/protocol/udp.go b/proxy/vmess/protocol/udp.go index 00d4669ec..e4e5d6787 100644 --- a/proxy/vmess/protocol/udp.go +++ b/proxy/vmess/protocol/udp.go @@ -20,6 +20,11 @@ type VMessUDP struct { data []byte } +func (message *VMessUDP) ToPacket() v2net.Packet { + dest := v2net.NewUDPDestination(message.address) + return v2net.NewPacket(dest, message.data, false) +} + func ReadVMessUDP(buffer []byte, userset user.UserSet) (*VMessUDP, error) { userHash := buffer[:user.IDBytesLen] userId, timeSec, valid := userset.GetUser(userHash) diff --git a/proxy/vmess/vmessin_udp.go b/proxy/vmess/vmessin_udp.go new file mode 100644 index 000000000..48061931c --- /dev/null +++ b/proxy/vmess/vmessin_udp.go @@ -0,0 +1,57 @@ +package vmess + +import ( + "net" + + "github.com/v2ray/v2ray-core/common/log" + v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy/vmess/protocol" +) + +const ( + bufferSize = 2 * 1024 +) + +func (handler *VMessInboundHandler) 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("VMessIn failed to listen UDP on port %d: %v", port, err) + return err + } + + go handler.AcceptPackets(conn) + return nil +} + +func (handler *VMessInboundHandler) AcceptPackets(conn *net.UDPConn) error { + for { + buffer := make([]byte, 0, bufferSize) + nBytes, addr, err := conn.ReadFromUDP(buffer) + if err != nil { + log.Error("VMessIn failed to read UDP packets: %v", err) + return err + } + request, err := protocol.ReadVMessUDP(buffer[:nBytes], handler.clients) + if err != nil { + log.Error("VMessIn failed to parse UDP request: %v", err) + return err + } + + udpPacket := request.ToPacket() + go handler.handlePacket(conn, udpPacket, addr) + } +} + +func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, packet v2net.Packet, clientAddr *net.UDPAddr) { + ray := handler.vPoint.DispatchToOutbound(packet) + close(ray.InboundInput()) + + if data, ok := <-ray.InboundOutput(); ok { + conn.WriteToUDP(data, clientAddr) + } +}