예제 #1
0
파일: main.go 프로젝트: yuanjs/kcptun
// handle multiplex-ed connection
func handleMux(conn io.ReadWriteCloser, target string) {
	// stream multiplex
	var mux *yamux.Session
	config := &yamux.Config{
		AcceptBacklog:          256,
		EnableKeepAlive:        true,
		KeepAliveInterval:      30 * time.Second,
		ConnectionWriteTimeout: 30 * time.Second,
		MaxStreamWindowSize:    16777216,
		LogOutput:              os.Stderr,
	}
	m, err := yamux.Server(conn, config)
	if err != nil {
		log.Println(err)
		return
	}
	mux = m
	defer mux.Close()

	for {
		p1, err := mux.Accept()
		if err != nil {
			log.Println(err)
			return
		}
		p2, err := net.DialTimeout("tcp", target, 5*time.Second)
		if err != nil {
			log.Println(err)
			return
		}
		go handleClient(p1, p2)
	}
}
예제 #2
0
파일: tunnels.go 프로젝트: keshavdv/subway
func handleCreateTunnel(session *yamux.Session, port int) (url string, err error) {
	// TODO: Attempt to bind to local port
	addr := fmt.Sprintf("127.0.0.1:%v", port)
	log.WithFields(logrus.Fields{
		"server": addr,
	}).Info("attempting to connect to server")
	local, err := net.Dial("tcp", addr)
	if err != nil {
		return "", errors.New("Could not establish connection to host port.")
	}
	log.WithFields(logrus.Fields{
		"server": addr,
	}).Info("connected to server")

	// Establish stream
	stream, err := session.Open()
	if err != nil {
		return "", errors.New("Could not create stream.")
	}

	// TODO: send control message
	log.WithFields(logrus.Fields{
		"server": addr,
	}).Info("sending TunnelRequest")
	req := &msg.TunnelRequest{
		Port: port,
	}
	if err := msg.WriteMsg(stream, req); err != nil {
		return "", err
	}

	// TODO: wait for ack w/ url
	log.WithFields(logrus.Fields{
		"server": addr,
	}).Info("waiting for TunnelReply")

	var res msg.TunnelReply
	if err := msg.ReadMsgInto(stream, &res); err != nil {
		return "", err
	}
	log.WithFields(logrus.Fields{
		"server": addr,
		"port":   port,
		"uri":    res.URI,
	}).Info("received TunnelReply")
	url = res.URI

	// TODO: Update global state for later control messages

	// TODO: launch goroutine to proxy data
	go proxy.Proxy(stream, local)

	return url, nil
}
예제 #3
0
func acceptStreams(logger log.Logger, session *yamux.Session, streamCh chan net.Conn) grim.TaskFunc {
	return func(ctx context.Context) {
		defer close(streamCh)
		for {
			select {
			case <-ctx.Done():
				return
			default:
				stream, err := session.Accept()
				if err != nil {
					if err != io.EOF {
						logger.Error("multiplex conn accept failed", "err", err)
					}
					return
				}
				streamCh <- stream
			}
		}
	}
}