func (request *Socks5Request) Destination() v2net.Destination { switch request.AddrType { case AddrTypeIPv4: return v2net.TCPDestination(v2net.IPAddress(request.IPv4[:]), request.Port) case AddrTypeIPv6: return v2net.TCPDestination(v2net.IPAddress(request.IPv6[:]), request.Port) case AddrTypeDomain: return v2net.TCPDestination(v2net.ParseAddress(request.Domain), request.Port) default: panic("Unknown address type") } }
func TestTCPDestinationEquals(t *testing.T) { assert := assert.On(t) dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(nil)).IsFalse() dest2 := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(dest2)).IsTrue() dest3 := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Bool(dest.Equals(dest3)).IsFalse() dest4 := v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80) assert.Bool(dest.Equals(dest4)).IsFalse() }
func TestDomainNotMatchingDomain(t *testing.T) { v2testing.Current(t) rawJson := `{ "type": "field", "domain": ["google.com", "v2ray.com"], "tag": "test" }` rule := parseRule([]byte(rawJson)) dest := v2net.TCPDestination(v2net.DomainAddress("baidu.com"), 80) assert.Bool(rule.Apply(dest)).IsFalse() dest = v2net.TCPDestination(v2net.DomainAddress("www.google.com"), 80) assert.Bool(rule.Apply(dest)).IsTrue() }
func TestSinglePacket(t *testing.T) { v2testing.Current(t) port := v2nettesting.PickPort() tcpServer := &tcp.Server{ Port: port, MsgProcessor: func(data []byte) []byte { buffer := make([]byte, 0, 2048) buffer = append(buffer, []byte("Processed: ")...) buffer = append(buffer, data...) return buffer }, } _, err := tcpServer.Start() assert.Error(err).IsNil() freedom := &FreedomConnection{} traffic := ray.NewRay() data2Send := "Data to be sent to remote" payload := alloc.NewSmallBuffer().Clear().Append([]byte(data2Send)) packet := v2net.NewPacket(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), port), payload, false) err = freedom.Dispatch(packet, traffic) assert.Error(err).IsNil() close(traffic.InboundInput()) respPayload := <-traffic.InboundOutput() defer respPayload.Release() assert.Bytes(respPayload.Value).Equals([]byte("Processed: Data to be sent to remote")) _, open := <-traffic.InboundOutput() assert.Bool(open).IsFalse() tcpServer.Close() }
func TestIPResolution(t *testing.T) { assert := assert.On(t) space := app.NewSpace() space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, proxyman.NewDefaultOutboundHandlerManager()) space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space)) r, _ := router.CreateRouter("rules", &rules.RouterRuleConfig{}, space) space.BindApp(router.APP_ID, r) dnsServer := dns.NewCacheServer(space, &dns.Config{ Hosts: map[string]net.IP{ "v2ray.com": net.IP([]byte{127, 0, 0, 1}), }, }) space.BindApp(dns.APP_ID, dnsServer) freedom := NewFreedomConnection( &Config{DomainStrategy: DomainStrategyUseIP}, space, &proxy.OutboundHandlerMeta{ Address: v2net.AnyIP, StreamSettings: &internet.StreamSettings{ Type: internet.StreamConnectionTypeRawTCP, }, }) space.Initialize() ipDest := freedom.ResolveIP(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), v2net.Port(80))) assert.Destination(ipDest).IsTCP() assert.Address(ipDest.Address()).Equals(v2net.LocalHostIP) }
func (this *Receiver) UnmarshalJSON(data []byte) error { type RawConfigTarget struct { Address *v2net.AddressJson `json:"address"` Port v2net.Port `json:"port"` Users []*protocol.User `json:"users"` } var rawConfig RawConfigTarget if err := json.Unmarshal(data, &rawConfig); err != nil { return err } if len(rawConfig.Users) == 0 { log.Error("VMess: 0 user configured for VMess outbound.") return internal.ErrBadConfiguration } this.Accounts = rawConfig.Users if rawConfig.Address == nil { log.Error("VMess: Address is not set in VMess outbound config.") return internal.ErrBadConfiguration } if rawConfig.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) { rawConfig.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil)) } this.Destination = v2net.TCPDestination(rawConfig.Address.Address, rawConfig.Port) return nil }
func (this *ClientConfig) UnmarshalJSON(data []byte) error { type ServerConfig struct { Address *v2net.AddressJson `json:"address"` Port v2net.Port `json:"port"` Users []json.RawMessage `json:"users"` } type JsonConfig struct { Servers []*ServerConfig `json:"servers"` } jsonConfig := new(JsonConfig) if err := json.Unmarshal(data, jsonConfig); err != nil { return errors.New("Socks|Client: Failed to parse config: " + err.Error()) } this.Servers = make([]*protocol.ServerSpec, len(jsonConfig.Servers)) for idx, serverConfig := range jsonConfig.Servers { server := protocol.NewServerSpec(v2net.TCPDestination(serverConfig.Address.Address, serverConfig.Port), protocol.AlwaysValid()) for _, rawUser := range serverConfig.Users { user := new(protocol.User) if err := json.Unmarshal(rawUser, user); err != nil { return errors.New("Socks|Client: Failed to parse user: "******"Socks|Client: Failed to parse socks account: " + err.Error()) } user.Account = account server.AddUser(user) } this.Servers[idx] = server } return nil }
func TestReceiverUser(t *testing.T) { assert := assert.On(t) id := protocol.NewID(uuid.New()) alters := protocol.NewAlterIDs(id, 100) account := &protocol.VMessAccount{ ID: id, AlterIDs: alters, } user := protocol.NewUser(account, protocol.UserLevel(0), "") rec := NewReceiver(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80), user) assert.Bool(rec.HasUser(user)).IsTrue() assert.Int(len(rec.Accounts)).Equals(1) id2 := protocol.NewID(uuid.New()) alters2 := protocol.NewAlterIDs(id2, 100) account2 := &protocol.VMessAccount{ ID: id2, AlterIDs: alters2, } user2 := protocol.NewUser(account2, protocol.UserLevel(0), "") assert.Bool(rec.HasUser(user2)).IsFalse() rec.AddUser(user2) assert.Bool(rec.HasUser(user2)).IsTrue() assert.Int(len(rec.Accounts)).Equals(2) }
// 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 TestTCPDestination(t *testing.T) { v2testing.Current(t) dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) v2netassert.Destination(dest).IsTCP() v2netassert.Destination(dest).IsNotUDP() assert.String(dest).Equals("tcp:1.2.3.4:80") }
func (request *Socks5Request) Destination() v2net.Destination { switch request.AddrType { case AddrTypeIPv4: return v2net.TCPDestination(v2net.IPAddress(request.IPv4[:]), request.Port) case AddrTypeIPv6: return v2net.TCPDestination(v2net.IPAddress(request.IPv6[:]), request.Port) case AddrTypeDomain: maybeIP := net.ParseIP(request.Domain) if maybeIP != nil { return v2net.TCPDestination(v2net.IPAddress(maybeIP), request.Port) } else { return v2net.TCPDestination(v2net.DomainAddress(request.Domain), request.Port) } default: panic("Unknown address type") } }
func TestTCPDestination(t *testing.T) { assert := assert.On(t) dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80) assert.Destination(dest).IsTCP() assert.Destination(dest).IsNotUDP() assert.Destination(dest).EqualsString("tcp:1.2.3.4:80") }
func TestIPRule(t *testing.T) { assert := assert.On(t) rule := ParseRule([]byte(`{ "type": "field", "ip": [ "10.0.0.0/8", "192.0.0.0/24" ], "network": "tcp", "outboundTag": "direct" }`)) assert.Pointer(rule).IsNotNil() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80))).IsFalse() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80))).IsTrue() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80))).IsFalse() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{192, 0, 0, 1}), 80))).IsTrue() }
func TestServerList(t *testing.T) { assert := assert.On(t) list := NewServerList() list.AddServer(NewServerSpec(v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(1)), AlwaysValid())) assert.Uint32(list.Size()).Equals(1) list.AddServer(NewServerSpec(v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(2)), BeforeTime(time.Now().Add(time.Second)))) assert.Uint32(list.Size()).Equals(2) server := list.GetServer(1) assert.Port(server.Destination().Port()).Equals(2) time.Sleep(2 * time.Second) server = list.GetServer(1) assert.Pointer(server).IsNil() server = list.GetServer(0) assert.Port(server.Destination().Port()).Equals(1) }
func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) { primary := protocol.NewID(cmd.ID) alters := protocol.NewAlterIDs(primary, cmd.AlterIds) account := &protocol.VMessAccount{ ID: primary, AlterIDs: alters, } user := protocol.NewUser(account, cmd.Level, "") dest := v2net.TCPDestination(cmd.Host, cmd.Port) this.receiverManager.AddDetour(NewReceiver(dest, user), cmd.ValidMin) }
func TestDomainRule(t *testing.T) { assert := assert.On(t) rule := ParseRule([]byte(`{ "type": "field", "domain": [ "ooxx.com", "oxox.com", "regexp:\\.cn$" ], "network": "tcp", "outboundTag": "direct" }`)) assert.Pointer(rule).IsNotNil() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80))).IsTrue() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.aabb.com"), 80))).IsFalse() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80))).IsFalse() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.12306.cn"), 80))).IsTrue() assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.acn.com"), 80))).IsFalse() }
func TestPortMatching(t *testing.T) { v2testing.Current(t) rule := &FieldRule{ Port: &v2nettesting.PortRange{ FromValue: 0, ToValue: 100, }, } dest := v2net.TCPDestination(v2net.DomainAddress("www.v2ray.com"), 80) assert.Bool(rule.Apply(dest)).IsTrue() }
func TestPortNotMatching(t *testing.T) { v2testing.Current(t) rawJson := `{ "type": "field", "port": "80-100", "tag": "test" }` rule := parseRule([]byte(rawJson)) dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 79) assert.Bool(rule.Apply(dest)).IsFalse() }
func TestIPListMatching(t *testing.T) { v2testing.Current(t) rawJson := `{ "type": "field", "ip": ["10.0.0.0/8", "192.168.0.0/16"], "tag": "test" }` rule := parseRule([]byte(rawJson)) dest := v2net.TCPDestination(v2net.IPAddress([]byte{192, 168, 1, 1}), 80) assert.Bool(rule.Apply(dest)).IsTrue() }
func (this *Config) UnmarshalJSON(data []byte) error { type RawConfigTarget struct { Address *v2net.AddressJson `json:"address"` Port v2net.Port `json:"port"` Users []json.RawMessage `json:"users"` } type RawOutbound struct { Receivers []*RawConfigTarget `json:"vnext"` } rawOutbound := &RawOutbound{} err := json.Unmarshal(data, rawOutbound) if err != nil { return errors.New("VMessOut: Failed to parse config: " + err.Error()) } if len(rawOutbound.Receivers) == 0 { log.Error("VMessOut: 0 VMess receiver configured.") return internal.ErrBadConfiguration } serverSpecs := make([]*protocol.ServerSpec, len(rawOutbound.Receivers)) for idx, rec := range rawOutbound.Receivers { if len(rec.Users) == 0 { log.Error("VMess: 0 user configured for VMess outbound.") return internal.ErrBadConfiguration } if rec.Address == nil { log.Error("VMess: Address is not set in VMess outbound config.") return internal.ErrBadConfiguration } if rec.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) { rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil)) } spec := protocol.NewServerSpec(v2net.TCPDestination(rec.Address.Address, rec.Port), protocol.AlwaysValid()) for _, rawUser := range rec.Users { user := new(protocol.User) if err := json.Unmarshal(rawUser, user); err != nil { log.Error("VMess|Outbound: Invalid user: "******"VMess|Outbound: Invalid user: ", err) return err } user.Account = account spec.AddUser(user) } serverSpecs[idx] = spec } this.Receivers = serverSpecs return nil }
func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error) { port := defaultPort host, rawPort, err := net.SplitHostPort(rawHost) if err != nil { if addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, "missing port") { host = rawHost } else { return nil, err } } else { intPort, err := strconv.Atoi(rawPort) if err != nil { return nil, err } port = v2net.Port(intPort) } if ip := net.ParseIP(host); ip != nil { return v2net.TCPDestination(v2net.IPAddress(ip), port), nil } return v2net.TCPDestination(v2net.DomainAddress(host), port), nil }
func (server *Server) Start() (v2net.Destination, error) { listener, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: []byte{0, 0, 0, 0}, Port: int(server.Port), Zone: "", }) if err != nil { return nil, err } go server.acceptConnections(listener) localAddr := listener.Addr().(*net.TCPAddr) return v2net.TCPDestination(v2net.IPAddress(localAddr.IP), v2net.Port(localAddr.Port)), nil }
func TestSimpleRouter(t *testing.T) { v2testing.Current(t) router := NewRouter().AddRule( &Rule{ Tag: "test", Condition: NewNetworkMatcher(v2net.Network("tcp").AsList()), }) tag, err := router.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80)) assert.Error(err).IsNil() assert.StringLiteral(tag).Equals("test") }
func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) { primary := protocol.NewID(cmd.ID) alters := protocol.NewAlterIDs(primary, cmd.AlterIds) account := &vmess.Account{ ID: primary, AlterIDs: alters, } user := protocol.NewUser(cmd.Level, "") user.Account = account dest := v2net.TCPDestination(cmd.Host, cmd.Port) until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute) this.serverList.AddServer(protocol.NewServerSpec(dest, protocol.BeforeTime(until), user)) }
func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) { defer conn.Close() var dest v2net.Destination if this.config.FollowRedirect { originalDest := GetOriginalDestination(conn) if originalDest != nil { log.Info("Dokodemo: Following redirect to: ", originalDest) dest = originalDest } } if dest == nil && this.address != nil && this.port > v2net.Port(0) { dest = v2net.TCPDestination(this.address, this.port) } if dest == nil { log.Info("Dokodemo: Unknown destination, stop forwarding...") return } log.Info("Dokodemo: Handling request to ", dest) ray := this.packetDispatcher.DispatchToOutbound(dest) defer ray.InboundOutput().Release() var inputFinish, outputFinish sync.Mutex inputFinish.Lock() outputFinish.Lock() reader := v2net.NewTimeOutReader(this.config.Timeout, conn) defer reader.Release() go func() { v2reader := v2io.NewAdaptiveReader(reader) defer v2reader.Release() v2io.Pipe(v2reader, ray.InboundInput()) inputFinish.Unlock() ray.InboundInput().Close() }() go func() { v2writer := v2io.NewAdaptiveWriter(conn) defer v2writer.Release() v2io.Pipe(ray.InboundOutput(), v2writer) outputFinish.Unlock() }() outputFinish.Lock() inputFinish.Lock() }
func TestTCPBind(t *testing.T) { v2testing.Current(t) targetPort := v2nettesting.PickPort() tcpServer := &tcp.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 := tcpServer.Start() assert.Error(err).IsNil() defer tcpServer.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(2), 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, 7, 0, 1, 0, 0, 0, 0, 0, 0}) conn.Close() CloseAllServers() }
func TestServerPicker(t *testing.T) { assert := assert.On(t) list := NewServerList() list.AddServer(NewServerSpec(v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(1)), AlwaysValid())) list.AddServer(NewServerSpec(v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(2)), BeforeTime(time.Now().Add(time.Second)))) list.AddServer(NewServerSpec(v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(3)), BeforeTime(time.Now().Add(time.Second)))) picker := NewRoundRobinServerPicker(list) server := picker.PickServer() assert.Port(server.Destination().Port()).Equals(1) server = picker.PickServer() assert.Port(server.Destination().Port()).Equals(2) server = picker.PickServer() assert.Port(server.Destination().Port()).Equals(3) server = picker.PickServer() assert.Port(server.Destination().Port()).Equals(1) time.Sleep(2 * time.Second) server = picker.PickServer() assert.Port(server.Destination().Port()).Equals(1) server = picker.PickServer() assert.Port(server.Destination().Port()).Equals(1) }
func TestUnreachableDestination(t *testing.T) { v2testing.Current(t) freedom := &FreedomConnection{} traffic := ray.NewRay() data2Send := "Data to be sent to remote" payload := alloc.NewSmallBuffer().Clear().Append([]byte(data2Send)) packet := v2net.NewPacket(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 128), payload, false) err := freedom.Dispatch(packet, traffic) assert.Error(err).IsNotNil() _, open := <-traffic.InboundOutput() assert.Bool(open).IsFalse() }
func TestDialWithLocalAddr(t *testing.T) { assert := assert.On(t) server := &tcp.Server{ Port: v2nettesting.PickPort(), } dest, err := server.Start() assert.Error(err).IsNil() defer server.Close() conn, err := DialToDest(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port())) assert.Error(err).IsNil() assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port().String()) conn.Close() }
func TestDialDomain(t *testing.T) { assert := assert.On(t) server := &tcp.Server{ Port: v2nettesting.PickPort(), } dest, err := server.Start() assert.Error(err).IsNil() defer server.Close() conn, err := DialToDest(nil, v2net.TCPDestination(v2net.DomainAddress("local.v2ray.com"), dest.Port())) assert.Error(err).IsNil() assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port().String()) conn.Close() }