Esempio n. 1
0
// 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(log.LV_ACT_FRM) {
		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("CloseWrite %s by peer\n", e.dest)
		}
	}

	for i, e := q.buffer.Len(), q.buffer.Front(); i > 0; i, e = i-1, e.Next() {
		f := e.Value.(*frame)
		if f != nil {
			f.free()
		}
	}

	q.buffer = nil
	if force {
		atomic.StoreUint32(&e.closed, TCP_CLOSED)
		SafeClose(e.conn)
	} else {
		closeW(e.conn)
	}
}
Esempio n. 2
0
func (ctx *bootContext) startServer() {
	defer func() {
		sigChan <- Bye
	}()
	var (
		conn *net.TCPConn
		ln   *net.TCPListener
		err  error
	)

	server := NewServer(ctx.cman)
	addr := ctx.cman.ListenAddr(SR_SERVER)

	ln, err = net.ListenTCP("tcp", addr)
	fatalError(err)
	defer ln.Close()

	ctx.register(server, ln)
	log.Infoln(versionString())
	log.Infoln("Server is listening on", addr)

	for {
		conn, err = ln.AcceptTCP()
		if err == nil {
			go server.TunnelServe(conn)
		} else {
			SafeClose(conn)
		}
	}
}
Esempio n. 3
0
func (ctx *bootContext) startClient() {
	defer func() {
		sigChan <- Bye
	}()
	var (
		conn *net.TCPConn
		ln   *net.TCPListener
		err  error
	)

	client := NewClient(ctx.cman)
	addr := ctx.cman.ListenAddr(SR_CLIENT)

	ln, err = net.ListenTCP("tcp", addr)
	fatalError(err)
	defer ln.Close()

	ctx.register(client, ln)
	log.Infoln(versionString())
	log.Infoln("Proxy(SOCKS5/HTTP) is listening on", addr)

	// connect to server
	go client.StartTun(true)

	for {
		conn, err = ln.AcceptTCP()
		if err == nil {
			go client.ClientServe(conn)
		} else {
			SafeClose(conn)
		}
	}
}
Esempio n. 4
0
func (n *d5sman) authenticate(conn *Conn, session *Session) error {
	var err error
	setRTimeout(conn)
	hashSRand, err := ReadFullByLen(1, conn)
	if err != nil {
		// client aborted
		if IsClosedError(err) {
			return ABORTED_ERROR.Apply(err)
		} else {
			return exception.Spawn(&err, "srand: read connection")
		}
	}

	myHashSRand := hash256(n.sRand)
	if !bytes.Equal(hashSRand, myHashSRand) {
		// MITM ?
		return INCONSISTENT_HASH
	}

	// client identity
	setRTimeout(conn)
	idBuf, err := ReadFullByLen(1, conn)
	if err != nil {
		return exception.Spawn(&err, "auth: read connection")
	}

	user, passwd, err := n.deserializeIdentity(idBuf)
	if err != nil {
		return err
	}

	if log.V(log.LV_LOGIN) {
		log.Infoln("Login request:", user)
	}

	pass, err := n.AuthSys.Authenticate(user, passwd)
	if !pass {
		// authSys denied
		log.Warningf("Auth %s:%s failed: %v\n", user, passwd, err)
		// reply failed msg
		conn.Write([]byte{1, 0})
		return VALIDATION_FAILED
	}

	session.indentifySession(user, conn)
	w := newMsgWriter()
	w.WriteL1Msg([]byte{AUTH_PASS})
	w.WriteL2Msg(n.tunParams.serialize())
	// send tokens
	num := maxInt(GENERATE_TOKEN_NUM, n.Parallels+2)
	tokens := n.sessionMgr.createTokens(session, num)
	w.WriteL2Msg(tokens[1:]) // skip index=0

	setWTimeout(conn)
	err = w.WriteTo(conn)
	return exception.Spawn(&err, "setting: write connection")
}
Esempio n. 5
0
func NewGeoIPFilter(keyword string) (f *GeoIPFilter, e error) {
	if len(keyword) != 2 {
		return nil, fmt.Errorf("filter keyword must be 2-byte country_iso_code")
	}
	f = new(GeoIPFilter)
	f.keyword = StoU16(strings.ToUpper(keyword))
	f.tab = deserialize(buildGeoDB())
	log.Infoln("Init DestIPFilter with target keyword", keyword)
	return
}
Esempio n. 6
0
func (h *ConnPool) Select() *Conn {
	h.lock.Lock()
	defer h.lock.Unlock()
	if h.pool.Len() < 1 {
		return nil
	}
	sort.Sort(h.pool)
	if log.V(log.LV_TUN_SELECT) {
		log.Infoln("Selected tun", h.pool[0].LocalAddr())
	}
	selected := h.pool[0]
	atomic.AddInt64(&selected.priority.rank, SELECT_DECREASE)
	return selected
}
Esempio n. 7
0
func sendFrame(frm *frame) bool {
	dst := frm.conn.conn
	if log.V(log.LV_DAT_FRM) {
		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 false
	}
	// an error occured
	if log.V(log.LV_WARN_EDGE) {
		log.Warningf("Write edge (%s) error (%v) %s\n", frm.conn.dest, ew, frm)
	}
	return true
}
Esempio n. 8
0
func waitSignal() {
	USR2 := syscall.Signal(12) // fake signal-USR2 for windows
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM, USR2)
	for sig := range sigChan {
		switch sig {
		case Bye:
			log.Exitln("Exiting.")
			context.doClose()
			return
		case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM:
			log.Exitln("Terminated by", sig)
			context.doClose()
			return
		case USR2:
			context.doStats()
		default:
			log.Infoln("Ingore signal", sig)
		}
	}
}
Esempio n. 9
0
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)
		}
	}
}
Esempio n. 10
0
// TODO notify peer to slow down when queue increased too fast
func (p *multiplexer) Listen(tun *Conn, handler event_handler, interval int) error {
	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)
		idle   = NewIdler(interval, p.isClient)
		router = p.router
		nr     int
		er     error
		frm    *frame
		key    string
	)
	if !p.isClient {
		// server first ping client
		// make client 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, er = parse_frame(header)
			if er == nil && len(frm.data) > 0 {
				// read All and discard tail random
				nr, er = io.ReadFull(tun, frm.data)
				frm.data = frm.data[:frm.length]
			}
		}
		if er != nil {
			// shutdown
			if atomic.LoadInt32(&p.status) < 0 {
				time.Sleep(time.Second)
				return nil
			}
			switch idle.consumeError(er) {
			case ERR_NEW_PING:
				if er = idle.ping(tun); er == nil {
					continue
				}
			case ERR_PING_TIMEOUT:
				er = ex.New("Peer was unresponsive then close")
			}
			// abandon this connection
			return er
		}
		// prefix tun.identifier
		key = sessionKey(tun, frm.sid)

		switch frm.action {
		case FRAME_ACTION_CLOSE_W:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.bitwiseCompareAndSet(TCP_CLOSE_W)
				edge.deliver(frm)
			}

		case FRAME_ACTION_CLOSE_R:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.bitwiseCompareAndSet(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(log.LV_WARN) {
					log.Warningln("Peer sent data to an unexisted socket.", key, frm)
				}
				// trigger sending close to notice peer.
				pack(header, FRAME_ACTION_CLOSE_R, frm.sid, nil)
				if er = frameWriteBuffer(tun, header); er != nil {
					return er
				}
			}

		case FRAME_ACTION_OPEN:
			router.preRegister(key)
			p.wg.Add(1)
			go p.connectToDest(frm, key, tun)

		case FRAME_ACTION_OPEN_N, FRAME_ACTION_OPEN_Y, FRAME_ACTION_OPEN_DENIED:
			edge, _ := router.getRegistered(key)
			if edge != nil {
				if log.V(log.LV_ACT_FRM) {
					log.Infoln(p.role, "received OPEN_x", frm)
				}
				edge.ready <- frm.action
				close(edge.ready)
			} else {
				if log.V(log.LV_WARN) {
					log.Warningln("Peer sent OPEN_x to an unexisted socket.", key, frm)
				}
			}

		case FRAME_ACTION_PING:
			if er = idle.pong(tun); er == nil {
				atomic.AddInt32(&p.pingCnt, 1)
			} else { // reply pong failed
				return er
			}

		case FRAME_ACTION_PONG:
			if idle.verify() {
				if p.isClient && idle.lastPing > 0 {
					sRtt, devRtt := idle.updateRtt()
					atomic.StoreInt32(&p.sRtt, sRtt)
					if DEBUG {
						log.Infof("sRtt=%d devRtt=%d", sRtt, devRtt)
						if devRtt+(sRtt>>2) > sRtt {
							// restart ???
							log.Warningf("Network jitter sRtt=%d devRtt=%d", sRtt, devRtt)
						}
					}
				}
			} else {
				log.Warningln("Incorrect action_pong received")
			}

		case FRAME_ACTION_TOKENS:
			handler(evt_tokens, frm.data)

		default: // impossible
			return fmt.Errorf("Unrecognized %s", frm)
		}
		tun.Update()
	}
}