Ejemplo n.º 1
0
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()
}
Ejemplo n.º 2
0
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}))
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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,
		})
	}
}
Ejemplo n.º 5
0
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,
		})
	}
}
Ejemplo n.º 6
0
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")
}
Ejemplo n.º 7
0
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{}
}
Ejemplo n.º 8
0
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)
}
Ejemplo n.º 9
0
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)
}
Ejemplo n.º 10
0
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
}
Ejemplo n.º 11
0
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
}
Ejemplo n.º 12
0
// 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
}
Ejemplo n.º 13
0
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
}
Ejemplo n.º 14
0
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
}
Ejemplo n.º 15
0
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
}
Ejemplo n.º 16
0
// 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
}
Ejemplo n.º 17
0
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()
		}()
	}
}
Ejemplo n.º 18
0
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)
	}
}
Ejemplo n.º 19
0
func (request *Socks5UDPRequest) Destination() v2net.Destination {
	return v2net.UDPDestination(request.Address, request.Port)
}
Ejemplo n.º 20
0
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()
}
Ejemplo n.º 21
0
	"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
}
Ejemplo n.º 22
0
func (this *RequestHeader) Destination() v2net.Destination {
	if this.Command == RequestCommandUDP {
		return v2net.UDPDestination(this.Address, this.Port)
	}
	return v2net.TCPDestination(this.Address, this.Port)
}
Ejemplo n.º 23
0
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)
	})
}
Ejemplo n.º 24
0
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()
}
Ejemplo n.º 25
0
func (v *RequestHeader) Destination() v2net.Destination {
	if v.Command == RequestCommandUDP {
		return v2net.UDPDestination(v.Address, v.Port)
	}
	return v2net.TCPDestination(v.Address, v.Port)
}
Ejemplo n.º 26
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: 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()
}