Skip to content

Commit 2d920a0

Browse files
Merge pull request #248 from xicilion/master
Add callback to get unhandled STUN binding requests from mux
2 parents 60bcb33 + a9f5fbc commit 2d920a0

File tree

5 files changed

+107
-9
lines changed

5 files changed

+107
-9
lines changed

include/juice/juice.h

+11
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ typedef void (*juice_cb_gathering_done_t)(juice_agent_t *agent, void *user_ptr);
6767
typedef void (*juice_cb_recv_t)(juice_agent_t *agent, const char *data, size_t size,
6868
void *user_ptr);
6969

70+
typedef struct juice_mux_binding_request {
71+
const char *local_ufrag;
72+
const char *remote_ufrag;
73+
74+
const char *address;
75+
uint16_t port;
76+
} juice_mux_binding_request_t;
77+
78+
typedef void (*juice_cb_mux_incoming_t)(const juice_mux_binding_request_t *info, void *user_ptr);
79+
7080
typedef struct juice_turn_server {
7181
const char *host;
7282
const char *username;
@@ -121,6 +131,7 @@ JUICE_EXPORT int juice_get_selected_addresses(juice_agent_t *agent, char *local,
121131
char *remote, size_t remote_size);
122132
JUICE_EXPORT int juice_set_local_ice_attributes(juice_agent_t *agent, const char *ufrag, const char *pwd);
123133
JUICE_EXPORT const char *juice_state_to_string(juice_state_t state);
134+
JUICE_EXPORT int juice_mux_listen(const char *bind_address, int local_port, juice_cb_mux_incoming_t cb, void *user_ptr);
124135

125136
// ICE server
126137

src/conn.c

+60-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static void release_registry(conn_mode_entry_t *entry) {
109109

110110
// registry must be locked
111111

112-
if (registry->agents_count == 0) {
112+
if (registry->agents_count == 0 && registry->cb_mux_incoming == NULL) {
113113
JLOG_DEBUG("No connection left, destroying connections registry");
114114
mutex_unlock(&registry->mutex);
115115

@@ -254,3 +254,62 @@ int conn_get_addrs(juice_agent_t *agent, addr_record_t *records, size_t size) {
254254

255255
return get_mode_entry(agent)->get_addrs_func(agent, records, size);
256256
}
257+
258+
static int juice_mux_stop_listen(const char *bind_address, int local_port) {
259+
(void)bind_address;
260+
(void)local_port;
261+
262+
conn_mode_entry_t *entry = &mode_entries[JUICE_CONCURRENCY_MODE_MUX];
263+
264+
mutex_lock(&entry->mutex);
265+
266+
conn_registry_t *registry = entry->registry;
267+
if (!registry) {
268+
mutex_unlock(&entry->mutex);
269+
return -1;
270+
}
271+
272+
mutex_lock(&registry->mutex);
273+
274+
registry->cb_mux_incoming = NULL;
275+
registry->mux_incoming_user_ptr = NULL;
276+
conn_mux_interrupt_registry(registry);
277+
278+
release_registry(entry);
279+
280+
mutex_unlock(&entry->mutex);
281+
282+
return 0;
283+
}
284+
285+
int juice_mux_listen(const char *bind_address, int local_port, juice_cb_mux_incoming_t cb, void *user_ptr)
286+
{
287+
if (!cb)
288+
return juice_mux_stop_listen(bind_address, local_port);
289+
290+
conn_mode_entry_t *entry = &mode_entries[JUICE_CONCURRENCY_MODE_MUX];
291+
292+
udp_socket_config_t config;
293+
config.bind_address = bind_address;
294+
config.port_begin = config.port_end = local_port;
295+
296+
mutex_lock(&entry->mutex);
297+
298+
if (entry->registry) {
299+
mutex_unlock(&entry->mutex);
300+
JLOG_DEBUG("juice_mux_listen needs to be called before establishing any mux connection.");
301+
return -1;
302+
}
303+
304+
conn_registry_t *registry = acquire_registry(entry, &config);
305+
mutex_unlock(&entry->mutex);
306+
307+
if (!registry)
308+
return -2;
309+
310+
registry->cb_mux_incoming = cb;
311+
registry->mux_incoming_user_ptr = user_ptr;
312+
mutex_unlock(&registry->mutex);
313+
314+
return 0;
315+
}

src/conn.h

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ typedef struct conn_registry {
3030
juice_agent_t **agents;
3131
int agents_size;
3232
int agents_count;
33+
juice_cb_mux_incoming_t cb_mux_incoming;
34+
void *mux_incoming_user_ptr;
3335
} conn_registry_t;
3436

3537
int conn_create(juice_agent_t *agent, udp_socket_config_t *config);

src/conn_mux.c

+33-8
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ int conn_mux_prepare(conn_registry_t *registry, struct pollfd *pfd, timestamp_t
243243
}
244244

245245
int count = registry->agents_count;
246+
if (registry->cb_mux_incoming)
247+
++count;
246248
mutex_unlock(&registry->mutex);
247249
return count;
248250
}
@@ -295,6 +297,25 @@ static juice_agent_t *lookup_agent(conn_registry_t *registry, char *buf, size_t
295297
}
296298
}
297299

300+
if (registry->cb_mux_incoming) {
301+
JLOG_DEBUG("Found STUN request with unknown ICE ufrag");
302+
char host[ADDR_MAX_NUMERICHOST_LEN];
303+
if (getnameinfo((const struct sockaddr *)&src->addr, src->len, host, ADDR_MAX_NUMERICHOST_LEN, NULL, 0, NI_NUMERICHOST)) {
304+
JLOG_ERROR("getnameinfo failed, errno=%d", sockerrno);
305+
return NULL;
306+
}
307+
308+
juice_mux_binding_request_t incoming_info;
309+
310+
incoming_info.local_ufrag = local_ufrag;
311+
incoming_info.remote_ufrag = separator + 1;
312+
incoming_info.address = host;
313+
incoming_info.port = addr_get_port((struct sockaddr *)src);
314+
315+
registry->cb_mux_incoming(&incoming_info, registry->mux_incoming_user_ptr);
316+
317+
return NULL;
318+
}
298319
} else {
299320
if (!STUN_IS_RESPONSE(msg.msg_class)) {
300321
JLOG_INFO("Got unexpected STUN message from unknown source address");
@@ -479,14 +500,7 @@ void conn_mux_unlock(juice_agent_t *agent) {
479500
mutex_unlock(&registry->mutex);
480501
}
481502

482-
int conn_mux_interrupt(juice_agent_t *agent) {
483-
conn_impl_t *conn_impl = agent->conn_impl;
484-
conn_registry_t *registry = conn_impl->registry;
485-
486-
mutex_lock(&registry->mutex);
487-
conn_impl->next_timestamp = current_timestamp();
488-
mutex_unlock(&registry->mutex);
489-
503+
int conn_mux_interrupt_registry(conn_registry_t *registry) {
490504
JLOG_VERBOSE("Interrupting connections thread");
491505

492506
registry_impl_t *registry_impl = registry->impl;
@@ -503,6 +517,17 @@ int conn_mux_interrupt(juice_agent_t *agent) {
503517
return 0;
504518
}
505519

520+
int conn_mux_interrupt(juice_agent_t *agent) {
521+
conn_impl_t *conn_impl = agent->conn_impl;
522+
conn_registry_t *registry = conn_impl->registry;
523+
524+
mutex_lock(&registry->mutex);
525+
conn_impl->next_timestamp = current_timestamp();
526+
mutex_unlock(&registry->mutex);
527+
528+
return conn_mux_interrupt_registry(registry);
529+
}
530+
506531
int conn_mux_send(juice_agent_t *agent, const addr_record_t *dst, const char *data, size_t size,
507532
int ds) {
508533
conn_impl_t *conn_impl = agent->conn_impl;

src/conn_mux.h

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ int conn_mux_init(juice_agent_t *agent, conn_registry_t *registry, udp_socket_co
2424
void conn_mux_cleanup(juice_agent_t *agent);
2525
void conn_mux_lock(juice_agent_t *agent);
2626
void conn_mux_unlock(juice_agent_t *agent);
27+
int conn_mux_interrupt_registry(conn_registry_t *registry);
2728
int conn_mux_interrupt(juice_agent_t *agent);
2829
int conn_mux_send(juice_agent_t *agent, const addr_record_t *dst, const char *data, size_t size,
2930
int ds);

0 commit comments

Comments
 (0)