func (tc *TunnelConn) handleIn(fd int) {
	targetFd := tc.getPeerFd(fd)
	// Block reading while more than 1KB need to be sent
	if ts, ok := writeCache[targetFd]; ok && len(ts) > 1024 {
		return
	}
	for num := len(buf); num == len(buf); {
		var err error
		num, err = tc.readOnce(fd)
		if num <= 0 || err != nil {
			return
		}

		toSend := getToSend(targetFd, buf[:num])
		sent, left, err := tc.writeOnce(targetFd, toSend)
		if err != nil {
			return
		}

		tc.RelTunnel.PassSize += uint64(sent)
		if left != nil {
			saveLeft(targetFd, left)
			continue
		}
		if _, ok := writeCache[targetFd]; ok {
			delete(writeCache, targetFd)
		}
		if tc.RelTunnel.PassSize > tc.RelTunnel.Limit {
			logger.Log(logger.INFO, "Block port [%d]", tc.RelTunnel.EPort)
			tc.shutdown()
			return
		}
	}
}
Пример #2
0
func Run(t *Tunnel) {
	var err error
	epollFd, err = syscall.EpollCreate(1024)
	if err != nil {
		logger.Log(logger.ERR, "Create epoll fd error [%s]", err)
		os.Exit(-2)
	}

	for _, step := range initStep {
		err = step.Action(t)
		if err != nil {
			fmt.Fprintf(os.Stderr, step.ErrFmt, err)
			os.Exit(-2)
		}
	}
	runTunnel = t

	events := make([]syscall.EpollEvent, 10, 10)
	for {
		en, err := syscall.EpollWait(epollFd, events, 1000)
		if err != nil {
			logger.Log(logger.ERR, "Wail epoll fd error [%s]", err)
			os.Exit(-2)
		}
		for i := 0; i < en; i++ {
			ee := events[i]
			if runTunnel.LFd == int(ee.Fd) {
				runTunnel.newConn()
				continue
			}
			tc, ok := fdTunnelConn[int(ee.Fd)]
			if !ok {
				continue
			}
			if ee.Events&syscall.EPOLLIN != 0 {
				tc.handleIn(int(ee.Fd))
			}
			if ee.Events&syscall.EPOLLOUT != 0 {
				tc.handleOut(int(ee.Fd))
			}
			if ee.Events&syscall.EPOLLHUP != 0 {
				tc.shutdown()
			}
		}
	}
}
Пример #3
0
func Stop() {
	logger.Log(logger.INFO, "Stop proxy server")
	if runTunnel != nil {
		syscall.Close(runTunnel.LFd)
		for _, tc := range fdTunnelConn {
			syscall.Close(tc.EFd)
			syscall.Close(tc.IFd)
		}
	}
}
Пример #4
0
func (t *Tunnel) newConn() {
	tc := TunnelConn{RelTunnel: t}
	for _, step := range pathAddStep {
		err := step.Action(&tc)
		if err != nil {
			logger.Log(logger.ERR, step.ErrFmt, t.EPort, err)
		}
	}
	timePassed := uint(time.Since(t.CheckTime).Seconds())
	if timePassed > t.Window {
		logger.Log(logger.INFO, "Resume port [%d] Capacity [%d]", t.EPort, t.Limit)
		// CheckTime is added on by times of window
		t.CheckTime = t.CheckTime.Add(time.Duration(timePassed-timePassed%t.Window) * time.Second)
		t.PassSize = 0
	} else if t.PassSize > t.Limit {
		logger.Log(logger.INFO, "Block port [%d]", t.EPort)
		tc.shutdown()
	}
	fdTunnelConn[tc.IFd], fdTunnelConn[tc.EFd] = &tc, &tc
}
func (tc *TunnelConn) handleOut(fd int) {
	out, ok := writeCache[fd]
	if !ok {
		return
	}
	num, err := syscall.Write(fd, out)
	if err != nil && err != syscall.EAGAIN {
		logger.Log(logger.ERR, "Write cache to fd [%d] error [%s]", fd, err)
		tc.shutdown()
	} else if err == nil && num < len(out) {
		writeCache[fd] = out[num:]
	} else if err == nil {
		delete(writeCache, fd)
	}
}
func (tc *TunnelConn) writeOnce(fd int, content []byte) (sent int, left []byte, err error) {
	sent, err = syscall.Write(fd, content)
	if err != nil && err != syscall.EAGAIN {
		logger.Log(logger.ERR, "Write fd [%d] send num [%d] ret [%d] error [%s]", fd, len(content), sent, err)
		tc.shutdown()
		return
	}
	if sent > 0 && sent < len(content) {
		left = content[sent:]
	} else if sent <= 0 && err == syscall.EAGAIN {
		sent = 0
		left = content
		err = nil
	}
	return
}