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 TestDnsAdd(t *testing.T) { assert := assert.On(t) space := app.NewSpace() outboundHandlerManager := proxyman.NewDefaultOutboundHandlerManager() outboundHandlerManager.SetDefaultHandler( freedom.NewFreedomConnection( &freedom.Config{}, space, &proxy.OutboundHandlerMeta{ Address: v2net.AnyIP, StreamSettings: &internet.StreamSettings{ Type: internet.StreamConnectionTypeRawTCP, }, })) space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager) space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space)) domain := "local.v2ray.com" server := NewCacheServer(space, &Config{ NameServers: []v2net.Destination{ v2net.UDPDestination(v2net.IPAddress([]byte{8, 8, 8, 8}), v2net.Port(53)), }, }) space.BindApp(APP_ID, server) space.Initialize() ips := server.Get(domain) assert.Int(len(ips)).Equals(1) assert.IP(ips[0].To4()).Equals(net.IP([]byte{127, 0, 0, 1})) }
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.Family().IsDomain() { return errors.New(ip.Address.String() + " is not an IP.") } this.Hosts[domain] = ip.Address.IP() } } return nil }
func (v *UDPHub) start() { v.cancel.WaitThread() defer v.cancel.FinishThread() oobBytes := make([]byte, 256) for v.Running() { buffer := buf.NewSmall() var noob int var addr *net.UDPAddr err := buffer.AppendSupplier(func(b []byte) (int, error) { n, nb, _, a, e := ReadUDPMsg(v.conn, b, oobBytes) noob = nb addr = a return n, e }) if err != nil { log.Info("UDP|Hub: Failed to read UDP msg: ", err) buffer.Release() continue } session := new(proxy.SessionInfo) session.Source = v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)) if v.option.ReceiveOriginalDest && noob > 0 { session.Destination = RetrieveOriginalDest(oobBytes[:noob]) } v.queue.Enqueue(UDPPayload{ payload: buffer, session: session, }) } }
func (this *UDPHub) start() { this.cancel.WaitThread() defer this.cancel.FinishThread() oobBytes := make([]byte, 256) for this.Running() { buffer := this.pool.Allocate() nBytes, noob, _, addr, err := ReadUDPMsg(this.conn, buffer.Value, oobBytes) if err != nil { log.Info("UDP|Hub: Failed to read UDP msg: ", err) buffer.Release() continue } buffer.Slice(0, nBytes) session := new(proxy.SessionInfo) session.Source = v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)) if this.option.ReceiveOriginalDest && noob > 0 { session.Destination = RetrieveOriginalDest(oobBytes[:noob]) } this.queue.Enqueue(UDPPayload{ payload: buffer, session: session, }) } }
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 RetrieveOriginalDest(oob []byte) v2net.Destination { msgs, err := syscall.ParseSocketControlMessage(oob) if err != nil { return v2net.Destination{} } for _, msg := range msgs { if msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_RECVORIGDSTADDR { ip := v2net.IPAddress(msg.Data[4:8]) port := v2net.PortFromBytes(msg.Data[2:4]) return v2net.UDPDestination(ip, port) } else if msg.Header.Level == syscall.SOL_IPV6 && msg.Header.Type == syscall.IP_RECVORIGDSTADDR { ip := v2net.IPAddress(msg.Data[8:24]) port := v2net.PortFromBytes(msg.Data[2:4]) return v2net.UDPDestination(ip, port) } } return v2net.Destination{} }
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, session *proxy.SessionInfo) { if session.Destination == nil && this.address != nil && this.port > 0 { session.Destination = v2net.UDPDestination(this.address, this.port) } if session.Destination == nil { log.Info("Dokodemo: Unknown destination, stop forwarding...") return } this.udpServer.Dispatch(session, payload, this.handleUDPResponse) }
func (v *DokodemoDoor) handleUDPPackets(payload *buf.Buffer, session *proxy.SessionInfo) { if session.Destination.Network == v2net.Network_Unknown && v.address != nil && v.port > 0 { session.Destination = v2net.UDPDestination(v.address, v.port) } if session.Destination.Network == v2net.Network_Unknown { log.Info("Dokodemo: Unknown destination, stop forwarding...") return } session.Inbound = v.meta v.udpServer.Dispatch(session, payload, v.handleUDPResponse) }
func (this *Server) listenUDP() error { this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher) udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, udp.ListenOption{Callback: this.handleUDPPayload}) if err != nil { log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port) return err } this.udpMutex.Lock() this.udpAddress = v2net.UDPDestination(this.config.Address, this.meta.Port) this.udpHub = udpHub this.udpMutex.Unlock() return nil }
func (v *Server) listenUDP() error { v.udpServer = udp.NewUDPServer(v.packetDispatcher) udpHub, err := udp.ListenUDP(v.meta.Address, v.meta.Port, udp.ListenOption{Callback: v.handleUDPPayload}) if err != nil { log.Error("Socks: Failed to listen on udp (", v.meta.Address, ":", v.meta.Port, "): ", err) return err } v.udpMutex.Lock() v.udpAddress = v2net.UDPDestination(v.config.GetNetAddress(), v.meta.Port) v.udpHub = udpHub v.udpMutex.Unlock() return nil }
// Private: Visible for testing. 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.Network == v2net.Network_TCP { dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port) } else { dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port) } } return dests }
func (server *Server) Start() (v2net.Destination, error) { conn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: []byte{127, 0, 0, 1}, Port: int(server.Port), Zone: "", }) if err != nil { return nil, err } server.Port = v2net.Port(conn.LocalAddr().(*net.UDPAddr).Port) server.conn = conn go server.handleConnection(conn) localAddr := conn.LocalAddr().(*net.UDPAddr) return v2net.UDPDestination(v2net.IPAddress(localAddr.IP), v2net.Port(localAddr.Port)), 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 }
func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) { udpDest := v2net.UDPDestination(dest.Address(), dest.Port()) log.Info("KCP|Dialer: Dialing KCP to ", udpDest) conn, err := internet.DialToDest(src, udpDest) if err != nil { log.Error("KCP|Dialer: Failed to dial to dest: ", err) return nil, err } cpip, err := effectiveConfig.GetAuthenticator() if err != nil { log.Error("KCP|Dialer: Failed to create authenticator: ", err) return nil, err } 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 }
// Private: Visible for testing. func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination { if !destination.Address.Family().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.Network == v2net.Network_TCP { 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 (w *udpWorker) callback(b *buf.Buffer, source v2net.Destination, originalDest v2net.Destination) { conn, existing := w.getConnection(source) conn.input <- b.Bytes() if !existing { go func() { ctx := w.ctx ctx, cancel := context.WithCancel(ctx) conn.cancel = cancel if originalDest.IsValid() { ctx = proxy.ContextWithOriginalDestination(ctx, originalDest) } if len(w.tag) > 0 { ctx = proxy.ContextWithInboundTag(ctx, w.tag) } ctx = proxy.ContextWithSource(ctx, source) ctx = proxy.ContextWithInboundDestination(ctx, v2net.UDPDestination(w.address, w.port)) w.proxy.Process(ctx, v2net.Network_UDP, conn) w.removeConn(source) cancel() }() } }
func (this *UDPHub) start() { this.Lock() this.accepting = true this.Unlock() oobBytes := make([]byte, 256) for this.Running() { buffer := alloc.NewBuffer() nBytes, noob, _, addr, err := ReadUDPMsg(this.conn, buffer.Value, oobBytes) if err != nil { log.Info("UDP|Hub: Failed to read UDP msg: ", err) buffer.Release() continue } buffer.Slice(0, nBytes) session := new(proxy.SessionInfo) session.Source = v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)) if this.option.ReceiveOriginalDest && noob > 0 { session.Destination = RetrieveOriginalDest(oobBytes[:noob]) } go this.option.Callback(buffer, session) } }
func (request *Socks5UDPRequest) Destination() v2net.Destination { return v2net.UDPDestination(request.Address, request.Port) }
func TestDialAndListen(t *testing.T) { assert := assert.On(t) listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0)) assert.Error(err).IsNil() port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port) 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() }
"v2ray.com/core/app/dispatcher" "v2ray.com/core/common/buf" "v2ray.com/core/common/dice" "v2ray.com/core/common/log" v2net "v2ray.com/core/common/net" "v2ray.com/core/transport/internet/udp" ) 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 }
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 *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.SessionInfo) { defer payload.Release() source := session.Source 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(&proxy.SessionInfo{Source: source, Destination: 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 request.Address.Family() { case v2net.AddressFamilyIPv4: writer.Write([]byte{AddrTypeIPv4}) writer.Write(request.Address.IP()) case v2net.AddressFamilyIPv6: writer.Write([]byte{AddrTypeIPv6}) writer.Write(request.Address.IP()) case v2net.AddressFamilyDomain: writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))}) writer.Write([]byte(request.Address.Domain())) } writer.Write(request.Port.Bytes(nil)) 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) { assert := assert.On(t) udpServer := &udp.Server{ 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}), udpServer.Port)) 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.LocalHostIP, udpServer.Port), []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.LocalHostIP, udpServer.Port), []byte("Processed: UDP request to udp server."))) } udpConn.Close() conn.Close() CloseAllServers() }
func (v *RequestHeader) Destination() v2net.Destination { if v.Command == RequestCommandUDP { return v2net.UDPDestination(v.Address, v.Port) } return v2net.TCPDestination(v.Address, v.Port) }
func TestDialAndListen(t *testing.T) { assert := assert.On(t) listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0), internet.ListenOptions{ Stream: &internet.StreamConfig{ Network: v2net.Network_KCP, NetworkSettings: []*internet.NetworkSettings{ { Network: v2net.Network_KCP, Settings: serial.ToTypedMessage(&Config{}), }, }, }, }) assert.Error(err).IsNil() port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port) 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), internet.DialerOptions{ Stream: &internet.StreamConfig{ Network: v2net.Network_KCP, NetworkSettings: []*internet.NetworkSettings{ { Network: v2net.Network_KCP, Settings: serial.ToTypedMessage(&Config{}), }, }, }, }) 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() for i := 0; i < 60 && listerner.ActiveConnections() > 0; i++ { time.Sleep(500 * time.Millisecond) } assert.Int(listerner.ActiveConnections()).Equals(0) listerner.Close() }