package main import ( "fmt" "io" "net" "os" "strings" "time" ) // getWindowsHostIP obtiene la IP del host Windows desde WSL2. // Lee /etc/resolv.conf que WSL2 configura con la IP del host. func getWindowsHostIP() string { data, err := os.ReadFile("/etc/resolv.conf") if err != nil { return "" } for _, line := range strings.Split(string(data), "\n") { line = strings.TrimSpace(line) if strings.HasPrefix(line, "nameserver ") { ip := strings.TrimPrefix(line, "nameserver ") ip = strings.TrimSpace(ip) if ip != "" { return ip } } } return "" } // getWindowsGatewayIP obtiene la IP del gateway (host Windows) desde la tabla de rutas. func getWindowsGatewayIP() string { data, err := os.ReadFile("/proc/net/route") if err != nil { return "" } for _, line := range strings.Split(string(data), "\n") { fields := strings.Fields(line) if len(fields) >= 3 && fields[1] == "00000000" { // default route hexIP := fields[2] if len(hexIP) == 8 { // /proc/net/route stores IPs as little-endian 32-bit hex // "011017AC" -> bytes [01,10,17,AC] -> IP 172.23.16.1 (reversed) var a, b, c, d uint8 fmt.Sscanf(hexIP[0:2], "%02x", &a) fmt.Sscanf(hexIP[2:4], "%02x", &b) fmt.Sscanf(hexIP[4:6], "%02x", &c) fmt.Sscanf(hexIP[6:8], "%02x", &d) return fmt.Sprintf("%d.%d.%d.%d", d, c, b, a) } } } return "" } // waitForCDP espera a que el puerto CDP esté accesible desde WSL. func waitForCDP(host string, port int, timeout time.Duration) error { deadline := time.Now().Add(timeout) addr := fmt.Sprintf("%s:%d", host, port) for time.Now().Before(deadline) { conn, err := net.DialTimeout("tcp", addr, 300*time.Millisecond) if err == nil { conn.Close() return nil } time.Sleep(300 * time.Millisecond) } return fmt.Errorf("CDP %s no disponible despues de %s", addr, timeout) } // startCDPProxy levanta un proxy TCP local que reenvía conexiones al host Windows. // Chrome CDP solo acepta conexiones desde localhost, así que el proxy en WSL // conecta al host Windows vía portproxy/netsh y expone el puerto localmente. // Retorna el puerto local del proxy y una función para cerrarlo. func startCDPProxy(windowsHost string, remotePort, localPort int) (net.Listener, error) { ln, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", localPort)) if err != nil { return nil, fmt.Errorf("proxy listen: %w", err) } go func() { for { client, err := ln.Accept() if err != nil { return // listener cerrado } go proxyConn(client, windowsHost, remotePort) } }() return ln, nil } func proxyConn(client net.Conn, host string, port int) { defer client.Close() remote, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), 5*time.Second) if err != nil { return } defer remote.Close() go io.Copy(remote, client) io.Copy(client, remote) }