sctplab/usrsctp

What does usrsctp_conninput do?

hassanctech opened this issue · 1 comments

This API usrsctp_conninput is missing from the documentation: https://github.com/sctplab/usrsctp/blob/master/Manual.md

Searching other issues / comments what I've been able to gather is (1) the first argument is supposed to be an address if you're using a custom transport. I'm using this in WebRTC so SCTP over DTLS for data channel. What exactly counts here as a "custom transport"? I see examples with all the following: arbitrary struct address, (void*) 1, null. What exactly is the expectation here? What exactly does this API do, it appears it is responsible for some sort of chunking of the incoming buffer. As a user of this library I'd like to understand under what circumstance this API needs to be called, under what circumstances the first parameter needs to be provided (since it doesn't appear this API makes any network calls rather it just processes what was received on the network thread.

In the mediasoup(v3) WebRTC project, the usrsctp_conninput function is used to pass sctp data received from the DTLs layer. It waits for a callback function onRecvSctpData which is registered using the usrsctp_socket function
usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, onRecvSctpData, nullptr, 0, static_cast<void*>(this)); .

When the server (mediasoup) receives an SCTP message, you can set a breakpoint in the onRecvSctpData function using the following command in gdb:

gdb -p `pidof mediasoup-worker`
b onRecvSctpData 

The gdb backtrace for the breakpoint is as follows:

(gdb) bt
#0  onRecvSctpData (data=0x2586a90, len=3, rcv=..., flags=128, ulpInfo=0x257f4f0) at ../src/RTC/SctpAssociation.cpp:40
#1  0x00000000007bd234 in sctp_invoke_recv_callback (inp=0x257f880, stcb=0x25d4e50, control=0x25feb90, inp_read_lock_held=0) at ../deps/usrsctp/usrsctp/usrsctplib/netinet/sctputil.c:5337
#2  0x00000000007bd8e2 in sctp_add_to_readq (inp=0x257f880, stcb=0x25d4e50, control=0x25feb90, sb=0x257f6e8, end=1, inp_read_lock_held=0, so_locked=0)
    at ../deps/usrsctp/usrsctp/usrsctplib/netinet/sctputil.c:5449
#3  0x00000000007d7730 in sctp_process_a_data_chunk (stcb=0x25d4e50, asoc=0x25d4ea8, m=0x7fffd2613008, offset=12, chk_length=19, net=0x25d56d0, high_tsn=0x7fffd2612f40, abort_flag=0x7fffd2612dbc, 
    break_flag=0x7fffd2612dc0, last_chunk=1, chk_type=0 '\000') at ../deps/usrsctp/usrsctp/usrsctplib/netinet/sctp_indata.c:2150
#4  0x00000000007d9526 in sctp_process_data (mm=0x7fffd2613008, iphlen=0, offset=0x7fffd2612e90, length=32, inp=0x257f880, stcb=0x25d4e50, net=0x25d56d0, high_tsn=0x7fffd2612f40)
    at ../deps/usrsctp/usrsctp/usrsctplib/netinet/sctp_indata.c:2808
#5  0x000000000076d92c in sctp_common_input_processing (mm=0x7fffd2613008, iphlen=0, offset=12, length=32, src=0x7fffd2613020, dst=0x7fffd2613010, sh=0x25fe9c0, ch=0x25fe9cc, compute_crc=1 '\001', 
    ecn_bits=0 '\000', vrf_id=0, port=0) at ../deps/usrsctp/usrsctp/usrsctplib/netinet/sctp_input.c:6066
#6  0x000000000075cf8f in usrsctp_conninput (addr=0x257f4f0, buffer=0x151b800 <RTC::DtlsTransport::sslReadBuffer>, length=32, ecn_bits=0 '\000')
    at ../deps/usrsctp/usrsctp/usrsctplib/user_socket.c:3382
#7  0x000000000066cf9f in RTC::SctpAssociation::ProcessSctpData (this=0x257f4f0, data=0x151b800 <RTC::DtlsTransport::sslReadBuffer> "\023\210\023\210\277\301>w<\315\375c", len=32)
    at ../src/RTC/SctpAssociation.cpp:319
#8  0x0000000000690a0a in RTC::Transport::ReceiveSctpData (this=0x256d210, data=0x151b800 <RTC::DtlsTransport::sslReadBuffer> "\023\210\023\210\277\301>w<\315\375c", len=32)
    at ../src/RTC/Transport.cpp:1666
 ...

Summarized as follow:

  1. The usrsctp_conninput act as a input function
  2. When the socket recv msg, it will call the callback sctp_invoke_recv_callback which register in usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, onRecvSctpData, nullptr, 0, static_cast<void*>(this))
  3. onRecvSctpData will handle recevied msg ,then forward to other consumer socket

It's important to note that the first argument, void *addr in usrsctp_conninput, is an object pointer rather than a real IPv4 (or IPv6) address with a port. It represents an instance of SctpAssociation, acting as a context that will be invoked in the future when the onRecvSctpData function is called.

Hope this explanation is helpful for anyone who may be confused about usrsctp_conninput.
Any corrections or additional information would be greatly appreciated.