Giter Club home page Giter Club logo

usrsctp's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usrsctp's Issues

Homebrew: please create tags

In order to adopt the new GitHub repository as its upstream, the Homebrew formula will need a release tag that can be assigned to the stable spec. This allows a tarball of the tag to be downloaded from GitHub and the sha256 of the tarball to be recorded in the formula to ensure integrity.

Memory leak because no thread cleanup possible

The send callback may or may not be called inside an internal separated thread (timer, other events, etc). When the call is made from a separate thread, the app-level code may or may not use things in the thread local storage. For example, when OpenSSL routines are used in that callback, they may generate/allocate new objects in the thread local storage. When the SCTP stack is dismantled with usrsctp_finish, there is no way to cleanup the TLS objects allocated in callback. Things like ERR_remove_thread_state from openssl are now impossible to call as part of the thread which created/accessed the OpenSSL error codes.

==77507== 24 bytes in 1 blocks are still reachable in loss record 1 of 4        
==77507==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==77507==    by 0x53E518: default_malloc_ex (mem.c:79)                          
==77507==    by 0x53EBCF: CRYPTO_malloc (mem.c:342)                             
==77507==    by 0x57714E: lh_insert (lhash.c:191)                               
==77507==    by 0x5784E0: int_thread_set_item (err.c:518)                       
==77507==    by 0x57985A: ERR_get_state (err.c:1037)                            
==77507==    by 0x578EFF: get_error_values (err.c:807)                          
==77507==    by 0x578DA8: ERR_peek_error (err.c:769)                            
==77507==    by 0x50035E: SSL_get_error (ssl_lib.c:2705) 

C_FLAGS and CXX_FLAGS modified globally

This is a pretty huge antipattern that prevents the project from being easily transitively included in an existing CMake project. Variables should only be set on a specific target

Examples under windows (again)

Hi.

Trying to use sctp, but unsuccessful:

start discard_server.exe 11111 22222
client 127.0.0.1 9 0 22222 11111 - just sleep at usrsctp_connect.

Well, try http_client example from #76:
http_client 212.201.121.100 80 0 9899 9899 - works fine.
http_client 212.201.121.100 80 - some infinite loop:

...
chunk OUTPUT returns <-- sleep 3 seconds
recv_function_raw: Received 76 bytes. - calling sctp_common_input_processing with off=32
stcb:00000000 inp:00000000
stcb is 00000000
Timer type 5 goes off
Error count for 007D9590 now 1 thresh:5
Overall error count for 007D8B58 now 0 thresh:10 state:201
Timer now complete (type = 5)
Timer type 5 goes off
Error count for 007D9590 now 2 thresh:5
Overall error count for 007D8B58 now 0 thresh:10 state:201
Timer now complete (type = 5)
recv_function_raw: Received 76 bytes. - calling sctp_common_input_processing with off=32
stcb:00000000 inp:00000000
stcb is 00000000
Timer type 5 goes off
Error count for 007D9590 now 3 thresh:5
Overall error count for 007D8B58 now 0 thresh:10 state:201
Timer now complete (type = 5)
... and so on

Here is a logs: http_client-sctp-raw.log, http_client-sctp-caps.log.

Windows 7 x64, http_client debug x86.

Http_client not building on windows and fix

Hello,
I don't know how to submit a fix, so I posted here. At current source http_client can't build. Error:

warning C4013: 'snprintf' undefined; assuming extern returning int

Fix:
Need to change
if (argc > 6) { snprintf(request, sizeof(request), "%s %s %s", request_prefix, argv[6], request_postfix); } else { snprintf(request, sizeof(request), "%s %s %s", request_prefix, "/", request_postfix); }
to
if (argc > 6) { _snprintf(request, sizeof(request), "%s %s %s", request_prefix, argv[6], request_postfix); } else { _snprintf(request, sizeof(request), "%s %s %s", request_prefix, "/", request_postfix); }

And insert
`#ifdef _WIN32

define _CRT_SECURE_NO_WARNINGS

endif`

Becouse of:

warning C4996: '_snprintf': This function or variable may be unsafe. Consider using _snprintf_s instead. To disable deprecation, use _CRT_SECURE
_NO_WARNINGS. See online help for details.

struct socket to int

Hello,
Is it possible to get socket number from struct socket? Can't find struct socket declaration

Why close() cannot terminate a waiting connect()?

This is what I do:

  1. Create a socket with socket()
  2. Start a thread that calls close() after 1 second.
  3. Call connect() to a remote address where there is no server listening.
  4. I expect the close() can unblock the connect() which would return an error, but I see the close() goes through, while the connect() never unblocks.

It seems that the close() would directly destroy the condition variable that the connect() is waiting for.

Am I using it incorrectly? What is the suggested/legit way to timeout a connect() call?

Thanks.

If usrsctp thread safe?

In other words: I've a multi-thread app which runs N threads (each one running a libuv events loop for UDP/TCP etc), and I want to add usrsctp on top of it.

Can I safely call usrsctp_init() on the main thread (which runs before all the others are created) and use this lib within the other threads?

To be clear: each thread manages its own UDP/TCP connections.

Thanks a lot.

Visual C++ multithreaded: srand(time(NULL)). Same seeding for one second.

I have visual c++ application (at least VS2013+debug win64 libs) with usrsctp_init and usrsctp_connect performed immediately after launch. I start 10 apps at the same time. Each SCTP_INIT have the same initial vtag and 9 apps unable to connect.

This is because time(NULL) is the same for all 10 apps and is not appropriate choice for srand() seed.

usrsctplib need more complicated seed for srand.

Set SCTP thread names

It would be useful to name the threads created in usrsctplib/user_recv_thread.c.

Here's sample code for Linux:

    if (prctl (PR_SET_NAME, (unsigned long int) thread_name, 0, 0, 0))
      printf("Failed to set thread name");

For Darwin:

  if (pthread_setname_np (name))
      printf("Failed to set thread name");

For Windows:

