func TestUDPDestinationEquals(t *testing.T) { assert := assert.On(t) dest := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(nil)).IsFalse() dest2 := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(dest2)).IsTrue() dest3 := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(dest3)).IsFalse() dest4 := v2net.UDPDestination(v2net.DomainAddress("v2ray.com"), 80) assert.Bool(dest.Equals(dest4)).IsFalse() }
func (this *Config) UnmarshalJSON(data []byte) error { type JsonConfig struct { Servers []v2net.AddressJson `json:"servers"` Hosts map[string]v2net.AddressJson `json:"hosts"` } jsonConfig := new(JsonConfig) if err := json.Unmarshal(data, jsonConfig); err != nil { return err } this.NameServers = make([]v2net.Destination, len(jsonConfig.Servers)) for idx, server := range jsonConfig.Servers { this.NameServers[idx] = v2net.UDPDestination(server.Address, v2net.Port(53)) } if jsonConfig.Hosts != nil { this.Hosts = make(map[string]net.IP) for domain, ip := range jsonConfig.Hosts { if ip.Address.IsDomain() { return errors.New(ip.Address.String() + " is not an IP.") } this.Hosts[domain] = ip.Address.IP() } } return nil }
func (this *DokodemoDoor) handleUDPPackets() { for this.accepting { buffer := alloc.NewBuffer() this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() return } nBytes, addr, err := this.udpConn.ReadFromUDP(buffer.Value) this.udpMutex.RUnlock() buffer.Slice(0, nBytes) if err != nil { buffer.Release() log.Error("Dokodemo failed to read from UDP: ", err) return } packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), buffer, false) ray := this.space.PacketDispatcher().DispatchToOutbound(packet) close(ray.InboundInput()) for payload := range ray.InboundOutput() { this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() return } this.udpConn.WriteToUDP(payload.Value, addr) this.udpMutex.RUnlock() } } }
// Destination is the final destination of this request. func (this *VMessRequest) Destination() v2net.Destination { if this.Command == CmdTCP { return v2net.TCPDestination(this.Address, this.Port) } else { return v2net.UDPDestination(this.Address, this.Port) } }
func TestUDPDestination(t *testing.T) { assert := assert.On(t) dest := v2net.UDPDestination(v2net.IPAddress([]byte{0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}), 53) assert.Destination(dest).IsNotTCP() assert.Destination(dest).IsUDP() assert.Destination(dest).EqualsString("udp:[2001:4860:4860::8888]:53") }
func (this *SocksServer) ListenUDP(port v2net.Port) error { this.udpServer = hub.NewUDPServer(this.packetDispatcher) udpHub, err := hub.ListenUDP(port, this.handleUDPPayload) if err != nil { log.Error("Socks: Failed to listen on udp port ", port) return err } this.udpMutex.Lock() this.udpAddress = v2net.UDPDestination(this.config.Address, port) this.udpHub = udpHub this.udpMutex.Unlock() return nil }
func (server *Server) Start() (v2net.Destination, error) { conn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: []byte{0, 0, 0, 0}, Port: int(server.Port), Zone: "", }) if err != nil { return nil, err } go server.handleConnection(conn) localAddr := conn.LocalAddr().(*net.UDPAddr) return v2net.UDPDestination(v2net.IPAddress(localAddr.IP), v2net.Port(localAddr.Port)), nil }
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) { packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false) this.udpServer.Dispatch(dest, packet, func(packet v2net.Packet) { defer packet.Chunk().Release() this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() return } this.udpHub.WriteTo(packet.Chunk().Value, packet.Destination()) this.udpMutex.RUnlock() }) }
func (this *UDPHub) start() { this.accepting = true for this.accepting { buffer := alloc.NewBuffer() nBytes, addr, err := this.conn.ReadFromUDP(buffer.Value) if err != nil { buffer.Release() continue } buffer.Slice(0, nBytes) dest := v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)) go this.callback(buffer, dest) } }
// @Private func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination { ips := this.dnsServer.Get(dest.Address().Domain()) if len(ips) == 0 { return nil } dests := make([]v2net.Destination, len(ips)) for idx, ip := range ips { if dest.IsTCP() { dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port()) } else { dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port()) } } return dests }
func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) { udpDest := v2net.UDPDestination(dest.Address(), dest.Port()) log.Info("Dialling KCP to ", udpDest) conn, err := internet.DialToDest(src, udpDest) if err != nil { return nil, err } cpip := NewSimpleAuthenticator() conv := uint16(atomic.AddUint32(&globalConv, 1)) session := NewConnection(conv, conn, conn.LocalAddr().(*net.UDPAddr), conn.RemoteAddr().(*net.UDPAddr), cpip) session.FetchInputFrom(conn) return session, nil }
func (this *SocksServer) ListenUDP(port v2net.Port) 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 } udpAddress = v2net.UDPDestination(v2net.IPAddress(this.config.IP()), port) go this.AcceptPackets(conn) return nil }
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) { packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false) ray := this.packetDispatcher.DispatchToOutbound(packet) close(ray.InboundInput()) for resp := range ray.InboundOutput() { this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() resp.Release() return } this.udpHub.WriteTo(resp.Value, dest) this.udpMutex.RUnlock() resp.Release() } }
func (this *SocksServer) ListenUDP(port v2net.Port) 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 ", port, ": ", err) return err } this.udpMutex.Lock() this.udpAddress = v2net.UDPDestination(this.config.Address, port) this.udpConn = conn this.udpMutex.Unlock() go this.AcceptPackets() return nil }
func (this *Config) UnmarshalJSON(data []byte) error { type JsonConfig struct { Port v2net.Port `json:"port"` // Port of this Point server. LogConfig *LogConfig `json:"log"` RouterConfig *router.Config `json:"routing"` DNSConfig *dns.Config `json:"dns"` InboundConfig *InboundConnectionConfig `json:"inbound"` OutboundConfig *OutboundConnectionConfig `json:"outbound"` InboundDetours []*InboundDetourConfig `json:"inboundDetour"` OutboundDetours []*OutboundDetourConfig `json:"outboundDetour"` Transport *transport.Config `json:"transport"` } jsonConfig := new(JsonConfig) if err := json.Unmarshal(data, jsonConfig); err != nil { return errors.New("Point: Failed to parse config: " + err.Error()) } this.Port = jsonConfig.Port this.LogConfig = jsonConfig.LogConfig this.RouterConfig = jsonConfig.RouterConfig if jsonConfig.InboundConfig == nil { return errors.New("Point: Inbound config is not specified.") } this.InboundConfig = jsonConfig.InboundConfig if jsonConfig.OutboundConfig == nil { return errors.New("Point: Outbound config is not specified.") } this.OutboundConfig = jsonConfig.OutboundConfig this.InboundDetours = jsonConfig.InboundDetours this.OutboundDetours = jsonConfig.OutboundDetours if jsonConfig.DNSConfig == nil { jsonConfig.DNSConfig = &dns.Config{ NameServers: []v2net.Destination{ v2net.UDPDestination(v2net.DomainAddress("localhost"), v2net.Port(53)), }, } } this.DNSConfig = jsonConfig.DNSConfig this.TransportConfig = jsonConfig.Transport return nil }
// @Private func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination { if !destination.Address().IsDomain() { return destination } ips := this.dns.Get(destination.Address().Domain()) if len(ips) == 0 { log.Info("Freedom: DNS returns nil answer. Keep domain as is.") return destination } ip := ips[dice.Roll(len(ips))] var newDest v2net.Destination if destination.IsTCP() { newDest = v2net.TCPDestination(v2net.IPAddress(ip), destination.Port()) } else { newDest = v2net.UDPDestination(v2net.IPAddress(ip), destination.Port()) } log.Info("Freedom: Changing destination from ", destination, " to ", newDest) return newDest }
func TestDialAndListen(t *testing.T) { assert := assert.On(t) port := v2nettesting.PickPort() listerner, err := NewListener(v2net.LocalHostIP, port) assert.Error(err).IsNil() go func() { for { conn, err := listerner.Accept() if err != nil { break } go func() { payload := make([]byte, 4096) for { nBytes, err := conn.Read(payload) if err != nil { break } for idx, b := range payload[:nBytes] { payload[idx] = b ^ 'c' } conn.Write(payload[:nBytes]) } conn.Close() }() } }() wg := new(sync.WaitGroup) for i := 0; i < 10; i++ { clientConn, err := DialKCP(v2net.LocalHostIP, v2net.UDPDestination(v2net.LocalHostIP, port)) assert.Error(err).IsNil() wg.Add(1) go func() { clientSend := make([]byte, 1024*1024) rand.Read(clientSend) go clientConn.Write(clientSend) clientReceived := make([]byte, 1024*1024) nBytes, _ := io.ReadFull(clientConn, clientReceived) assert.Int(nBytes).Equals(len(clientReceived)) clientConn.Close() clientExpected := make([]byte, 1024*1024) for idx, b := range clientSend { clientExpected[idx] = b ^ 'c' } assert.Bytes(clientReceived).Equals(clientExpected) wg.Done() }() } wg.Wait() time.Sleep(15 * time.Second) assert.Int(listerner.ActiveConnections()).Equals(0) listerner.Close() }
func (this *Server) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destination) { defer payload.Release() ivLen := this.config.Cipher.IVSize() iv := payload.Value[:ivLen] key := this.config.Key payload.SliceFrom(ivLen) stream, err := this.config.Cipher.NewDecodingStream(key, iv) if err != nil { log.Error("Shadowsocks: Failed to create decoding stream: ", err) return } reader := crypto.NewCryptionReader(stream, payload) request, err := ReadRequest(reader, NewAuthenticator(HeaderKeyGenerator(key, iv)), true) if err != nil { if err != io.EOF { log.Access(source, "", log.AccessRejected, err) log.Warning("Shadowsocks: Invalid request from ", source, ": ", err) } return } //defer request.Release() dest := v2net.UDPDestination(request.Address, request.Port) log.Access(source, dest, log.AccessAccepted, "") log.Info("Shadowsocks: Tunnelling request to ", dest) this.udpServer.Dispatch(source, dest, request.DetachUDPPayload(), func(destination v2net.Destination, payload *alloc.Buffer) { defer payload.Release() response := alloc.NewBuffer().Slice(0, ivLen) defer response.Release() rand.Read(response.Value) respIv := response.Value stream, err := this.config.Cipher.NewEncodingStream(key, respIv) if err != nil { log.Error("Shadowsocks: Failed to create encoding stream: ", err) return } writer := crypto.NewCryptionWriter(stream, response) switch { case request.Address.IsIPv4(): writer.Write([]byte{AddrTypeIPv4}) writer.Write(request.Address.IP()) case request.Address.IsIPv6(): writer.Write([]byte{AddrTypeIPv6}) writer.Write(request.Address.IP()) case request.Address.IsDomain(): writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))}) writer.Write([]byte(request.Address.Domain())) } writer.Write(request.Port.Bytes()) writer.Write(payload.Value) if request.OTA { respAuth := NewAuthenticator(HeaderKeyGenerator(key, respIv)) respAuth.Authenticate(response.Value, response.Value[ivLen:]) } this.udpHub.WriteTo(response.Value, source) }) }
func TestUDPAssociate(t *testing.T) { v2testing.Current(t) targetPort := v2nettesting.PickPort() udpServer := &udp.Server{ Port: targetPort, MsgProcessor: func(data []byte) []byte { buffer := make([]byte, 0, 2048) buffer = append(buffer, []byte("Processed: ")...) buffer = append(buffer, data...) return buffer }, } _, err := udpServer.Start() assert.Error(err).IsNil() defer udpServer.Close() assert.Error(InitializeServerSetOnce("test_1")).IsNil() socksPort := v2net.Port(50000) conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: []byte{127, 0, 0, 1}, Port: int(socksPort), }) authRequest := socks5AuthMethodRequest(byte(0)) nBytes, err := conn.Write(authRequest) assert.Int(nBytes).Equals(len(authRequest)) assert.Error(err).IsNil() authResponse := make([]byte, 1024) nBytes, err = conn.Read(authResponse) assert.Error(err).IsNil() assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0}) connectRequest := socks5Request(byte(3), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort)) nBytes, err = conn.Write(connectRequest) assert.Int(nBytes).Equals(len(connectRequest)) assert.Error(err).IsNil() connectResponse := make([]byte, 1024) nBytes, err = conn.Read(connectResponse) assert.Error(err).IsNil() assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 127, 0, 0, 1, byte(socksPort >> 8), byte(socksPort)}) udpConn, err := net.DialUDP("udp", nil, &net.UDPAddr{ IP: []byte{127, 0, 0, 1}, Port: int(socksPort), }) assert.Error(err).IsNil() for i := 0; i < 100; i++ { udpPayload := "UDP request to udp server." udpRequest := socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte(udpPayload)) nBytes, err = udpConn.Write(udpRequest) assert.Int(nBytes).Equals(len(udpRequest)) assert.Error(err).IsNil() udpResponse := make([]byte, 1024) nBytes, err = udpConn.Read(udpResponse) assert.Error(err).IsNil() assert.Bytes(udpResponse[:nBytes]).Equals( socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte("Processed: UDP request to udp server."))) } udpConn.Close() conn.Close() CloseAllServers() }
func (this *Shadowsocks) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destination) { defer payload.Release() iv := payload.Value[:this.config.Cipher.IVSize()] key := this.config.Key payload.SliceFrom(this.config.Cipher.IVSize()) reader, err := this.config.Cipher.NewDecodingStream(key, iv, payload) if err != nil { log.Error("Shadowsocks: Failed to create decoding stream: ", err) return } request, err := ReadRequest(reader, NewAuthenticator(HeaderKeyGenerator(key, iv)), true) if err != nil { log.Access(source, serial.StringLiteral(""), log.AccessRejected, serial.StringLiteral(err.Error())) log.Warning("Shadowsocks: Invalid request from ", source, ": ", err) return } dest := v2net.UDPDestination(request.Address, request.Port) log.Access(source, dest, log.AccessAccepted, serial.StringLiteral("")) log.Info("Shadowsocks: Tunnelling request to ", dest) packet := v2net.NewPacket(dest, request.UDPPayload, false) this.udpServer.Dispatch(source, packet, func(packet v2net.Packet) { defer packet.Chunk().Release() response := alloc.NewBuffer().Slice(0, this.config.Cipher.IVSize()) defer response.Release() rand.Read(response.Value) respIv := response.Value writer, err := this.config.Cipher.NewEncodingStream(key, respIv, response) if err != nil { log.Error("Shadowsocks: Failed to create encoding stream: ", err) return } switch { case request.Address.IsIPv4(): writer.Write([]byte{AddrTypeIPv4}) writer.Write(request.Address.IP()) case request.Address.IsIPv6(): writer.Write([]byte{AddrTypeIPv6}) writer.Write(request.Address.IP()) case request.Address.IsDomain(): writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))}) writer.Write([]byte(request.Address.Domain())) } writer.Write(request.Port.Bytes()) writer.Write(packet.Chunk().Value) if request.OTA { respAuth := NewAuthenticator(HeaderKeyGenerator(key, respIv)) respAuth.Authenticate(response.Value, response.Value[this.config.Cipher.IVSize():]) } this.udpHub.WriteTo(response.Value, source) }) }
func (request *Socks5UDPRequest) Destination() v2net.Destination { return v2net.UDPDestination(request.Address, request.Port) }
func (this *RequestHeader) Destination() v2net.Destination { if this.Command == RequestCommandUDP { return v2net.UDPDestination(this.Address, this.Port) } return v2net.TCPDestination(this.Address, this.Port) }
func (this *SocksServer) AcceptPackets() error { for this.accepting { buffer := alloc.NewBuffer() this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() return nil } nBytes, addr, err := this.udpConn.ReadFromUDP(buffer.Value) this.udpMutex.RUnlock() if err != nil { log.Error("Socks: failed to read UDP packets: ", err) buffer.Release() continue } log.Info("Socks: Client UDP connection from ", addr) request, err := protocol.ReadUDPRequest(buffer.Value[:nBytes]) buffer.Release() if err != nil { log.Error("Socks: failed to parse UDP request: ", err) continue } if request.Data == nil || request.Data.Len() == 0 { continue } if request.Fragment != 0 { log.Warning("Socks: Dropping fragmented UDP packets.") // TODO handle fragments request.Data.Release() continue } udpPacket := v2net.NewPacket(request.Destination(), request.Data, false) log.Info("Socks: Send packet to ", udpPacket.Destination(), " with ", request.Data.Len(), " bytes") this.udpServer.Dispatch( v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)), udpPacket, func(packet v2net.Packet) { response := &protocol.Socks5UDPRequest{ Fragment: 0, Address: udpPacket.Destination().Address(), Port: udpPacket.Destination().Port(), Data: packet.Chunk(), } log.Info("Socks: Writing back UDP response with ", response.Data.Len(), " bytes to ", packet.Destination()) udpMessage := alloc.NewSmallBuffer().Clear() response.Write(udpMessage) this.udpMutex.RLock() if !this.accepting { this.udpMutex.RUnlock() return } nBytes, err := this.udpConn.WriteToUDP(udpMessage.Value, &net.UDPAddr{ IP: packet.Destination().Address().IP(), Port: int(packet.Destination().Port()), }) this.udpMutex.RUnlock() udpMessage.Release() response.Data.Release() if err != nil { log.Error("Socks: failed to write UDP message (", nBytes, " bytes) to ", packet.Destination(), ": ", err) } }) } return nil }
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) { this.udpServer.Dispatch(dest, v2net.UDPDestination(this.address, this.port), payload, this.handleUDPResponse) }
"github.com/v2ray/v2ray-core/common/dice" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/transport/internet/udp" "github.com/miekg/dns" ) const ( DefaultTTL = uint32(3600) CleanupInterval = time.Second * 120 CleanupThreshold = 512 ) var ( pseudoDestination = v2net.UDPDestination(v2net.LocalHostIP, v2net.Port(53)) ) type ARecord struct { IPs []net.IP Expire time.Time } type NameServer interface { QueryA(domain string) <-chan *ARecord } type PendingRequest struct { expire time.Time response chan<- *ARecord }