Bug 1395246: nullcheck DataChannel SendPacket calls, add some diagnostics r=drno
authorRandell Jesup <rjesup@jesup.org>
Thu, 07 Jun 2018 15:26:25 -0400
changeset 476049 4d7a8d001f087fc500be3b4ca2469310fa39e6be
parent 476048 5cd3f1a923eff54b648a02a24a52c37c17b4412b
child 476050 ea21bf3e665d10066b6dce39873de9b353a12e57
child 476106 6d5b2000e405ba68971554d6803c02fcc4935f1a
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1395246
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1395246: nullcheck DataChannel SendPacket calls, add some diagnostics r=drno
netwerk/sctp/datachannel/DataChannel.cpp
netwerk/sctp/datachannel/DataChannel.h
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -313,16 +313,19 @@ DataChannelConnection::DataChannelConnec
   mSocket = nullptr;
   mMasterSocket = nullptr;
   mListener = listener;
   mLocalPort = 0;
   mRemotePort = 0;
   mPendingType = PENDING_NONE;
   LOG(("Constructor DataChannelConnection=%p, listener=%p", this, mListener.get()));
   mInternalIOThread = nullptr;
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  mShutdown = false;
+#endif
 }
 
 DataChannelConnection::~DataChannelConnection()
 {
   LOG(("Deleting DataChannelConnection %p", (void *) this));
   // This may die on the MainThread, or on the STS thread
   ASSERT_WEBRTC(mState == CLOSED);
   MOZ_ASSERT(!mMasterSocket);
@@ -390,16 +393,19 @@ void DataChannelConnection::DestroyOnSTS
 {
   if (aSocket && aSocket != aMasterSocket)
     usrsctp_close(aSocket);
   if (aMasterSocket)
     usrsctp_close(aMasterSocket);
 
   usrsctp_deregister_address(static_cast<void *>(this));
   LOG(("Deregistered %p from the SCTP stack.", static_cast<void *>(this)));
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  mShutdown = true;
+#endif
 
   disconnect_all();
 
   // we may have queued packet sends on STS after this; dispatch to ourselves before finishing here
   // so we can be sure there aren't anymore runnables active that can try to touch the flow.
   // DON'T use RUN_ON_THREAD, it queue-jumps!
   mSTS->Dispatch(WrapRunnable(RefPtr<DataChannelConnection>(this),
                               &DataChannelConnection::DestroyOnSTSFinal),
@@ -826,29 +832,33 @@ DataChannelConnection::SctpDtlsInput(Tra
   MutexAutoLock lock(mLock);
   usrsctp_conninput(static_cast<void *>(this), data, len, 0);
 }
 
 int
 DataChannelConnection::SendPacket(unsigned char data[], size_t len, bool release)
 {
   //LOG(("%p: SCTP/DTLS sent %ld bytes", this, len));
-  int res = mTransportFlow->SendPacket(data, len) < 0 ? 1 : 0;
+  int res = 0;
+  if (mTransportFlow) {
+    res = mTransportFlow->SendPacket(data, len) < 0 ? 1 : 0;
+  }
   if (release)
     delete [] data;
   return res;
 }
 
 /* static */
 int
 DataChannelConnection::SctpDtlsOutput(void *addr, void *buffer, size_t length,
                                       uint8_t tos, uint8_t set_df)
 {
   DataChannelConnection *peer = static_cast<DataChannelConnection *>(addr);
   int res;
+  MOZ_DIAGNOSTIC_ASSERT(!peer->mShutdown);
 
   if (MOZ_LOG_TEST(gSCTPLog, LogLevel::Debug)) {
     char *buf;
 
     if ((buf = usrsctp_dumppacket(buffer, length, SCTP_DUMP_OUTBOUND)) != nullptr) {
       SCTP_LOG(("%s", buf));
       usrsctp_freedumpbuffer(buf);
     }
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -134,18 +134,18 @@ public:
   public:
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(DataChannelConnection::DataConnectionListener)
     virtual ~DataConnectionListener() = default;
 
     // Called when a new DataChannel has been opened by the other side.
     virtual void NotifyDataChannel(already_AddRefed<DataChannel> channel) = 0;
   };
 
-  explicit DataChannelConnection(DataConnectionListener *listener,
-                                 nsIEventTarget *aTarget);
+  DataChannelConnection(DataConnectionListener *listener,
+                        nsIEventTarget *aTarget);
 
   bool Init(unsigned short aPort, uint16_t aNumStreams, bool aMaxMessageSizeSet,
             uint64_t aMaxMessageSize);
 
   void Destroy(); // So we can spawn refs tied to runnables in shutdown
   // Finish Destroy on STS to avoid SCTP race condition with ABORT from far end
   void DestroyOnSTS(struct socket *aMasterSocket,
                     struct socket *aSocket);
@@ -337,16 +337,20 @@ private:
   nsCOMPtr<nsIEventTarget> mSTS;
 #endif
   uint16_t mLocalPort; // Accessed from connect thread
   uint16_t mRemotePort;
 
   nsCOMPtr<nsIThread> mInternalIOThread;
   uint8_t mPendingType;
   nsCString mRecvBuffer;
+
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  bool mShutdown;
+#endif
 };
 
 #define ENSURE_DATACONNECTION \
   do { MOZ_ASSERT(mConnection); if (!mConnection) { return; } } while (0)
 
 class DataChannel {
 public:
   enum {