-
-
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?
Conversation
change argument at callback function. |
src/conn.c
Outdated
@@ -247,3 +247,30 @@ 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_bind_stun(const char *bind_address, int local_port, juice_cb_stun_binding_t cb) |
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.
Is it possible to unbind from the address to allow closing all open sockets?
Would you just call this again with NULL
as the cb
argument?
This should be okay, but I need to do some testing to make sure the socket will be closed automatically. I'll add it. |
It turned out to be a little more complicated than I expected, but I did it. |
Awesome! Is the new I'm thinking of the case where a user specifies multiple listeners running on different ports - they should be stoppable independently of each other. |
I discussed this with @paullouisageneau . Currently, Juice actually only supports one port for mux. After the first mux connects to the specified port, all other mux connections will use this port. So Juice will only have one mux socket at a time. |
This will prevent people doing things like opening multiple WebRTC-Direct listeners or running more than one js-libp2p node in the same process since they'll try to use the same UDP port for incoming connections. These aren't very common deployment patterns, though it's not unheard of, and it's done quite often while running unit/integration/interop tests. It would be good to fix this, though probably not in this PR. |
Calls the functions added to libjuice in paullouisageneau/libjuice#248 Exports a `OnUnhandledStunRequest` function that can be passed a callback that will be invoked when an incoming STUN message is received that has no corresponding agent for the ICE ufrag. Closes paullouisageneau#1166
I also hope to achieve this refactoring, but that might be a big project. In the end, it's basically a combination of con_mux and conn_poll. |
@paullouisageneau do you have any feedback on this PR or the functionality it adds? |
This is not just a fix, as it affects how the API for this feature is designed. I think it needs to be accounted for, if not implemented, sooner than later. You have to design the interface in accordance now because you can't break compatibility later. This is native library packaged in a few distributions and releasing a new major version is complicated. |
@paullouisageneau Thank you very much for your feedback, I will make the changes according to your suggestions as soon as possible. |
Do you have any more suggestions for this pull request, @paullouisageneau? |
@xicilion this PR still only allows a single muxed port per process, or am I reading it wrong? @paullouisageneau requested it support multiple ports - #248 (comment) |
To support multiple ports, we'll need to almost rewrite the implementation of conn_mux.c. Currently, juice_mux_listen and juice_mux_stop_listen are already compatible with supporting multiple ports in the future. I think this time we can start by only adding the listen feature. |
@@ -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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
According to the RFC document:
[7.1.2](https://www.rfc-editor.org/rfc/rfc8445.html#section-7.1.2). USE-CANDIDATE
The controlling agent MUST include the USE-CANDIDATE attribute in
order to nominate a candidate pair ([Section 8.1.1](https://www.rfc-editor.org/rfc/rfc8445.html#section-8.1.1)). The controlled
agent MUST NOT include the USE-CANDIDATE attribute in a Binding
request.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
2024-07-31 23:04:44.369 VERB [387904] [rtc::impl::IceTransport::LogCallback@372] juice: conn.c:125: 0 connection left
2024-07-31 23:04:44.369 VERB [387904] [rtc::impl::IceTransport::LogCallback@372] juice: agent.c:192: Destroyed agent
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:449: Leaving poll
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:417: No more datagrams to receive
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:447: Entering poll for 60000 ms
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:449: Leaving poll
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:363: Demultiplexing incoming datagram from 127.0.0.1:54664
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:255: Looking up agent from address
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:485: Not a STUN message: magic number invalid
2024-07-31 23:04:44.369 INFO [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:266: Got non-STUN message from unknown source address
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:368: Agent not found for incoming datagram, dropping
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:417: No more datagrams to receive
2024-07-31 23:04:44.369 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:447: Entering poll for 60000 ms
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:449: Leaving poll
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:363: Demultiplexing incoming datagram from 127.0.0.1:54664
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:255: Looking up agent from address
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:270: Looking up agent from STUN message content
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:528: Reading STUN message, class=0x0, method=0x1
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x6, length=67
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:700: Reading username
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:707: Got username: libp2p+webrtc+v1/5fhhLR3XJZHejuox:libp2p+webrtc+v1/5fhhLR3XJZHejuox
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0xC057, length=4
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:1014: Ignoring unknown optional STUN attribute type 0xC057
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x802A, length=8
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:906: Found ICE controlling attribute
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x25, length=0
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:901: Found use candidate flag
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x24, length=4
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:891: Reading priority
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:897: Got priority: 1845501695
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x8, length=20
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:711: Reading message integrity
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x8028, length=4
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:729: Reading fingerprint
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:745: STUN fingerprint check succeeded
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:545: Finished reading STUN attributes
2024-07-31 23:04:44.553 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:368: Agent not found for incoming datagram, dropping
===========================================================================
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:363: Demultiplexing incoming datagram from 127.0.0.1:54664
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:255: Looking up agent from address
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:270: Looking up agent from STUN message content
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:528: Reading STUN message, class=0x0, method=0x1
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x6, length=67
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:700: Reading username
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:707: Got username: libp2p+webrtc+v1/5fhhLR3XJZHejuox:libp2p+webrtc+v1/5fhhLR3XJZHejuox
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0xC057, length=4
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:1014: Ignoring unknown optional STUN attribute type 0xC057
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x802A, length=8
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:906: Found ICE controlling attribute
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x24, length=4
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:891: Reading priority
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:897: Got priority: 1845501695
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x8, length=20
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:711: Reading message integrity
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:622: Reading attribute 0x8028, length=4
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:729: Reading fingerprint
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:745: STUN fingerprint check succeeded
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: stun.c:545: Finished reading STUN attributes
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:307: Found STUN request with unknown ICE ufrag
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:368: Agent not found for incoming datagram, dropping
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:408: Receiving datagram
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:417: No more datagrams to receive
2024-07-31 23:04:49.570 VERB [387845] [rtc::impl::IceTransport::LogCallback@372] juice: conn_mux.c:447: Entering poll for 60000 ms
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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
An agent must not include the USE-CANDIDATE attribute when sending a binding request.
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.
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.
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 comment
The 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.
Is anything else needed here? I'm looking forward to seeing this completed so we can unblock libp2p/js-libp2p#2583 |
juice_cb_mux_incoming_t cb_mux_incoming; | ||
void *mux_incoming_user_ptr; |
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 they are specific to the mux implementation, they should be moved to struct registry_impl
in conn_mux.c
instead, and you can then drop the mux_
prefix in the names.
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
If juice_mux_stop_listen()
now has the same bind_address
and local_port
parameters as juice_mux_listen()
, why not simply call juice_mux_listen(bind_address, local_port, NULL)
to stop listening? It would also permit multiple ports in the future, while being less clumsy that those two useless parameters.
@@ -64,6 +64,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_incoming { |
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
.
In order to implement WebRTC Direct PeerB, we need to capture STUN requests from unknown clients and return the client's information. Once PeerB receives this information, it will construct the client's SDP and establish a connection with the client on its own.