Repository: libp2p/go-libp2p
Pull request #1749 (2022-09-13 17:17:28)

webtransport: add and check the ?type=noise URL parameter
As required by the spec.


Patch:
diff --git a/p2p/security/noise/handshake.go b/p2p/security/noise/handshake.go
index bb68196c..c5aa968c 100644
--- a/p2p/security/noise/handshake.go
+++ b/p2p/security/noise/handshake.go
@@ -122,8 +122,6 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) {
 			if err := s.earlyDataHandler.Received(ctx, s.insecureConn, initialPayload); err != nil {
 				return err
 			}
-		} else if len(initialPayload) > 0 {
-			return fmt.Errorf("received unexpected early data (%d bytes)", len(initialPayload))
 		}
 
 		// stage 1 //
diff --git a/p2p/transport/webtransport/listener.go b/p2p/transport/webtransport/listener.go
index ca8fe1cf..bf0405a4 100644
--- a/p2p/transport/webtransport/listener.go
+++ b/p2p/transport/webtransport/listener.go
@@ -87,7 +87,10 @@ func newListener(laddr ma.Multiaddr, transport tpt.Transport, noise *noise.Trans
 		serverClosed:    make(chan struct{}),
 		addr:            udpConn.LocalAddr(),
 		multiaddr:       localMultiaddr,
-		server:          webtransport.Server{H3: http3.Server{TLSConfig: tlsConf}},
+		server: webtransport.Server{
+			H3:          http3.Server{TLSConfig: tlsConf},
+			CheckOrigin: func(r *http.Request) bool { return true },
+		},
 	}
 	ln.ctx, ln.ctxCancel = context.WithCancel(context.Background())
 	mux := http.NewServeMux()
@@ -105,6 +108,11 @@ func newListener(laddr ma.Multiaddr, transport tpt.Transport, noise *noise.Trans
 }
 
 func (l *listener) httpHandler(w http.ResponseWriter, r *http.Request) {
+	typ, ok := r.URL.Query()["type"]
+	if !ok || len(typ) != 1 || typ[0] != "noise" {
+		w.WriteHeader(http.StatusBadRequest)
+		return
+	}
 	remoteMultiaddr, err := stringToWebtransportMultiaddr(r.RemoteAddr)
 	if err != nil {
 		// This should never happen.
@@ -124,7 +132,6 @@ func (l *listener) httpHandler(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	// TODO: check ?type=multistream URL param
 	sess, err := l.server.Upgrade(w, r)
 	if err != nil {
 		log.Debugw("upgrade failed", "error", err)
diff --git a/p2p/transport/webtransport/transport.go b/p2p/transport/webtransport/transport.go
index 03cacb13..42b5fcef 100644
--- a/p2p/transport/webtransport/transport.go
+++ b/p2p/transport/webtransport/transport.go
@@ -150,7 +150,7 @@ func (t *transport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tp
 }
 
 func (t *transport) dial(ctx context.Context, addr string, certHashes []multihash.DecodedMultihash) (*webtransport.Session, error) {
-	url := fmt.Sprintf("https://%s%s", addr, webtransportHTTPEndpoint)
+	url := fmt.Sprintf("https://%s%s?type=noise", addr, webtransportHTTPEndpoint)
 	var tlsConf *tls.Config
 	if t.tlsClientConf != nil {
 		tlsConf = t.tlsClientConf.Clone()


Test patch:
diff --git a/p2p/security/noise/transport_test.go b/p2p/security/noise/transport_test.go
index 108efec8..f86705f4 100644
--- a/p2p/security/noise/transport_test.go
+++ b/p2p/security/noise/transport_test.go
@@ -510,7 +510,7 @@ func TestEarlyDataRejected(t *testing.T) {
 	}
 }
 
-func TestEarlyDataRejectedWithNoHandler(t *testing.T) {
+func TestEarlyDataAcceptedWithNoHandler(t *testing.T) {
 	clientEDH := &earlyDataHandler{
 		send: func(ctx context.Context, conn net.Conn, id peer.ID) []byte { return []byte("foobar") },
 	}
@@ -526,14 +526,14 @@ func TestEarlyDataRejectedWithNoHandler(t *testing.T) {
 		errChan <- err
 	}()
 
-	_, err = initTransport.SecureOutbound(context.Background(), respConn, respTransport.localID)
-	require.Error(t, err)
+	conn, err := initTransport.SecureOutbound(context.Background(), respConn, respTransport.localID)
+	require.NoError(t, err)
+	defer conn.Close()
 
 	select {
 	case <-time.After(500 * time.Millisecond):
 		t.Fatal("timeout")
 	case err := <-errChan:
-		require.Error(t, err)
-		require.Contains(t, err.Error(), "received unexpected early data")
+		require.NoError(t, err)
 	}
 }