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 }
func tunnel(sconn net.Conn) { // buff := make([]byte, 0xff) // read control message to figure out what port is being forwarded var req msg.TunnelRequest if err := msg.ReadMsgInto(sconn, &req); err != nil { log.Error(err.Error()) } log.WithFields(logrus.Fields{ "client": sconn.RemoteAddr(), "proxy_port": req.Port, }).Info("received TunnelRequest") // bind to available local port to proxy local, _ := net.Listen("tcp", ":0") defer local.Close() log.Info(local.Addr()) // send url back in ack message hostname, _ := os.Hostname() port := local.Addr().(*net.TCPAddr).Port res := &msg.TunnelReply{ URI: fmt.Sprintf("tcp://%s:%d", hostname, port), } if err := msg.WriteMsg(sconn, res); err != nil { log.Error(err.Error()) return } // TODO: start proxying for { conn, err := local.Accept() if err != nil { // handle error log.Error("err") } log.Info("new conn") go proxy.Proxy(conn, sconn) // _, err := sconn.Read(buff) // if err != nil { // if err == io.EOF { // break // } // log.Printf("Stream read error: %s", err) // break // } // // log.Printf("stream sent %d bytes: %s", n, buff[:n]) // sconn.Write([]byte("GET /\n\n")) } }