tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DataChannelDcSctp.h (8291B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNELDCSCTP_H_
      8 #define NETWERK_SCTP_DATACHANNEL_DATACHANNELDCSCTP_H_
      9 
     10 #include "DataChannel.h"
     11 #include "net/dcsctp/public/dcsctp_socket.h"
     12 #include "net/dcsctp/public/dcsctp_socket_factory.h"
     13 
     14 namespace mozilla {
     15 using namespace dcsctp;
     16 
     17 class DataChannelConnectionDcSctp : public DataChannelConnection,
     18                                    public DcSctpSocketCallbacks {
     19 public:
     20  DataChannelConnectionDcSctp(DataConnectionListener* aListener,
     21                              nsISerialEventTarget* aTarget,
     22                              MediaTransportHandler* aHandler);
     23 
     24  // DataChannelConnection API
     25  void Destroy() override;
     26  bool RaiseStreamLimitTo(uint16_t aNewLimit) override;
     27  void OnTransportReady() override;
     28  bool Init(const uint16_t aLocalPort, const uint16_t aNumStreams) override;
     29  int SendMessage(DataChannel& aChannel, OutgoingMsg&& aMsg) override;
     30  void OnSctpPacketReceived(const MediaPacket& aPacket) override;
     31  bool ResetStreams(nsTArray<uint16_t>& aStreams) override;
     32  // This is called after an ACK comes in, to prompt subclasses to deliver
     33  // anything they've buffered while awaiting the ACK.
     34  void OnStreamOpen(uint16_t aStream) override;
     35 
     36  // DcSctpSocketCallbacks API
     37 
     38  // Called when the library wants the packet serialized as `data` to be sent.
     39  //
     40  // Note that it's NOT ALLOWED to call into this library from within this
     41  // callback.
     42  SendPacketStatus SendPacketWithStatus(
     43      webrtc::ArrayView<const uint8_t> aData) override;
     44 
     45  // Called when the library wants to create a Timeout. The callback must return
     46  // an object that implements that interface.
     47  //
     48  // Low precision tasks are scheduled more efficiently by using leeway to
     49  // reduce Idle Wake Ups and is the preferred precision whenever possible. High
     50  // precision timeouts do not have this leeway, but is still limited by OS
     51  // timer precision. At the time of writing, kLow's additional leeway may be up
     52  // to 17 ms, but please see webrtc::TaskQueueBase::DelayPrecision for
     53  // up-to-date information.
     54  //
     55  // Note that it's NOT ALLOWED to call into this library from within this
     56  // callback.
     57  std::unique_ptr<Timeout> CreateTimeout(
     58      webrtc::TaskQueueBase::DelayPrecision aPrecision) override;
     59  void HandleTimeout(TimeoutID aId);
     60 
     61  // Called when the library needs a random number uniformly distributed between
     62  // `low` (inclusive) and `high` (exclusive). The random numbers used by the
     63  // library are not used for cryptographic purposes. There are no requirements
     64  // that the random number generator must be secure.
     65  //
     66  // Note that it's NOT ALLOWED to call into this library from within this
     67  // callback.
     68  uint32_t GetRandomInt(uint32_t aLow, uint32_t aHigh) override;
     69 
     70  // Called when the library has received an SCTP message in full and delivers
     71  // it to the upper layer.
     72  //
     73  // It is allowed to call into this library from within this callback.
     74  void OnMessageReceived(DcSctpMessage aMessage) override;
     75 
     76  // Triggered when an non-fatal error is reported by either this library or
     77  // from the other peer (by sending an ERROR command). These should be logged,
     78  // but no other action need to be taken as the association is still viable.
     79  //
     80  // It is allowed to call into this library from within this callback.
     81  void OnError(ErrorKind aError, absl::string_view aMessage) override;
     82 
     83  // Triggered when the socket has aborted - either as decided by this socket
     84  // due to e.g. too many retransmission attempts, or by the peer when
     85  // receiving an ABORT command. No other callbacks will be done after this
     86  // callback, unless reconnecting.
     87  //
     88  // It is allowed to call into this library from within this callback.
     89  void OnAborted(ErrorKind aError, absl::string_view aMessage) override;
     90 
     91  // Called when calling `Connect` succeeds, but also for incoming successful
     92  // connection attempts.
     93  //
     94  // It is allowed to call into this library from within this callback.
     95  void OnConnected() override;
     96 
     97  // Called when the socket is closed in a controlled way. No other
     98  // callbacks will be done after this callback, unless reconnecting.
     99  //
    100  // It is allowed to call into this library from within this callback.
    101  void OnClosed() override;
    102 
    103  // On connection restarted (by peer). This is just a notification, and the
    104  // association is expected to work fine after this call, but there could have
    105  // been packet loss as a result of restarting the association.
    106  //
    107  // It is allowed to call into this library from within this callback.
    108  void OnConnectionRestarted() override;
    109 
    110  // Indicates that a stream reset request has failed.
    111  //
    112  // It is allowed to call into this library from within this callback.
    113  void OnStreamsResetFailed(webrtc::ArrayView<const StreamID> aOutgoingStreams,
    114                            absl::string_view aReason) override;
    115 
    116  // Indicates that a stream reset request has been performed.
    117  //
    118  // It is allowed to call into this library from within this callback.
    119  void OnStreamsResetPerformed(
    120      webrtc::ArrayView<const StreamID> aOutgoingStreams) override;
    121 
    122  // When a peer has reset some of its outgoing streams, this will be called. An
    123  // empty list indicates that all streams have been reset.
    124  //
    125  // It is allowed to call into this library from within this callback.
    126  void OnIncomingStreamsReset(
    127      webrtc::ArrayView<const StreamID> aIncomingStreams) override;
    128 
    129  // Will be called when the amount of data buffered to be sent falls to or
    130  // below the threshold set when calling `SetBufferedAmountLowThreshold`.
    131  //
    132  // It is allowed to call into this library from within this callback.
    133  void OnBufferedAmountLow(StreamID aStreamId) override;
    134 
    135  void OnLifecycleMessageFullySent(LifecycleId aLifecycleId) override;
    136  void OnLifecycleMessageExpired(LifecycleId aLifecycleId,
    137                                 bool aMaybeDelivered) override;
    138 
    139 private:
    140  void UpdateBufferedAmount(StreamID aStreamId);
    141  void OnDCEPMessageDone(LifecycleId aLifecycleId);
    142 
    143  bool HasPreChannelData(uint16_t aStream) const;
    144 
    145  std::unique_ptr<DcSctpSocketInterface> mDcSctp;
    146  std::set<uint16_t> mStreamsAwaitingAck;
    147 
    148  // dcsctp counts DCEP payloads as part of bufferedAmount and bufferedamountlow
    149  // This is wrong. dcsctp does not make it easy to tell whether any DCEP has
    150  // been sent when bufferedAmount decreases. We can set bufferedAmount
    151  // thresholds to detect when any data is sent, but those callbacks don't tell
    152  // us whether that data was DCEP or not. We can also monitor the lifecycle of
    153  // packets, but we will not be able to detect when a large packet is partially
    154  // sent. We need to combine these approaches to figure out how much actual
    155  // data is buffered. We take advantage of a couple of things:
    156  //
    157  // 1. DCEP messages are small enough that partial sends will not happen,
    158  // meaning that we can expect OnLifecycleMessageFullySent to accurately
    159  // reflect how much DCEP has just been sent.
    160  // 2. OnBufferedAmountLow and OnLifecycleMessageFullySent are called in the
    161  // same task when data is sent.
    162  //
    163  // The basic idea is to track the total of both DCEP and data bytes using the
    164  // OnBufferedAmountLow callback, and subtract the DCEP bytes if we see
    165  // OnLifecycleMessageFullySent callback/s for the DCEP messages. This
    166  // subtraction is done in a dispatched task; inside of that task we will not
    167  // have cases where OnBufferedAmountLow has fired, but the corresponding
    168  // OnLifecycleMessageFullySent (if any) have not.
    169 
    170  std::map<uint16_t, size_t> mBufferedAmounts;
    171  std::map<uint16_t, int> mDCEPBytesSent;
    172  uint64_t mNextLifecycleId = 1;
    173  // lifecycle-id -> (stream-id, amount)
    174  std::map<uint64_t, std::pair<uint16_t, size_t>> mBufferedDCEPBytes;
    175  // Holding tank for messages whose channel has not been created yet.
    176  std::vector<IncomingMsg> mPreChannelData;
    177 };
    178 
    179 }  // namespace mozilla
    180 
    181 #endif  // NETWERK_SCTP_DATACHANNEL_DATACHANNELDCSCTP_H_