forked from mirrors/gecko-dev
This allows sending and receiving arbitrarily (we limit to 1 GiB atm) sized messages while not relying on the deprecated PPID fragmentation/reassembly mode. The code already supports the ndata extension but it's not activated, yet. Without the SCTP ndata extension, a large data channel message will monopolise the SCTP association. While this is a problem, it is a temporary solution until the extension is being activated. Keep in mind that every application that uses data channels currently does fragmentation/reassembly on application-level and it's unlikely that this will change until the popular implementations (libwebrtc) implement EOR as well. Moreover, until the WebRTC API specifies an API that hands over partial messages, doing application-level fragmentation/reassembly is still useful for very large messages (sadly). We fall back to PPID-based fragmentation/reassembly mode IFF a=max-message-size is not set in the SDP and the negotiated amount of SCTP inbound streams is exactly 256. Other implementations should avoid using this combination (to be precise, other implementations should send a=max-message-size). It also changes behaviour of RTCDataChannel.send which now raises TypeError in case the message is too large for the other peer to receive. This is a necessity to ensure that implementations that do not look at the EOR flag when receiving are always able to receive our messages. Even if these implementations do not set a=max-message-size, we use a safe default value (64 KiB, dictated by the spec) that every implementation should be able to receive, with or without EOR support. * Due to the use of explicit EOR, this required some major refactoring of all send-related and deferred sending functions (which is now a lot less complex). There's now only one place where `usrsctp_sendv` is being used. * All data channel messages and DCEP messages will be sent without copying them first. Only in case this fails (e.g. usrsctp's buffer is full), the message will be copied and added to a buffer queue. * Queued data channel messages will now be re-sent fairly (round-robin). * Maximum message size and the PPID-based fragmentation are configurable using about:config (media.peerconnection.sctp.force_ppid_fragmentation and media.peerconnection.sctp.force_maximum_message_size). * Enable interleaving of incoming messages for different streams (preparation for SCTP ndata, has no effect until it is enabled). * Enable interleaving of outgoing messages (disabled if SCTP ndata has not been negotiated). * Add pending messages flag to reduce performance impact from frequent calls to SendDeferredMessages. * Handle partial delivery events (for cases where a partially delivered message is being aborted). * Close a data channel/the connection in case the message is too large to be handled (this is only applied in cases where the remote peer ignores our announced local maximum message size). * Various size_t to uint32_t conversions (message length) and back should be safe now. * Remove aUsingDtls/mUsingDtls from DataChannelConnection. * Set maximum message size in SDP and in the data channel stack. * Replace implicit NS_ENSURE_*'s with explicit NS_WARN_IF's. * Add SetMaxMessageSize method for late-applying those signalling parameters when a data channel has been created before the remote SDP was available. * Limit remote maximum message size and add a GetMaxMessageSize method for a future implementation of RTCSctpTransport.maxMessageSize. MozReview-Commit-ID: FlmZrpC5zVI --HG-- extra : rebase_source : 54e1b838c788a3abbded4fb32fe7c2788f8a9bc0
90 lines
3.3 KiB
C
90 lines
3.3 KiB
C
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNELPROTOCOL_H_
|
|
#define NETWERK_SCTP_DATACHANNEL_DATACHANNELPROTOCOL_H_
|
|
|
|
#if defined(__GNUC__)
|
|
#define SCTP_PACKED __attribute__((packed))
|
|
#elif defined(_MSC_VER)
|
|
#pragma pack (push, 1)
|
|
#define SCTP_PACKED
|
|
#else
|
|
#error "Unsupported compiler"
|
|
#endif
|
|
|
|
#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256
|
|
// Do not change this value!
|
|
#define WEBRTC_DATACHANNEL_STREAMS_OLDER_FIREFOX 256
|
|
#define WEBRTC_DATACHANNEL_PORT_DEFAULT 5000
|
|
// TODO: Bug 1381146, change once we resolve the nsCString limitation
|
|
#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_LOCAL 1073741823
|
|
#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE_DEFAULT 65535
|
|
// TODO: Bug 1382779, once resolved, can be increased to min(Uint8ArrayMaxSize, UINT32_MAX)
|
|
// TODO: Bug 1381146, once resolved, can be increased to whatever we support then (hopefully
|
|
// SIZE_MAX) or be removed
|
|
#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE 2147483637
|
|
|
|
#define DATA_CHANNEL_PPID_CONTROL 50
|
|
#define DATA_CHANNEL_PPID_BINARY_PARTIAL 52
|
|
#define DATA_CHANNEL_PPID_BINARY 53
|
|
#define DATA_CHANNEL_PPID_DOMSTRING_PARTIAL 54
|
|
#define DATA_CHANNEL_PPID_DOMSTRING 51
|
|
|
|
#define DATA_CHANNEL_MAX_BINARY_FRAGMENT 0x4000
|
|
|
|
#define DATA_CHANNEL_FLAGS_READY 0x00000001
|
|
#define DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED 0x00000002
|
|
#define DATA_CHANNEL_FLAGS_FINISH_OPEN 0x00000004
|
|
#define DATA_CHANNEL_FLAGS_EXTERNAL_NEGOTIATED 0x00000008
|
|
#define DATA_CHANNEL_FLAGS_WAITING_ACK 0x00000010
|
|
#define DATA_CHANNEL_FLAGS_CLOSING_TOO_LARGE 0x00000020
|
|
|
|
#define DATA_CHANNEL_BUFFER_MESSAGE_FLAGS_TOO_LARGE 0x01
|
|
#define DATA_CHANNEL_BUFFER_MESSAGE_FLAGS_BUFFERED 0x02
|
|
#define DATA_CHANNEL_BUFFER_MESSAGE_FLAGS_COMPLETE 0x04
|
|
|
|
#define INVALID_STREAM (0xFFFF)
|
|
// max is 0xFFFF: Streams 0 to 0xFFFE = 0xFFFF streams
|
|
#define MAX_NUM_STREAMS (2048)
|
|
|
|
struct rtcweb_datachannel_open_request {
|
|
uint8_t msg_type; // DATA_CHANNEL_OPEN
|
|
uint8_t channel_type;
|
|
int16_t priority;
|
|
uint32_t reliability_param;
|
|
uint16_t label_length;
|
|
uint16_t protocol_length;
|
|
char label[1]; // (and protocol) keep VC++ happy...
|
|
} SCTP_PACKED;
|
|
|
|
struct rtcweb_datachannel_ack {
|
|
uint8_t msg_type; // DATA_CHANNEL_ACK
|
|
} SCTP_PACKED;
|
|
|
|
/* msg_type values: */
|
|
/* 0-1 were used in an early version of the protocol with 3-way handshakes */
|
|
#define DATA_CHANNEL_ACK 2
|
|
#define DATA_CHANNEL_OPEN_REQUEST 3
|
|
|
|
/* channel_type values: */
|
|
#define DATA_CHANNEL_RELIABLE 0x00
|
|
#define DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT 0x01
|
|
#define DATA_CHANNEL_PARTIAL_RELIABLE_TIMED 0x02
|
|
|
|
#define DATA_CHANNEL_RELIABLE_UNORDERED 0x80
|
|
#define DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED 0x81
|
|
#define DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED 0x82
|
|
|
|
#define ERR_DATA_CHANNEL_ALREADY_OPEN 1
|
|
#define ERR_DATA_CHANNEL_NONE_AVAILABLE 2
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma pack (pop)
|
|
#undef SCTP_PACKED
|
|
#endif
|
|
|
|
#endif
|