From d984608d02db280f2039ac776cde5efb00164bb4 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 09:36:26 -0400 Subject: [PATCH 1/3] bring back team tracking via websockets --- clientcore/egress_consumer_ws.go | 15 ++++++++++++++- egress/egresslib.go | 32 ++++++++++++++++++++++++++------ quickstart.sh | 10 ++++++---- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/clientcore/egress_consumer_ws.go b/clientcore/egress_consumer_ws.go index 65c0df04..84060aa1 100644 --- a/clientcore/egress_consumer_ws.go +++ b/clientcore/egress_consumer_ws.go @@ -6,6 +6,7 @@ package clientcore import ( "context" + "fmt" "sync" "time" @@ -39,8 +40,20 @@ func NewEgressConsumerWebSocket(options *EgressOptions, wg *sync.WaitGroup) *Wor ctx, cancel := context.WithTimeout(ctx, options.ConnectTimeout) defer cancel() + teamId := "team_not_set" + // TODO: get the teamId or userId from somewhere. + // This will most likely be a lantern userId, if the user is signed in + + // This is a way to pass metadata from widget -> egress, + // the websocket package doesn't support sending other headers, so it is passed + // through the "Sec-WebSocket-Protocol" header with a prefix, so it can be read later in the egress server + // and then attached to the QUIC stream that is created there + wsDialOpts := &websocket.DialOptions{ + Subprotocols: []string{fmt.Sprintf("%v%v", common.TeamIdPrefix, teamId)}, + } + // TODO: WSS - c, _, err := websocket.Dial(ctx, options.Addr+options.Endpoint, nil) + c, _, err := websocket.Dial(ctx, options.Addr+options.Endpoint, wsDialOpts) if err != nil { common.Debugf("Couldn't connect to egress server at %v: %v", options.Addr, err) <-time.After(options.ErrorBackoff) diff --git a/egress/egresslib.go b/egress/egresslib.go index dc017eac..9e1c2a3b 100644 --- a/egress/egresslib.go +++ b/egress/egresslib.go @@ -11,6 +11,7 @@ import ( "math/big" "net" "net/http" + "strings" "sync/atomic" "time" @@ -151,11 +152,28 @@ func generateTLSConfig() *tls.Config { } } +func extractTeamId(r *http.Request) string { + v := r.Header.Values("Sec-Websocket-Protocol") + for _, s := range v { + if strings.HasPrefix(s, common.TeamIdPrefix) { + return strings.TrimPrefix(s, common.TeamIdPrefix) + } + } + return "" +} + func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) { // TODO: InsecureSkipVerify=true just disables origin checking, we need to instead add origin // patterns as strings using AcceptOptions.OriginPattern // TODO: disabling compression is a workaround for a WebKit bug: // https://github.com/getlantern/broflake/issues/45 + + teamId := extractTeamId(r) + if teamId == "" { + teamId = "no_team_recieved" + } + common.Debugf("WebSocket connection request from %v with teamId %v", r.RemoteAddr, teamId) + c, err := websocket.Accept( w, r, @@ -184,10 +202,6 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) { defer wspconn.Close() - if err != nil { - return - } - common.Debugf("Accepted a new WebSocket connection! (%v total)", atomic.AddUint64(&nClients, 1)) nClientsCounter.Add(context.Background(), 1) @@ -200,7 +214,12 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) { for { conn, err := listener.Accept(context.Background()) if err != nil { - common.Debugf("%v QUIC listener error (%v), closing!", wspconn.addr, err) + switch websocket.CloseStatus(err) { + case websocket.StatusNormalClosure, websocket.StatusGoingAway: + common.Debugf("%v closed normally", wspconn.addr) + default: + common.Debugf("%v QUIC listener error (%v), closing!", wspconn.addr, err) + } listener.Close() break } @@ -233,6 +252,7 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) { }, AddrLocal: l.addr, AddrRemote: tcpAddr, + TeamId: teamId, } } }() @@ -302,7 +322,7 @@ func NewListener(ctx context.Context, ll net.Listener, certPEM, keyPEM string) ( // We use this wrapped listener to enable our local HTTP proxy to listen for WebSocket connections l := proxyListener{ - Listener: &net.TCPListener{}, + Listener: ll, connections: make(chan net.Conn, 2048), tlsConfig: tlsConfig, addr: ll.Addr(), diff --git a/quickstart.sh b/quickstart.sh index 73b1c3be..9346fc74 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -159,10 +159,12 @@ elif [ "$1" == "egress" ]; then echo "Using custom egress option" commands=("${custom_egress_commands[@]}") elif [ "$1" == "wt" ]; then - #create a self-signed certificate for localhost - openssl req -x509 -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.crt -subj '/CN=localhost' -addext 'subjectAltName = DNS:localhost' - echo "Using webtransports option" - commands=("${wt_commands[@]}") + echo "webtransports not supported" + usage; + # #create a self-signed certificate for localhost + # openssl req -x509 -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.crt -subj '/CN=localhost' -addext 'subjectAltName = DNS:localhost' + # echo "Using webtransports option" + # commands=("${wt_commands[@]}") else echo "Unknown option $1"; usage; From 6561021b728fdedc431ba6d08a47fa9040307a1d Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 10:31:25 -0400 Subject: [PATCH 2/3] remove old team code --- clientcore/quic.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clientcore/quic.go b/clientcore/quic.go index 208192be..4ff074d0 100644 --- a/clientcore/quic.go +++ b/clientcore/quic.go @@ -95,10 +95,6 @@ func (c *QUICLayer) DialAndMaintainQUICConnection() { return } - teamId := "teamid-not-set" - teamDatagram := []byte(common.TeamIdPrefix + teamId) - conn.SendDatagram(teamDatagram) - connEstablished <- conn }() From 54d41cc949bfc2523d0298aa14650201a6e96f99 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 11 Jul 2025 13:43:44 -0400 Subject: [PATCH 3/3] remove extra ENV vars from quickstart --- quickstart.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstart.sh b/quickstart.sh index 9346fc74..4e46e15f 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -139,8 +139,8 @@ wt_commands=( "TLS_CERT=localhost.crt TLS_KEY=localhost.key PORT=8000 go run ./egress/cmd/egress.go" # Start desktop proxy with webtransports enabled, and pointed to the correct certs - "WEBTRANSPORT=1 CA=localhost.crt SERVER_NAME=localhost EGRESS=https://localhost:8001 TAG=bob NETSTATED=$NETSTATE_DEFAULT FREDDIE=$FREDDIE_DEFAULT PORT=$PROXYPORT_DEFAULT ./cmd/dist/bin/desktop" - + "$desktop_start" + # build and start native binary widget with webtransports enabled "WEBTRANSPORT=1 CA=localhost.crt EGRESS=https://localhost:8001 TAG=alice NETSTATED=$NETSTATE_DEFAULT FREDDIE=$FREDDIE_DEFAULT ./cmd/dist/bin/widget" )