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) } }
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) } } }
// 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 }
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 }
// 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 }
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) } } }
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) } } }