chromium/services/network/public/mojom/web_transport.mojom

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module network.mojom;

import "mojo/public/mojom/base/read_only_buffer.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/network_param.mojom";

// Represents a WebTransport error.
// See also: net/quic/quic_transport_client.h
struct WebTransportError {
  // A net error (see net/base/net_errors.h).
  int32 net_error = 0;

  // A QUIC error (see
  // net/third_party/quiche/src/quiche/quic/core/quic_error_codes.h).
  // TODO(ricea): Rename this.
  int32 quic_error = 0;

  // Human-readable error summary.
  string details;

  // WebTransport requires that the connection errors have to be
  // undistinguishable until the peer is confirmed to be a WebTransport
  // endpoint.  See https://w3c.github.io/web-transport/#protocol-security
  bool safe_to_report_details = false;
};

// The fingerprint of a certificate accompanied with the hash algorithm.
// https://w3c.github.io/web-transport/#web-transport-configuration
// https://www.w3.org/TR/webrtc/#dom-rtcdtlsfingerprint
struct WebTransportCertificateFingerprint {
  string algorithm;
  string fingerprint;
};

// Data (possibly) attached when WebTransport is closed gracefully.
// https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3/#section-5
// https://w3c.github.io/webtransport/#web-transport-close-info
struct WebTransportCloseInfo {
  uint32 code;
  string reason;
};

// Stats for a WebTransport session.
// https://w3c.github.io/webtransport/#web-transport-stats
struct WebTransportStats {
  mojo_base.mojom.Time timestamp;
  mojo_base.mojom.TimeDelta min_rtt;
  mojo_base.mojom.TimeDelta smoothed_rtt;
  mojo_base.mojom.TimeDelta rtt_variation;
  uint64 estimated_send_rate_bps;

  // We only ever return WebTransportDatagramStats as a part of
  // WebTransportStats; thus those two structs are merged here.
  uint64 datagrams_expired_outgoing;
  uint64 datagrams_lost_outgoing;
};

// A mojo interface for https://w3c.github.io/web-transport/#web-transport.
// This is typically implemented in the network service, and used by renderer.
// WebTransport represents a WebTransport over HTTP/3 session, which has
// multiple unidirectional and bidirectional streams and one bidirectional
// channel for datagrams.
//
// A stream can be created either by client or server.
// A stream is active until any of the following event happens:
//  [incoming] Closed by the server (OnIncomingStreamClosed with fin)
//  [incoming] Aborted by the server (OnIncomingStreamClosed without fin, or
//                                    OnReceivedResetStream)
//  [incoming] Cancelled by the client (StopSending)
//  [outgoing] Closed by the client (SendFin)
//  [outgoing] Aborted by the client (AbortStream)
//  [outgoing] Cancelled by the server (OnReceivedStopSending)
// Once a stream is aborted or cancelled, the data pipe is closed immediately.
// When a stream is closed, the writable side closes the data pipe immediately,
// and the readable side tries to read data already written to the pipe.
//
// When an outgoing stream is closed (by the client), the client waits for the
// FIN signal to be acknowledged by the server, as the ACK signal is useful
// for web applications. OnOutgoingStreamClosed is the ACK signal.
//
// Any stream is aborted or cancelled when the associated WebTransport session
// is terminated.
interface WebTransport {
  // A datagram message is sent from the client. The response message represents
  // whether the peer has sent or discarded the datagram.
  SendDatagram(mojo_base.mojom.ReadOnlyBuffer data) => (bool result);

  // Stream creation initiated by the client. |succeeded| represents whether
  // the stream is created successfully, and |stream_id| is meaningful only
  // when |succeeded| is true. |writable| is nullable, to support both
  // unidirectional and bidirectional streams.
  CreateStream(handle<data_pipe_consumer> readable,
               handle<data_pipe_producer>? writable) =>
      (bool succeeded, uint32 stream_id);

