コード例 #1
0
ファイル: client.go プロジェクト: noscripter/deblocus
func (c *Client) ClientServe(conn net.Conn) {
	var done bool
	defer func() {
		ex.Catch(recover(), nil)
		if !done {
			SafeClose(conn)
		}
	}()

	reqNum := atomic.AddInt32(&c.reqCnt, 1)
	pbConn := NewPushbackInputStream(conn)
	proto, err := detectProtocol(pbConn)
	if err != nil {
		// chrome will make some advance connections and then aborted
		// cause a EOF
		if err != io.EOF && err != io.ErrUnexpectedEOF {
			log.Warningln(err)
		}
		return
	}

	switch proto {
	case PROT_SOCKS5:
		s5 := socks5Handler{pbConn}
		if s5.handshake() {
			if literalTarget, ok := s5.readRequest(); ok {
				c.mux.HandleRequest("SOCKS5", conn, literalTarget)
				done = true
			}
		}
	case PROT_HTTP:
		proto, target, err := httpProxyHandshake(pbConn)
		if err != nil {
			log.Warningln(err)
			break
		}
		switch proto {
		case PROT_HTTP:
			// plain http
			c.mux.HandleRequest("HTTP", pbConn, target)
		case PROT_HTTP_T:
			// http tunnel
			c.mux.HandleRequest("HTTP/T", conn, target)
		case PROT_LOCAL:
			// target is requestUri
			c.localServlet(conn, target)
		}
		done = true
	default:
		log.Warningln("Unrecognized request from", conn.RemoteAddr())
		time.Sleep(REST_INTERVAL)
	}
	// client setSeed at every 32 req
	if reqNum&0x1f == 0x1f {
		myRand.setSeed(0)
	}
}
コード例 #2
0
ファイル: queue.go プロジェクト: noscripter/deblocus
func (r *egressRouter) clean() {
	defer func() {
		ex.Catch(recover(), nil)
	}()
	r.lock.Lock()
	defer r.lock.Unlock()
	for k, e := range r.registry {
		// call conn.LocalAddr will give rise to checking fd.
		if e == nil || e.closed_gte(TCP_CLOSED) || e.conn.LocalAddr() == nil {
			delete(r.registry, k)
		}
	}
}
コード例 #3
0
ファイル: multiplexer.go プロジェクト: xyz12810/deblocus
// destroy each listener of all pooled tun, and destroy egress queues
func (p *multiplexer) destroy() {
	if atomic.LoadInt32(&p.status) < 0 {
		return
	}
	defer func() {
		if !ex.Catch(recover(), nil) {
			atomic.StoreInt32(&p.status, MUX_CLOSED)
		}
	}()
	atomic.StoreInt32(&p.status, MUX_PENDING_CLOSE)
	p.router.destroy() // destroy queue
	p.pool.destroy()
	p.router = nil
	p.pool = nil
}
コード例 #4
0
ファイル: d5.go プロジェクト: noscripter/deblocus
func (n *d5cman) Connect(p *tunParams) (conn *Conn, err error) {
	var rawConn net.Conn
	defer func() {
		n.dbcHello, n.sRand = nil, nil
		if exception.Catch(recover(), &err) {
			SafeClose(rawConn)
			if t, y := err.(*exception.Exception); y {
				// must terminate
				switch t.Origin {
				case ERR_TIME_ERROR:
					line := string(bytes.Repeat([]byte{'+'}, 30))
					log.Warningln(line)
					log.Warningln("Maybe your clock is inaccurate, or your client credential is invalid.")
					log.Warningln(line)
					os.Exit(2)
				case INCOMPATIBLE_VERSION:
					log.Warningln(err)
					os.Exit(3)
				}
			}
		}
	}()
	rawConn, err = net.DialTimeout("tcp", n.sAddr, GENERAL_SO_TIMEOUT)
	n.dhKey, _ = crypto.NewDHKey(DH_METHOD)
	if err != nil {
		return
	}

	conn = NewConn(rawConn, nullCipherKit)
	if err = n.requestDHExchange(conn); err != nil {
		return
	}
	var cf *CipherFactory
	cf, err = n.finishDHExchange(conn)
	if err != nil {
		return
	}
	if err = n.validate(conn); err != nil {
		return
	}
	if err = n.authThenFinishSetting(conn, p); err != nil {
		return
	}
	p.cipherFactory = cf
	conn.SetId(n.provider, false)
	return
}
コード例 #5
0
ファイル: d5.go プロジェクト: noscripter/deblocus
// new connection
func (n *d5sman) fullHandshake(conn *Conn) (session *Session, err error) {
	defer func() {
		if exception.Catch(recover(), &err) {
			if t, y := err.(*exception.Exception); y && t.Origin == ABORTED_ERROR {
				log.Warningf("Handshake aborted by client from=%s", n.clientAddr)
			} else {
				log.Warningf("Handshake error=%v from=%s", err, n.clientAddr)
			}
		}
	}()
	var cf *CipherFactory
	n.isNewSession = true
	cf, err = n.finishDHExchange(conn)
	if err != nil {
		return
	}
	session = n.NewSession(cf)
	err = n.authenticate(conn, session)
	return
}
コード例 #6
0
ファイル: multiplexer.go プロジェクト: xyz12810/deblocus
func (p *multiplexer) connectToDest(frm *frame, key string, tun *Conn) {
	defer func() {
		p.wg.Done()
		ex.Catch(recover(), nil)
	}()
	var (
		dstConn net.Conn
		err     error
		target  = string(frm.data)
		denied  = false
	)
	if p.filter != nil {
		denied = p.filter.Filter(target)
	}
	if !denied {
		dstConn, err = dialer.Dial("tcp", target)
	}
	if err != nil || denied {
		p.router.removePreRegistered(key)
		if denied {
			frm.action = FRAME_ACTION_OPEN_DENIED
			log.Warningf("Denied request [%s] for %s\n", target, key)
		} else {
			frm.action = FRAME_ACTION_OPEN_N
			log.Warningf("Cannot connect to [%s] for %s error: %s\n", target, key, err)
		}
		frameWriteHead(tun, frm)
	} else {
		edge := p.router.register(key, target, tun, dstConn, false) // write edge
		if log.V(log.LV_SVR_OPEN) {
			log.Infoln("OPEN", target, "for", key)
		}
		dstConn.SetReadDeadline(ZERO_TIME)
		frm.action = FRAME_ACTION_OPEN_Y
		if frameWriteHead(tun, frm) == nil {
			p.relay(edge, tun, frm.sid) // read edge
		} else { // send open_y failed
			SafeClose(tun)
		}
	}
}
コード例 #7
0
ファイル: server.go プロジェクト: noscripter/deblocus
func (t *Server) TunnelServe(raw *net.TCPConn) {
	var conn = NewConn(raw, nullCipherKit)
	defer func() {
		ex.Catch(recover(), nil)
	}()

	man := &d5sman{
		Server:     t,
		clientAddr: raw.RemoteAddr(),
	}
	// read atomically
	tcPool := *(*[]uint64)(atomic.LoadPointer(&t.tcPool))
	session, err := man.Connect(conn, tcPool)

	if err == nil {
		go session.DataTunServe(conn, man.isNewSession)
	} else {
		SafeClose(raw)
		if session != nil {
			t.sessionMgr.clearTokens(session)
		}
	}
}