// Listen for incoming control and proxy connections // We listen for incoming control and proxy connections on the same port // for ease of deployment. The hope is that by running on port 443, using // TLS and running all connections over the same port, we can bust through // restrictive firewalls. func tunnelListener(addr string, tlsConfig *tls.Config) { // listen for incoming connections listener, err := conn.Listen(addr, "tun", tlsConfig) if err != nil { panic(err) } log.Info("Listening for control and proxy connections on %s", listener.Addr.String()) for c := range listener.Conns { go func(tunnelConn conn.Conn) { tunnelConn.SetReadDeadline(time.Now().Add(connReadTimeout)) var rawMsg msg.Message if rawMsg, err = msg.ReadMsg(tunnelConn); err != nil { tunnelConn.Error("Failed to read message: %v", err) tunnelConn.Close() return } // don't timeout after the initial read, tunnel heartbeating will kill // dead connections tunnelConn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Auth: NewControl(tunnelConn, m) case *msg.RegProxy: NewProxy(tunnelConn, m) default: tunnelConn.Close() } }(c) } }
/** * Listens for new http connections from the public internet */ func httpListener(addr *net.TCPAddr) { // bind/listen for incoming connections listener, err := conn.Listen(addr, "pub", nil) if err != nil { panic(err) } log.Info("Listening for public http connections on %v", listener.Port) for conn := range listener.Conns { go httpHandler(conn) } }
/** * Listens for new control connections from tunnel clients */ func controlListener(addr *net.TCPAddr, domain string) { // listen for incoming connections listener, err := conn.Listen(addr, "ctl", tls.Config) if err != nil { panic(err) } log.Info("Listening for control connections on %d", listener.Port) for c := range listener.Conns { NewControl(c) } }
// Listen for incoming control and proxy connections // We listen for incoming control and proxy connections on the same port // for ease of deployment. The hope is that by running on port 443, using // TLS and running all connections over the same port, we can bust through // restrictive firewalls. func tunnelListener(addr string, tlsConfig *tls.Config, secret string) { // listen for incoming connections listener, err := conn.Listen(addr, "tun", tlsConfig) if err != nil { panic(err) } log.Info("Listening for control and proxy connections on %s", listener.Addr.String()) if secret != "" { log.Info("Clients should use '%s' as secret", secret) } for c := range listener.Conns { go func(tunnelConn conn.Conn) { // don't crash on panics defer func() { if r := recover(); r != nil { tunnelConn.Info("tunnelListener failed with error %v: %s", r, debug.Stack()) } }() tunnelConn.SetReadDeadline(time.Now().Add(connReadTimeout)) var rawMsg msg.Message if rawMsg, err = msg.ReadMsg(tunnelConn); err != nil { tunnelConn.Warn("Failed to read message: %v", err) tunnelConn.Close() return } // don't timeout after the initial read, tunnel heartbeating will kill // dead connections tunnelConn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { case *msg.Auth: NewControl(tunnelConn, m, secret) case *msg.RegProxy: NewProxy(tunnelConn, m) default: tunnelConn.Close() } }(c) } }
// Listens for new http(s) connections from the public internet func startHttpListener(addr string, tlsCfg *tls.Config) (listener *conn.Listener) { // bind/listen for incoming connections var err error if listener, err = conn.Listen(addr, "pub", tlsCfg); err != nil { panic(err) } proto := "http" if tlsCfg != nil { proto = "https" } log.Info("Listening for public %s connections on %v", proto, listener.Addr.String()) go func() { for conn := range listener.Conns { go httpHandler(conn, proto) } }() return }
/** * Listens for new proxy connections from tunnel clients */ func proxyListener(addr *net.TCPAddr, domain string) { listener, err := conn.Listen(addr, "pxy", tls.Config) if err != nil { panic(err) } // set global proxy addr variable proxyAddr = fmt.Sprintf("%s:%d", domain, listener.Port) log.Info("Listening for proxy connection on %d", listener.Port) for proxyConn := range listener.Conns { go func(conn conn.Conn) { // fail gracefully if the proxy connection dies defer func() { if r := recover(); r != nil { conn.Warn("Failed with error: %v", r) conn.Close() } }() // read the proxy register message var regPxy msg.RegProxyMsg if err = msg.ReadMsgInto(conn, ®Pxy); err != nil { panic(err) } // look up the tunnel for this proxy conn.Info("Registering new proxy for %s", regPxy.Url) tunnel := tunnels.Get(regPxy.Url) if tunnel == nil { panic("No tunnel found for: " + regPxy.Url) } // register the proxy connection with the tunnel tunnel.RegisterProxy(conn) }(proxyConn) } }