Skip to content
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

Using str0m in rust-libp2p #166

Closed
thomaseizinger opened this issue May 14, 2023 · 19 comments
Closed

Using str0m in rust-libp2p #166

thomaseizinger opened this issue May 14, 2023 · 19 comments

Comments

@thomaseizinger
Copy link
Collaborator

Following the advice from here, I am opening a separate issue!

Here is what we want to do: Have libp2p applications running in the browser connect to server nodes that don't have a valid TLS certificate. Being in the browser, we don't have control over the WebRTC stack but use the RTCPeerConnection API.

The entire protocol is described here: https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md#browser-to-public-server

We also don't have separate STUN servers. Instead, the client knows the server's address through an out-of-band mechanism. We have a self-descriptive address format that looks like this:

/ip4/172.28.0.1/udp/9999/webrtc/certhash/uEiD8c9GWyEurSjh9UkY-YWXaXBJZIHo179zx9IpgDFFKgw/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN

The component after the /certhash part (uEiD8c9GWyEurSjh9UkY-YWXaXBJZIHo179zx9IpgDFFKgw) is the server's certificate fingerprint. This gives us enough information to directly connect to the server.

We want to use str0m for the server part of this setup. The node will always be publicly reachable, hence we are in ICE-lite mode. We only ever need data channels, no media.

Concrete questions I have:

  • Is there a way how I can disable certificate fingerprint validation?
  • The spec describes to perform SDP munging but that doesn't seem to be possible with the sdp_api. I think I achieved the same thing with the direct_api and adding candidates myself. Is there something I should be aware of when doing it that way?

More general questions:

  • Is this possible at all with str0m?
  • Is this a usecase you want to support?
@xnorpx
Copy link
Collaborator

xnorpx commented May 14, 2023

@thomaseizinger direct api is probably the way to go here instead of fighting sdp.

regarding
"At this point B does not know the TLS certificate fingerprint of A. Thus B can not verify A's TLS certificate fingerprint during the DTLS handshake. Instead B needs to disable certificate fingerprint verification (see e.g. Pion's disableCertificateFingerprintVerification option)."

What is the corresponding setting in webrtc-rs?

@thomaseizinger
Copy link
Collaborator Author

@thomaseizinger direct api is probably the way to go here instead of fighting sdp.

Cool, thanks for the confirmation!

regarding "At this point B does not know the TLS certificate fingerprint of A. Thus B can not verify A's TLS certificate fingerprint during the DTLS handshake. Instead B needs to disable certificate fingerprint verification (see e.g. Pion's disableCertificateFingerprintVerification option)."

What is the corresponding setting in webrtc-rs?

https://docs.rs/webrtc/latest/webrtc/api/setting_engine/struct.SettingEngine.html#method.disable_certificate_fingerprint_verification

@thomaseizinger
Copy link
Collaborator Author

regarding "At this point B does not know the TLS certificate fingerprint of A. Thus B can not verify A's TLS certificate fingerprint during the DTLS handshake. Instead B needs to disable certificate fingerprint verification (see e.g. Pion's disableCertificateFingerprintVerification option)."
What is the corresponding setting in webrtc-rs?

docs.rs/webrtc/latest/webrtc/api/setting_engine/struct.SettingEngine.html#method.disable_certificate_fingerprint_verification

This is how we use it: https://github.com/libp2p/rust-libp2p/blob/a00daca5fa39e68437c91335f46dcd4c685dee18/transports/webrtc/src/tokio/upgrade.rs#L132-L156

@xnorpx
Copy link
Collaborator

xnorpx commented May 14, 2023

if you just bypass it in your fork, can you get it to work?

https://github.com/algesten/str0m/blob/c41fd6413fd5662a7903c4cec954c54284966dfb/src/lib.rs#LL1082C17-L1093C18

essentially just make this section noop

@thomaseizinger
Copy link
Collaborator Author

I'll try but I am not seeing any errors regarding dTLS failures at the moment.

I've pasted my latest logs here: #164 (comment)

For some reason, the candidates I am adding fail. Any idea why?

@xnorpx
Copy link
Collaborator

xnorpx commented May 14, 2023

Not sure based on that log.

