示例#1
0
func (p *multiplexer) connectToDest(frm *frame, key string, tun *Conn) {
	defer func() {
		ex.CatchException(recover())
	}()
	var (
		dstConn net.Conn
		err     error
		target  = string(frm.data)
	)
	dstConn, err = net.DialTimeout("tcp", target, GENERAL_SO_TIMEOUT)
	frm.length = 0
	if err != nil {
		p.router.removePreRegistered(key)
		log.Errorf("Cannot connect to [%s] for %s error: %s\n", target, key, err)
		frm.action = FRAME_ACTION_OPEN_N
		tunWrite2(tun, frm)
	} else {
		if log.V(1) {
			log.Infoln("OPEN", target, "for", key)
		}
		dstConn.SetReadDeadline(ZERO_TIME)
		edge := p.router.register(key, target, tun, dstConn, false) // write edge
		frm.action = FRAME_ACTION_OPEN_Y
		if tunWrite2(tun, frm) == nil {
			p.relay(edge, tun, frm.sid) // read edge
		} else { // send open_y failed
			SafeClose(tun)
		}
	}
}
func (nego *d5SNegotiation) verifyThenDHExchange(conn net.Conn, credBuf []byte) (key []byte, err error) {
	userIdentity, err := RSADecrypt(credBuf, nego.RSAKeys.priv)
	ThrowErr(err)
	clientIdentity := string(userIdentity)
	if log.V(2) {
		log.Infoln("Auth clientIdentity:", clientIdentity)
	}
	allow, ex := nego.AuthSys.Authenticate(userIdentity)
	cDHPub, err := ReadFullByLen(2, conn)
	if !allow {
		log.Warningf("Auth %s failed: %v\n", clientIdentity, ex)
		conn.Write([]byte{0, 1, 0xff})
		return nil, ex
	}
	nego.clientIdentity = clientIdentity
	key = takeSharedKey(nego.dhKeys, cDHPub)
	//	if log.V(5) {
	//		dumpHex("Sharedkey", key)
	//	}
	buf := new(bytes.Buffer)
	buf.Write(nego.dhKeys.pubLen)
	buf.Write(nego.dhKeys.pub)
	_, err = buf.WriteTo(conn)
	return
}
func (context *bootContext) startServer() {
	defer func() {
		ex.CatchException(recover())
		sigChan <- t.Bye
	}()
	var conf = t.Parse_d5sFile(context.config)
	context.setLogVerbose(conf.Verbose)
	log.Info(versionString())
	log.Infoln("Server is listening on", conf.ListenAddr)

	ln, err := net.ListenTCP("tcp", conf.ListenAddr)
	if err != nil {
		log.Fatalln(err)
	}
	defer ln.Close()

	dhKeys := t.GenerateDHKeyPairs()
	server := t.NewServer(conf, dhKeys)
	context.statser = server
	for {
		conn, err := ln.AcceptTCP()
		if err == nil {
			go server.TunnelServe(conn)
		} else {
			t.SafeClose(conn)
		}
	}
}
func (t *signalTunnel) acknowledged() {
	if log.V(4) {
		log.Infoln("Ping/acknowledged by", t.remoteAddr)
	}
	t.tun.SetReadDeadline(ZERO_TIME)
	t.active(-2) // so slow down the tempo
}
func (context *bootContext) startClient() {
	defer func() {
		ex.CatchException(recover())
		sigChan <- t.Bye
	}()
	var conf = t.Parse_d5cFile(context.config)
	context.setLogVerbose(conf.Verbose)
	log.Info(versionString())
	log.Infoln("Socks5/Http is working at", conf.ListenAddr)

	mgr := NewClientMgr(conf)
	context.statser = mgr

	ln, err := net.ListenTCP("tcp", conf.ListenAddr)
	if err != nil {
		log.Fatalln(err)
	}
	defer ln.Close()
	for {
		conn, err := ln.Accept()
		if err == nil {
			go mgr.selectClientServ(conn)
		} else {
			t.SafeClose(conn)
		}
	}
}
func (t *signalTunnel) imAlive() {
	if log.V(4) {
		log.Infoln("Ping/responded to", t.remoteAddr)
	}
	t.active(-1) // up tempo for become a sender
	_, err := t.postCommand(CTL_PONG, nil)
	if err != nil {
		SafeClose(t.tun)
		log.Warningln("Reply ping failed and then closed", t.remoteAddr, err)
	}
}
示例#7
0
文件: queue.go 项目: hangim/deblocus
// close for ending of queued task
func (q *equeue) _close(force bool, close_code uint) {
	q.lock.Lock()
	defer q.lock.Unlock()
	e := q.edge
	if log.V(4) {
		switch close_code {
		case CLOSED_BY_ERR:
			log.Infoln("terminate", e.dest)
		case CLOSED_FORCE:
			log.Infoln("close", e.dest)
		case CLOSED_WRITE:
			log.Infof("closeW %s by peer\n", e.dest)
		}
	}
	q.buffer.Init()
	q.buffer = nil
	if force {
		e.closed = TCP_CLOSE_R | TCP_CLOSE_W
		SafeClose(e.conn)
	} else {
		closeW(e.conn)
	}
}
示例#8
0
文件: client.go 项目: hangim/deblocus
func (c *Client) initialNegotiation() (tun *Conn) {
	var tp = new(tunParams)
	var err error
	tun, err = c.nego.negotiate(tp)
	if err != nil {
		log.Errorf("Failed to connect %s, Retry after %s\n", c.nego.RemoteName(), RETRY_INTERVAL)
		return nil
	}
	c.token = tp.token
	tp.token = nil
	c.tp = tp

	log.Infoln("Login to the gateway", c.nego.RemoteName(), "successfully")
	return tun
}
示例#9
0
文件: queue.go 项目: hangim/deblocus
func sendFrame(frm *frame) (werr bool) {
	dst := frm.conn.conn
	if log.V(5) {
		log.Infoln("SEND queue", frm)
	}
	dst.SetWriteDeadline(time.Now().Add(GENERAL_SO_TIMEOUT))
	nw, ew := dst.Write(frm.data)
	if nw == int(frm.length) && ew == nil {
		return
	}
	werr = true
	// an error occured
	log.Warningf("Write edge(%s) error(%v). %s\n", frm.conn.dest, ew, frm)
	return
}
func (t *signalTunnel) areYouAlive() {
	if log.V(4) {
		log.Infoln("Ping/launched to", t.remoteAddr)
	}
	_, err := t.postCommand(CTL_PING, nil)
	// Either waiting pong timeout or send ping failed
	if err != nil {
		SafeClose(t.tun)
		log.Warningln("Ping remote failed and then closed", t.remoteAddr, err)
	} else {
		t.tun.SetReadDeadline(time.Now().Add(GENERAL_SO_TIMEOUT * 2))
		// impossible call by timer, will reset by acknowledged or read timeout.
		t.active(-1)
	}
}
func waitSignal() {
	USR2 := syscall.Signal(12) // fake signal-USR2 for windows
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, USR2)
	for sig := range sigChan {
		switch sig {
		case t.Bye:
			log.Exitln("Exiting.")
			return
		case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM:
			log.Exitln("Terminated by", sig)
			return
		case USR2:
			context.doStats()
		default:
			log.Infoln("Ingore signal", sig)
		}
	}
}
func (t *signalTunnel) active(times int64) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if times > 0 { // active link in transferring
		var d = (times - t.lastResetTime) << 1
		// allow reset at least half interval
		if d > int64(t.interval/time.Second) {
			if log.V(4) {
				log.Infoln("suppress the next ping task")
			}
			t.lastResetTime = times
			t.lived.Reset(t.interval)
		}
	} else if times < 0 { // scheduled ping
		t.interval = t.baseInterval * time.Duration(-times)
		t.lastResetTime = time.Now().Unix()
		t.lived.Reset(t.interval)
	}
}
func (s *S5Step1) respondSocks5() bool {
	var ack = []byte{5, 0, 0, 1, 0, 0, 0, 0, 0, 0}
	if s.err != nil {
		// handshake error feedback
		if ex, y := s.err.(*exception.Exception); y {
			ack[1] = byte(ex.Code())
		} else {
			ack[1] = 0x1
		}
		s.conn.Write(ack)
		s.conn.Close()
		return true
	}
	// accept
	_, err := s.conn.Write(ack)
	if err != nil {
		log.Infoln(err)
		return true
	}
	return false
}
func (c *Client) eventHandler(e event, msg ...interface{}) {
	var mlen = len(msg)
	switch e {
	case evt_st_closed:
		atomic.StoreInt32(&c.State, -1)
		c.clearTokens()
		log.Errorf("Lost connection of gateway %s. Reconnect after %s\n", c.nego.RemoteName(), RETRY_INTERVAL)
		go c.StartSigTun(mlen > 0)
	case evt_st_ready:
		atomic.StoreInt32(&c.State, 0)
		log.Infoln("Tunnel negotiated with gateway", msg[0], "successfully")
		go c.startMultiplexer()
	case evt_dt_closed:
		go c.startDataTun(mlen > 0)
	case evt_st_msg:
		if mlen == 1 {
			go c.commandHandler(msg[0].(byte), nil)
		} else {
			go c.commandHandler(msg[0].(byte), msg[1].([]byte))
		}
	case evt_st_active:
		c.sigTun.active(msg[0].(int64))
	}
}
示例#15
0
// TODO notify peer to slow down when queue increased too fast
func (p *multiplexer) Listen(tun *Conn, handler event_handler, interval int) {
	tun.priority = &TSPriority{0, 1e9}
	p.pool.Push(tun)
	defer p.onTunDisconnected(tun, handler)
	tun.SetSockOpt(1, 0, 1)
	var (
		header = make([]byte, FRAME_HEADER_LEN)
		router = p.router
		idle   = NewIdler(interval, p.isClient)
		nr     int
		er     error
		frm    *frame
		key    string
	)
	if !p.isClient {
		// first ping frame will let client to be aware of using a valid token.
		idle.ping(tun)
	}
	for {
		idle.newRound(tun)
		nr, er = io.ReadFull(tun, header)
		if nr == FRAME_HEADER_LEN {
			frm = _parseFrameHeader(header)
			if frm.length > 0 {
				nr, er = io.ReadFull(tun, frm.data)
			}
		}
		if er != nil {
			switch idle.consumeError(er) {
			case ERR_NEW_PING:
				if idle.ping(tun) == nil {
					continue
				}
			case ERR_PING_TIMEOUT:
				if log.V(2) {
					log.Warningln("Peer was unresponsive then close", tun.identifier)
				}
			default:
				if log.V(2) {
					log.Warningln("Read tunnel", tun.identifier, er)
				}
			}
			return // error, abandon tunnel
		}
		key = sessionKey(tun, frm.sid)

		switch frm.action {
		case FRAME_ACTION_CLOSE_W:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.closed |= TCP_CLOSE_W
				edge.deliver(frm)
			}
		case FRAME_ACTION_CLOSE_R:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.closed |= TCP_CLOSE_R
				closeR(edge.conn)
			}
		case FRAME_ACTION_DATA:
			edge, pre := router.getRegistered(key)
			if edge != nil {
				edge.deliver(frm)
			} else if pre {
				router.preDeliver(key, frm)
			} else {
				if log.V(2) {
					log.Warningln("peer send data to an unexisted socket.", key, frm)
				}
				// trigger sending close to notice peer.
				_frame(header, FRAME_ACTION_CLOSE_R, frm.sid, nil)
				if tunWrite1(tun, header) != nil {
					return
				}
			}
		case FRAME_ACTION_OPEN:
			router.preRegister(key)
			go p.connectToDest(frm, key, tun)
		case FRAME_ACTION_OPEN_N, FRAME_ACTION_OPEN_Y:
			edge, _ := router.getRegistered(key)
			if edge != nil {
				if log.V(4) {
					if frm.action == FRAME_ACTION_OPEN_Y {
						log.Infoln(p.role, "recv OPEN_Y", frm)
					} else {
						log.Infoln(p.role, "recv OPEN_N", frm)
					}
				}
				edge.ready <- frm.action
				close(edge.ready)
			} else {
				if log.V(2) {
					log.Warningln("peer send OPENx to an unexisted socket.", key, frm)
				}
			}
		case FRAME_ACTION_PING:
			if idle.pong(tun) == nil {
				atomic.AddInt32(&p.pingCnt, 1)
			} else { // reply pong failed
				return
			}
		case FRAME_ACTION_PONG:
			if !idle.verify() {
				log.Warningln("Incorrect action_pong received")
			}
		case FRAME_ACTION_TOKENS:
			handler(evt_tokens, frm.data)
		default:
			log.Errorln(p.role, "Unrecognized", frm)
		}
		tun.Update()
	}
}
// TODO notify peer to slow down when queue increased too fast
func (p *multiplexer) Listen(tun *Conn, handler event_handler, interval int) {
	if p.isClient {
		tun.priority = &TSPriority{0, 1e9}
		p.pool.Push(tun)
	}
	defer p.onTunDisconnected(tun, handler)
	tun.SetSockOpt(1, 1, 0)
	var (
		header     = make([]byte, FRAME_HEADER_LEN)
		router     = p.router
		idle       = NewIdler(interval, p.isClient)
		lastActive = time.Now().Unix()
		nr         int
		er         error
		now        int64
		frm        *frame
		key        string
	)
	for {
		idle.newRound(tun)
		nr, er = io.ReadFull(tun, header)
		if nr == FRAME_HEADER_LEN {
			frm = _parseFrameHeader(header)
			if frm.length > 0 {
				nr, er = io.ReadFull(tun, frm.data)
			}
		}
		if er != nil {
			switch idle.consumeError(er) {
			case ERR_NEW_PING:
				if idle.ping(tun) == nil {
					continue
				}
			case ERR_PING_TIMEOUT:
				log.Errorln("Peer was unresponsive then close", tun.identifier)
			default:
				log.Errorln("Read tunnel", tun.identifier, er)
			}
			return // error, abandon tunnel
		}
		key = sessionKey(tun, frm.sid)

		switch frm.action {
		case FRAME_ACTION_CLOSE_W:
			if edge := router.getRegistered(key); edge != nil {
				edge.closed |= TCP_CLOSE_W
				edge.deliver(frm)
			}
		case FRAME_ACTION_CLOSE_R:
			if edge := router.getRegistered(key); edge != nil {
				edge.closed |= TCP_CLOSE_R
				closeR(edge.conn)
			}
		case FRAME_ACTION_DATA:
			edge := router.getRegistered(key)
			if edge == nil {
				if log.V(2) {
					log.Warningln("peer send data to an unexisted socket.", key, frm)
				}
				// trigger sending close to notice peer.
				_frame(header, FRAME_ACTION_CLOSE_R, frm.sid, nil)
				if tunWrite1(tun, header) != nil {
					return
				}
			} else {
				edge.deliver(frm)
			}
		case FRAME_ACTION_OPEN:
			go p.connectToDest(frm, key, tun)
		case FRAME_ACTION_OPEN_N, FRAME_ACTION_OPEN_Y:
			edge := router.getRegistered(key)
			if edge == nil {
				if log.V(2) {
					log.Warningln("peer send OPENx to an unexisted socket.", key, frm)
				}
			} else {
				if log.V(4) {
					if frm.action == FRAME_ACTION_OPEN_Y {
						log.Infoln(p.mode, "recv OPEN_Y", frm)
					} else {
						log.Infoln(p.mode, "recv OPEN_N", frm)
					}
				}
				edge.ready <- frm.action
				close(edge.ready)
			}
		case FRAME_ACTION_PING:
			if idle.pong(tun) != nil {
				return
			}
		case FRAME_ACTION_PONG:
			if !idle.verify() {
				log.Warningln("Incorrect action_pong received")
			}
		default:
			log.Errorln(p.mode, "Unrecognized", frm)
		}

		// prevent frequently calling, especially in high-speed transmitting.
		if now = time.Now().Unix(); (now-lastActive) > 2 && handler != nil {
			lastActive = now
			handler(evt_st_active, now)
		}
		if p.isClient {
			tun.Update()
		}
	}
}