diff --git a/internal/tunnel/client.go b/internal/tunnel/client.go index f80ea5c..0d7b045 100644 --- a/internal/tunnel/client.go +++ b/internal/tunnel/client.go @@ -45,9 +45,71 @@ func NewClient(serverAddr, localPort, authToken, hostHeader string, localHTTPS b } } -// ... Start() code ... +func (c *Client) Start() error { + config := &ssh.ClientConfig{ + User: "grokway", + Auth: []ssh.AuthMethod{ + ssh.Password(c.AuthToken), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), // Dev only + Timeout: 5 * time.Second, + } -// ... acceptLoop() code ... + c.Events <- fmt.Sprintf("Connecting to %s...", c.ServerAddr) + client, err := ssh.Dial("tcp", c.ServerAddr, config) + if err != nil { + return err + } + c.SSHClient = client + c.Events <- "SSH Connected!" + + // Request remote listening (Reverse Forwarding) + // Bind to 0.0.0.0 on server, random port (0) + listener, err := client.Listen("tcp", "0.0.0.0:0") + if err != nil { + return fmt.Errorf("failed to request port forwarding: %w", err) + } + c.Listener = listener + + // Query server for assigned slug + ok, slugBytes, err := client.SendRequest("grokway-whoami", true, nil) + slug := "test-slug" // Fallback + if err == nil && ok { + slug = string(slugBytes) + c.Events <- fmt.Sprintf("Server assigned domain: %s", slug) + } else { + c.Events <- "Failed to query domain from server, using fallback" + } + + hostname := "localhost" // This should match what the server is running on actually + + // Assuming HTTP proxy is on port 8080 of the same host as SSH server (but different port) + // We extract host from c.ServerAddr + host, _, _ := net.SplitHostPort(c.ServerAddr) + if host == "" { + host = hostname + } + + c.PublicURL = fmt.Sprintf("https://%s.%s", slug, host) + c.Events <- fmt.Sprintf("Tunnel established! Public URL: %s", c.PublicURL) + + go c.acceptLoop() + + return nil +} + +func (c *Client) acceptLoop() { + for { + remoteConn, err := c.Listener.Accept() + if err != nil { + c.Events <- fmt.Sprintf("Accept error: %s", err) + break + } + + c.Events <- "New Request received" + go c.handleConnection(remoteConn) + } +} func (c *Client) handleConnection(remoteConn net.Conn) { defer remoteConn.Close()