void
SetThreadName (DWORD dwThreadID, LPCSTR szThreadName)
{
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = szThreadName;
  info.dwThreadID = dwThreadID;
  info.dwFlags = 0;

  __try {
    RaiseException (0x406D1388, 0, sizeof (info) / sizeof (DWORD),
        (DWORD *) & info);
  }
  __except (EXCEPTION_CONTINUE_EXECUTION) {
  }
}

There is no "./configure"

The manual says:

Unix-like Operating Systems

In the folder usrsctp type
$ ./configure
$ make

But there is no "configure" script in the source (but "configure.am). The doc should tell how to get it.

sctp_os_macosx.h missing?

netinet/sctp_os.h references netinet/sctp_os_macosx.h, but that file doesn't exist. I don't know how this built before on mac os!

Stream priority

How do I assign a priority to a stream? I couldn't find any indication in the manual.

I wanted to use the SCTP_SS_VALUE socket option but this is not in usrsctp.h, so maybe a better way exists.

Thanks in advance

usrsctp_connect(): ability to timeout?

currently, usrsctp_connect() waits indefinitely for the connection, even if SCTP_NODELAY has been set on the socket, whereas applications may prefer to time out if the peer never becomes available.

is this by design, or would a timeout be a feasible addition?

Receiving a complete unordered message while reassembling another message causes the association to be aborted

I can reproduce this by simulating network reordering and alternating between sending messages that get fragmented (size greater than MTU) and smaller messages that aren't fragmented.

The problem seems to be this block of code:

        /* Its a complete segment. Lets validate we
         * don't have a re-assembly going on with
         * the same Stream/Seq (for ordered) or in
         * the same Stream for unordered.
         */
        SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for msg in case we have dup\n",
            chunk_flags);`
        if (find_reasm_entry(strm, msg_id, ordered, old_data)) {
            SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
                chunk_flags,
                msg_id);

            goto err_out;
        }

I don't understand why this is necessary. If fragmented segments can be received while reassembling another fragmented message, why can't a complete segment be received? That seems the simpler case to handle. If I remove this condition, things work as expected.

struct sockaddr has no member sa_len error when compiling on linux

got this error

...
user_socket.c: In function 'usrsctp_getassocid':
user_socket.c:723:44: error: 'struct sockaddr' has no member named 'sa_len'
  memcpy((caddr_t)&sp.spinfo_address, sa, sa->sa_len);

compiling 63fcb4e on linux.

struct sockaddr has no sa_len on linux (http://stackoverflow.com/q/7581782) and e.g. this code does:

#ifndef NOT_HAVE_SA_LEN
#define GET_SA_LEN(X) (sizeof(struct sockaddr) > ((struct sockaddr*)&(X))->sa_len ? \
                       sizeof(struct sockaddr) : ((struct sockaddr*)&(X))->sa_len   )
#elif HAVE_IPV6
#define GET_SA_LEN(X) (((struct sockaddr*)&(X))->sa_family == AF_INET  ? sizeof(struct sockaddr_in) : \
                       ((struct sockaddr*)&(X))->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr))
#else
#define GET_SA_LEN(X) (((struct sockaddr*)&(X))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr))
#endif

to deal w/ that.

Timing issues with bindx and SET_PEER_PRIMARY_ADDR

Scenario: SCTP connection fully established; v6 one-to-many sockets on both sides; one v4 and one v6 address in association on server's side, one v4 address on client's side; sending data is possible in both directions

If I add the client's v6 address, let the program sleep() for around 5 seconds and then call SET_PEER_PRIMARY_ADDR, everything works as intended.
If I add the client's v6 address and do not let the program sleep() (long enough), but instead call SET_PEER_PRIMARY_ADDR immediately, only the ADD_ADDR succeeds while the SET_PEER_PRIMARY_ADDR fails silently on the server's side.

Alleged reason: usrsctp sends a SET_PEER_PRIMARY_ADDR command out considerably faster than an SCTP_BINDX_ADD_ADDR. E.g. usrsctp sent the SCTP_BINDX_ADD_ADDR 1.5 seconds after SET_PEER_PRIMARY_ADDR.

Debug output client side:

*adding addresses*
Ok laddr->ifa:0x21bcd10 is possible, v6 addAddress returned
*set peer primary address*
asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: IPv6 address: abcd::dcba:port:0 scope:0
set_primary_ip_address_sa: queued on tcb=0x21bdf90, IPv6 address: abcd::dcba:port:0 scope:1501644365
asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: IPv6 address: abcd::dcba:port:0 scope:0

(note: not the actual address; *foo*: my own output)

Both ASCONF's get acknowledged, so without involving the upper layer I can not know explicitly, whether the calls succeeded or failed.
I can only guess implicitly, when the server won't use the address as intended.

The SCTP implementation could keep track of ADD/REM_ADDRs calls and giving some kind of notification to the upper layer when the ACK arrives.
One could wait with SET_PEER_PRIMARY_ADDR for that notification.
Perhaps a dedicated error cause could also help in the long term.

Is there an intended or optimal way to handle these timing issues when adding or removing addresses or setting the peer's primary address?

I hope I have stated the issue clear enough.
I can add more debug output, pcap's and/or my source code if necessary, though source code could take some time.

Thank you for looking into it!

bindx() returns EINVAL

Hi,

I tried to use bindx() like the example below in Linux. While the individual bind() work (commented out), the bindx() doesn't. Is it the correct syntax?

Thanks in advance.

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <usrsctp.h>
#include <stdarg.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


static inline void CHECK(int val, char* str)
{
        if (val!=0) {
                perror(str);
                exit(1);
        }
}

int main(void) 
{
        struct socket* sk; 
        struct sockaddr_in addr[2];

        usrsctp_init(0, NULL, NULL);

        int rv; 

        /* create a socket 1-to-many */
        sk = usrsctp_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 
                NULL, NULL, 0, NULL);   
        CHECK(sk==NULL, "usrsctp_socket");

        /* bind the socket to a local addr */ 
        addr[0].sin_family = AF_INET;
        addr[0].sin_port = htons(5000);
        addr[0].sin_addr.s_addr = inet_addr("127.0.0.1");

        addr[1].sin_family = AF_INET;
        addr[1].sin_port = htons(5000);
        addr[1].sin_addr.s_addr = inet_addr("127.0.0.2");

        rv = usrsctp_bindx(sk, (struct sockaddr *)addr, 2, SCTP_BINDX_ADD_ADDR);
        // rv = usrsctp_bind(sk, (struct sockaddr *)&addr[0], sizeof(struct sockaddr_in));
        // rv = usrsctp_bind(sk, (struct sockaddr *)&addr[1], sizeof(struct sockaddr_in));
        CHECK(rv<0, "usrsctp_bind"); 

        return 0;
}

Valgrind - OS X 10.10 - Darwin 14.5.0 x86_64

Memcheck, a memory error detector
Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
Command: ./ekr_loop
Parent PID: 68438

Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s)
   at 0x10036A93A: setsockopt (in /usr/lib/system/libsystem_kernel.dylib)
   by 0x100003944: recv_thread_init (user_recv_thread.c:1127)
   by 0x100052309: sctp_init (sctp_usrreq.c:170)
   by 0x1000010A7: main (ekr_loop.c:278)
 Address 0x104791914 is on thread 1's stack
 in frame #1, created by recv_thread_init (user_recv_thread.c:1081)
 Uninitialised value was created by a stack allocation
   at 0x10004AE5B: sctp_pcb_init (sctp_pcb.c:6850)

Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s)
   at 0x10036A93A: setsockopt (in /usr/lib/system/libsystem_kernel.dylib)
   by 0x100003C0A: recv_thread_init (user_recv_thread.c:1220)
   by 0x100052309: sctp_init (sctp_usrreq.c:170)
   by 0x1000010A7: main (ekr_loop.c:278)
 Address 0x104791914 is on thread 1's stack
 in frame #1, created by recv_thread_init (user_recv_thread.c:1081)
 Uninitialised value was created by a stack allocation
   at 0x10004AE5B: sctp_pcb_init (sctp_pcb.c:6850)

Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s)
   at 0x10036A93A: setsockopt (in /usr/lib/system/libsystem_kernel.dylib)
   by 0x100004125: recv_thread_init (user_recv_thread.c:1366)
   by 0x100052309: sctp_init (sctp_usrreq.c:170)
   by 0x1000010A7: main (ekr_loop.c:278)
 Address 0x104791914 is on thread 1's stack
 in frame #1, created by recv_thread_init (user_recv_thread.c:1081)
 Uninitialised value was created by a stack allocation
   at 0x10004AE5B: sctp_pcb_init (sctp_pcb.c:6850)

Conditional jump or move depends on uninitialised value(s)
   at 0x10046AC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
   by 0x10025E9F6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
   by 0x100268E45: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
   by 0x10028E80E: __v2printf (in /usr/lib/system/libsystem_c.dylib)
   by 0x10028EAE0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
   by 0x1002649D1: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
   by 0x100262837: printf (in /usr/lib/system/libsystem_c.dylib)
   by 0x10000126A: main (ekr_loop.c:360)
 Uninitialised value was created by a stack allocation
   at 0x100264A58: __vfprintf (in /usr/lib/system/libsystem_c.dylib)

UNKNOWN host message [id 412, to mach_host_self(), reply 0x30f]
UNKNOWN host message [id 222, to mach_host_self(), reply 0x30f]
UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
Thread 8:
Conditional jump or move depends on uninitialised value(s)
   at 0x10046AC47: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
   by 0x10025E9F6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
   by 0x100268E45: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
   by 0x10028E80E: __v2printf (in /usr/lib/system/libsystem_c.dylib)
   by 0x10028EAE0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
   by 0x1002649D1: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
   by 0x100262837: printf (in /usr/lib/system/libsystem_c.dylib)
   by 0x1000018C0: receive_cb (ekr_loop.c:121)
   by 0x100065BA3: sctp_append_to_readq (sctputil.c:5062)
   by 0x10001723E: sctp_service_reassembly (sctp_indata.c:464)
   by 0x100019A2A: sctp_process_data (sctp_indata.c:1236)
   by 0x1000210E9: sctp_common_input_processing (sctp_input.c:6151)
 Uninitialised value was created by a stack allocation
   at 0x100264A58: __vfprintf (in /usr/lib/system/libsystem_c.dylib)


HEAP SUMMARY:
    in use at exit: 54,745 bytes in 449 blocks
  total heap usage: 22,036 allocs, 21,587 frees, 15,737,811 bytes allocated

LEAK SUMMARY:
   definitely lost: 0 bytes in 0 blocks
   indirectly lost: 0 bytes in 0 blocks
     possibly lost: 0 bytes in 0 blocks
   still reachable: 19,970 bytes in 24 blocks
        suppressed: 34,775 bytes in 425 blocks
Reachable blocks (those to which a pointer was found) are not shown.
To see them, rerun with: --leak-check=full --show-leak-kinds=all

For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 715 errors from 5 contexts (suppressed: 22 from 22)

Missing license declarations

Manual.tex and programs/datachan.h don't have license declarations. It gives us issues with with our automated license checker because of that.

RFC 2960 support

Does usrsctp support RFC 2960? I know it's obsolete, but there is a lot of old equipment in use which supports only RFC 2960, but there are no good open-source implementations of it AFAIK. So you have to retreat to using Cisco or other gear to talk to existing equipment.

Poor performance sending to WebRTC

Hi, sorry if this isn't the right place to ask questions like this, but I'm trying to use usrsctp in a native app to connect to Chrome, and I'm getting really poor performance.

I'm using sctp wrapped in dtls sent over an libnice connection, using this small library: https://github.com/xhs/librtcdc

While I can get my library to connect and send messages, it seems to be only sending a single message per second, and any further messages get queued in the send queue (which doesn't seem to be getting serviced).

My main question is how I can go about debugging issues like this, and where to start looking when I experience issues using the usrctp library. I've tried hacking in some debug printfs, which has shown that my messages are being queued, but I couldn't figure out how to enable detailed logging from the library.

Any help much appreciated :)

Unable to cleanly close socket when callback API is used

It looks like, when callback mode is used, it's impossible to close socket without race condition.
usrsctp_close frees the socket without waiting for the callback thread to finish.

See following example. I've added some sleeps so the problem is reproduced every time. But, even without them, it will crash after enough iterations.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <usrsctp.h>
#include <assert.h>
#include <arpa/inet.h>

static int receive_cb(struct socket* socket, union sctp_sockstore address, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info) {
    if(data == NULL) {
        usrsctp_close(socket);
        printf("Closed from callback\n");
        return 1;
    }
    printf("In receive_cb\n");
    sleep(2);
    printf("Still in receive_cb\n");
    free(data);
    return 1;
}

static struct socket* socketListen(int localPort) {
    struct socket* socket = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL);
    assert(socket != NULL);
    struct sockaddr_in address = {
        .sin_family = AF_INET,
        .sin_port = htons(localPort),
    };
    assert(usrsctp_bind(socket, (struct sockaddr *)&address, sizeof(address)) == 0);
    assert(usrsctp_listen(socket, 1) == 0);
    return socket;
}

static struct socket* socketConnect(const char* remoteAddress, int remotePort) {
    struct socket* socket = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL);
    assert(socket != NULL);
    struct sockaddr_in address = {
        .sin_family = AF_INET,
        .sin_port = htons(remotePort),
    };
    assert(inet_pton(AF_INET, remoteAddress, &address.sin_addr) == 1);
    assert(usrsctp_connect(socket, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) == 0);
    return socket;
}

int main(int argc, char* argv[]) {
    usrsctp_init(8080, NULL, NULL);

    struct socket* server = socketListen(9);
    struct socket* client = socketConnect("127.0.0.1", 9);

    int n = 0xaabbccdd;
    usrsctp_sendv(client, &n, sizeof(n), NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0);
    sleep(1);
    usrsctp_close(server);
    usrsctp_close(client);
    printf("Connections closed\n");
    sleep(2);
}

When run with valgrind it produces following result:

# valgrind ./test
==20921== Memcheck, a memory error detector
==20921== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20921== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==20921== Command: ./test
==20921==
In receive_cb
Connections closed
Still in receive_cb
==20921== Thread 3:
==20921== Invalid read of size 4
==20921==    at 0x805B9C8: sctp_calc_rwnd (sctp_indata.c:87)
==20921==    by 0x805B9F8: sctp_set_rwnd (sctp_indata.c:65)
==20921==    by 0x807423C: sctp_send_sack (sctp_output.c:10857)
==20921==    by 0x8062D5A: sctp_process_data (sctp_indata.c:2594)
==20921==    by 0x806F59C: sctp_common_input_processing (sctp_input.c:6156)
==20921==    by 0x804B812: recv_function_raw (user_recv_thread.c:431)
==20921==    by 0x48FD954: start_thread (pthread_create.c:300)
==20921==    by 0x4BF01DD: clone (clone.S:130)
==20921==  Address 0x6f0f04c is 228 bytes inside a block of size 416 free'd
==20921==    at 0x48DAB6A: free (vg_replace_malloc.c:366)
==20921==    by 0x804E723: sodealloc (user_socket.c:213)
==20921==    by 0x80504A9: usrsctp_close (user_socket.c:2086)
==20921==    by 0x804914C: main (test.c:55)
==20921==
==20921== Invalid read of size 4
==20921==    at 0x807E7B3: sctp_med_chunk_output (sctp_output.c:8283)
==20921==    by 0x8080979: sctp_chunk_output (sctp_output.c:10493)
==20921==    by 0x806F667: sctp_common_input_processing (sctp_input.c:6216)
==20921==    by 0x804B812: recv_function_raw (user_recv_thread.c:431)
==20921==    by 0x48FD954: start_thread (pthread_create.c:300)
==20921==    by 0x4BF01DD: clone (clone.S:130)
==20921==  Address 0x6f0f0cc is 356 bytes inside a block of size 416 free'd
==20921==    at 0x48DAB6A: free (vg_replace_malloc.c:366)
==20921==    by 0x804E723: sodealloc (user_socket.c:213)
==20921==    by 0x80504A9: usrsctp_close (user_socket.c:2086)
==20921==    by 0x804914C: main (test.c:55)
==20921==
==20921==
==20921== HEAP SUMMARY:
==20921==     in use at exit: 372,784 bytes in 410 blocks
==20921==   total heap usage: 571 allocs, 161 frees, 444,252 bytes allocated
==20921==
==20921== LEAK SUMMARY:
==20921==    definitely lost: 0 bytes in 0 blocks
==20921==    indirectly lost: 0 bytes in 0 blocks
==20921==      possibly lost: 816 bytes in 6 blocks
==20921==    still reachable: 371,968 bytes in 404 blocks
==20921==         suppressed: 0 bytes in 0 blocks
==20921== Rerun with --leak-check=full to see details of leaked memory
==20921==
==20921== For counts of detected and suppressed errors, rerun with: -v
==20921== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 8)

Is this a bug or am I doing something wrong? I've tried several workarounds and it looks there is just no way to close/interrupt SCTP socket from another thread.

Logic error in usrsctp

The VC++ /analyze builder for Chromium is reporting a logic error in usrsctp. Specifically it points out that the last line of this code fragment from third_party\usrsctp\usrsctplib\usrsctplib\user_socket.c is buggy:

struct socket *
usrsctp_socket(int domain, int type, int protocol,
int (_receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info),
int (_send_cb)(struct socket *sock, uint32_t sb_free),
uint32_t sb_threshold,
void *ulp_info)
{
struct socket *so;

if ((protocol = IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {

The line unconditionally assigns to protocol, instead of comparing against it. This was reported in November of 2014 to Michael Tüxen [email protected] and was fixed upstream but that fix seems to have gone away? The original fix was in https://code.google.com/p/sctp-refimpl/source/detail?r=9063 but there is no apparent sign of it in the history.

The bug is apparently not causing any current problems in Chromium but it is incorrect and could be causing problems elsewhere.

The warning is:
third_party\usrsctp\usrsctplib\usrsctplib\user_socket.c(1365) : warning C6282: Incorrect operator: assignment of constant in Boolean context. Consider using '==' instead.

File descriptor

Hi there,
Im trying to modify a multiplatform project to adopt SCTP (including windows) and i think your project is a perfect fit. As far as i know, file descriptors actually are an integer number in comparison with windows that are a void handle. Usrsctp API is similar to sctp bsd sockets but it works with a socket struct instead of integers. What is the relation between the socket struct and file descriptors and how using this socket we will fetch the file descriptor number ? I need to dothis since all the other codebase of the project to which i am trying to use usrsctp works with FD integers, so if you can tell me how i will manage to get the fd from that socket it would be great.
Thank you

Connection between client and server started in one process using UDP_ENCAPS

I want make some game working via sctp.
now game can works in next modes:
client (will connect to remote server)
server
server-client (start server; then start client and connect to server; allow connect other players)
singleplayer ( start server; then start client and connect to server ) (same as server-client, but deny external connects)

Now client and server works fine.
but server-client possible only in sudo mode without using udp_encaps

i found manual packet sending in ekr_loop.c is this only way?

Callbacks fired with invalid data

I've been banging my head against this all day, and I just can't seem to figure it out.

Basically, I'm trying to create a very simple ICE <-> DTLS <-> SCTP example to try and understand things better, and I just can't seem to get the sctp data-ready callback to work. ICE seems to work fine, I can finish my DTLS handshake fine, I can send the SCTP handshake packets (and cookie packets) back-and-forth, but the moment SCTP decides it wants to send something to my app it freaks out.

Here's an brief snippet from my log:

Ok, Common input processing called, m:0xb5cdb00 iphlen:0 offset:12 length:136 stcb:0xb5bc640
stcb:0xb5bc640 state:4
sctp_process_control: iphlen=0, offset=12, length=136 stcb:0xb5bc640
sctp_process_control: processing a chunk type=11, len=4
SCTP_COOKIE-ACK, stcb 0xb5bc640
sctp_handle_cookie_ack: handling COOKIE-ACK
moving to OPEN state
data of length 189316272 received on stream 123 with SSN 34835, TSN 0, PPID 2965129227 (bad callback with weird values)
SCTP: Invalid user_data received (callback doesn't have my user_data set)
data of length 189316272 received on stream 123 with SSN 34835, TSN 0, PPID 2965129227 (bad callback again)
data of length 189316272 received on stream 123 with SSN 34835, TSN 0, PPID 2965129227 (and again)
Check for chunk output prw:131072 tqe:0 tf=0
Calling chunk OUTPUT
SCTP: Data ready, encrypting 28 bytes
SCTP: Connected (usrsctp_connect has returned successfully)
m-c-o put out 1
Ok, we have put out 1 chunks

Are there any caveats to using usrsctp with C++ code? That's the only thing I can think of right now that I'm doing any differently from other libraries I've seen and used.

And advice much appreciated!

Unordered reassembly can add chunks to the wrong message.

Suppose I send two messages, each getting split into two fragments, and they arrive in this order:

  1. Message B fragment 1
  2. Message A fragment 1
  3. Message A fragment 2
  4. Message B fragment 2

The result is that the first complete message assembled is: [A1]
And the second is: [B1][A2][B2]

The reason is that when receiving the "first" chunks out of order, this "swap the mbufs" code doesn't modify tail_mbuf:

/* swap the mbufs */
tdata = control->data;                                                                       
control->data = chk->data;                                                                   
chk->data = tdata;

As a result, when adding A2 to tail_mbuf, it's actually being appended onto B1 instead of A1.

I think this can be fixed by just adding sctp_setup_tail_pointer; that's working for me so far. If you agree, I can make a pull request.

Visual C++ multithreaded: srandom() generates the same values on different threads.

Visual C++ runtime uses per-thread internal state, so it is safe to call srand() for each thread.
Having application with usrsctp_init called on main thread and usrsctp_connect called on different thread.
On subsequent application runs sctp.inital_vtag is always the same(41 for example), because srand() called only on main thread. It is deep hidden from application developers and produces many strange behaviors on subsequent and parallel application calls.

Valgrind - FreeBSD 11.0-CURRENT amd64

Memcheck, a memory error detector
 Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
 Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
 Command: ./ekr_loop
 Parent PID: 86141

Syscall param ioctl(generic) points to uninitialised byte(s)
    at 0x518F7BA: ioctl (in /lib/libc.so.7)
    by 0x5137DB2: if_nametoindex (in /lib/libc.so.7)
    by 0x4061B8: sctp_init_ifns_for_vrf (sctp_bsd_addr.c:479)
    by 0x4061B8: sctp_init_vrf_list (sctp_bsd_addr.c:676)
    by 0x42CC62: sctp_pcb_init (sctp_pcb.c:6834)
    by 0x4320DF: sctp_init (sctp_usrreq.c:170)
    by 0x4017F2: main (ekr_loop.c:278)
  Address 0x7fef00974 is on thread 1's stack
  in frame #1, created by if_nametoindex (???)

 Syscall param ioctl(generic) points to uninitialised byte(s)
    at 0x518F7BA: ioctl (in /lib/libc.so.7)
    by 0x42F263: sctp_userspace_get_mtu_from_ifn (sctp_userspace.c:49)
    by 0x425279: sctp_add_addr_to_vrf (sctp_pcb.c:612)
    by 0x4061E6: sctp_init_ifns_for_vrf (sctp_bsd_addr.c:477)
    by 0x4061E6: sctp_init_vrf_list (sctp_bsd_addr.c:676)
    by 0x42CC62: sctp_pcb_init (sctp_pcb.c:6834)
    by 0x4320DF: sctp_init (sctp_usrreq.c:170)
    by 0x4017F2: main (ekr_loop.c:278)
  Address 0x7fef00928 is on thread 1's stack
  in frame #1, created by sctp_userspace_get_mtu_from_ifn (sctp_userspace.c:41)


 HEAP SUMMARY:
     in use at exit: 12,992 bytes in 21 blocks
   total heap usage: 21,548 allocs, 21,527 frees, 15,851,333 bytes allocated

 LEAK SUMMARY:
    definitely lost: 0 bytes in 0 blocks
    indirectly lost: 0 bytes in 0 blocks
      possibly lost: 0 bytes in 0 blocks
    still reachable: 12,992 bytes in 21 blocks
         suppressed: 0 bytes in 0 blocks
 Rerun with --leak-check=full to see details of leaked memory

 For counts of detected and suppressed errors, rerun with: -v
 Use --track-origins=yes to see where uninitialised values come from
 ERROR SUMMARY: 25 errors from 2 contexts (suppressed: 0 from 0)

Unable to shutdown sctp

I'm having an issue where usrsctp_finish will never return 0 and shutdown cleanly. The code causing the problem is
if (SCTP_INP_INFO_TRYLOCK()) {
if (!LIST_EMPTY(&SCTP_BASE_INFO(listhead))) {
SCTP_INP_INFO_RUNLOCK();
return (-1);
}

Where listhead is never emptied and therefor gets stuck in a loop. Before calling usrsctp_finish I've tried using
usrsctp_shutdown(sctpSocket, SHUT_WR)
and
usrsctp_deregister_address(ulp_info);
usrsctp_close(sock);
Or combinations of the two without any success. I'm not sure if this is a bug or something I've missed? I'm using it under usermode windows.

Empty sndinfo during initial sendv won't return with set assoc_id

Using one-to-many style sockets I want to establish a completely new association to my server by sending the first data packets using usrsctp_sendv().
As I will need the association ID of the newly established association in the future, I set infotype to SCTP_SENDV_SNDINFO and supply an all-NULL struct sctp_sndinfo.
According to the RFC, when usrsctp_sendv() returns, the snd_assoc_id field should contain the association ID:
RFC6458, Page 100

"For a one-to-many style socket, if the struct sctp_sndinfo attribute
is provided, the snd_assoc_id field must be 0. When this function
returns, the snd_assoc_id field will contain the association
identifier of the newly established association."

Unfortunately it doesn't, snd_assoc_id will still be 0.

small warn

I have this compiler warn, which doesn't allow me to treat all warnings as errors

/usrsctplib/netinet/sctp_output.c:11009:24: warning: ‘strseq_m’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     strseq_m->reserved = ntohs(0);
                        ^
../usrsctplib/usrsctplib/netinet/sctp_output.c:11005:22: warning: ‘strseq’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     strseq->sequence = ntohs(at->rec.data.stream_seq);

Memory leak under Windows

usrsctptest4
This is after applying this PR: #48
I'm not really familiar with Windows, so I could be doing something wrong, but it appears there may be leaks some place else.

The Windows UMDH utility seems to point to some suspicious parts in sctp_init_ifns_for_vrf():
https://github.com/sctplab/usrsctp/blob/master/usrsctplib/netinet/sctp_bsd_addr.c#L356-L362 and
https://github.com/sctplab/usrsctp/blob/master/usrsctplib/netinet/sctp_bsd_addr.c#L404-L409.

Here's the UMDH log from the test program I used:
stackdiff.txt

Using SCTP through the loopback

Hi,

I'm quite new to SCTP, so bear with me.

I tried to do some simple tests using the loopback in Linux (pls see sctp.c and tcp.c programs below). For this I assigned also 127.0.0.2 to the loopback.

While with TCP I could get a connection, with SCTP I couldn't. I could only get a connection with SCTP if both client and server were bound to 127.0.0.1.

I expected to be able to use the range whole 127.0.0.0/8 for the loopback. Is this possible?

Thanks.

sctp.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <usrsctp.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

#define SERVER_PORT   8888
#define CLIENT_PORT   5000
#define SERVER_ADDR   "127.0.0.1"
#define CLIENT_ADDR   "127.0.0.2"


struct socket *srv_sk, *cli_sk;
struct sockaddr_in srv_addr, cli_addr;

pthread_t client_thread;

static inline void check(int val, char* str)
{
    if (val<0) {
        perror(str);
        exit(1);
    }
}


static void server()
{
    int rv;

    /* create a socket 1-to-many */
    srv_sk = usrsctp_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 
        NULL, NULL, 0, NULL);
    if (srv_sk == NULL) {   
        perror("usrsctp_socket");
        exit(1);
    }

    /* bind the socket to a local addr */ 
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    srv_addr.sin_port = htons(SERVER_PORT);

    rv = usrsctp_bind(srv_sk, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr_in));
    check(rv, "usrsctp_bind (server)");

    /* listen for connections */
    rv = usrsctp_listen(srv_sk, 3);
    check(rv, "usrsctp_listen");

}

static void* client(void* p)
{
    int rv;

    /* create a socket 1-to-1 */
    cli_sk = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, 
        NULL, NULL, 0, NULL);

    if (cli_sk == NULL) {
        perror("usrsctp_socket (client)");
        exit(1);
    }

    /* bind the socket to a local addr */ 
    cli_addr.sin_family = AF_INET;
    cli_addr.sin_port = htons(CLIENT_PORT);
    cli_addr.sin_addr.s_addr = inet_addr(CLIENT_ADDR);
    rv = usrsctp_bind(cli_sk, (struct sockaddr *)&cli_addr, sizeof(struct sockaddr_in));
    check(rv, "usrsctp_bind (client)");

    /* connect to server */ 
    rv = usrsctp_connect(cli_sk, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr_in));
    check(rv, "sctp_connect");

    for(;;);
}

static void debug_printf(const char *format, ...)
{
        va_list ap;

        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
}

int main(void) 
{
    usrsctp_init(0, NULL, debug_printf);
    usrsctp_sysctl_set_sctp_no_csum_on_loopback(0);
#ifdef SCTP_DEBUG
        usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL);
#endif
    server();

    pthread_create(&client_thread, NULL, client, NULL);

    for(;;);

    return 0;
}

tcp.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <usrsctp.h>
#include <stdarg.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

#define SERVER_PORT   8888
#define CLIENT_PORT   5000
#define SERVER_ADDR   "127.0.0.1"
#define CLIENT_ADDR   "127.0.0.2"


int srv_sk, cli_sk;
struct sockaddr_in srv_addr, cli_addr;

pthread_t client_thread;

void inline check(int val, char* str)
{
    if (val<0) {
        perror(str);
        exit(1);
    }
}

void server()
{
    int rv;

    /* create a TCP socket */
    srv_sk = socket(AF_INET, SOCK_STREAM, 0); 
    if (srv_sk == 0) {  
        perror("socket");
        exit(1);
    }

    /* bind the socket to a local addr */ 
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    srv_addr.sin_port = htons(SERVER_PORT);

    rv = bind(srv_sk, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr_in));
    check(rv, "bind (server)");

    /* listen for connections */
    rv = listen(srv_sk, 3);
    check(rv, "listen");

}


void* client(void* p)
{
    int rv;

    /* create a TCP socket */
    cli_sk = socket(AF_INET, SOCK_STREAM, 0);

    if (cli_sk == 0) {
        perror("socket (client)");
        exit(1);
    }

    /* bind the socket to a local addr */ 
    cli_addr.sin_family = AF_INET;
    cli_addr.sin_port = htons(CLIENT_PORT);
    cli_addr.sin_addr.s_addr = inet_addr(CLIENT_ADDR);
    rv = bind(cli_sk, (struct sockaddr*)&cli_addr, sizeof(struct sockaddr_in));
    check(rv, "bind (client)");

    /* connect to server */ 
    rv = connect(cli_sk, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr_in));
    check(rv, "connect");

    for(;;);
}

void main() 
{
    usrsctp_init(0, NULL, NULL);
    usrsctp_sysctl_set_sctp_no_csum_on_loopback(0);

    server();

    pthread_create(&client_thread, NULL, client, NULL);

    for(;;);
}

Examples don't work under Windows

Hi,

I tried to build and execute usrsctp library examples under Windows but they don't work. The examples was built by MSVC with Windows 10.
I found that problem was caused by commits "Use SOCKET for sockets on Windows" and "More SOCKET stuff". When these commits are disabled everything works OK.

Best regards, Radek

flags zero in call-back

Hi,

I have this simple setup with a server and client in two different Linux VMs.
The problem is that when the receiving call-back function "rcb" is called, "flags" is zero although I know that this is an SCTP_ASSOC_CHANGE notification.

If it's useful, I can provide the VM and the script to run them. It's only about 30MB.

Thanks in advance.

server.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <usrsctp.h>
#include <stdarg.h>
#include <strings.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFER_SIZE 20000

#define SERVER_PORT 5000
#define SERVER_ADDR  "10.0.0.1"

void inline CHECK(int val, char* str)
{
    if (val!=0) {
        perror(str);
        exit(1);
    }
}


static int
rcb(struct socket *sock, union sctp_sockstore addr, void *data,
           size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
    printf("CALL BACK: %d\n", flags);

    if (flags & MSG_NOTIFICATION)
        printf("notification\n");

    free(data);
    return (1);
}

void main() 
{
    int rv;
    struct socket* sk;
    struct sockaddr_in addr;
    struct sctp_event ev;

    int msg_flags;

    usrsctp_init(0, NULL, NULL);

    /* create a socket 1-to-many */
    sk = usrsctp_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 
        rcb, NULL, 0, NULL);    
    CHECK(sk==NULL, "usrsctp_socket");

    /* enables assoc change */
    ev.se_assoc_id = SCTP_ALL_ASSOC;
    ev.se_type = SCTP_ASSOC_CHANGE;
    ev.se_on = 1;
    rv = usrsctp_setsockopt(sk, IPPROTO_SCTP, SCTP_EVENT, &ev, sizeof(ev));
    CHECK(rv<0, "setsockopt(SCTP_EVENT)");

    /* bind the socket to a local addr */ 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);
    addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);

    rv = usrsctp_bind(sk, (struct sockaddr *)&addr, sizeof(addr));
    CHECK(rv<0, "usrsctp_bind"); 

    rv = usrsctp_listen(sk, 3);
    CHECK(rv<0, "usrsctp_listen");

    printf("START RECV\n");

    for(;;);
}

client.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <usrsctp.h>
#include <stdarg.h>
#include <pthread.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define SERVER_PORT   5000
#define SERVER_ADDR   "10.0.0.1"

#define CLIENT_PORT   5001
#define CLIENT_ADDR  "10.0.1.1"

void inline CHECK(int val, char* str)
{
    if (val!=0) {
        perror(str);
        exit(1);
    }
}


void main() 
{
    int rv; 

    struct sockaddr_in srv;
    struct sockaddr_in addr;
    struct socket* sk;

    usrsctp_init(0, NULL, NULL);

    /* create a socket 1-to-1 */
    sk = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, 
        NULL, NULL, 0, NULL);   
    CHECK(sk==NULL, "usrsctp_socket");

    /* bind the socket to a local addr */ 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(CLIENT_PORT);
    addr.sin_addr.s_addr = inet_addr(CLIENT_ADDR);

    rv = usrsctp_bind(sk, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
    CHECK(rv<0, "usrsctp_bind");

    /* connect to server */ 
    srv.sin_family = AF_INET;
    srv.sin_port = htons(SERVER_PORT);
    srv.sin_addr.s_addr = inet_addr(SERVER_ADDR);

    rv = sctp_connect(sk, &srv);
    CHECK(rv<0, "sctp_connect");

    for(;;);
}

stream reset and data sending

Suppose we have an SCTP ongoing between 2 peers: A and B.
A opens a stream S
B gets informed about the new stream and S is created on its side

Suppose A wants to send a large buffer. For this explanation, we consider this a large buffer:
abcdefghijklmnopqrtsovw

A will call usrsctp_sendv(...) with all necessary parameters, and the library takes that buffer and enqueues it for sending. The actual sending may or may not occur right away. Suppose is not happening right away, and the large buffer (or parts of it), gets enqueued inside the library.

At this point, if A resets the stream by doing usrsctp_setsockopt(..., SCTP_RESET_STREAMS, ...), the internal queue is not discarded. That would not be a problem if the control messages are sent AFTER the data itself, but the control messages are taking priority and they will be sent first.

Now, B will get the stream reset event immediately followed by data. The correct behavior should be one of this:

  1. get the stream reset event and the in-transit data will be lost and never received. This requires A to completely erase the associated buffers BEFORE sending the reset event
  2. get the data as it was queued up and than get the reset event

Crash in sctp_add_to_readq()

Hello

We use jitsi-videobridge which uses usrsctp internally to implement its data channels. Under load in a production environment, we have observed frequent crashes in "sctp_add_to_readq()".

We have modified the videobridge to receive a small message over the data channel for each connected client in a conference, which is then fanned out to other clients. The message is sent at 10Hz per client. Typically conferences are small (<10 users). Usually only 1-2 clients per conference are sending the message simultaneously, often none are.

We've been unable to reproduce the crash in our testing environment. We are able to reproduce a frequent "resource temporarily unavailable" message in our testing, which appears to originate in usrsctp itself when it detects that it can't add more data because the recipient's queue is already full (via a EWOULDBLOCK return code in sctp_output.c), but we don't know if that is related to the crash.

We have removed this excess use of the data channel, but will still observed at least one crash since deploying that code. The usrsctp library that the videobridge uses is old and we are thinking of updating it to try to fix the issue. Have there been any known fixes in this area, over the past year?

Here is the specific version we are using:
https://github.com/sctplab/usrsctp/blob/c53d43ee76673ee281806497eb43750c239c145f/usrsctplib/netinet/sctputil.c

Thanks

Can I block a connection or an association when using callback?

I want to prevent the peer from writing more data to this socket. According to RFC4960 I need to tell the peer that my rwnd is 0.
I can stop calling recv() when in non-callback mode. But when using a callback, I can't stop the calling of the callback. Are there any APIs can help?

CMake builds empty .lib and .dll?

Hello,
After build with cmake .dll file is empty. My CMake outputs:

D:\Desktop\usrsctp>cmake D:\Downloads\usrsctp-0.9.3.0\usrsctplib
-- Building for: Visual Studio 12 2013
-- The C compiler identification is MSVC 18.0.40629.0
-- The CXX compiler identification is MSVC 18.0.40629.0
-- Check for working C compiler using: Visual Studio 12 2013
-- Check for working C compiler using: Visual Studio 12 2013 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Visual Studio 12 2013
-- Check for working CXX compiler using: Visual Studio 12 2013 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Check size of ssize_t
-- Check size of ssize_t - failed
-- Looking for sys/socket.h
-- Looking for sys/socket.h - not found
-- Looking for sys/queue.h
-- Looking for sys/queue.h - not found
-- Looking for linux/if_addr.h
-- Looking for linux/if_addr.h - not found
-- Looking for linux/rtnetlink.h
-- Looking for linux/rtnetlink.h - not found
-- Looking for netinet/ip_icmp.h
-- Looking for netinet/ip_icmp.h - not found
-- Looking for socket
-- Looking for socket - not found
-- Looking for inet_addr
-- Looking for inet_addr - not found
-- Performing Test HAVE_SA_LEN
-- Performing Test HAVE_SA_LEN - Failed
-- Performing Test HAVE_SIN_LEN
-- Performing Test HAVE_SIN_LEN - Failed
-- Performing Test HAVE_SIN6_LEN
-- Performing Test HAVE_SIN6_LEN - Failed
-- link library: ws2_32
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Desktop/usrsctp

Build output:

D:\Desktop\usrsctp>cmake --build .
Microsoft (R) Build Engine version 12.0.40629.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 2016-04-21 19:02:34.
Project "D:\Desktop\usrsctp\ALL_BUILD.vcxproj" on node 1 (default targets).
Project "D:\Desktop\usrsctp\ALL_BUILD.vcxproj" (1) is building "D:\Desktop\usrsctp\ZERO_CHECK.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
......
FinalizeBuildStatus:
Deleting file "usrsctp-static.dir\Debug\usrsctp-static.tlog\unsuccessfulbuild".
Touching "usrsctp-static.dir\Debug\usrsctp-static.tlog\usrsctp-static.lastbuildstate".
Done Building Project "D:\Desktop\usrsctp\usrsctp-static.vcxproj" (default targets).
PrepareForBuild:
Creating directory "Win32\Debug\ALL_BUILD".
Creating directory "Win32\Debug\ALL_BUILD\ALL_BUILD.tlog".
InitializeBuildStatus:
Creating "Win32\Debug\ALL_BUILD\ALL_BUILD.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
Building Custom Rule D:/Downloads/usrsctp-0.9.3.0/usrsctplib/CMakeLists.txt
CMake does not need to re-run because D:\Desktop\usrsctp\CMakeFiles\generate.stamp is up-to-date.
FinalizeBuildStatus:
Deleting file "Win32\Debug\ALL_BUILD\ALL_BUILD.tlog\unsuccessfulbuild".
Touching "Win32\Debug\ALL_BUILD\ALL_BUILD.tlog\ALL_BUILD.lastbuildstate".
Done Building Project "D:\Desktop\usrsctp\ALL_BUILD.vcxproj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:29.41

With DLL Export Viewer I see this is empty
When I try to load .lib file I get:

Error 17 error LNK2001: unresolved external symbol

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.