  // Accepts a bidirectional stream created by the server.
  AcceptBidirectionalStream() => (uint32 stream_id,
                  handle<data_pipe_consumer> readable,
                  handle<data_pipe_producer> writable);

  // Accepts a unidirectional stream created by the server.
  AcceptUnidirectionalStream() => (uint32 stream_id,
                  handle<data_pipe_consumer> readable);

  // Expresses that the client will not write data to the stream for
  // |stream_id|. After calling this function on a stream, the client will not
  // be able to write any data to the stream, but it may be able to use other
  // functions such as reading data from the stream.
  SendFin(uint32 stream_id);

  // Aborts the stream for `stream_id`.
  // `code` is an error code as described at
  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-resetting-data-streams.
  AbortStream(uint32 stream_id, uint8 code);

  // Sends a STOP_SENDING message on an incoming or bidirectional stream.
  // `code` is an error code as described at
  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-resetting-data-streams.
  StopSending(uint32 stream_id, uint8 code);

  // Sets the duration which determines whether an outgoing datagram should be
  // discarded due to being in the queue for too long. A duration of 0 means to
  // use an implementation-defined default.
  SetOutgoingDatagramExpirationDuration(mojo_base.mojom.TimeDelta duration);

  // Provides the latest stats for the session.
  GetStats() => (WebTransportStats? stats);

  // https://w3c.github.io/webtransport/#session-terminate
  // This is the last message and it is not allowed to call methods after
  // calling this.
  Close(WebTransportCloseInfo? close_info);
};

// A mojo interface for the client of WebTransport.
// This is typically implemented in renderer, and used by the network service.
interface WebTransportClient {
  // A datagram message is sent from the server.
  OnDatagramReceived(mojo_base.mojom.ReadOnlyBuffer data);

  // Notifies that the server will not write data to the Stream for |stream_id|.
  // |fin_received| is true when FIN is received from the server.
  // Note that OnIncomingStreamClosed and OnOutgoingStreamClosed can both be
  // dispatched to the same stream, if it is a bidirectional stream.
  OnIncomingStreamClosed(uint32 stream_id, bool fin_received);

  // Notifies that all outstanding data has been received by the server on the
  // Stream for |stream_id| and it is now closed.
  OnOutgoingStreamClosed(uint32 stream_id);

  // Called when an outgoing or bidirectional stream gets a STOP_SENDING signal.
  // https://w3c.github.io/webtransport/#stream-signal-stop_sending
  // `stream_error_code` is an error code as described at
  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-resetting-data-streams.
  OnReceivedStopSending(uint32 stream_id, uint32 stream_error_code);

  // Called when an incoming or bidirectional stream gets a RESET_STREAM signal.
  // https://w3c.github.io/webtransport/#stream-signal-reset
  // `stream_error_code` is an error code as described at
  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-resetting-data-streams.
  OnReceivedResetStream(uint32 stream_id, uint32 stream_error_code);

  // Called when the session is terminated cleanly.
  // https://w3c.github.io/webtransport/#session-terminated
  // This is the last message and it is not allowed to call methods after
  // calling this.
  OnClosed(WebTransportCloseInfo? close_info, WebTransportStats final_stats);
};

// Used to create a WebTransport session. This is split from WebTransport
// so that the handshake part can be intercepted, by Chrome extensions for
// example.
// Some parameters may contain information that cannot be handed to the
// initiator renderer due to security and privacy reasons. There should be
// an WebTransportHandshakeClient implementation in the browser process
// which ensures that a WebTransportHandshakeClient implemented in renderers
// doesn't see such information.
interface WebTransportHandshakeClient {
  // Called when the handshake succeeds.
  OnConnectionEstablished(pending_remote<WebTransport> transport,
                          pending_receiver<WebTransportClient> client,
                          HttpResponseHeaders response_headers,
                          WebTransportStats initial_stats);

  // Called when the handshake fails.
  // |error| contains the error details. The actual error information issued
  // by the network service should not be handed to the initiator renderer.
  OnHandshakeFailed(WebTransportError? error);
};