コード例 #1
0
ファイル: output.go プロジェクト: ChoyesYan/v2ray-core
func (this *AuthenticationWriter) Write(payload *alloc.Buffer) error {
	defer payload.Release()

	this.Authenticator.Seal(payload)
	_, err := this.Writer.Write(payload.Value)
	return err
}
コード例 #2
0
func (this *OutboundConnectionHandler) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	this.Destination = destination
	this.ConnOutput.Write(payload.Value)
	payload.Release()

	writeFinish := &sync.Mutex{}

	writeFinish.Lock()

	go func() {
		v2writer := v2io.NewAdaptiveWriter(this.ConnOutput)
		defer v2writer.Release()

		v2io.Pipe(input, v2writer)
		writeFinish.Unlock()
		input.Release()
	}()

	writeFinish.Lock()

	v2reader := v2io.NewAdaptiveReader(this.ConnInput)
	defer v2reader.Release()

	v2io.Pipe(v2reader, output)
	output.Close()

	return nil
}
コード例 #3
0
ファイル: dokodemo.go プロジェクト: ChoyesYan/v2ray-core
func (this *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) {
	defer payload.Release()
	this.udpMutex.RLock()
	defer this.udpMutex.RUnlock()
	if !this.accepting {
		return
	}
	this.udpHub.WriteTo(payload.Value, dest)
}
コード例 #4
0
ファイル: blackhole.go プロジェクト: ChoyesYan/v2ray-core
func (this *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	payload.Release()

	this.response.WriteTo(ray.OutboundOutput())
	ray.OutboundOutput().Close()

	ray.OutboundInput().Release()

	return nil
}
コード例 #5
0
ファイル: writer.go プロジェクト: ChoyesYan/v2ray-core
// Write implements Writer.Write(). Write() takes ownership of the given buffer.
func (this *AdaptiveWriter) Write(buffer *alloc.Buffer) error {
	defer buffer.Release()
	for !buffer.IsEmpty() {
		nBytes, err := this.writer.Write(buffer.Value)
		if err != nil {
			return err
		}
		buffer.SliceFrom(nBytes)
	}
	return nil
}
コード例 #6
0
ファイル: listener.go プロジェクト: ChoyesYan/v2ray-core
func (this *Listener) OnReceive(payload *alloc.Buffer, src v2net.Destination) {
	defer payload.Release()

	if valid := this.block.Open(payload); !valid {
		log.Info("KCP|Listener: discarding invalid payload from ", src)
		return
	}
	if !this.running {
		return
	}
	this.Lock()
	defer this.Unlock()
	if !this.running {
		return
	}
	if payload.Len() < 4 {
		return
	}
	conv := serial.BytesToUint16(payload.Value)
	cmd := Command(payload.Value[2])
	sourceId := src.NetAddr() + "|" + serial.Uint16ToString(conv)
	conn, found := this.sessions[sourceId]
	if !found {
		if cmd == CommandTerminate {
			return
		}
		log.Debug("KCP|Listener: Creating session with id(", sourceId, ") from ", src)
		writer := &Writer{
			id:       sourceId,
			hub:      this.hub,
			dest:     src,
			listener: this,
		}
		srcAddr := &net.UDPAddr{
			IP:   src.Address().IP(),
			Port: int(src.Port()),
		}
		conn = NewConnection(conv, writer, this.localAddr, srcAddr, this.block)
		select {
		case this.awaitingConns <- conn:
		case <-time.After(time.Second * 5):
			conn.Close()
			return
		}
		this.sessions[sourceId] = conn
	}
	conn.Input(payload.Value)
}
コード例 #7
0
ファイル: udp.go プロジェクト: yorkzhy/v2ray-core
func (this *SocksServer) handleUDPPayload(payload *alloc.Buffer, source v2net.Destination) {
	log.Info("Socks: Client UDP connection from ", source)
	request, err := protocol.ReadUDPRequest(payload.Value)
	payload.Release()

	if err != nil {
		log.Error("Socks: Failed to parse UDP request: ", err)
		return
	}
	if request.Data.Len() == 0 {
		request.Data.Release()
		return
	}
	if request.Fragment != 0 {
		log.Warning("Socks: Dropping fragmented UDP packets.")
		// TODO handle fragments
		request.Data.Release()
		return
	}

	udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
	log.Info("Socks: Send packet to ", udpPacket.Destination(), " with ", request.Data.Len(), " bytes")
	this.udpServer.Dispatch(source, 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.udpHub.WriteTo(udpMessage.Value, packet.Destination())
		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)
		}
	})
}
コード例 #8
0
ファイル: server.go プロジェクト: xiaomotou/v2ray-core
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)
	})
}
コード例 #9
0
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)
	})
}
コード例 #10
0
ファイル: reader.go プロジェクト: ChoyesYan/v2ray-core
func (this *AuthChunkReader) Read() (*alloc.Buffer, error) {
	var buffer *alloc.Buffer
	if this.last != nil {
		buffer = this.last
		this.last = nil
	} else {
		buffer = alloc.NewBufferWithSize(4096).Clear()
	}

	if this.chunkLength == -1 {
		for buffer.Len() < 6 {
			_, err := buffer.FillFrom(this.reader)
			if err != nil {
				buffer.Release()
				return nil, io.ErrUnexpectedEOF
			}
		}
		length := serial.BytesToUint16(buffer.Value[:2])
		this.chunkLength = int(length) - 4
		this.validator = NewValidator(serial.BytesToUint32(buffer.Value[2:6]))
		buffer.SliceFrom(6)
		if buffer.Len() < this.chunkLength && this.chunkLength <= 2048 {
			_, err := buffer.FillFrom(this.reader)
			if err != nil {
				buffer.Release()
				return nil, io.ErrUnexpectedEOF
			}
		}
	} else if buffer.Len() < this.chunkLength {
		_, err := buffer.FillFrom(this.reader)
		if err != nil {
			buffer.Release()
			return nil, io.ErrUnexpectedEOF
		}
	}

	if this.chunkLength == 0 {
		buffer.Release()
		return nil, io.EOF
	}

	if buffer.Len() < this.chunkLength {
		this.validator.Consume(buffer.Value)
		this.chunkLength -= buffer.Len()
	} else {
		this.validator.Consume(buffer.Value[:this.chunkLength])
		if !this.validator.Validate() {
			buffer.Release()
			return nil, transport.ErrCorruptedPacket
		}
		leftLength := buffer.Len() - this.chunkLength
		if leftLength > 0 {
			this.last = alloc.NewBufferWithSize(leftLength + 4096).Clear()
			this.last.Append(buffer.Value[this.chunkLength:])
			buffer.Slice(0, this.chunkLength)
		}

		this.chunkLength = -1
		this.validator = nil
	}

	return buffer, nil
}
コード例 #11
0
ファイル: freedom.go プロジェクト: ChoyesYan/v2ray-core
func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	log.Info("Freedom: Opening connection to ", destination)

	defer payload.Release()
	defer ray.OutboundInput().Release()
	defer ray.OutboundOutput().Close()

	var conn internet.Connection
	if this.domainStrategy == DomainStrategyUseIP && destination.Address().IsDomain() {
		destination = this.ResolveIP(destination)
	}
	err := retry.Timed(5, 100).On(func() error {
		rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.StreamSettings)
		if err != nil {
			return err
		}
		conn = rawConn
		return nil
	})
	if err != nil {
		log.Warning("Freedom: Failed to open connection to ", destination, ": ", err)
		return err
	}
	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	var readMutex, writeMutex sync.Mutex
	readMutex.Lock()
	writeMutex.Lock()

	conn.Write(payload.Value)

	go func() {
		v2writer := v2io.NewAdaptiveWriter(conn)
		defer v2writer.Release()

		v2io.Pipe(input, v2writer)
		writeMutex.Unlock()
	}()

	go func() {
		defer readMutex.Unlock()

		var reader io.Reader = conn

		timeout := this.timeout
		if destination.IsUDP() {
			timeout = 16
		}
		if timeout > 0 {
			reader = v2net.NewTimeOutReader(int(timeout) /* seconds */, conn)
		}

		v2reader := v2io.NewAdaptiveReader(reader)
		defer v2reader.Release()

		v2io.Pipe(v2reader, output)
		ray.OutboundOutput().Close()
	}()

	writeMutex.Lock()
	if tcpConn, ok := conn.(*tcp.RawConnection); ok {
		tcpConn.CloseWrite()
	}
	readMutex.Lock()

	return nil
}