Beispiel #1
0
func (v *CacheServer) Get(domain string) []net.IP {
	if ip, found := v.hosts[domain]; found {
		return []net.IP{ip}
	}

	domain = dnsmsg.Fqdn(domain)
	ips := v.GetCached(domain)
	if ips != nil {
		return ips
	}

	for _, server := range v.servers {
		response := server.QueryA(domain)
		select {
		case a, open := <-response:
			if !open || a == nil {
				continue
			}
			v.Lock()
			v.records[domain] = &DomainRecord{
				A: a,
			}
			v.Unlock()
			log.Debug("DNS: Returning ", len(a.IPs), " IPs for domain ", domain)
			return a.IPs
		case <-time.After(QueryTimeout):
		}
	}

	log.Debug("DNS: Returning nil for domain ", domain)
	return nil
}
Beispiel #2
0
func (ws *wsconn) pingPong() {
	pongRcv := make(chan int, 1)
	ws.wsc.SetPongHandler(func(data string) error {
		pongRcv <- 0
		return nil
	})

	go func() {
		for !ws.connClosing {
			ws.wlock.Lock()
			ws.wsc.WriteMessage(websocket.PingMessage, nil)
			ws.wlock.Unlock()
			tick := time.After(time.Second * 3)

			select {
			case <-pongRcv:
			case <-tick:
				if !ws.connClosing {
					log.Debug("WS:Closing as ping is not responded~" + ws.wsc.UnderlyingConn().LocalAddr().String() + "-" + ws.wsc.UnderlyingConn().RemoteAddr().String())
				}
				ws.Close()
			}
			<-time.After(time.Second * 27)
		}

		return
	}()

}
Beispiel #3
0
func (this *ChunkReader) Read() (*alloc.Buffer, error) {
	buffer := alloc.NewLargeBuffer()
	if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil {
		buffer.Release()
		return nil, err
	}
	// There is a potential buffer overflow here. Large buffer is 64K bytes,
	// while uin16 + 10 will be more than that
	length := serial.BytesToUint16(buffer.Value[:2]) + AuthSize
	if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil {
		buffer.Release()
		return nil, err
	}
	buffer.Slice(0, int(length))

	authBytes := buffer.Value[:AuthSize]
	payload := buffer.Value[AuthSize:]

	actualAuthBytes := this.auth.Authenticate(nil, payload)
	if !bytes.Equal(authBytes, actualAuthBytes) {
		buffer.Release()
		log.Debug("AuthenticationReader: Unexpected auth: ", authBytes)
		return nil, transport.ErrCorruptedPacket
	}
	buffer.SliceFrom(AuthSize)

	return buffer, nil
}
Beispiel #4
0
func (v *Connection) SetState(state State) {
	current := v.Elapsed()
	atomic.StoreInt32((*int32)(&v.state), int32(state))
	atomic.StoreUint32(&v.stateBeginTime, current)
	log.Debug("KCP|Connection: #", v.conv, " entering state ", state, " at ", current)

	switch state {
	case StateReadyToClose:
		v.receivingWorker.CloseRead()
	case StatePeerClosed:
		v.sendingWorker.CloseWrite()
	case StateTerminating:
		v.receivingWorker.CloseRead()
		v.sendingWorker.CloseWrite()
		v.pingUpdater.interval = time.Second
	case StatePeerTerminating:
		v.sendingWorker.CloseWrite()
		v.pingUpdater.interval = time.Second
	case StateTerminated:
		v.receivingWorker.CloseRead()
		v.sendingWorker.CloseWrite()
		v.pingUpdater.interval = time.Second
		v.dataUpdater.WakeUp()
		v.pingUpdater.WakeUp()
		go v.Terminate()
	}
}
Beispiel #5
0
func (this *Connection) flush() {
	current := this.Elapsed()

	if this.State() == StateTerminated {
		return
	}
	if this.State() == StateActive && current-atomic.LoadUint32(&this.lastIncomingTime) >= 30000 {
		this.Close()
	}
	if this.State() == StateReadyToClose && this.sendingWorker.IsEmpty() {
		this.SetState(StateTerminating)
	}

	if this.State() == StateTerminating {
		log.Debug("KCP|Connection: #", this.conv, " sending terminating cmd.")
		seg := NewCmdOnlySegment()
		defer seg.Release()

		seg.Conv = this.conv
		seg.Command = CommandTerminate
		this.output.Write(seg)
		this.output.Flush()

		if current-atomic.LoadUint32(&this.stateBeginTime) > 8000 {
			this.SetState(StateTerminated)
		}
		return
	}
	if this.State() == StatePeerTerminating && current-atomic.LoadUint32(&this.stateBeginTime) > 4000 {
		this.SetState(StateTerminating)
	}

	if this.State() == StateReadyToClose && current-atomic.LoadUint32(&this.stateBeginTime) > 15000 {
		this.SetState(StateTerminating)
	}

	// flush acknowledges
	this.receivingWorker.Flush(current)
	this.sendingWorker.Flush(current)

	if current-atomic.LoadUint32(&this.lastPingTime) >= 3000 {
		seg := NewCmdOnlySegment()
		seg.Conv = this.conv
		seg.Command = CommandPing
		seg.ReceivinNext = this.receivingWorker.nextNumber
		seg.SendingNext = this.sendingWorker.firstUnacknowledged
		seg.PeerRTO = this.roundTrip.Timeout()
		if this.State() == StateReadyToClose {
			seg.Option = SegmentOptionClose
		}
		this.output.Write(seg)
		this.lastPingTime = current
		seg.Release()
	}

	// flash remain segments
	this.output.Flush()
}
Beispiel #6
0
func (this *Listener) OnReceive(payload *alloc.Buffer, session *proxy.SessionInfo) {
	defer payload.Release()

	src := session.Source

	if valid := this.authenticator.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),
		}
		auth, err := this.config.GetAuthenticator()
		if err != nil {
			log.Error("KCP|Listener: Failed to create authenticator: ", err)
		}
		conn = NewConnection(conv, writer, this.Addr().(*net.UDPAddr), srcAddr, auth, this.config)
		select {
		case this.awaitingConns <- conn:
		case <-time.After(time.Second * 5):
			conn.Close()
			return
		}
		this.sessions[sourceId] = conn
	}
	conn.Input(payload.Value)
}
Beispiel #7
0
func (v *TimedInboundRay) Release() {
	log.Debug("UDP Server: Releasing TimedInboundRay: ", v.name)
	v.Lock()
	defer v.Unlock()
	if v.server == nil {
		return
	}
	v.server = nil
	v.inboundRay.InboundInput().Close()
	v.inboundRay.InboundOutput().Release()
	v.inboundRay = nil
}
Beispiel #8
0
func (this *TimedInboundRay) Release() {
	log.Debug("UDP Server: Releasing TimedInboundRay: ", this.name)
	this.Lock()
	defer this.Unlock()
	if this.server == nil {
		return
	}
	this.server = nil
	this.inboundRay.InboundInput().Close()
	this.inboundRay.InboundOutput().Release()
	this.inboundRay = nil
}
Beispiel #9
0
func (this *Listener) Remove(dest string) {
	if !this.running {
		return
	}
	this.Lock()
	defer this.Unlock()
	if !this.running {
		return
	}
	log.Debug("KCP|Listener: Removing session ", dest)
	delete(this.sessions, dest)
}
Beispiel #10
0
func Pipe(reader Reader, writer Writer) error {
	for {
		buffer, err := reader.Read()
		if err != nil {
			log.Debug("IO: Pipe exits as ", err)
			return err
		}

		if buffer.IsEmpty() {
			buffer.Release()
			continue
		}

		err = writer.Write(buffer)
		if err != nil {
			log.Debug("IO: Pipe exits as ", err)
			buffer.Release()
			return err
		}
	}
}
Beispiel #11
0
func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) {
	p, err := proxy.CreateInboundHandler(ctx, proxyConfig)
	if err != nil {
		return nil, err
	}

	h := &AlwaysOnInboundHandler{
		proxy: p,
	}

	nl := p.Network()
	pr := receiverConfig.PortRange
	address := receiverConfig.Listen.AsAddress()
	if address == nil {
		address = net.AnyIP
	}
	for port := pr.From; port <= pr.To; port++ {
		if nl.HasNetwork(net.Network_TCP) {
			log.Debug("Proxyman|DefaultInboundHandler: creating tcp worker on ", address, ":", port)
			worker := &tcpWorker{
				address:          address,
				port:             net.Port(port),
				proxy:            p,
				stream:           receiverConfig.StreamSettings,
				recvOrigDest:     receiverConfig.ReceiveOriginalDestination,
				tag:              tag,
				allowPassiveConn: receiverConfig.AllowPassiveConnection,
			}
			h.workers = append(h.workers, worker)
		}

		if nl.HasNetwork(net.Network_UDP) {
			worker := &udpWorker{
				tag:          tag,
				proxy:        p,
				address:      address,
				port:         net.Port(port),
				recvOrigDest: receiverConfig.ReceiveOriginalDestination,
			}
			h.workers = append(h.workers, worker)
		}
	}

	return h, nil
}
Beispiel #12
0
func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buffer) bool {
	log.Debug("UDP Server: Locating existing connection for ", name)
	this.RLock()
	defer this.RUnlock()
	if entry, found := this.conns[name]; found {
		outputStream := entry.InboundInput()
		if outputStream == nil {
			return false
		}
		err := outputStream.Write(payload)
		if err != nil {
			go entry.Release()
			return false
		}
		return true
	}
	return false
}
Beispiel #13
0
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection) error {
	log.Debug("Dokodemo: processing connection from: ", conn.RemoteAddr())
	conn.SetReusable(false)
	ctx = proxy.ContextWithDestination(ctx, net.Destination{
		Network: network,
		Address: d.address,
		Port:    d.port,
	})
	inboundRay := d.packetDispatcher.DispatchToOutbound(ctx)

	requestDone := signal.ExecuteAsync(func() error {
		defer inboundRay.InboundInput().Close()

		timedReader := net.NewTimeOutReader(d.config.Timeout, conn)
		chunkReader := buf.NewReader(timedReader)

		if err := buf.PipeUntilEOF(chunkReader, inboundRay.InboundInput()); err != nil {
			log.Info("Dokodemo: Failed to transport request: ", err)
			return err
		}

		return nil
	})

	responseDone := signal.ExecuteAsync(func() error {
		v2writer := buf.NewWriter(conn)

		if err := buf.PipeUntilEOF(inboundRay.InboundOutput(), v2writer); err != nil {
			log.Info("Dokodemo: Failed to transport response: ", err)
			return err
		}
		return nil
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		inboundRay.InboundInput().CloseError()
		inboundRay.InboundOutput().CloseError()
		log.Info("Dokodemo: Connection ends with ", err)
		return err
	}

	return nil
}
Beispiel #14
0
func (v *Dispatcher) Dispatch(ctx context.Context, destination v2net.Destination, payload *buf.Buffer, callback ResponseCallback) {
	// TODO: Add user to destString
	destString := destination.String()
	log.Debug("UDP|Server: Dispatch request: ", destString)

	inboundRay, existing := v.getInboundRay(ctx, destination)
	outputStream := inboundRay.InboundInput()
	if outputStream != nil {
		if err := outputStream.Write(payload); err != nil {
			v.RemoveRay(destString)
		}
	}
	if !existing {
		go func() {
			handleInput(inboundRay.InboundOutput(), callback)
			v.RemoveRay(destString)
		}()
	}
}
Beispiel #15
0
func (v *Connection) flush() {
	current := v.Elapsed()

	if v.State() == StateTerminated {
		return
	}
	if v.State() == StateActive && current-atomic.LoadUint32(&v.lastIncomingTime) >= 30000 {
		v.Close()
	}
	if v.State() == StateReadyToClose && v.sendingWorker.IsEmpty() {
		v.SetState(StateTerminating)
	}

	if v.State() == StateTerminating {
		log.Debug("KCP|Connection: #", v.conv, " sending terminating cmd.")
		v.Ping(current, CommandTerminate)
		v.output.Flush()

		if current-atomic.LoadUint32(&v.stateBeginTime) > 8000 {
			v.SetState(StateTerminated)
		}
		return
	}
	if v.State() == StatePeerTerminating && current-atomic.LoadUint32(&v.stateBeginTime) > 4000 {
		v.SetState(StateTerminating)
	}

	if v.State() == StateReadyToClose && current-atomic.LoadUint32(&v.stateBeginTime) > 15000 {
		v.SetState(StateTerminating)
	}

	// flush acknowledges
	v.receivingWorker.Flush(current)
	v.sendingWorker.Flush(current)

	if current-atomic.LoadUint32(&v.lastPingTime) >= 3000 {
		v.Ping(current, CommandPing)
	}

	// flash remain segments
	v.output.Flush()
}
Beispiel #16
0
// Private: Visible for testing.
func (v *UDPNameServer) HandleResponse(payload *buf.Buffer) {
	msg := new(dns.Msg)
	err := msg.Unpack(payload.Bytes())
	if err != nil {
		log.Warning("DNS: Failed to parse DNS response: ", err)
		return
	}
	record := &ARecord{
		IPs: make([]net.IP, 0, 16),
	}
	id := msg.Id
	ttl := DefaultTTL
	log.Debug("DNS: Handling response for id ", id, " content: ", msg.String())

	v.Lock()
	request, found := v.requests[id]
	if !found {
		v.Unlock()
		return
	}
	delete(v.requests, id)
	v.Unlock()

	for _, rr := range msg.Answer {
		switch rr := rr.(type) {
		case *dns.A:
			record.IPs = append(record.IPs, rr.A)
			if rr.Hdr.Ttl < ttl {
				ttl = rr.Hdr.Ttl
			}
		case *dns.AAAA:
			record.IPs = append(record.IPs, rr.AAAA)
			if rr.Hdr.Ttl < ttl {
				ttl = rr.Hdr.Ttl
			}
		}
	}
	record.Expire = time.Now().Add(time.Second * time.Duration(ttl))

	request.response <- record
	close(request.response)
}
Beispiel #17
0
func (v *ConnectionCache) Get(dest string) net.Conn {
	v.Lock()
	defer v.Unlock()

	list, found := v.cache[dest]
	if !found {
		return nil
	}

	firstValid := FindFirstValid(list)
	if firstValid == -1 {
		delete(v.cache, dest)
		return nil
	}
	res := list[firstValid].conn
	list = list[firstValid+1:]
	v.cache[dest] = list
	log.Debug("WS:Conn Cache used.")
	return res
}
Beispiel #18
0
func (this *Connection) SetState(state State) {
	current := this.Elapsed()
	atomic.StoreInt32((*int32)(&this.state), int32(state))
	atomic.StoreUint32(&this.stateBeginTime, current)
	log.Debug("KCP|Connection: #", this.conv, " entering state ", state, " at ", current)

	switch state {
	case StateReadyToClose:
		this.receivingWorker.CloseRead()
	case StatePeerClosed:
		this.sendingWorker.CloseWrite()
	case StateTerminating:
		this.receivingWorker.CloseRead()
		this.sendingWorker.CloseWrite()
	case StatePeerTerminating:
		this.sendingWorker.CloseWrite()
	case StateTerminated:
		this.receivingWorker.CloseRead()
		this.sendingWorker.CloseWrite()
	}
}
Beispiel #19
0
// Private: Visible for testing.
func (v *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
	var id uint16
	v.Lock()
	if len(v.requests) > CleanupThreshold && v.nextCleanup.Before(time.Now()) {
		v.nextCleanup = time.Now().Add(CleanupInterval)
		go v.Cleanup()
	}

	for {
		id = uint16(dice.Roll(65536))
		if _, found := v.requests[id]; found {
			continue
		}
		log.Debug("DNS: Add pending request id ", id)
		v.requests[id] = &PendingRequest{
			expire:   time.Now().Add(time.Second * 8),
			response: response,
		}
		break
	}
	v.Unlock()
	return id
}
Beispiel #20
0
func (this *UDPServer) Dispatch(session *proxy.SessionInfo, payload *alloc.Buffer, callback UDPResponseCallback) {
	source := session.Source
	destination := session.Destination

	// TODO: Add user to destString
	destString := source.String() + "-" + destination.String()
	log.Debug("UDP Server: Dispatch request: ", destString)
	if this.locateExistingAndDispatch(destString, payload) {
		return
	}

	log.Info("UDP Server: establishing new connection for ", destString)
	inboundRay := this.packetDispatcher.DispatchToOutbound(session)
	timedInboundRay := NewTimedInboundRay(destString, inboundRay, this)
	outputStream := timedInboundRay.InboundInput()
	if outputStream != nil {
		outputStream.Write(payload)
	}

	this.Lock()
	this.conns[destString] = timedInboundRay
	this.Unlock()
	go this.handleConnection(timedInboundRay, source, callback)
}
Beispiel #21
0
func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
	buffer := make([]byte, 512)

	_, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen])
	if err != nil {
		log.Info("Raw: Failed to read request header: ", err)
		return nil, io.EOF
	}

	user, timestamp, valid := this.userValidator.Get(buffer[:protocol.IDBytesLen])
	if !valid {
		return nil, protocol.ErrInvalidUser
	}

	timestampHash := md5.New()
	timestampHash.Write(hashTimestamp(timestamp))
	iv := timestampHash.Sum(nil)
	account := user.Account.(*vmess.Account)
	aesStream := crypto.NewAesDecryptionStream(account.ID.CmdKey(), iv)
	decryptor := crypto.NewCryptionReader(aesStream, reader)

	nBytes, err := io.ReadFull(decryptor, buffer[:41])
	if err != nil {
		log.Debug("Raw: Failed to read request header (", nBytes, " bytes): ", err)
		return nil, err
	}
	bufferLen := nBytes

	request := &protocol.RequestHeader{
		User:    user,
		Version: buffer[0],
	}

	if request.Version != Version {
		log.Info("Raw: Invalid protocol version ", request.Version)
		return nil, protocol.ErrInvalidVersion
	}

	this.requestBodyIV = append([]byte(nil), buffer[1:17]...)   // 16 bytes
	this.requestBodyKey = append([]byte(nil), buffer[17:33]...) // 16 bytes
	this.responseHeader = buffer[33]                            // 1 byte
	request.Option = protocol.RequestOption(buffer[34])         // 1 byte + 2 bytes reserved
	request.Command = protocol.RequestCommand(buffer[37])

	request.Port = v2net.PortFromBytes(buffer[38:40])

	switch buffer[40] {
	case AddrTypeIPv4:
		nBytes, err = io.ReadFull(decryptor, buffer[41:45]) // 4 bytes
		bufferLen += 4
		if err != nil {
			log.Debug("VMess: Failed to read target IPv4 (", nBytes, " bytes): ", err)
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[41:45])
	case AddrTypeIPv6:
		nBytes, err = io.ReadFull(decryptor, buffer[41:57]) // 16 bytes
		bufferLen += 16
		if err != nil {
			log.Debug("VMess: Failed to read target IPv6 (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[41:57])
	case AddrTypeDomain:
		nBytes, err = io.ReadFull(decryptor, buffer[41:42])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		domainLength := int(buffer[41])
		if domainLength == 0 {
			return nil, transport.ErrCorruptedPacket
		}
		nBytes, err = io.ReadFull(decryptor, buffer[42:42+domainLength])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		bufferLen += 1 + domainLength
		request.Address = v2net.DomainAddress(string(buffer[42 : 42+domainLength]))
	}

	nBytes, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+4])
	if err != nil {
		log.Debug("VMess: Failed to read checksum (", nBytes, " bytes): ", nBytes, err)
		return nil, err
	}

	fnv1a := fnv.New32a()
	fnv1a.Write(buffer[:bufferLen])
	actualHash := fnv1a.Sum32()
	expectedHash := serial.BytesToUint32(buffer[bufferLen : bufferLen+4])

	if actualHash != expectedHash {
		return nil, transport.ErrCorruptedPacket
	}

	return request, nil
}