@@ -119,6 +119,13 @@ void janus_sctp_handle_remote_error_event(struct sctp_remote_error *sre);
119119void janus_sctp_handle_send_failed_event (struct sctp_send_failed_event * ssfe );
120120void janus_sctp_handle_notification (janus_sctp_association * sctp , union sctp_notification * notif , size_t n );
121121
122+ /* We need to keep a map of associations with random IDs, as usrsctp will
123+ * use the pointer to our structures in the actual messages instead */
124+ static janus_mutex sctp_mutex ;
125+ static GHashTable * sctp_ids = NULL ;
126+ static void janus_sctp_association_unref (janus_sctp_association * sctp );
127+
128+ /* SCTP management code */
122129static gboolean sctp_running ;
123130int janus_sctp_init (void ) {
124131 /* Initialize the SCTP stack */
@@ -131,12 +138,25 @@ int janus_sctp_init(void) {
131138 JANUS_LOG (LOG_ERR , "Error creating folder %s, expect problems...\n" , debug_folder );
132139 }
133140#endif
141+
142+ /* Create a map of local IDs too, to map them to our SCTP associations */
143+ janus_mutex_init (& sctp_mutex );
144+ sctp_ids = g_hash_table_new_full (NULL , NULL , NULL , (GDestroyNotify )janus_sctp_association_unref );
145+
134146 return 0 ;
135147}
136148
137149void janus_sctp_deinit (void ) {
138150 usrsctp_finish ();
139151 sctp_running = FALSE;
152+ janus_mutex_lock (& sctp_mutex );
153+ g_hash_table_unref (sctp_ids );
154+ janus_mutex_unlock (& sctp_mutex );
155+ }
156+
157+ static void janus_sctp_association_unref (janus_sctp_association * sctp ) {
158+ if (sctp )
159+ janus_refcount_decrease (& sctp -> ref );
140160}
141161
142162static void janus_sctp_association_free (const janus_refcount * sctp_ref ) {
@@ -205,9 +225,25 @@ janus_sctp_association *janus_sctp_association_create(janus_dtls_srtp *dtls, jan
205225 }
206226 sctp -> stream_buffer_counter = 0 ;
207227
208- usrsctp_register_address ((void * )sctp );
228+ /* Create a unique ID to map locally: this is what we'll pass to
229+ * usrsctp_socket, which means that's what we'll get in callbacks
230+ * too: we can then use the map to retrieve the actual struct */
231+ janus_mutex_lock (& sctp_mutex );
232+ while (sctp -> map_id == 0 ) {
233+ sctp -> map_id = janus_random_uint32 ();
234+ if (g_hash_table_lookup (sctp_ids , GUINT_TO_POINTER (sctp -> map_id )) != NULL ) {
235+ /* ID already taken, try another one */
236+ sctp -> map_id = 0 ;
237+ }
238+ }
239+ janus_refcount_increase (& sctp -> ref );
240+ g_hash_table_insert (sctp_ids , GUINT_TO_POINTER (sctp -> map_id ), sctp );
241+ janus_mutex_unlock (& sctp_mutex );
242+
243+ usrsctp_register_address (GUINT_TO_POINTER (sctp -> map_id ));
209244 usrsctp_sysctl_set_sctp_ecn_enable (0 );
210- if ((sock = usrsctp_socket (AF_CONN , SOCK_STREAM , IPPROTO_SCTP , janus_sctp_incoming_data , NULL , 0 , (void * )sctp )) == NULL ) {
245+ if ((sock = usrsctp_socket (AF_CONN , SOCK_STREAM , IPPROTO_SCTP , janus_sctp_incoming_data , NULL , 0 ,
246+ GUINT_TO_POINTER (sctp -> map_id ))) == NULL ) {
211247 JANUS_LOG (LOG_ERR , "[%" SCNu64 "] Error creating usrsctp socket... (%d)\n" , sctp -> handle_id , errno );
212248 janus_sctp_association_destroy (sctp );
213249 return NULL ;
@@ -274,7 +310,7 @@ janus_sctp_association *janus_sctp_association_create(janus_dtls_srtp *dtls, jan
274310 memset (& sconn , 0 , sizeof (struct sockaddr_conn ));
275311 sconn .sconn_family = AF_CONN ;
276312 sconn .sconn_port = htons (sctp -> local_port );
277- sconn .sconn_addr = ( void * ) sctp ;
313+ sconn .sconn_addr = GUINT_TO_POINTER ( sctp -> map_id ) ;
278314 if (usrsctp_bind (sock , (struct sockaddr * )& sconn , sizeof (struct sockaddr_conn )) < 0 ) {
279315 JANUS_LOG (LOG_ERR , "[%" SCNu64 "] Error binding client on port %" SCNu16 " (%d)\n" , sctp -> handle_id , sctp -> local_port , errno );
280316 janus_sctp_association_destroy (sctp );
@@ -293,7 +329,7 @@ janus_sctp_association *janus_sctp_association_create(janus_dtls_srtp *dtls, jan
293329 memset (& rconn , 0 , sizeof (struct sockaddr_conn ));
294330 rconn .sconn_family = AF_CONN ;
295331 rconn .sconn_port = htons (sctp -> remote_port );
296- rconn .sconn_addr = ( void * ) sctp ;
332+ rconn .sconn_addr = GUINT_TO_POINTER ( sctp -> map_id ) ;
297333#ifdef HAVE_SCONN_LEN
298334 rconn .sconn_len = sizeof (struct sockaddr_conn );
299335#endif
@@ -311,8 +347,13 @@ void janus_sctp_association_destroy(janus_sctp_association *sctp) {
311347 if (sctp == NULL || !g_atomic_int_compare_and_exchange (& sctp -> destroyed , 0 , 1 ))
312348 return ;
313349
314- usrsctp_deregister_address (sctp );
315- if (sctp -> sock != NULL ) {
350+ if (sctp -> map_id != 0 ) {
351+ usrsctp_deregister_address (GUINT_TO_POINTER (sctp -> map_id ));
352+ janus_mutex_lock (& sctp_mutex );
353+ g_hash_table_remove (sctp_ids , GUINT_TO_POINTER (sctp -> map_id ));
354+ janus_mutex_unlock (& sctp_mutex );
355+ }
356+ if (sctp -> sock != NULL ) {
316357 usrsctp_shutdown (sctp -> sock , SHUT_RDWR );
317358 usrsctp_close (sctp -> sock );
318359 }
@@ -334,11 +375,13 @@ void janus_sctp_data_from_dtls(janus_sctp_association *sctp, char *buf, int len)
334375 }
335376 }
336377#endif
337- usrsctp_conninput (( void * ) sctp , buf , len , 0 );
378+ usrsctp_conninput (GUINT_TO_POINTER ( sctp -> map_id ) , buf , len , 0 );
338379}
339380
340381int janus_sctp_data_to_dtls (void * instance , void * buffer , size_t length , uint8_t tos , uint8_t set_df ) {
341- janus_sctp_association * sctp = (janus_sctp_association * )instance ;
382+ janus_mutex_lock (& sctp_mutex );
383+ janus_sctp_association * sctp = (janus_sctp_association * )g_hash_table_lookup (sctp_ids , instance );
384+ janus_mutex_unlock (& sctp_mutex );
342385 if (sctp == NULL || sctp -> handle == NULL )
343386 return -1 ;
344387 JANUS_LOG (LOG_HUGE , "[%" SCNu64 "] Data from SCTP to DTLS stack: %zu bytes\n" , sctp -> handle_id , length );
@@ -358,7 +401,9 @@ int janus_sctp_data_to_dtls(void *instance, void *buffer, size_t length, uint8_t
358401}
359402
360403static int janus_sctp_incoming_data (struct socket * sock , union sctp_sockstore addr , void * data , size_t datalen , struct sctp_rcvinfo rcv , int flags , void * ulp_info ) {
361- janus_sctp_association * sctp = (janus_sctp_association * )ulp_info ;
404+ janus_mutex_lock (& sctp_mutex );
405+ janus_sctp_association * sctp = (janus_sctp_association * )g_hash_table_lookup (sctp_ids , ulp_info );
406+ janus_mutex_unlock (& sctp_mutex );
362407 if (sctp == NULL || sctp -> dtls == NULL ) {
363408 free (data );
364409 return 0 ;
0 commit comments