usrsctp: Remove usage of usrsctp_getladdrs()

Using usrsctp_getladdrs() would sometimes be flagged by TSAN for a lock
order inversion. It was used to retrieve the "id" of the socket on the
transport.
The "id" is instead stored in the "ulp_info" parameter, which is
passed with each callback from usrsctp.

Bug: webrtc:12823
Change-Id: Ifb3d7780273a460e677526dd3a93f9365b29300c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/229000
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34784}
diff --git a/media/sctp/usrsctp_transport.cc b/media/sctp/usrsctp_transport.cc
index ce868a1..c7e3016 100644
--- a/media/sctp/usrsctp_transport.cc
+++ b/media/sctp/usrsctp_transport.cc
@@ -490,114 +490,54 @@
                                  void* ulp_info) {
     AutoFreedPointer owned_data(data);
 
-    absl::optional<uintptr_t> id = GetTransportIdFromSocket(sock);
-    if (!id) {
-      RTC_LOG(LS_ERROR)
-          << "OnSctpInboundPacket: Failed to get transport ID from socket "
-          << sock;
-      return kSctpErrorReturn;
-    }
-
     if (!g_transport_map_) {
       RTC_LOG(LS_ERROR)
           << "OnSctpInboundPacket called after usrsctp uninitialized?";
       return kSctpErrorReturn;
     }
+
+    uintptr_t id = reinterpret_cast<uintptr_t>(ulp_info);
+
     // PostsToTransportThread protects against the transport being
     // simultaneously deregistered/deleted, since this callback may come from
     // the SCTP timer thread and thus race with the network thread.
     bool found = g_transport_map_->PostToTransportThread(
-        *id, [owned_data{std::move(owned_data)}, length, rcv,
-              flags](UsrsctpTransport* transport) {
+        id, [owned_data{std::move(owned_data)}, length, rcv,
+             flags](UsrsctpTransport* transport) {
           transport->OnDataOrNotificationFromSctp(owned_data.get(), length, rcv,
                                                   flags);
         });
     if (!found) {
       RTC_LOG(LS_ERROR)
-          << "OnSctpInboundPacket: Failed to get transport for socket ID "
-          << *id << "; possibly was already destroyed.";
+          << "OnSctpInboundPacket: Failed to get transport for socket ID " << id
+          << "; possibly was already destroyed.";
       return kSctpErrorReturn;
     }
     return kSctpSuccessReturn;
   }
 
-  static absl::optional<uintptr_t> GetTransportIdFromSocket(
-      struct socket* sock) {
-    absl::optional<uintptr_t> ret;
-    struct sockaddr* addrs = nullptr;
-    int naddrs = usrsctp_getladdrs(sock, 0, &addrs);
-    if (naddrs <= 0 || addrs[0].sa_family != AF_CONN) {
-      return ret;
-    }
-    // usrsctp_getladdrs() returns the addresses bound to this socket, which
-    // contains the UsrsctpTransport id as sconn_addr.  Read the id,
-    // then free the list of addresses once we have the pointer.  We only open
-    // AF_CONN sockets, and they should all have the sconn_addr set to the
-    // id of the transport that created them, so [0] is as good as any other.
-    struct sockaddr_conn* sconn =
-        reinterpret_cast<struct sockaddr_conn*>(&addrs[0]);
-    ret = reinterpret_cast<uintptr_t>(sconn->sconn_addr);
-    usrsctp_freeladdrs(addrs);
-
-    return ret;
-  }
-
-  // TODO(crbug.com/webrtc/11899): This is a legacy callback signature, remove
-  // when usrsctp is updated.
-  static int SendThresholdCallback(struct socket* sock, uint32_t sb_free) {
-    // Fired on our I/O thread. UsrsctpTransport::OnPacketReceived() gets
-    // a packet containing acknowledgments, which goes into usrsctp_conninput,
-    // and then back here.
-    absl::optional<uintptr_t> id = GetTransportIdFromSocket(sock);
-    if (!id) {
-      RTC_LOG(LS_ERROR)
-          << "SendThresholdCallback: Failed to get transport ID from socket "
-          << sock;
-      return 0;
-    }
-    if (!g_transport_map_) {
-      RTC_LOG(LS_ERROR)
-          << "SendThresholdCallback called after usrsctp uninitialized?";
-      return 0;
-    }
-    bool found = g_transport_map_->PostToTransportThread(
-        *id, [](UsrsctpTransport* transport) {
-          transport->OnSendThresholdCallback();
-        });
-    if (!found) {
-      RTC_LOG(LS_ERROR)
-          << "SendThresholdCallback: Failed to get transport for socket ID "
-          << *id << "; possibly was already destroyed.";
-    }
-    return 0;
-  }
-
   static int SendThresholdCallback(struct socket* sock,
                                    uint32_t sb_free,
                                    void* ulp_info) {
     // Fired on our I/O thread. UsrsctpTransport::OnPacketReceived() gets
     // a packet containing acknowledgments, which goes into usrsctp_conninput,
     // and then back here.
-    absl::optional<uintptr_t> id = GetTransportIdFromSocket(sock);
-    if (!id) {
-      RTC_LOG(LS_ERROR)
-          << "SendThresholdCallback: Failed to get transport ID from socket "
-          << sock;
-      return 0;
-    }
     if (!g_transport_map_) {
       RTC_LOG(LS_ERROR)
           << "SendThresholdCallback called after usrsctp uninitialized?";
       return 0;
     }
+
+    uintptr_t id = reinterpret_cast<uintptr_t>(ulp_info);
+
     bool found = g_transport_map_->PostToTransportThread(
-        *id, [](UsrsctpTransport* transport) {
+        id, [](UsrsctpTransport* transport) {
           transport->OnSendThresholdCallback();
         });
     if (!found) {
       RTC_LOG(LS_ERROR)
           << "SendThresholdCallback: Failed to get transport for socket ID "
-          << *id << "; possibly was already destroyed.";
+          << id << "; possibly was already destroyed.";
     }
     return 0;
   }
@@ -977,7 +917,7 @@
 
   sock_ = usrsctp_socket(
       AF_CONN, SOCK_STREAM, IPPROTO_SCTP, &UsrSctpWrapper::OnSctpInboundPacket,
-      &UsrSctpWrapper::SendThresholdCallback, kSendThreshold, this);
+      &UsrSctpWrapper::SendThresholdCallback, kSendThreshold, nullptr);
   if (!sock_) {
     RTC_LOG_ERRNO(LS_ERROR) << debug_name_
                             << "->OpenSctpSocket(): "
@@ -993,6 +933,7 @@
     return false;
   }
   id_ = g_transport_map_->Register(this);
+  usrsctp_set_ulpinfo(sock_, reinterpret_cast<void*>(id_));
   // Register our id as an address for usrsctp. This is used by SCTP to
   // direct the packets received (by the created socket) to this class.
   usrsctp_register_address(reinterpret_cast<void*>(id_));