Here is a branch, were I disabled the certificate verification.

c1e76f5

@xnorpx
Copy link
Collaborator

xnorpx commented May 15, 2023

// We keep propagating client events until all clients respond with a timeout.
// if to_propagate.len() > timeouts.len() {
// propagate(&mut clients, to_propagate);
// // Start over to propagate more client data until all are timeouts.
// continue;
// }

You would need this to send responses to your client.

@xnorpx
Copy link
Collaborator

xnorpx commented May 15, 2023

it probably easier use the http example just to get connection + datachannel going rather than using the chat example.

@thomaseizinger
Copy link
Collaborator Author

// We keep propagating client events until all clients respond with a timeout.
// if to_propagate.len() > timeouts.len() {
// propagate(&mut clients, to_propagate);
// // Start over to propagate more client data until all are timeouts.
// continue;
// }

You would need this to send responses to your client.

Good hint, thank you! :)

@thomaseizinger
Copy link
Collaborator Author

it probably easier use the http example just to get connection + datachannel going rather than using the chat example.

I didn't realize that was a separate example!

I just found https://github.com/algesten/str0m/blob/main/tests/data-channel-direct.rs which gave me some ideas on what I want to test.

@algesten
Copy link
Owner

@thomaseizinger sorry if I'm being dense. Was there a link to a repro so I could play around?

@thomaseizinger
Copy link
Collaborator Author

@thomaseizinger sorry if I'm being dense. Was there a link to a repro so I could play around?

It is a branch on my fork: https://github.com/thomaseizinger/str0m/tree/libp2p-webrtc-playground

@xnorpx
Copy link
Collaborator

xnorpx commented May 15, 2023

@algesten

git clone https://github.com/thomaseizinger/str0m str0m_p2p

cd str0m_p2p

git checkout libp2p-webrtc-playground

cargo run --example chat

look for:
use: info!("Listening on {multiaddr}");
2023-05-15T15:25:48.793542Z INFO chat: Listening on /ip4/X.X.X.X/udp/9999/webrtc/certhash/uEiD8c9GWyEurSjh9UkY-YWXaXBJZIHo179zx9IpgDFFKgw/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN

use
/ip4/X.X.X.X/udp/9999/webrtc/certhash/uEiD8c9GWyEurSjh9UkY-YWXaXBJZIHo179zx9IpgDFFKgw/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN

in bootnode multiaddr in

https://tomaka.github.io/test-browser-node/index.html

@thomaseizinger
Copy link
Collaborator Author

Thanks! Sorry for not giving more detailed instructions.

Does it even makes sense to test this on a single machine or do I need two? The connection seems to fail with:

2023-05-15T15:25:00.752411Z DEBUG str0m::ice::agent: Remove failed pair: CandidatePair(0-0 prio=9151313343271665150 state=Waiting attempts=0 unanswered=0 remote=0 last=None nom=None)
2023-05-15T15:25:00.752438Z  INFO str0m::ice::agent: State change (no possible pairs): Checking -> Disconnected

I don't really know what to look for next. It seems like the connection is not established?

@xnorpx
Copy link
Collaborator

xnorpx commented May 15, 2023

Should be able to connect fine on the same machine.

I would:

  • port your code to the chat example.
  • ensure your run loop is complete with both poll output (write to socket) and read from socket.

focus on the things that are "funky" like the ice credentials and how the candidate looks like.

@altonen
Copy link
Contributor

altonen commented Sep 1, 2023

@thomaseizinger

You need to call Rtc::handle_input() and pass the received STUN message to make progress. I've created a PR #324 that adds the remaining bits in order to implement WebRTC direct using str0m.

@algesten
Copy link
Owner

algesten commented Sep 1, 2023

@thomaseizinger can this one be closed now, or are there more things outstanding?

@thomaseizinger
Copy link
Collaborator Author

@thomaseizinger can this one be closed now, or are there more things outstanding?

In #324, @altonen mentioned that they managed to implement it which would be amazing! I'll defer to them here! :)

I am excited to see the code!

@altonen
Copy link
Contributor

altonen commented Sep 3, 2023

I think this can be closed, str0m has everything needed to implement WebRTC Direct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants