Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What does usrsctp_conninput do? #678

Open
hassanctech opened this issue Jul 10, 2023 · 1 comment
Open

What does usrsctp_conninput do? #678

hassanctech opened this issue Jul 10, 2023 · 1 comment

Comments

@hassanctech
Copy link

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.

@grootgordon
Copy link
Contributor

grootgordon commented Dec 14, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants