Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion clientcore/egress_consumer_ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package clientcore

import (
"context"
"fmt"
"sync"
"time"

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 0 additions & 4 deletions clientcore/quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ func (c *QUICLayer) DialAndMaintainQUICConnection() {
return
}

teamId := "teamid-not-set"
teamDatagram := []byte(common.TeamIdPrefix + teamId)
conn.SendDatagram(teamDatagram)

connEstablished <- conn
}()

Expand Down
32 changes: 26 additions & 6 deletions egress/egresslib.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"math/big"
"net"
"net/http"
"strings"
"sync/atomic"
"time"

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)

Expand All @@ -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
}
Expand Down Expand Up @@ -233,6 +252,7 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) {
},
AddrLocal: l.addr,
AddrRemote: tcpAddr,
TeamId: teamId,
}
}
}()
Expand Down Expand Up @@ -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(),
Expand Down
14 changes: 8 additions & 6 deletions quickstart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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;
Expand Down