-
-
Notifications
You must be signed in to change notification settings - Fork 82
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
support juice_bind_stun to reflect stun requests from unbound client. #248
base: master
Are you sure you want to change the base?
Changes from 10 commits
94272e4
59957aa
06a925b
63651ed
50fa27a
5b818b1
f17129c
20755dc
9ede09b
2c155ae
4a0a896
1fb20f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,7 +108,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(®istry->mutex); | ||
|
||
|
@@ -247,3 +247,59 @@ 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); | ||
} | ||
|
||
int juice_mux_stop_listen(const char *bind_address, int local_port) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
(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(®istry->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) | ||
{ | ||
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; | ||
xicilion marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
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(®istry->mutex); | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
Comment on lines
+33
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since they are specific to the mux implementation, they should be moved to |
||
} conn_registry_t; | ||
|
||
int conn_create(juice_agent_t *agent, udp_socket_config_t *config); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(®istry->mutex); | ||
return count; | ||
} | ||
|
@@ -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"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found an issue here. When connecting to the server using a browser and the server closes the peer connection, the browser will continue to send STUN messages, and the incoming event will be triggered again. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the RFC document:
An agent must not include the USE-CANDIDATE attribute when sending a binding request. I tested this in practice, the binding request message received has use_candidate=0. After the connection is closed, the browser continues to send stun messages with use_candidate=1. I will proceed to test further based on this strategy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
===========================================================================
After successfully intercepting dozens of messages, the browser still stubbornly sent a binding request message with USE-CANDIDATE set to 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I examined numerous attributes in the STUN message, but did not identify any additional characteristics that could be utilized to detect the binding request after the connection is terminated. @paullouisageneau need your help, do you have any suggestions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think you misunderstood what USE-CANDIDATE means. The RFC says "The controlled agent MUST NOT include the USE-CANDIDATE attribute in a Binding request". Only the controlling agent includes it to nominate a candidate pair (i.e. to tell the controlled agent which pair to use), otherwise it's not present.
To my knowledge there is no way to know the connection state from STUN attributes, since the ICE layer is unaware of upper layers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I have already canceled this commit. I cached the information of the just closed RTCPeerConnection at the business layer for a while, and blocked the same request from being accepted. |
||
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_incoming_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"); | ||
|
@@ -479,14 +500,7 @@ void conn_mux_unlock(juice_agent_t *agent) { | |
mutex_unlock(®istry->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(®istry->mutex); | ||
conn_impl->next_timestamp = current_timestamp(); | ||
mutex_unlock(®istry->mutex); | ||
|
||
int conn_mux_interrupt_registry(conn_registry_t *registry) { | ||
JLOG_VERBOSE("Interrupting connections thread"); | ||
|
||
registry_impl_t *registry_impl = registry->impl; | ||
|
@@ -502,6 +516,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(®istry->mutex); | ||
conn_impl->next_timestamp = current_timestamp(); | ||
mutex_unlock(®istry->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; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this does not actually represent incoming connections in the end (for instance in the case of closed connections), I think it should be renamed for clarity. For instance
juice_mux_binding_request
.