Skip to content

Commit

Permalink
Merge pull request #248 from xicilion/master
Browse files Browse the repository at this point in the history
Add callback to get unhandled STUN binding requests from mux
  • Loading branch information
paullouisageneau authored Jan 9, 2025
2 parents 60bcb33 + a9f5fbc commit 2d920a0
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 9 deletions.
11 changes: 11 additions & 0 deletions include/juice/juice.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ typedef void (*juice_cb_gathering_done_t)(juice_agent_t *agent, void *user_ptr);
typedef void (*juice_cb_recv_t)(juice_agent_t *agent, const char *data, size_t size,
void *user_ptr);

typedef struct juice_mux_binding_request {
const char *local_ufrag;
const char *remote_ufrag;

const char *address;
uint16_t port;
} juice_mux_binding_request_t;

typedef void (*juice_cb_mux_incoming_t)(const juice_mux_binding_request_t *info, void *user_ptr);

typedef struct juice_turn_server {
const char *host;
const char *username;
Expand Down Expand Up @@ -121,6 +131,7 @@ JUICE_EXPORT int juice_get_selected_addresses(juice_agent_t *agent, char *local,
char *remote, size_t remote_size);
JUICE_EXPORT int juice_set_local_ice_attributes(juice_agent_t *agent, const char *ufrag, const char *pwd);
JUICE_EXPORT const char *juice_state_to_string(juice_state_t state);
JUICE_EXPORT int juice_mux_listen(const char *bind_address, int local_port, juice_cb_mux_incoming_t cb, void *user_ptr);

// ICE server

Expand Down
61 changes: 60 additions & 1 deletion src/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static void release_registry(conn_mode_entry_t *entry) {

// registry must be locked

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

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

return get_mode_entry(agent)->get_addrs_func(agent, records, size);
}

static int juice_mux_stop_listen(const char *bind_address, int local_port) {
(void)bind_address;
(void)local_port;

conn_mode_entry_t *entry = &mode_entries[JUICE_CONCURRENCY_MODE_MUX];

mutex_lock(&entry->mutex);

conn_registry_t *registry = entry->registry;
if (!registry) {
mutex_unlock(&entry->mutex);
return -1;
}

mutex_lock(&registry->mutex);

registry->cb_mux_incoming = NULL;
registry->mux_incoming_user_ptr = NULL;
conn_mux_interrupt_registry(registry);

release_registry(entry);

mutex_unlock(&entry->mutex);

return 0;
}

int juice_mux_listen(const char *bind_address, int local_port, juice_cb_mux_incoming_t cb, void *user_ptr)
{
if (!cb)
return juice_mux_stop_listen(bind_address, local_port);

conn_mode_entry_t *entry = &mode_entries[JUICE_CONCURRENCY_MODE_MUX];

udp_socket_config_t config;
config.bind_address = bind_address;
config.port_begin = config.port_end = local_port;

mutex_lock(&entry->mutex);

if (entry->registry) {
mutex_unlock(&entry->mutex);
JLOG_DEBUG("juice_mux_listen needs to be called before establishing any mux connection.");
return -1;
}

conn_registry_t *registry = acquire_registry(entry, &config);
mutex_unlock(&entry->mutex);

if (!registry)
return -2;

registry->cb_mux_incoming = cb;
registry->mux_incoming_user_ptr = user_ptr;
mutex_unlock(&registry->mutex);

return 0;
}
2 changes: 2 additions & 0 deletions src/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ typedef struct conn_registry {
juice_agent_t **agents;
int agents_size;
int agents_count;
juice_cb_mux_incoming_t cb_mux_incoming;
void *mux_incoming_user_ptr;
} conn_registry_t;

int conn_create(juice_agent_t *agent, udp_socket_config_t *config);
Expand Down
41 changes: 33 additions & 8 deletions src/conn_mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ int conn_mux_prepare(conn_registry_t *registry, struct pollfd *pfd, timestamp_t
}

int count = registry->agents_count;
if (registry->cb_mux_incoming)
++count;
mutex_unlock(&registry->mutex);
return count;
}
Expand Down Expand Up @@ -295,6 +297,25 @@ static juice_agent_t *lookup_agent(conn_registry_t *registry, char *buf, size_t
}
}

if (registry->cb_mux_incoming) {
JLOG_DEBUG("Found STUN request with unknown ICE ufrag");
char host[ADDR_MAX_NUMERICHOST_LEN];
if (getnameinfo((const struct sockaddr *)&src->addr, src->len, host, ADDR_MAX_NUMERICHOST_LEN, NULL, 0, NI_NUMERICHOST)) {
JLOG_ERROR("getnameinfo failed, errno=%d", sockerrno);
return NULL;
}

juice_mux_binding_request_t incoming_info;

incoming_info.local_ufrag = local_ufrag;
incoming_info.remote_ufrag = separator + 1;
incoming_info.address = host;
incoming_info.port = addr_get_port((struct sockaddr *)src);

registry->cb_mux_incoming(&incoming_info, registry->mux_incoming_user_ptr);

return NULL;
}
} else {
if (!STUN_IS_RESPONSE(msg.msg_class)) {
JLOG_INFO("Got unexpected STUN message from unknown source address");
Expand Down Expand Up @@ -479,14 +500,7 @@ void conn_mux_unlock(juice_agent_t *agent) {
mutex_unlock(&registry->mutex);
}

int conn_mux_interrupt(juice_agent_t *agent) {
conn_impl_t *conn_impl = agent->conn_impl;
conn_registry_t *registry = conn_impl->registry;

mutex_lock(&registry->mutex);
conn_impl->next_timestamp = current_timestamp();
mutex_unlock(&registry->mutex);

int conn_mux_interrupt_registry(conn_registry_t *registry) {
JLOG_VERBOSE("Interrupting connections thread");

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

int conn_mux_interrupt(juice_agent_t *agent) {
conn_impl_t *conn_impl = agent->conn_impl;
conn_registry_t *registry = conn_impl->registry;

mutex_lock(&registry->mutex);
conn_impl->next_timestamp = current_timestamp();
mutex_unlock(&registry->mutex);

return conn_mux_interrupt_registry(registry);
}

int conn_mux_send(juice_agent_t *agent, const addr_record_t *dst, const char *data, size_t size,
int ds) {
conn_impl_t *conn_impl = agent->conn_impl;
Expand Down
1 change: 1 addition & 0 deletions src/conn_mux.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int conn_mux_init(juice_agent_t *agent, conn_registry_t *registry, udp_socket_co
void conn_mux_cleanup(juice_agent_t *agent);
void conn_mux_lock(juice_agent_t *agent);
void conn_mux_unlock(juice_agent_t *agent);
int conn_mux_interrupt_registry(conn_registry_t *registry);
int conn_mux_interrupt(juice_agent_t *agent);
int conn_mux_send(juice_agent_t *agent, const addr_record_t *dst, const char *data, size_t size,
int ds);
Expand Down

0 comments on commit 2d920a0

Please sign in to comment.