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 }