Example #1
0
func (this *VMessInboundConfig) Build() (*loader.TypedSettings, error) {
	config := new(inbound.Config)

	if this.Defaults != nil {
		config.Default = this.Defaults.Build()
	}

	if this.DetourConfig != nil {
		config.Detour = this.DetourConfig.Build()
	} else if this.Features != nil && this.Features.Detour != nil {
		config.Detour = this.Features.Detour.Build()
	}

	config.User = make([]*protocol.User, len(this.Users))
	for idx, rawData := range this.Users {
		user := new(protocol.User)
		if err := json.Unmarshal(rawData, user); err != nil {
			return nil, errors.New("VMess|Inbound: Invalid user: "******"VMess|Inbound: Invalid user: " + err.Error())
		}
		user.Account = loader.NewTypedSettings(account.Build())
		config.User[idx] = user
	}

	return loader.NewTypedSettings(config), nil
}
Example #2
0
func (this *ShadowsocksServerConfig) Build() (*loader.TypedSettings, error) {
	config := new(shadowsocks.ServerConfig)
	config.UdpEnabled = this.UDP

	if len(this.Password) == 0 {
		return nil, errors.New("Shadowsocks password is not specified.")
	}
	account := &shadowsocks.Account{
		Password: this.Password,
		Ota:      shadowsocks.Account_Auto,
	}
	cipher := strings.ToLower(this.Cipher)
	switch cipher {
	case "aes-256-cfb":
		account.CipherType = shadowsocks.CipherType_AES_256_CFB
	case "aes-128-cfb":
		account.CipherType = shadowsocks.CipherType_AES_128_CFB
	case "chacha20":
		account.CipherType = shadowsocks.CipherType_CHACHA20
	case "chacha20-ietf":
		account.CipherType = shadowsocks.CipherType_CHACHA20_IEFT
	default:
		return nil, errors.New("Unknown cipher method: " + cipher)
	}

	config.User = &protocol.User{
		Email:   this.Email,
		Level:   uint32(this.Level),
		Account: loader.NewTypedSettings(account),
	}

	return loader.NewTypedSettings(config), nil
}
Example #3
0
func (this *ShadowsocksClientConfig) Build() (*loader.TypedSettings, error) {
	config := new(shadowsocks.ClientConfig)

	if len(this.Servers) == 0 {
		return nil, errors.New("0 Shadowsocks server configured.")
	}

	serverSpecs := make([]*protocol.ServerEndpoint, len(this.Servers))
	for idx, server := range this.Servers {
		if server.Address == nil {
			return nil, errors.New("Shadowsocks server address is not set.")
		}
		if server.Port == 0 {
			return nil, errors.New("Invalid Shadowsocks port.")
		}
		if len(server.Password) == 0 {
			return nil, errors.New("Shadowsocks password is not specified.")
		}
		account := &shadowsocks.Account{
			Password: server.Password,
			Ota:      shadowsocks.Account_Enabled,
		}
		if !server.Ota {
			account.Ota = shadowsocks.Account_Disabled
		}
		cipher := strings.ToLower(server.Cipher)
		switch cipher {
		case "aes-256-cfb":
			account.CipherType = shadowsocks.CipherType_AES_256_CFB
		case "aes-128-cfb":
			account.CipherType = shadowsocks.CipherType_AES_128_CFB
		case "chacha20":
			account.CipherType = shadowsocks.CipherType_CHACHA20
		case "chacha20-ietf":
			account.CipherType = shadowsocks.CipherType_CHACHA20_IEFT
		default:
			return nil, errors.New("Unknown cipher method: " + cipher)
		}

		ss := &protocol.ServerEndpoint{
			Address: server.Address.Build(),
			Port:    uint32(server.Port),
			User: []*protocol.User{
				{
					Email:   server.Email,
					Account: loader.NewTypedSettings(account),
				},
			},
		}

		serverSpecs[idx] = ss
	}

	config.Server = serverSpecs

	return loader.NewTypedSettings(config), nil
}
Example #4
0
func TestUDPEncoding(t *testing.T) {
	assert := assert.On(t)

	request := &protocol.RequestHeader{
		Version: Version,
		Command: protocol.RequestCommandUDP,
		Address: v2net.LocalHostIP,
		Port:    1234,
		User: &protocol.User{
			Email: "*****@*****.**",
			Account: loader.NewTypedSettings(&Account{
				Password:   "******",
				CipherType: CipherType_AES_128_CFB,
				Ota:        Account_Disabled,
			}),
		},
	}

	data := alloc.NewLocalBuffer(256).Clear().AppendString("test string")
	encodedData, err := EncodeUDPPacket(request, data)
	assert.Error(err).IsNil()

	decodedRequest, decodedData, err := DecodeUDPPacket(request.User, encodedData)
	assert.Error(err).IsNil()
	assert.Bytes(decodedData.Value).Equals(data.Value)
	assert.Address(decodedRequest.Address).Equals(request.Address)
	assert.Port(decodedRequest.Port).Equals(request.Port)
}
Example #5
0
func (this *SocksServerConfig) Build() (*loader.TypedSettings, error) {
	config := new(socks.ServerConfig)
	if this.AuthMethod == AuthMethodNoAuth {
		config.AuthType = socks.AuthType_NO_AUTH
	} else if this.AuthMethod == AuthMethodUserPass {
		config.AuthType = socks.AuthType_PASSWORD
	} else {
		return nil, errors.New("Unknown socks auth method: " + this.AuthMethod)
	}

	if len(this.Accounts) > 0 {
		config.Accounts = make(map[string]string, len(this.Accounts))
		for _, account := range this.Accounts {
			config.Accounts[account.Username] = account.Password
		}
	}

	config.UdpEnabled = this.UDP
	if this.Host != nil {
		config.Address = this.Host.Build()
	}

	config.Timeout = this.Timeout
	return loader.NewTypedSettings(config), nil
}
Example #6
0
func (this *HttpServerConfig) Build() (*loader.TypedSettings, error) {
	config := &http.ServerConfig{
		Timeout: this.Timeout,
	}

	return loader.NewTypedSettings(config), nil
}
Example #7
0
func (this *userByEmail) Get(email string) (*protocol.User, bool) {
	var user *protocol.User
	var found bool
	this.RLock()
	user, found = this.cache[email]
	this.RUnlock()
	if !found {
		this.Lock()
		user, found = this.cache[email]
		if !found {
			account := &vmess.Account{
				Id:      uuid.New().String(),
				AlterId: uint32(this.defaultAlterIDs),
			}
			user = &protocol.User{
				Level:   this.defaultLevel,
				Email:   email,
				Account: loader.NewTypedSettings(account),
			}
			this.cache[email] = user
		}
		this.Unlock()
	}
	return user, found
}
Example #8
0
func TestTCPRequest(t *testing.T) {
	assert := assert.On(t)

	request := &protocol.RequestHeader{
		Version: Version,
		Command: protocol.RequestCommandTCP,
		Address: v2net.LocalHostIP,
		Option:  RequestOptionOneTimeAuth,
		Port:    1234,
		User: &protocol.User{
			Email: "*****@*****.**",
			Account: loader.NewTypedSettings(&Account{
				Password:   "******",
				CipherType: CipherType_CHACHA20,
			}),
		},
	}

	data := alloc.NewLocalBuffer(256).Clear().AppendString("test string")
	cache := alloc.NewBuffer().Clear()

	writer, err := WriteTCPRequest(request, cache)
	assert.Error(err).IsNil()

	writer.Write(data)

	decodedRequest, reader, err := ReadTCPSession(request.User, cache)
	assert.Error(err).IsNil()
	assert.Address(decodedRequest.Address).Equals(request.Address)
	assert.Port(decodedRequest.Port).Equals(request.Port)

	decodedData, err := reader.Read()
	assert.Error(err).IsNil()
	assert.Bytes(decodedData.Value).Equals([]byte("test string"))
}
func (this *KCPConfig) Build() (*loader.TypedSettings, error) {
	config := new(kcp.Config)

	if this.Mtu != nil {
		mtu := *this.Mtu
		if mtu < 576 || mtu > 1460 {
			return nil, fmt.Errorf("KCP|Config: Invalid MTU size: %d", mtu)
		}
		config.Mtu = &kcp.MTU{Value: mtu}
	}
	if this.Tti != nil {
		tti := *this.Tti
		if tti < 10 || tti > 100 {
			return nil, fmt.Errorf("KCP|Config: Invalid TTI: %d", tti)
		}
		config.Tti = &kcp.TTI{Value: tti}
	}
	if this.UpCap != nil {
		config.UplinkCapacity = &kcp.UplinkCapacity{Value: *this.UpCap}
	}
	if this.DownCap != nil {
		config.DownlinkCapacity = &kcp.DownlinkCapacity{Value: *this.DownCap}
	}
	if this.Congestion != nil {
		config.Congestion = *this.Congestion
	}
	if this.ReadBufferSize != nil {
		size := *this.ReadBufferSize
		if size > 0 {
			config.ReadBuffer = &kcp.ReadBuffer{Size: size * 1024 * 1024}
		} else {
			config.ReadBuffer = &kcp.ReadBuffer{Size: 512 * 1024}
		}
	}
	if this.WriteBufferSize != nil {
		size := *this.WriteBufferSize
		if size > 0 {
			config.WriteBuffer = &kcp.WriteBuffer{Size: size * 1024 * 1024}
		} else {
			config.WriteBuffer = &kcp.WriteBuffer{Size: 512 * 1024}
		}
	}
	if len(this.HeaderConfig) > 0 {
		headerConfig, _, err := kcpHeaderLoader.Load(this.HeaderConfig)
		if err != nil {
			return nil, errors.New("KCP|Config: Failed to parse header config: " + err.Error())
		}
		ts, err := headerConfig.(Buildable).Build()
		if err != nil {
			return nil, errors.New("Failed to get KCP authenticator config: " + err.Error())
		}
		config.HeaderConfig = ts
	}

	return loader.NewTypedSettings(config), nil
}
Example #10
0
func (this *FreedomConfig) Build() (*loader.TypedSettings, error) {
	config := new(freedom.Config)
	config.DomainStrategy = freedom.Config_AS_IS
	domainStrategy := strings.ToLower(this.DomainStrategy)
	if domainStrategy == "useip" || domainStrategy == "use_ip" {
		config.DomainStrategy = freedom.Config_USE_IP
	}
	config.Timeout = this.Timeout
	return loader.NewTypedSettings(config), nil
}
Example #11
0
func (this *DokodemoConfig) Build() (*loader.TypedSettings, error) {
	config := new(dokodemo.Config)
	if this.Host != nil {
		config.Address = this.Host.Build()
	}
	config.Port = uint32(this.PortValue)
	config.NetworkList = this.NetworkList.Build()
	config.Timeout = this.TimeoutValue
	config.FollowRedirect = this.Redirect
	return loader.NewTypedSettings(config), nil
}
Example #12
0
func (this *WebSocketConfig) Build() (*loader.TypedSettings, error) {
	config := &ws.Config{
		Path: this.Path,
	}
	if this.ConnectionReuse != nil {
		config.ConnectionReuse = &ws.ConnectionReuse{
			Enable: *this.ConnectionReuse,
		}
	}
	return loader.NewTypedSettings(config), nil
}
Example #13
0
func (this *VMessOutboundConfig) Build() (*loader.TypedSettings, error) {
	config := new(outbound.Config)

	if len(this.Receivers) == 0 {
		return nil, errors.New("0 VMess receiver configured.")
	}
	serverSpecs := make([]*protocol.ServerEndpoint, len(this.Receivers))
	for idx, rec := range this.Receivers {
		if len(rec.Users) == 0 {
			return nil, errors.New("0 user configured for VMess outbound.")
		}
		if rec.Address == nil {
			return nil, errors.New("Address is not set in VMess outbound config.")
		}
		if rec.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
			rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(757086633, nil))
		}
		spec := &protocol.ServerEndpoint{
			Address: rec.Address.Build(),
			Port:    uint32(rec.Port),
		}
		for _, rawUser := range rec.Users {
			user := new(protocol.User)
			if err := json.Unmarshal(rawUser, user); err != nil {
				return nil, errors.New("VMess|Outbound: Invalid user: "******"VMess|Outbound: Invalid user: " + err.Error())
			}
			user.Account = loader.NewTypedSettings(account.Build())
			spec.User = append(spec.User, user)
		}
		serverSpecs[idx] = spec
	}
	config.Receiver = serverSpecs
	return loader.NewTypedSettings(config), nil
}
Example #14
0
func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
	account := &vmess.Account{
		Id:      cmd.ID.String(),
		AlterId: uint32(cmd.AlterIds),
	}

	user := &protocol.User{
		Email:   "",
		Level:   cmd.Level,
		Account: loader.NewTypedSettings(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))
}
Example #15
0
func (this *SocksClientConfig) Build() (*loader.TypedSettings, error) {
	config := new(socks.ClientConfig)
	config.Server = make([]*protocol.ServerEndpoint, len(this.Servers))
	for idx, serverConfig := range this.Servers {
		server := &protocol.ServerEndpoint{
			Address: serverConfig.Address.Build(),
			Port:    uint32(serverConfig.Port),
		}
		for _, rawUser := range serverConfig.Users {
			user := new(protocol.User)
			if err := json.Unmarshal(rawUser, user); err != nil {
				return nil, errors.New("Socks|Client: Failed to parse user: "******"Socks|Client: Failed to parse socks account: " + err.Error())
			}
			user.Account = loader.NewTypedSettings(account.Build())
			server.User = append(server.User, user)
		}
		config.Server[idx] = server
	}
	return loader.NewTypedSettings(config), nil
}
Example #16
0
func (this *BlackholeConfig) Build() (*loader.TypedSettings, error) {
	config := new(blackhole.Config)
	if this.Response != nil {
		response, _, err := configLoader.Load(this.Response)
		if err != nil {
			return nil, errors.New("Blackhole: Failed to parse response config: " + err.Error())
		}
		responseSettings, err := response.(Buildable).Build()
		if err != nil {
			return nil, err
		}
		config.Response = responseSettings
	}

	return loader.NewTypedSettings(config), nil
}
func (this *HTTPAuthenticator) Build() (*loader.TypedSettings, error) {
	config := new(http.Config)
	requestConfig, err := this.Request.Build()
	if err != nil {
		return nil, err
	}
	config.Request = requestConfig

	responseConfig, err := this.Response.Build()
	if err != nil {
		return nil, err
	}
	config.Response = responseConfig

	return loader.NewTypedSettings(config), nil
}
Example #18
0
func (this *TLSConfig) Build() (*loader.TypedSettings, error) {
	config := new(tls.Config)
	config.Certificate = make([]*tls.Certificate, len(this.Certs))
	for idx, certConf := range this.Certs {
		cert, err := ioutil.ReadFile(certConf.CertFile)
		if err != nil {
			return nil, errors.New("TLS: Failed to load certificate file: " + err.Error())
		}
		key, err := ioutil.ReadFile(certConf.KeyFile)
		if err != nil {
			return nil, errors.New("TLS: Failed to load key file: " + err.Error())
		}
		config.Certificate[idx] = &tls.Certificate{
			Key:         key,
			Certificate: cert,
		}
	}
	config.AllowInsecure = this.Insecure
	return loader.NewTypedSettings(config), nil
}
Example #19
0
func (this *TCPConfig) Build() (*loader.TypedSettings, error) {
	config := new(tcp.Config)
	if this.ConnectionReuse != nil {
		config.ConnectionReuse = &tcp.ConnectionReuse{
			Enable: *this.ConnectionReuse,
		}
	}
	if len(this.HeaderConfig) > 0 {
		headerConfig, _, err := tcpHeaderLoader.Load(this.HeaderConfig)
		if err != nil {
			return nil, errors.New("TCP|Config: Failed to parse header config: " + err.Error())
		}
		ts, err := headerConfig.(Buildable).Build()
		if err != nil {
			return nil, errors.New("Failed to get TCP authenticator config: " + err.Error())
		}
		config.HeaderSettings = ts
	}

	return loader.NewTypedSettings(config), nil
}
Example #20
0
func TestUDPReaderWriter(t *testing.T) {
	assert := assert.On(t)

	user := &protocol.User{
		Account: loader.NewTypedSettings(&Account{
			Password:   "******",
			CipherType: CipherType_CHACHA20_IEFT,
		}),
	}
	cache := alloc.NewBuffer().Clear()
	writer := &UDPWriter{
		Writer: cache,
		Request: &protocol.RequestHeader{
			Version: Version,
			Address: v2net.DomainAddress("v2ray.com"),
			Port:    123,
			User:    user,
			Option:  RequestOptionOneTimeAuth,
		},
	}

	reader := &UDPReader{
		Reader: cache,
		User:   user,
	}

	err := writer.Write(alloc.NewBuffer().Clear().AppendString("test payload"))
	assert.Error(err).IsNil()

	payload, err := reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload")

	err = writer.Write(alloc.NewBuffer().Clear().AppendString("test payload 2"))
	assert.Error(err).IsNil()

	payload, err = reader.Read()
	assert.Error(err).IsNil()
	assert.String(payload.String()).Equals("test payload 2")
}
Example #21
0
func TestRequestSerialization(t *testing.T) {
	assert := assert.On(t)

	user := &protocol.User{
		Level: 0,
		Email: "*****@*****.**",
	}
	account := &vmess.Account{
		Id:      uuid.New().String(),
		AlterId: 0,
	}
	user.Account = loader.NewTypedSettings(account)

	expectedRequest := &protocol.RequestHeader{
		Version: 1,
		User:    user,
		Command: protocol.RequestCommandTCP,
		Option:  protocol.RequestOption(0),
		Address: v2net.DomainAddress("www.v2ray.com"),
		Port:    v2net.Port(443),
	}

	buffer := alloc.NewBuffer().Clear()
	client := NewClientSession(protocol.DefaultIDHash)
	client.EncodeRequestHeader(expectedRequest, buffer)

	userValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
	userValidator.Add(user)

	server := NewServerSession(userValidator)
	actualRequest, err := server.DecodeRequestHeader(buffer)
	assert.Error(err).IsNil()

	assert.Byte(expectedRequest.Version).Equals(actualRequest.Version)
	assert.Byte(byte(expectedRequest.Command)).Equals(byte(actualRequest.Command))
	assert.Byte(byte(expectedRequest.Option)).Equals(byte(actualRequest.Option))
	assert.Address(expectedRequest.Address).Equals(actualRequest.Address)
	assert.Port(expectedRequest.Port).Equals(actualRequest.Port)
}
Example #22
0
func Test_listenWSAndDial_TLS(t *testing.T) {
	assert := assert.On(t)
	go func() {
		<-time.After(time.Second * 5)
		assert.Fail("Too slow")
	}()
	tlsSettings := &v2tls.Config{
		AllowInsecure: true,
		Certificate: []*v2tls.Certificate{
			{
				Certificate: ReadFile("./../../../testing/tls/cert.pem", assert),
				Key:         ReadFile("./../../../testing/tls/key.pem", assert),
			},
		},
	}

	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143, internet.ListenOptions{
		Stream: &internet.StreamConfig{
			SecurityType:     loader.GetType(new(v2tls.Config)),
			SecuritySettings: []*loader.TypedSettings{loader.NewTypedSettings(tlsSettings)},
			Network:          v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "wss",
						ConnectionReuse: &ConnectionReuse{
							Enable: true,
						},
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	go func() {
		conn, err := listen.Accept()
		assert.Error(err).IsNil()
		conn.Close()
		listen.Close()
	}()
	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{
		Stream: &internet.StreamConfig{
			SecurityType:     loader.GetType(new(v2tls.Config)),
			SecuritySettings: []*loader.TypedSettings{loader.NewTypedSettings(tlsSettings)},
			Network:          v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "wss",
						ConnectionReuse: &ConnectionReuse{
							Enable: true,
						},
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	conn.Close()
}
Example #23
0
func Test_listenWSAndDial(t *testing.T) {
	assert := assert.On(t)
	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13146, internet.ListenOptions{
		Stream: &internet.StreamConfig{
			Network: v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "ws",
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	go func() {
		conn, err := listen.Accept()
		assert.Error(err).IsNil()
		conn.Close()
		conn, err = listen.Accept()
		assert.Error(err).IsNil()
		conn.Close()
		conn, err = listen.Accept()
		assert.Error(err).IsNil()
		conn.Close()
		listen.Close()
	}()
	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13146), internet.DialerOptions{
		Stream: &internet.StreamConfig{
			Network: v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "ws",
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	conn.Close()
	<-time.After(time.Second * 5)
	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13146), internet.DialerOptions{
		Stream: &internet.StreamConfig{
			Network: v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "ws",
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	conn.Close()
	<-time.After(time.Second * 15)
	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13146), internet.DialerOptions{
		Stream: &internet.StreamConfig{
			Network: v2net.Network_WebSocket,
			NetworkSettings: []*internet.NetworkSettings{
				{
					Network: v2net.Network_WebSocket,
					Settings: loader.NewTypedSettings(&Config{
						Path: "ws",
					}),
				},
			},
		},
	})
	assert.Error(err).IsNil()
	conn.Close()
}
func (UTPAuthenticator) Build() (*loader.TypedSettings, error) {
	return loader.NewTypedSettings(new(utp.Config)), nil
}
Example #25
0
func (*HttpResponse) Build() (*loader.TypedSettings, error) {
	return loader.NewTypedSettings(new(blackhole.HTTPResponse)), nil
}
Example #26
0
func (this *Config) Build() (*core.Config, error) {
	config := new(core.Config)

	if this.LogConfig != nil {
		config.Log = this.LogConfig.Build()
	}

	if this.Transport != nil {
		ts, err := this.Transport.Build()
		if err != nil {
			return nil, err
		}
		config.Transport = ts
	}

	if this.RouterConfig != nil {
		routerConfig, err := this.RouterConfig.Build()
		if err != nil {
			return nil, err
		}
		config.App = append(config.App, loader.NewTypedSettings(routerConfig))
	}

	if this.DNSConfig != nil {
		config.App = append(config.App, loader.NewTypedSettings(this.DNSConfig.Build()))
	}

	if this.InboundConfig == nil {
		return nil, errors.New("No inbound config specified.")
	}

	if this.InboundConfig.Port == 0 && this.Port > 0 {
		this.InboundConfig.Port = this.Port
	}

	ic, err := this.InboundConfig.Build()
	if err != nil {
		return nil, err
	}
	config.Inbound = append(config.Inbound, ic)

	for _, rawInboundConfig := range this.InboundDetours {
		ic, err := rawInboundConfig.Build()
		if err != nil {
			return nil, err
		}
		config.Inbound = append(config.Inbound, ic)
	}

	oc, err := this.OutboundConfig.Build()
	if err != nil {
		return nil, err
	}
	config.Outbound = append(config.Outbound, oc)

	for _, rawOutboundConfig := range this.OutboundDetours {
		oc, err := rawOutboundConfig.Build()
		if err != nil {
			return nil, err
		}
		config.Outbound = append(config.Outbound, oc)
	}

	return config, nil
}
Example #27
0
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: loader.NewTypedSettings(&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: loader.NewTypedSettings(&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()
	time.Sleep(15 * time.Second)
	assert.Int(listerner.ActiveConnections()).Equals(0)

	listerner.Close()
}
func (NoOpConnectionAuthenticator) Build() (*loader.TypedSettings, error) {
	return loader.NewTypedSettings(new(noop.Config)), nil
}