Пример #1
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)
	}
}
Пример #2
0
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
	conn, err := net.Dial(firstPacket.Destination().Network(), firstPacket.Destination().Address().String())
	log.Info("Freedom: Opening connection to %s", firstPacket.Destination().String())
	if err != nil {
		close(ray.OutboundOutput())
		log.Error("Freedom: Failed to open connection: %s : %v", firstPacket.Destination().String(), err)
		return err
	}

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

	if chunk := firstPacket.Chunk(); chunk != nil {
		conn.Write(chunk.Value)
		chunk.Release()
	}

	if !firstPacket.MoreChunks() {
		writeMutex.Unlock()
	} else {
		go func() {
			v2net.ChanToWriter(conn, input)
			writeMutex.Unlock()
		}()
	}

	go func() {
		defer readMutex.Unlock()
		defer close(output)

		response, err := v2net.ReadFrom(conn, nil)
		log.Info("Freedom receives %d bytes from %s", response.Len(), conn.RemoteAddr().String())
		if response.Len() > 0 {
			output <- response
		} else {
			response.Release()
		}
		if err != nil {
			return
		}
		if firstPacket.Destination().IsUDP() {
			return
		}

		v2net.ReaderToChan(output, conn)
	}()

	writeMutex.Lock()
	if tcpConn, ok := conn.(*net.TCPConn); ok {
		tcpConn.CloseWrite()
	}
	readMutex.Lock()
	conn.Close()

	return nil
}
Пример #3
0
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()
}
Пример #4
0
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)
		}
	})
}
Пример #5
0
// Close closes the connection.
func (this *Connection) Close() error {
	if this == nil {
		return errClosedConnection
	}

	this.dataInputCond.Broadcast()
	this.dataOutputCond.Broadcast()

	state := this.State()
	if state == StateReadyToClose ||
		state == StateTerminating ||
		state == StateTerminated {
		return errClosedConnection
	}
	log.Info("KCP|Connection: Closing connection to ", this.remote)

	if state == StateActive {
		this.SetState(StateReadyToClose)
	}
	if state == StatePeerClosed {
		this.SetState(StateTerminating)
	}
	if state == StatePeerTerminating {
		this.SetState(StateTerminated)
	}

	return nil
}
Пример #6
0
// NewConnection create a new KCP connection between local and remote.
func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr, remote *net.UDPAddr, block Authenticator) *Connection {
	log.Info("KCP|Connection: creating connection ", conv)

	conn := new(Connection)
	conn.local = local
	conn.remote = remote
	conn.block = block
	conn.writer = writerCloser
	conn.since = nowMillisec()
	conn.dataInputCond = sync.NewCond(new(sync.Mutex))
	conn.dataOutputCond = sync.NewCond(new(sync.Mutex))

	authWriter := &AuthenticationWriter{
		Authenticator: block,
		Writer:        writerCloser,
	}
	conn.conv = conv
	conn.output = NewSegmentWriter(authWriter)

	conn.mss = authWriter.Mtu() - DataSegmentOverhead
	conn.roundTrip = &RountTripInfo{
		rto:    100,
		minRtt: effectiveConfig.Tti,
	}
	conn.interval = effectiveConfig.Tti
	conn.receivingWorker = NewReceivingWorker(conn)
	conn.fastresend = 2
	conn.congestionControl = effectiveConfig.Congestion
	conn.sendingWorker = NewSendingWorker(conn)

	go conn.updateTask()

	return conn
}
Пример #7
0
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
	log.Info("Freedom: Opening connection to ", firstPacket.Destination())

	var conn net.Conn
	err := retry.Timed(5, 100).On(func() error {
		rawConn, err := dialer.Dial(firstPacket.Destination())
		if err != nil {
			return err
		}
		conn = rawConn
		return nil
	})
	if err != nil {
		close(ray.OutboundOutput())
		log.Error("Freedom: Failed to open connection to ", firstPacket.Destination(), ": ", err)
		return err
	}
	defer conn.Close()

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

	if chunk := firstPacket.Chunk(); chunk != nil {
		conn.Write(chunk.Value)
		chunk.Release()
	}

	if !firstPacket.MoreChunks() {
		writeMutex.Unlock()
	} else {
		go func() {
			v2io.ChanToRawWriter(conn, input)
			writeMutex.Unlock()
		}()
	}

	go func() {
		defer readMutex.Unlock()
		defer close(output)

		var reader io.Reader = conn

		if firstPacket.Destination().IsUDP() {
			reader = v2net.NewTimeOutReader(16 /* seconds */, conn)
		}

		v2io.RawReaderToChan(output, reader)
	}()

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

	return nil
}
Пример #8
0
func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, request *protocol.VMessRequest, packet v2net.Packet, clientAddr *net.UDPAddr) {
	ray := handler.vPoint.DispatchToOutbound(packet)
	close(ray.InboundInput())

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

	buffer := bytes.NewBuffer(make([]byte, 0, bufferSize))

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

	hasData := false

	if data, ok := <-ray.InboundOutput(); ok {
		hasData = true
		responseWriter.Write(data)
	}

	if hasData {
		conn.WriteToUDP(buffer.Bytes(), clientAddr)
		log.Info("VMessIn sending %d bytes to %s", len(buffer.Bytes()), clientAddr.String())
	}
}
Пример #9
0
func (this *VMessInboundHandler) generateCommand(request *protocol.RequestHeader) protocol.ResponseCommand {
	if this.detours != nil {
		tag := this.detours.ToTag
		if this.inboundHandlerManager != nil {
			handler, availableMin := this.inboundHandlerManager.GetHandler(tag)
			inboundHandler, ok := handler.(*VMessInboundHandler)
			if ok {
				if availableMin > 255 {
					availableMin = 255
				}

				log.Info("VMessIn: Pick detour handler for port ", inboundHandler.Port(), " for ", availableMin, " minutes.")
				user := inboundHandler.GetUser(request.User.Email)
				if user == nil {
					return nil
				}
				return &protocol.CommandSwitchAccount{
					Port:     inboundHandler.Port(),
					ID:       user.Account.(*vmess.Account).ID.UUID(),
					AlterIds: uint16(len(user.Account.(*vmess.Account).AlterIDs)),
					Level:    user.Level,
					ValidMin: byte(availableMin),
				}
			}
		}
	}

	return nil
}
Пример #10
0
func (vconn *FreedomConnection) Start(ray core.OutboundRay) error {
	conn, err := net.Dial(vconn.packet.Destination().Network(), vconn.packet.Destination().Address().String())
	log.Info("Freedom: Opening connection to %s", vconn.packet.Destination().String())
	if err != nil {
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return log.Error("Freedom: Failed to open connection: %s : %v", vconn.packet.Destination().String(), err)
	}

	if chunk := vconn.packet.Chunk(); chunk != nil {
		conn.Write(chunk)
	}

	if !vconn.packet.MoreChunks() {
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return nil
	}

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	readFinish := make(chan bool)
	writeFinish := make(chan bool)

	go dumpInput(conn, input, writeFinish)
	go dumpOutput(conn, output, readFinish)
	go closeConn(conn, readFinish, writeFinish)
	return nil
}
Пример #11
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)
	}
}
Пример #12
0
func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, request *protocol.VMessRequest, packet v2net.Packet, clientAddr *net.UDPAddr) {
	ray := handler.vPoint.DispatchToOutbound(packet)
	close(ray.InboundInput())

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

	buffer := alloc.NewBuffer().Clear()
	defer buffer.Release()

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

	hasData := false

	if data, ok := <-ray.InboundOutput(); ok {
		hasData = true
		responseWriter.Write(data.Value)
		data.Release()
	}

	if hasData {
		conn.WriteToUDP(buffer.Value, clientAddr)
		log.Info("VMessIn sending %d bytes to %s", buffer.Len(), clientAddr.String())
	}
}
Пример #13
0
func startCommunicate(request *protocol.VMessRequest, dest *v2net.Destination, ray core.OutboundRay) error {
	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	conn, err := net.DialTCP(dest.Network(), nil, &net.TCPAddr{dest.Address().IP(), int(dest.Address().Port()), ""})
	if err != nil {
		log.Error("Failed to open tcp (%s): %v", dest.String(), err)
		close(output)
		return err
	}
	log.Info("VMessOut: Tunneling request for %s", request.Address.String())

	defer conn.Close()

	requestFinish := make(chan bool)
	responseFinish := make(chan bool)

	go handleRequest(conn, request, input, requestFinish)
	go handleResponse(conn, request, output, responseFinish)

	<-requestFinish
	conn.CloseWrite()
	<-responseFinish
	return nil
}
Пример #14
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)
	}
}
Пример #15
0
func (this *SocksServer) handlePacket(packet v2net.Packet, clientAddr *net.UDPAddr, targetAddr v2net.Address, port v2net.Port) {
	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
	close(ray.InboundInput())

	for data := range ray.InboundOutput() {
		response := &protocol.Socks5UDPRequest{
			Fragment: 0,
			Address:  targetAddr,
			Port:     port,
			Data:     data,
		}
		log.Info("Socks: Writing back UDP response with ", data.Len(), " bytes from ", targetAddr, " to ", clientAddr)

		udpMessage := alloc.NewSmallBuffer().Clear()
		response.Write(udpMessage)

		this.udpMutex.RLock()
		if !this.accepting {
			this.udpMutex.RUnlock()
			return
		}
		nBytes, err := this.udpConn.WriteToUDP(udpMessage.Value, clientAddr)
		this.udpMutex.RUnlock()
		udpMessage.Release()
		response.Data.Release()
		if err != nil {
			log.Error("Socks: failed to write UDP message (", nBytes, " bytes) to ", clientAddr, ": ", err)
		}
	}
}
Пример #16
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
}
Пример #17
0
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray core.OutboundRay, firstPacket v2net.Packet) error {
	conn, err := net.Dial(dest.Network(), dest.Address().String())
	if err != nil {
		log.Error("Failed to open %s: %v", dest.String(), err)
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return err
	}
	log.Info("VMessOut: Tunneling request to %s via %s", request.Address.String(), dest.String())

	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	go handleRequest(conn, request, firstPacket, input, &requestFinish)
	go handleResponse(conn, request, output, &responseFinish, dest.IsUDP())

	requestFinish.Lock()
	if tcpConn, ok := conn.(*net.TCPConn); ok {
		tcpConn.CloseWrite()
	}
	responseFinish.Lock()
	return nil
}
Пример #18
0
func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	defer ray.OutboundInput().Release()
	defer ray.OutboundOutput().Close()

	var rec *protocol.ServerSpec
	var conn internet.Connection

	err := retry.Timed(5, 100).On(func() error {
		rec = this.serverPicker.PickServer()
		rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), this.meta.StreamSettings)
		if err != nil {
			return err
		}
		conn = rawConn

		return nil
	})
	if err != nil {
		log.Error("VMess|Outbound: Failed to find an available destination:", err)
		return err
	}
	log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination)

	command := protocol.RequestCommandTCP
	if target.IsUDP() {
		command = protocol.RequestCommandUDP
	}
	request := &protocol.RequestHeader{
		Version: encoding.Version,
		User:    rec.PickUser(),
		Command: command,
		Address: target.Address(),
		Port:    target.Port(),
		Option:  protocol.RequestOptionChunkStream,
	}

	defer conn.Close()

	conn.SetReusable(true)
	if conn.Reusable() { // Conn reuse may be disabled on transportation layer
		request.Option.Set(protocol.RequestOptionConnectionReuse)
	}

	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	session := encoding.NewClientSession(protocol.DefaultIDHash)

	go this.handleRequest(session, conn, request, payload, input, &requestFinish)
	go this.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)

	requestFinish.Lock()
	responseFinish.Lock()
	return nil
}
Пример #19
0
func (this *Connection) Terminate() {
	if this == nil || this.writer == nil {
		return
	}
	log.Info("KCP|Connection: Terminating connection to ", this.RemoteAddr())

	this.writer.Close()
}
Пример #20
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.Info("Socks expected 2 bytes read, but only %d bytes read", nBytes)
		err = transport.CorruptedPacket
		return
	}

	if buffer.Value[0] == socks4Version {
		auth4.Version = buffer.Value[0]
		auth4.Command = buffer.Value[1]
		auth4.Port = binary.BigEndian.Uint16(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("Unknown protocol version %d", auth.version)
		err = proxy.InvalidProtocolVersion
		return
	}

	auth.nMethods = buffer.Value[1]
	if auth.nMethods <= 0 {
		log.Info("Zero length of authentication methods")
		err = transport.CorruptedPacket
		return
	}

	if nBytes-2 != int(auth.nMethods) {
		log.Info("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
		err = transport.CorruptedPacket
		return
	}
	copy(auth.authMethods[:], buffer.Value[2:nBytes])
	return
}
Пример #21
0
// @Private
func (this *DefaultDispatcher) FilterPacketAndDispatch(destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
	payload, err := link.OutboundInput().Read()
	if err != nil {
		log.Info("DefaultDispatcher: No payload towards ", destination, ", stopping now.")
		link.OutboundInput().Release()
		link.OutboundOutput().Release()
		return
	}
	dispatcher.Dispatch(destination, payload, link)
}
Пример #22
0
func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) {
	buffer := make([]byte, 256)
	nBytes, err := reader.Read(buffer)
	if err != nil {
		return
	}
	if nBytes < 2 {
		log.Info("Socks expected 2 bytes read, but only %d bytes read", nBytes)
		err = errors.NewCorruptedPacketError()
		return
	}

	if buffer[0] == socks4Version {
		auth4.Version = buffer[0]
		auth4.Command = buffer[1]
		auth4.Port = binary.BigEndian.Uint16(buffer[2:4])
		copy(auth4.IP[:], buffer[4:8])
		err = NewSocksVersion4Error()
		return
	}

	auth.version = buffer[0]
	if auth.version != socksVersion {
		err = errors.NewProtocolVersionError(int(auth.version))
		return
	}

	auth.nMethods = buffer[1]
	if auth.nMethods <= 0 {
		log.Info("Zero length of authentication methods")
		err = errors.NewCorruptedPacketError()
		return
	}

	if nBytes-2 != int(auth.nMethods) {
		log.Info("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
		err = errors.NewCorruptedPacketError()
		return
	}
	copy(auth.authMethods[:], buffer[2:nBytes])
	return
}
Пример #23
0
func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay {
	direct := ray.NewRay()
	dispatcher := this.ohm.GetDefaultHandler()

	if this.router != nil {
		if tag, err := this.router.TakeDetour(destination); err == nil {
			if handler := this.ohm.GetHandler(tag); handler != nil {
				log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
				dispatcher = handler
			} else {
				log.Warning("DefaultDispatcher: Nonexisting tag: ", tag)
			}
		} else {
			log.Info("DefaultDispatcher: Default route for ", destination)
		}
	}

	go this.FilterPacketAndDispatch(destination, direct, dispatcher)

	return direct
}
Пример #24
0
// @Private
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
	if !destination.Address().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.IsTCP() {
		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
}
Пример #25
0
func GetOriginalDestination(conn internet.Connection) v2net.Destination {
	tcpConn, ok := conn.(internet.SysFd)
	if !ok {
		log.Info("Dokodemo: Failed to get sys fd.")
		return nil
	}
	fd, err := tcpConn.SysFd()
	if err != nil {
		log.Info("Dokodemo: Failed to get original destination: ", err)
		return nil
	}

	addr, err := syscall.GetsockoptIPv6Mreq(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST)
	if err != nil {
		log.Info("Dokodemo: Failed to call getsockopt: ", err)
		return nil
	}
	ip := v2net.IPAddress(addr.Multiaddr[4:8])
	port := uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])
	return v2net.TCPDestination(ip, v2net.Port(port))
}
Пример #26
0
func (this *HttpProxyServer) handlePlainHTTP(request *http.Request, dest v2net.Destination, reader *bufio.Reader, writer io.Writer) {
	if len(request.URL.Host) <= 0 {
		hdr := http.Header(make(map[string][]string))
		hdr.Set("Connection", "close")
		response := &http.Response{
			Status:        "400 Bad Request",
			StatusCode:    400,
			Proto:         "HTTP/1.1",
			ProtoMajor:    1,
			ProtoMinor:    1,
			Header:        hdr,
			Body:          nil,
			ContentLength: 0,
			Close:         false,
		}

		buffer := alloc.NewSmallBuffer().Clear()
		response.Write(buffer)
		writer.Write(buffer.Value)
		buffer.Release()
		return
	}

	request.Host = request.URL.Host
	stripHopByHopHeaders(request)

	requestBuffer := alloc.NewBuffer().Clear()
	request.Write(requestBuffer)
	log.Info("Request to remote:\n%s", string(requestBuffer.Value))

	packet := v2net.NewPacket(dest, requestBuffer, true)
	ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
	defer close(ray.InboundInput())

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		responseReader := bufio.NewReader(NewChanReader(ray.InboundOutput()))
		responseBuffer := alloc.NewBuffer()
		defer responseBuffer.Release()
		response, err := http.ReadResponse(responseReader, request)
		if err != nil {
			return
		}
		responseBuffer.Clear()
		response.Write(responseBuffer)
		writer.Write(responseBuffer.Value)
		response.Body.Close()
	}()
	wg.Wait()
}
Пример #27
0
func (this *SocksServer) AcceptPackets() error {
	for this.accepting {
		buffer := alloc.NewBuffer()
		this.udpMutex.RLock()
		if !this.accepting {
			this.udpMutex.RUnlock()
			return nil
		}
		nBytes, addr, err := this.udpConn.ReadFromUDP(buffer.Value)
		this.udpMutex.RUnlock()
		if err != nil {
			log.Error("Socks: failed to read UDP packets: ", err)
			buffer.Release()
			continue
		}
		log.Info("Socks: Client UDP connection from ", addr)
		request, err := protocol.ReadUDPRequest(buffer.Value[:nBytes])
		buffer.Release()
		if err != nil {
			log.Error("Socks: failed to parse UDP request: ", err)
			continue
		}
		if request.Data == nil || request.Data.Len() == 0 {
			continue
		}
		if request.Fragment != 0 {
			log.Warning("Socks: Dropping fragmented UDP packets.")
			// TODO handle fragments
			request.Data.Release()
			continue
		}

		udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
		log.Info("Socks: Send packet to ", udpPacket.Destination(), " with ", request.Data.Len(), " bytes")
		go this.handlePacket(udpPacket, addr, request.Address, request.Port)
	}
	return nil
}
Пример #28
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 := make([]byte, 256)

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

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

	header := &protocol.ResponseHeader{
		Option: protocol.ResponseOption(buffer[1]),
	}

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

	return header, nil
}
Пример #29
0
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
	for _, rule := range this.config.Rules {
		if rule.Apply(dest) {
			return rule.Tag, nil
		}
	}
	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
		log.Info("Router: Looking up IP for ", dest)
		ipDests := this.ResolveIP(dest)
		if ipDests != nil {
			for _, ipDest := range ipDests {
				log.Info("Router: Trying IP ", ipDest)
				for _, rule := range this.config.Rules {
					if rule.Apply(ipDest) {
						return rule.Tag, nil
					}
				}
			}
		}
	}

	return "", ErrNoRuleApplicable
}
Пример #30
0
func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
	udpDest := v2net.UDPDestination(dest.Address(), dest.Port())
	log.Info("Dialling KCP to ", udpDest)
	conn, err := internet.DialToDest(src, udpDest)
	if err != nil {
		return nil, err
	}

	cpip := NewSimpleAuthenticator()
	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
}