Beispiel #1
1
func (server *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth protocol.Socks4AuthenticationRequest) error {
	result := protocol.Socks4RequestGranted
	if auth.Command == protocol.CmdBind {
		result = protocol.Socks4RequestRejected
	}
	socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])

	responseBuffer := alloc.NewSmallBuffer().Clear()
	socks4Response.Write(responseBuffer)
	writer.Write(responseBuffer.Value)
	responseBuffer.Release()

	if result == protocol.Socks4RequestRejected {
		log.Warning("Unsupported socks 4 command %d", auth.Command)
		return UnsupportedSocksCommand
	}

	dest := v2net.NewTCPDestination(v2net.IPAddress(auth.IP[:], auth.Port))
	data, err := v2net.ReadFrom(reader, nil)
	if err != nil {
		return err
	}

	packet := v2net.NewPacket(dest, data, true)
	server.transport(reader, writer, packet)
	return nil
}
Beispiel #2
0
func (this *Server) handleConnection(conn internet.Connection) {
	defer conn.Close()
	timedReader := v2net.NewTimeOutReader(this.config.Timeout, conn)
	reader := bufio.NewReaderSize(timedReader, 2048)

	request, err := http.ReadRequest(reader)
	if err != nil {
		if err != io.EOF {
			log.Warning("HTTP: Failed to read http request: ", err)
		}
		return
	}
	log.Info("HTTP: Request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]")
	defaultPort := v2net.Port(80)
	if strings.ToLower(request.URL.Scheme) == "https" {
		defaultPort = v2net.Port(443)
	}
	host := request.Host
	if len(host) == 0 {
		host = request.URL.Host
	}
	dest, err := parseHost(host, defaultPort)
	if err != nil {
		log.Warning("HTTP: Malformed proxy host (", host, "): ", err)
		return
	}
	log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
	if strings.ToUpper(request.Method) == "CONNECT" {
		this.handleConnect(request, dest, reader, conn)
	} else {
		this.handlePlainHTTP(request, dest, reader, conn)
	}
}
Beispiel #3
0
func (handler *VMessInboundHandler) AcceptPackets(conn *net.UDPConn) {
	for {
		buffer := make([]byte, bufferSize)
		nBytes, addr, err := conn.ReadFromUDP(buffer)
		if err != nil {
			log.Error("VMessIn failed to read UDP packets: %v", err)
			continue
		}

		reader := bytes.NewReader(buffer[:nBytes])
		requestReader := protocol.NewVMessRequestReader(handler.clients)

		request, err := requestReader.Read(reader)
		if err != nil {
			log.Warning("VMessIn: Invalid request from (%s): %v", addr.String(), err)
			continue
		}

		cryptReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader)
		if err != nil {
			log.Error("VMessIn: Failed to create decrypt reader: %v", err)
			continue
		}

		data := make([]byte, bufferSize)
		nBytes, err = cryptReader.Read(data)
		if err != nil {
			log.Warning("VMessIn: Unable to decrypt data: %v", err)
			continue
		}

		packet := v2net.NewPacket(request.Destination(), data[:nBytes], false)
		go handler.handlePacket(conn, request, packet, addr)
	}
}
Beispiel #4
0
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmdId byte, data []byte) {
	if len(data) < 4 {
		return
	}
	fnv1hash := fnv.New32a()
	fnv1hash.Write(data[4:])
	actualHashValue := fnv1hash.Sum32()
	expectedHashValue := serial.BytesLiteral(data[:4]).Uint32Value()
	if actualHashValue != expectedHashValue {
		return
	}
	data = data[4:]
	cmd, err := command.CreateResponseCommand(cmdId)
	if err != nil {
		log.Warning("VMessOut: Unknown response command (", cmdId, "): ", err)
		return
	}
	if err := cmd.Unmarshal(data); err != nil {
		log.Warning("VMessOut: Failed to parse response command: ", err)
		return
	}
	switch typedCommand := cmd.(type) {
	case *command.SwitchAccount:
		if typedCommand.Host == nil {
			typedCommand.Host = dest.Address()
		}
		this.handleSwitchAccount(typedCommand)
	default:
	}
}
Beispiel #5
0
func (this *HttpProxyServer) handleConnection(conn *hub.TCPConn) {
	defer conn.Close()
	reader := bufio.NewReader(conn)

	request, err := http.ReadRequest(reader)
	if err != nil {
		log.Warning("Failed to read http request: ", err)
		return
	}
	log.Info("Request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]")
	defaultPort := v2net.Port(80)
	if strings.ToLower(request.URL.Scheme) == "https" {
		defaultPort = v2net.Port(443)
	}
	host := request.Host
	if len(host) == 0 {
		host = request.URL.Host
	}
	dest, err := parseHost(host, defaultPort)
	if err != nil {
		log.Warning("Malformed proxy host (", host, "): ", err)
		return
	}
	if strings.ToUpper(request.Method) == "CONNECT" {
		this.handleConnect(request, dest, reader, conn)
	} else {
		this.handlePlainHTTP(request, dest, reader, conn)
	}
}
Beispiel #6
0
func ReadVMessUDP(buffer []byte, userset user.UserSet) (*VMessUDP, error) {
	userHash := buffer[:user.IDBytesLen]
	userId, timeSec, valid := userset.GetUser(userHash)
	if !valid {
		return nil, errors.NewAuthenticationError(userHash)
	}

	buffer = buffer[user.IDBytesLen:]
	aesCipher, err := aes.NewCipher(userId.CmdKey())
	if err != nil {
		return nil, err
	}
	aesStream := cipher.NewCFBDecrypter(aesCipher, user.Int64Hash(timeSec))
	aesStream.XORKeyStream(buffer, buffer)

	fnvHash := binary.BigEndian.Uint32(buffer[:4])
	fnv1a := fnv.New32a()
	fnv1a.Write(buffer[4:])
	fnvHashActual := fnv1a.Sum32()

	if fnvHash != fnvHashActual {
		log.Warning("Unexpected fhv hash %d, should be %d", fnvHashActual, fnvHash)
		return nil, errors.NewCorruptedPacketError()
	}

	buffer = buffer[4:]

	vmess := &VMessUDP{
		user:    *userId,
		version: buffer[0],
		token:   binary.BigEndian.Uint16(buffer[1:3]),
	}

	// buffer[3] is reserved

	port := binary.BigEndian.Uint16(buffer[4:6])
	addrType := buffer[6]
	var address v2net.Address
	switch addrType {
	case addrTypeIPv4:
		address = v2net.IPAddress(buffer[7:11], port)
		buffer = buffer[11:]
	case addrTypeIPv6:
		address = v2net.IPAddress(buffer[7:23], port)
		buffer = buffer[23:]
	case addrTypeDomain:
		domainLength := buffer[7]
		domain := string(buffer[8 : 8+domainLength])
		address = v2net.DomainAddress(domain, port)
		buffer = buffer[8+domainLength:]
	default:
		log.Warning("Unexpected address type %d", addrType)
		return nil, errors.NewCorruptedPacketError()
	}

	vmess.address = address
	vmess.data = buffer

	return vmess, nil
}
Beispiel #7
0
func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- []byte, finish *sync.Mutex, isUDP bool) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
	if err != nil {
		log.Error("VMessOut: Failed to create decrypt reader: %v", err)
		return
	}

	buffer := make([]byte, 2*1024)

	nBytes, err := decryptResponseReader.Read(buffer)
	if err != nil {
		//log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", nBytes, err)
		return
	}
	if !bytes.Equal(buffer[:4], request.ResponseHeader[:]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}

	output <- buffer[4:nBytes]

	if !isUDP {
		v2net.ReaderToChan(output, decryptResponseReader)
	}

	return
}
Beispiel #8
0
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamSettings) (*TCPHub, error) {
	var listener Listener
	var err error
	switch {
	case settings.IsCapableOf(StreamConnectionTypeTCP):
		listener, err = TCPListenFunc(address, port)
	case settings.IsCapableOf(StreamConnectionTypeKCP):
		listener, err = KCPListenFunc(address, port)
	case settings.IsCapableOf(StreamConnectionTypeRawTCP):
		listener, err = RawTCPListenFunc(address, port)
	default:
		log.Error("Internet|Listener: Unknown stream type: ", settings.Type)
		err = ErrUnsupportedStreamType
	}

	if err != nil {
		log.Warning("Internet|Listener: Failed to listen on ", address, ":", port)
		return nil, err
	}

	var tlsConfig *tls.Config
	if settings.Security == StreamSecurityTypeTLS {
		tlsConfig = settings.TLSSettings.GetTLSConfig()
	}

	hub := &TCPHub{
		listener:     listener,
		connCallback: callback,
		tlsConfig:    tlsConfig,
	}

	go hub.start()
	return hub, nil
}
Beispiel #9
0
func handleResponse(conn *net.TCPConn, request *protocol.VMessRequest, output chan<- []byte, finish *sync.Mutex) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
	if err != nil {
		log.Error("VMessOut: Failed to create decrypt reader: %v", err)
		return
	}

	response := protocol.VMessResponse{}
	nBytes, err := decryptResponseReader.Read(response[:])
	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", nBytes, err)
		log.Error(InfoTimeNotSync)
		return
	}
	if !bytes.Equal(response[:], request.ResponseHeader[:]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}

	v2net.ReaderToChan(output, decryptResponseReader)
	return
}
Beispiel #10
0
func (this *Server) handleConnection(connection internet.Connection) {
	defer connection.Close()

	timedReader := v2net.NewTimeOutReader(this.config.Timeout, connection)
	reader := v2io.NewBufferedReader(timedReader)
	defer reader.Release()

	writer := v2io.NewBufferedWriter(connection)
	defer writer.Release()

	auth, auth4, err := protocol.ReadAuthentication(reader)
	if err != nil && err != protocol.Socks4Downgrade {
		if err != io.EOF {
			log.Warning("Socks: failed to read authentication: ", err)
		}
		return
	}

	clientAddr := connection.RemoteAddr().String()
	if err != nil && err == protocol.Socks4Downgrade {
		this.handleSocks4(clientAddr, reader, writer, auth4)
	} else {
		this.handleSocks5(clientAddr, reader, writer, auth)
	}
}
Beispiel #11
0
func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
	aesStream := crypto.NewAesDecryptionStream(this.responseBodyKey, this.responseBodyIV)
	this.responseReader = crypto.NewCryptionReader(aesStream, reader)

	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	_, err := io.ReadFull(this.responseReader, buffer.Value[:4])
	if err != nil {
		log.Error("Raw: Failed to read response header: ", err)
		return nil, err
	}

	if buffer.Value[0] != this.responseHeader {
		log.Warning("Raw: Unexpected response header. Expecting %d, but actually %d", this.responseHeader, buffer.Value[0])
		return nil, transport.ErrorCorruptedPacket
	}

	header := new(protocol.ResponseHeader)

	if buffer.Value[2] != 0 {
		cmdId := buffer.Value[2]
		dataLen := int(buffer.Value[3])
		_, err := io.ReadFull(this.responseReader, buffer.Value[:dataLen])
		if err != nil {
			log.Error("Raw: Failed to read response command: ", err)
			return nil, err
		}
		data := buffer.Value[:dataLen]
		command, err := UnmarshalCommand(cmdId, data)
		header.Command = command
	}

	return header, nil
}
Beispiel #12
0
func (this *VMessOutboundHandler) handleResponse(session *raw.ClientSession, conn net.Conn, request *proto.RequestHeader, dest v2net.Destination, output chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer finish.Unlock()
	defer close(output)

	reader := v2io.NewBufferedReader(conn)

	header, err := session.DecodeResponseHeader(reader)
	if err != nil {
		log.Warning("VMessOut: Failed to read response: ", err)
		return
	}
	go this.handleCommand(dest, header.Command)

	reader.SetCached(false)
	decryptReader := session.DecodeResponseBody(conn)

	var bodyReader v2io.Reader
	if request.Option.IsChunkStream() {
		bodyReader = vmessio.NewAuthChunkReader(decryptReader)
	} else {
		bodyReader = v2io.NewAdaptiveReader(decryptReader)
	}

	v2io.ReaderToChan(output, bodyReader)

	return
}
Beispiel #13
0
// Start starts the Point server, and return any error during the process.
// In the case of any errors, the state of the server is unpredicatable.
func (this *Point) Start() error {
	if this.port <= 0 {
		log.Error("Invalid port ", this.port)
		return BadConfiguration
	}

	err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error {
		err := this.ich.Listen(this.port)
		if err != nil {
			return err
		}
		log.Warning("Point server started on port ", this.port)
		return nil
	})
	if err != nil {
		return err
	}

	for _, detourHandler := range this.idh {
		err := detourHandler.Start()
		if err != nil {
			return err
		}
	}

	return nil
}
Beispiel #14
0
func ReadUDPRequest(packet []byte) (request Socks5UDPRequest, err error) {
	// packet[0] and packet[1] are reserved
	request.Fragment = packet[2]

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case AddrTypeIPv4:
		ip := packet[4:8]
		port := binary.BigEndian.Uint16(packet[8:10])
		request.Address = v2net.IPAddress(ip, port)
		dataBegin = 10
	case AddrTypeIPv6:
		ip := packet[4:20]
		port := binary.BigEndian.Uint16(packet[20:22])
		request.Address = v2net.IPAddress(ip, port)
		dataBegin = 22
	case AddrTypeDomain:
		domainLength := int(packet[4])
		domain := string(packet[5 : 5+domainLength])
		port := binary.BigEndian.Uint16(packet[5+domainLength : 5+domainLength+2])
		request.Address = v2net.DomainAddress(domain, port)
		dataBegin = 5 + domainLength + 2
	default:
		log.Warning("Unknown address type %d", addrType)
		err = ErrorUnknownAddressType
		return
	}

	request.Data = make([]byte, len(packet)-dataBegin)
	copy(request.Data, packet[dataBegin:])

	return
}
Beispiel #15
0
func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
	if err != nil {
		log.Error("VMessOut: Failed to create decrypt reader: %v", err)
		return
	}

	buffer, err := v2net.ReadFrom(decryptResponseReader, nil)
	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", buffer.Len(), err)
		return
	}
	if buffer.Len() < 4 || !bytes.Equal(buffer.Value[:4], request.ResponseHeader[:]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}
	log.Info("VMessOut received %d bytes from %s", buffer.Len()-4, conn.RemoteAddr().String())

	buffer.SliceFrom(4)
	output <- buffer

	if !isUDP {
		v2net.ReaderToChan(output, decryptResponseReader)
	}

	return
}
Beispiel #16
0
func (server *SocksServer) AcceptPackets(conn *net.UDPConn) error {
	for {
		buffer := alloc.NewBuffer()
		nBytes, addr, err := conn.ReadFromUDP(buffer.Value)
		if err != nil {
			log.Error("Socks failed to read UDP packets: %v", err)
			buffer.Release()
			continue
		}
		log.Info("Client UDP connection from %v", addr)
		request, err := protocol.ReadUDPRequest(buffer.Value[:nBytes])
		buffer.Release()
		if err != nil {
			log.Error("Socks failed to parse UDP request: %v", err)
			request.Data.Release()
			continue
		}
		if request.Fragment != 0 {
			log.Warning("Dropping fragmented UDP packets.")
			// TODO handle fragments
			request.Data.Release()
			continue
		}

		udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
		log.Info("Send packet to %s with %d bytes", udpPacket.Destination().String(), request.Data.Len())
		go server.handlePacket(conn, udpPacket, addr, request.Address)
	}
}
Beispiel #17
0
func (this *VMessOutboundHandler) handleCommand(cmdId byte, data []byte) {
	cmd, err := command.CreateResponseCommand(cmdId)
	if err != nil {
		log.Warning("VMessOut: Unknown response command (", cmdId, "): ", err)
		return
	}
	if err := cmd.Unmarshal(data); err != nil {
		log.Warning("VMessOut: Failed to parse response command: ", err)
		return
	}
	switch typedCommand := cmd.(type) {
	case *command.SwitchAccount:
		this.handleSwitchAccount(typedCommand)
	default:
	}
}
Beispiel #18
0
func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destination, reader *bufio.Reader, writer io.Writer) {
	if len(request.URL.Host) <= 0 {
		response := this.GenerateResponse(400, "Bad Request")
		response.Write(writer)

		return
	}

	request.Host = request.URL.Host
	StripHopByHopHeaders(request)

	ray := this.packetDispatcher.DispatchToOutbound(dest)
	defer ray.InboundInput().Close()
	defer ray.InboundOutput().Release()

	var finish sync.WaitGroup
	finish.Add(1)
	go func() {
		defer finish.Done()
		requestWriter := v2io.NewBufferedWriter(v2io.NewChainWriter(ray.InboundInput()))
		err := request.Write(requestWriter)
		if err != nil {
			log.Warning("HTTP: Failed to write request: ", err)
			return
		}
		requestWriter.Flush()
	}()

	finish.Add(1)
	go func() {
		defer finish.Done()
		responseReader := bufio.NewReader(v2io.NewChanReader(ray.InboundOutput()))
		response, err := http.ReadResponse(responseReader, request)
		if err != nil {
			log.Warning("HTTP: Failed to read response: ", err)
			response = this.GenerateResponse(503, "Service Unavailable")
		}
		responseWriter := v2io.NewBufferedWriter(writer)
		err = response.Write(responseWriter)
		if err != nil {
			log.Warning("HTTP: Failed to write response: ", err)
			return
		}
		responseWriter.Flush()
	}()
	finish.Wait()
}
Beispiel #19
0
func (this *Point) GetHandler(context app.Context, tag string) (proxy.InboundHandler, int) {
	handler, found := this.taggedIdh[tag]
	if !found {
		log.Warning("Point: Unable to find an inbound handler with tag: ", tag)
		return nil, 0
	}
	return handler.GetConnectionHandler()
}
Beispiel #20
0
func (this *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error {
	defer connection.Close()

	connReader := v2net.NewTimeOutReader(16, connection)
	requestReader := protocol.NewVMessRequestReader(this.clients)

	request, err := requestReader.Read(connReader)
	if err != nil {
		log.Access(connection.RemoteAddr().String(), "", log.AccessRejected, err.Error())
		log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err)
		return err
	}
	log.Access(connection.RemoteAddr().String(), request.Address.String(), log.AccessAccepted, "")
	log.Debug("VMessIn: Received request for %s", request.Address.String())

	ray := this.space.PacketDispatcher().DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
	input := ray.InboundInput()
	output := ray.InboundOutput()
	var readFinish, writeFinish sync.Mutex
	readFinish.Lock()
	writeFinish.Lock()

	userSettings := vmess.GetUserSettings(request.User.Level)
	connReader.SetTimeOut(userSettings.PayloadReadTimeout)
	go handleInput(request, connReader, input, &readFinish)

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	aesStream, err := v2crypto.NewAesEncryptionStream(responseKey[:], responseIV[:])
	if err != nil {
		log.Error("VMessIn: Failed to create AES decryption stream: %v", err)
		close(input)
		return err
	}

	responseWriter := v2crypto.NewCryptionWriter(aesStream, connection)

	// Optimize for small response packet
	buffer := alloc.NewLargeBuffer().Clear()
	defer buffer.Release()
	buffer.AppendBytes(request.ResponseHeader[0] ^ request.ResponseHeader[1])
	buffer.AppendBytes(request.ResponseHeader[2] ^ request.ResponseHeader[3])
	buffer.AppendBytes(byte(0), byte(0))

	if data, open := <-output; open {
		buffer.Append(data.Value)
		data.Release()
		responseWriter.Write(buffer.Value)
		go handleOutput(request, responseWriter, output, &writeFinish)
		writeFinish.Lock()
	}

	connection.CloseWrite()
	readFinish.Lock()

	return nil
}
Beispiel #21
0
func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	nBytes, err := reader.Read(buffer.Value)
	if err != nil {
		return
	}
	if nBytes < 2 {
		log.Warning("Socks: expected 2 bytes read, but only ", nBytes, " bytes read")
		err = transport.ErrCorruptedPacket
		return
	}

	if buffer.Value[0] == socks4Version {
		auth4.Version = buffer.Value[0]
		auth4.Command = buffer.Value[1]
		auth4.Port = v2net.PortFromBytes(buffer.Value[2:4])
		copy(auth4.IP[:], buffer.Value[4:8])
		err = Socks4Downgrade
		return
	}

	auth.version = buffer.Value[0]
	if auth.version != socksVersion {
		log.Warning("Socks: Unknown protocol version ", auth.version)
		err = proxy.ErrInvalidProtocolVersion
		return
	}

	auth.nMethods = buffer.Value[1]
	if auth.nMethods <= 0 {
		log.Warning("Socks: Zero length of authentication methods")
		err = proxy.ErrInvalidAuthentication
		return
	}

	if nBytes-2 != int(auth.nMethods) {
		log.Warning("Socks: Unmatching number of auth methods, expecting ", auth.nMethods, ", but got ", nBytes)
		err = proxy.ErrInvalidAuthentication
		return
	}
	copy(auth.authMethods[:], buffer.Value[2:nBytes])
	return
}
Beispiel #22
0
func (handler *VMessInboundHandler) AcceptPackets(conn *net.UDPConn) {
	for {
		buffer := alloc.NewBuffer()
		nBytes, addr, err := conn.ReadFromUDP(buffer.Value)
		if err != nil {
			log.Error("VMessIn failed to read UDP packets: %v", err)
			buffer.Release()
			continue
		}

		reader := bytes.NewReader(buffer.Value[:nBytes])
		requestReader := protocol.NewVMessRequestReader(handler.clients)

		request, err := requestReader.Read(reader)
		if err != nil {
			log.Access(addr.String(), "", log.AccessRejected, err.Error())
			log.Warning("VMessIn: Invalid request from (%s): %v", addr.String(), err)
			buffer.Release()
			continue
		}
		log.Access(addr.String(), request.Address.String(), log.AccessAccepted, "")

		cryptReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader)
		if err != nil {
			log.Error("VMessIn: Failed to create decrypt reader: %v", err)
			buffer.Release()
			continue
		}

		data := alloc.NewBuffer()
		nBytes, err = cryptReader.Read(data.Value)
		buffer.Release()
		if err != nil {
			log.Warning("VMessIn: Unable to decrypt data: %v", err)
			data.Release()
			continue
		}
		data.Slice(0, nBytes)

		packet := v2net.NewPacket(request.Destination(), data, false)
		go handler.handlePacket(conn, request, packet, addr)
	}
}
Beispiel #23
0
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
	if len(packet) < 5 {
		return nil, transport.CorruptedPacket
	}
	request := new(Socks5UDPRequest)

	// packet[0] and packet[1] are reserved
	request.Fragment = packet[2]

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case AddrTypeIPv4:
		if len(packet) < 10 {
			return nil, transport.CorruptedPacket
		}
		ip := packet[4:8]
		request.Port = v2net.PortFromBytes(packet[8:10])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 10
	case AddrTypeIPv6:
		if len(packet) < 22 {
			return nil, transport.CorruptedPacket
		}
		ip := packet[4:20]
		request.Port = v2net.PortFromBytes(packet[20:22])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 22
	case AddrTypeDomain:
		domainLength := int(packet[4])
		if len(packet) < 5+domainLength+2 {
			return nil, transport.CorruptedPacket
		}
		domain := string(packet[5 : 5+domainLength])
		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
		maybeIP := net.ParseIP(domain)
		if maybeIP != nil {
			request.Address = v2net.IPAddress(maybeIP)
		} else {
			request.Address = v2net.DomainAddress(domain)
		}
		dataBegin = 5 + domainLength + 2
	default:
		log.Warning("Unknown address type ", addrType)
		return nil, ErrorUnknownAddressType
	}

	if len(packet) > dataBegin {
		request.Data = alloc.NewBuffer().Clear().Append(packet[dataBegin:])
	}

	return request, nil
}
Beispiel #24
0
func (dest *Destination) Network() string {
	switch dest.network {
	case NetTCP:
		return "tcp"
	case NetUDP:
		return "udp"
	default:
		log.Warning("Unknown network %d", dest.network)
		return "tcp"
	}
}
Beispiel #25
0
func (this *VMessOutboundHandler) handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) {
	defer finish.Unlock()
	aesStream, err := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:])
	if err != nil {
		log.Error("VMessOut: Failed to create AES encryption stream: ", err)
		return
	}
	encryptRequestWriter := v2crypto.NewCryptionWriter(aesStream, conn)

	buffer := alloc.NewBuffer().Clear()
	defer buffer.Release()
	buffer, err = request.ToBytes(protocol.NewRandomTimestampGenerator(protocol.Timestamp(time.Now().Unix()), 30), buffer)
	if err != nil {
		log.Error("VMessOut: Failed to serialize VMess request: ", err)
		return
	}

	// Send first packet of payload together with request, in favor of small requests.
	firstChunk := firstPacket.Chunk()
	moreChunks := firstPacket.MoreChunks()

	for firstChunk == nil && moreChunks {
		firstChunk, moreChunks = <-input
	}

	if firstChunk == nil && !moreChunks {
		log.Warning("VMessOut: Nothing to send. Existing...")
		return
	}

	if request.IsChunkStream() {
		vmessio.Authenticate(firstChunk)
	}

	aesStream.XORKeyStream(firstChunk.Value, firstChunk.Value)
	buffer.Append(firstChunk.Value)
	firstChunk.Release()

	_, err = conn.Write(buffer.Value)
	if err != nil {
		log.Error("VMessOut: Failed to write VMess request: ", err)
		return
	}

	if moreChunks {
		var streamWriter v2io.Writer
		streamWriter = v2io.NewAdaptiveWriter(encryptRequestWriter)
		if request.IsChunkStream() {
			streamWriter = vmessio.NewAuthChunkWriter(streamWriter)
		}
		v2io.ChanToWriter(streamWriter, input)
	}
	return
}
Beispiel #26
0
func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error {
	defer connection.Close()

	connReader := v2net.NewTimeOutReader(16, connection)
	requestReader := protocol.NewVMessRequestReader(handler.clients)

	request, err := requestReader.Read(connReader)
	if err != nil {
		log.Access(connection.RemoteAddr().String(), "", log.AccessRejected, err.Error())
		log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err)
		return err
	}
	log.Access(connection.RemoteAddr().String(), request.Address.String(), log.AccessAccepted, "")
	log.Debug("VMessIn: Received request for %s", request.Address.String())

	ray := handler.dispatcher.DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
	input := ray.InboundInput()
	output := ray.InboundOutput()
	var readFinish, writeFinish sync.Mutex
	readFinish.Lock()
	writeFinish.Lock()

	connReader.SetTimeOut(120)
	go handleInput(request, connReader, input, &readFinish)

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
	if err != nil {
		log.Error("VMessIn: Failed to create encrypt writer: %v", err)
		return err
	}

	// Optimize for small response packet
	buffer := alloc.NewLargeBuffer().Clear()
	buffer.Append(request.ResponseHeader)

	if data, open := <-output; open {
		buffer.Append(data.Value)
		data.Release()
		responseWriter.Write(buffer.Value)
		buffer.Release()
		go handleOutput(request, responseWriter, output, &writeFinish)
		writeFinish.Lock()
	}

	connection.CloseWrite()
	readFinish.Lock()

	return nil
}
Beispiel #27
0
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	_, err = io.ReadFull(reader, buffer.Value[:4])
	if err != nil {
		return
	}

	request = &Socks5Request{
		Version: buffer.Value[0],
		Command: buffer.Value[1],
		// buffer[2] is a reserved field
		AddrType: buffer.Value[3],
	}
	switch request.AddrType {
	case AddrTypeIPv4:
		_, err = io.ReadFull(reader, request.IPv4[:])
		if err != nil {
			return
		}
	case AddrTypeDomain:
		_, err = io.ReadFull(reader, buffer.Value[0:1])
		if err != nil {
			return
		}
		domainLength := buffer.Value[0]
		_, err = io.ReadFull(reader, buffer.Value[:domainLength])
		if err != nil {
			return
		}

		request.Domain = string(append([]byte(nil), buffer.Value[:domainLength]...))
	case AddrTypeIPv6:
		_, err = io.ReadFull(reader, request.IPv6[:])
		if err != nil {
			return
		}
	default:
		log.Warning("Socks: Unexpected address type ", request.AddrType)
		err = transport.ErrCorruptedPacket
		return
	}

	_, err = io.ReadFull(reader, buffer.Value[:2])
	if err != nil {
		return
	}

	request.Port = v2net.PortFromBytes(buffer.Value[:2])
	return
}
Beispiel #28
0
func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error {
	defer connection.Close()

	reader := protocol.NewVMessRequestReader(handler.clients)

	// Timeout 4 seconds to prevent DoS attack
	connection.SetReadDeadline(time.Now().Add(requestReadTimeOut))
	request, err := reader.Read(connection)
	if err != nil {
		log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err)
		return err
	}
	log.Debug("VMessIn: Received request for %s", request.Address.String())
	// Clear read timeout
	connection.SetReadDeadline(zeroTime)

	ray := handler.vPoint.NewInboundConnectionAccepted(request.Destination())
	input := ray.InboundInput()
	output := ray.InboundOutput()

	readFinish := make(chan bool)
	writeFinish := make(chan bool)

	go handleInput(request, connection, input, readFinish)

	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	response := protocol.NewVMessResponse(request)
	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
	if err != nil {
		return log.Error("VMessIn: Failed to create encrypt writer: %v", err)
	}

	// Optimize for small response packet
	buffer := make([]byte, 0, 1024)
	buffer = append(buffer, response[:]...)

	if data, open := <-output; open {
		buffer = append(buffer, data...)
		responseWriter.Write(buffer)
		go handleOutput(request, responseWriter, output, writeFinish)
		<-writeFinish
	}

	if tcpConn, ok := connection.(*net.TCPConn); ok {
		tcpConn.CloseWrite()
	}
	<-readFinish

	return nil
}
Beispiel #29
0
func (this *TCPListener) start() {
	this.accepting = true
	for this.accepting {
		conn, err := this.listener.AcceptTCP()
		if err != nil {
			log.Warning("Listener: Failed to accept new TCP connection: ", err)
			continue
		}
		go this.connCallback(&TCPConn{
			conn:     conn,
			listener: this,
		})
	}
}
Beispiel #30
0
func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protocol.VMessRequest, dest v2net.Destination, output chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
	if err != nil {
		log.Error("VMessOut: Failed to create AES encryption stream: ", err)
		return
	}
	decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)

	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()
	_, err = io.ReadFull(decryptResponseReader, buffer.Value[:4])

	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err)
		return
	}
	if !headerMatch(request, buffer.Value[0]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}

	if buffer.Value[2] != 0 {
		command := buffer.Value[2]
		dataLen := int(buffer.Value[3])
		_, err := io.ReadFull(decryptResponseReader, buffer.Value[:dataLen])
		if err != nil {
			log.Error("VMessOut: Failed to read response command: ", err)
			return
		}
		data := buffer.Value[:dataLen]
		go this.handleCommand(dest, command, data)
	}

	var reader v2io.Reader
	if request.IsChunkStream() {
		reader = vmessio.NewAuthChunkReader(decryptResponseReader)
	} else {
		reader = v2io.NewAdaptiveReader(decryptResponseReader)
	}

	v2io.ReaderToChan(output, reader)

	return
}