Skip to content
Merged
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
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ CLIENT_RELAY_IMAGE ?= moq-relay:latest
CLIENT_RELAY_URL ?= moqt://relay:4443
CLIENT_COMPOSE := docker compose -f interop/docker-compose.client.yml

# Transport our loopback relay must speak, derived from the URL scheme so the
# default moqt:// loopback uses raw QUIC and an https:// override uses
# WebTransport. Only consumed by our own relay image (third-party relays ignore
# MOQT_TRANSPORT); see interop/docker-compose.client.yml.
CLIENT_RELAY_TRANSPORT ?= $(if $(filter https://%,$(CLIENT_RELAY_URL)),webtransport,quic)

# Build our test-client image from this repo's sources.
interop-client-build:
docker build -f cmd/interop-client/Dockerfile.client -t moq-interop-client:latest .
Expand All @@ -91,7 +97,8 @@ interop-client-build:
# loopback works out of the box; harmless when targeting a third-party relay.
interop-client: interop-build interop-certs
@echo ">> interop-client: moq-interop-client -> $(CLIENT_RELAY_IMAGE) ($(CLIENT_RELAY_URL))"
RELAY_IMAGE=$(CLIENT_RELAY_IMAGE) RELAY_URL=$(CLIENT_RELAY_URL) $(CLIENT_ENV) \
RELAY_IMAGE=$(CLIENT_RELAY_IMAGE) RELAY_URL=$(CLIENT_RELAY_URL) \
MOQT_TRANSPORT=$(CLIENT_RELAY_TRANSPORT) $(CLIENT_ENV) \
$(CLIENT_COMPOSE) up --build --abort-on-container-exit --exit-code-from test-client; \
status=$$?; $(CLIENT_COMPOSE) down -v >/dev/null 2>&1; exit $$status

Expand Down
8 changes: 6 additions & 2 deletions cmd/relay/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ COPY cmd/relay/entrypoint-relay.sh /app/run_endpoint.sh
RUN chmod +x /app/run_endpoint.sh && mkdir -p /certs /mlog

# Defaults follow the runner conventions; override at `docker run`/compose time.
# MOQT_TRANSPORT defaults to webtransport: the runner's docker harness always
# dials the relay at https://relay:4443 (WebTransport / ALPN "h3") and exposes
# no knob to set MOQT_TRANSPORT, so a raw-QUIC default makes every client fail
# the TLS handshake with "no application protocol".
ENV MOQT_ROLE=relay \
MOQT_PORT=4443 \
MOQT_TRANSPORT=quic \
MOQT_WEBTRANSPORT_PATH=/moq
MOQT_TRANSPORT=webtransport \
MOQT_WEBTRANSPORT_PATH=/

EXPOSE 4443/udp

Expand Down
17 changes: 13 additions & 4 deletions cmd/relay/entrypoint-relay.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@
# MOQT_PORT UDP port to listen on (default: 4443)
# MOQT_CERT TLS certificate PEM (default: /certs/cert.pem)
# MOQT_KEY TLS private key PEM (default: /certs/priv.key)
# MOQT_TRANSPORT "quic" (moqt://) or "webtransport" (https://) (default: quic)
# MOQT_WEBTRANSPORT_PATH HTTP/3 CONNECT path for WebTransport (default: /moq)
# MOQT_TRANSPORT "quic" (moqt://) or "webtransport" (https://) (default: webtransport)
# The runner's docker harness always points the client
# at https://relay:4443 (WebTransport / ALPN "h3") and
# provides no way to set MOQT_TRANSPORT, so the relay
# must speak WebTransport by default or every handshake
# fails with "tls: no application protocol".
# MOQT_WEBTRANSPORT_PATH HTTP/3 CONNECT path for WebTransport (default: /)
# The runner dials a path-less https://relay:4443, so
# the CONNECT targets "/"; serving WebTransport at the
# root is what lets the upgrade succeed (otherwise the
# request 404s against the /moq handler).
#
# Mounts:
# /certs/cert.pem, /certs/priv.key
Expand All @@ -21,8 +30,8 @@ ROLE="${MOQT_ROLE:-relay}"
PORT="${MOQT_PORT:-4443}"
CERT="${MOQT_CERT:-/certs/cert.pem}"
KEY="${MOQT_KEY:-/certs/priv.key}"
TRANSPORT="${MOQT_TRANSPORT:-quic}"
WT_PATH="${MOQT_WEBTRANSPORT_PATH:-/moq}"
TRANSPORT="${MOQT_TRANSPORT:-webtransport}"
WT_PATH="${MOQT_WEBTRANSPORT_PATH:-/}"

if [ "$ROLE" != "relay" ]; then
echo "role '$ROLE' not supported (only 'relay')" >&2
Expand Down
25 changes: 16 additions & 9 deletions cmd/relay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,22 @@ func webTransportListener(addr, path string, tlsCfg *tls.Config) (*wtconn.Listen
mux := http.NewServeMux()
// Catch-all so requests that don't hit `path` (wrong URL, missing
// upgrade header, plain GET) get logged instead of silently 404'ing.
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
alpn := ""
if r.TLS != nil {
alpn = r.TLS.NegotiatedProtocol
}
log.Printf("http3: unmatched request %s %s%s proto=%s alpn=%q upgrade=%q",
r.Method, r.Host, r.URL.Path, r.Proto, alpn, r.Header.Get(":protocol"))
http.NotFound(w, r)
})
// Skip it when the upgrade handler itself owns "/" (path == "/"):
// registering two handlers for the same pattern panics the ServeMux,
// and a root-mounted upgrade already covers every request anyway. The
// interop runner dials a path-less URL (https://relay:4443), so the
// CONNECT targets "/" — see MOQT_WEBTRANSPORT_PATH in entrypoint-relay.sh.
if path != "/" {
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
alpn := ""
if r.TLS != nil {
alpn = r.TLS.NegotiatedProtocol
}
log.Printf("http3: unmatched request %s %s%s proto=%s alpn=%q upgrade=%q",
r.Method, r.Host, r.URL.Path, r.Proto, alpn, r.Header.Get(":protocol"))
http.NotFound(w, r)
})
}
h3 := &http3.Server{
TLSConfig: tlsCfg,
Handler: mux,
Expand Down
7 changes: 7 additions & 0 deletions interop/docker-compose.client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ services:
environment:
- MOQT_ROLE=relay
- MOQT_PORT=4443
# The default loopback (CLIENT_RELAY_IMAGE=moq-relay:latest, our own
# image) dials moqt://relay:4443, so the relay must speak raw QUIC — our
# image otherwise defaults to WebTransport (the external moq-interop-runner
# drives it that way). Defaults to quic to match the moqt:// URL; the
# Makefile derives it from CLIENT_RELAY_URL's scheme. Third-party relay
# images ignore this var and use their own transport conventions.
- MOQT_TRANSPORT=${MOQT_TRANSPORT:-quic}
# No healthcheck override here: third-party relay images ship their own
# (e.g. moq-rs uses `ss`, the moq-dev adapter greps /proc/net/udp6), and
# some are shell-less so a `sh -c` override would never pass. We rely on the
Expand Down