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

some questions about support for WebRTC Direct #1166

Open
xicilion opened this issue May 4, 2024 · 21 comments
Open

some questions about support for WebRTC Direct #1166

xicilion opened this issue May 4, 2024 · 21 comments

Comments

@xicilion
Copy link
Contributor

xicilion commented May 4, 2024

In the WebRTC specification, setLocalDescription accepts the full sessionDescription:
https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription#syntax

In general, applications do not need to set up sdp specifically, however libp2p is designed to establish connections independent of signaling by modifying ice-ufrag and ice-pwd:
https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md#browser-to-public-server

The setLocalDescription in libdatachannel only supports rtc::Description::Type, is there any way to implement a protocol like libp2p WebRTC Direct in libdatachannel?

@paullouisageneau
Copy link
Owner

This has already been discussed in #970 (comment) about disabling fingerprint validation, which would also be required by for this.

SDP munging between createOffer/createAnswer and setLocalDescription is forbidden in the WebRTC specification, even if Safari, Firefox, and Chrome don't enforce it:

If type is "offer", and sdp is not the empty string and not equal to connection.[[LastCreatedOffer]], then return a promise rejected with a newly created InvalidModificationError and abort these steps.

If type is "answer" or "pranswer", and sdp is not the empty string and not equal to connection.[[LastCreatedAnswer]], then return a promise rejected with a newly created InvalidModificationError and abort these steps.

Therefore, libdatachannel has no mechanism to set a modified local description by design to make the implementation way simpler (as it doesn't need to reparse the SDP and synchronize its internal state).

Not only changing the whole architecture to allow SDP munging hack is out of the question, but it would only allow you to implement "peer A" in the WebRTC Direct spec, since to implement "peer B" you would also need to modify the whole ICE ufrag and password generation and validation process, and you would need a specific ICE hook to create peer connections triggered by incoming STUN probes.

I suggest that WebRTC Direct could be implemented as a specific operating mode of libdatachannel instead, which would not emit a local description nor accept a remote one, but would perform the required ufrag and password operations under the hood and offer an API to listen on incoming peer connections.

@xicilion
Copy link
Contributor Author

xicilion commented May 4, 2024

Since we're thinking about supporting WebRTC Direct, wouldn't it be a good idea to consider specifying ice_ufrag and ice_pwd when creating the PeerConnection.
This would probably require juice_create to support it though.

And with the addition of disabling fingerprint authentication, and a stun event, it might be possible to build a somewhat more elegant implementation of WebRTC Direct.

@xicilion
Copy link
Contributor Author

xicilion commented May 5, 2024

I made some changes, passed in ice_ufrag and ice_pwd and initiated a connection to go-libp2p-server. Looking at the log the handshake is already successful, but onOpen cannot be triggered.
I traced the code and found that DataChannel::incoming is not receiving the MESSAGE_ACK message. So I triggered it when the function received Message::String and Message::Binary.

	case Message::String:
	case Message::Binary:
		if (!mIsOpen.exchange(true)) {
			triggerOpen();
		}

		mRecvQueue.push(message);
		triggerAvailable(mRecvQueue.size());
		break;

I'm not sure if this is a problem with the go-libp2p implementation. Is this an appropriate change?

@xicilion
Copy link
Contributor Author

xicilion commented May 5, 2024

I made some modifications to support setting up cert and key, and it's working fine so far.
#972

@xicilion xicilion changed the title Question about setting sdp in setLocalDescription me questions about support for WebRTC Direct May 5, 2024
@xicilion xicilion changed the title me questions about support for WebRTC Direct some questions about support for WebRTC Direct May 5, 2024
@paullouisageneau
Copy link
Owner

I made some changes, passed in ice_ufrag and ice_pwd and initiated a connection to go-libp2p-server. Looking at the log the handshake is already successful, but onOpen cannot be triggered. I traced the code and found that DataChannel::incoming is not receiving the MESSAGE_ACK message. So I triggered it when the function received Message::String and Message::Binary.

	case Message::String:
	case Message::Binary:
		if (!mIsOpen.exchange(true)) {
			triggerOpen();
		}

		mRecvQueue.push(message);
		triggerAvailable(mRecvQueue.size());
		break;

I'm not sure if this is a problem with the go-libp2p implementation. Is this an appropriate change?

No, this is not normal. If there is no ACK message, it's either a confusion between datachannels opened in-band and negotiated datachannels or a bug in the remote implementation.

@xicilion
Copy link
Contributor Author

xicilion commented May 5, 2024

Yes, it's confusing, I connect to libdatachannel's peer node and don't have this problem.

@xicilion
Copy link
Contributor Author

xicilion commented May 5, 2024

is a simplified piece of client-side code for WebRTC Direct.

const rtc = require('rtc');

const HANDSHAKE_TIMEOUT_MS = 10000;

async function main() {
    const ufrag = 'libp2p+webrtc+v1/' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
    const ip = '192.168.65.5';
    const port = 60916;
    var answerSdp = {
        "type": "answer",
        "sdp": `v=0\r\no=- 0 0 IN IP4 ${ip}\r\ns=-\r\nc=IN IP4 ${ip}\r\nt=0 0\r\na=ice-lite\r\nm=application ${port} UDP/DTLS/SCTP webrtc-datachannel\r\na=mid:0\r\na=setup:active\r\na=ice-ufrag:${ufrag}\r\na=ice-pwd:${ufrag}\r\na=fingerprint:SHA-256 07:E5:6F:2A:1A:0C:2C:32:0E:C1:C3:9C:34:5A:78:4E:A5:8B:32:05:D1:57:D6:F4:E7:02:41:12:E6:01:C6:8F\r\na=sctp-port:5000\r\na=max-message-size:16384\r\na=candidate:1467250027 1 UDP 1467250027 ${ip} ${port} typ host\r\n`
    };

    console.log(answerSdp);

    const peerConnection = new rtc.RTCPeerConnection({
        iceUfrag: ufrag,
        icePwd: ufrag,
        port: 12345,
        maxMessageSize: 16384
    });

    const dataChannelOpenPromise = new Promise((resolve, reject) => {
        console.log("peerConnection.createDataChannel");
        const handshakeDataChannel = peerConnection.createDataChannel('');
        const handshakeTimeout = setTimeout(() => {
            const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`;
            reject(new Error(error));
        }, HANDSHAKE_TIMEOUT_MS);

        handshakeDataChannel.onopen = (_) => {
            console.log('Data channel opened');
            clearTimeout(handshakeTimeout);
            resolve(handshakeDataChannel);
        };

        handshakeDataChannel.onerror = (event) => {
            console.error('Data channel error:', event);
            clearTimeout(handshakeTimeout);
            const error = `Error opening a data channel for handshaking.`;
            reject(new Error(error));
        };

        handshakeDataChannel.onmessage = (event) => {
            console.log('Data channel message:', event.data);
        };
    });

    await peerConnection.setRemoteDescription(answerSdp);
    console.log("setRemoteDescription ok");
    const handshakeDataChannel = await dataChannelOpenPromise;
    console.log("connect ok");
}

main();

@xicilion
Copy link
Contributor Author

xicilion commented May 5, 2024

Today, based on the implementation of the skipCheckFingerprint option, it is possible to implement a simple Peer B.
All that is left is the stun reflection mechanism, which will allow a more complete Peer B to be implemented.

The code for Peer B looks like this.

var rtc = require('rtc');

const key_pem =
    `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3bbuT2SjSlMZH/J1
vHwmF0Blb/DBc/v7f1Za9GPUXHmhRANCAATDpmYxZozjVw6xlERNjJJGgfY3bEmj
xAKFRq3nbxbDHvMEs34u9HntMZWJ0hp3GUC+Ax7JHTv3cYqSaAg2SpR4
-----END PRIVATE KEY-----`

const cert_pem =
    `-----BEGIN CERTIFICATE-----
MIIBgjCCASigAwIBAgIJAPMXEoZXOaDEMAoGCCqGSM49BAMCMEoxDzANBgNVBAMM
BmNhLmNvbTELMAkGA1UEBhMCVVMxCzAJBgNVBAcMAkNBMRAwDgYDVQQKDAdleGFt
cGxlMQswCQYDVQQIDAJDQTAeFw0yNDA1MDUxNjAzMjFaFw0yNDA4MTMxNjAzMjFa
MDExCzAJBgNVBAYTAkNOMRAwDgYDVQQKDAdiYW96LmNuMRAwDgYDVQQDDAdiYW96
Lm1lMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw6ZmMWaM41cOsZRETYySRoH2
N2xJo8QChUat528Wwx7zBLN+LvR57TGVidIadxlAvgMeyR0793GKkmgINkqUeKMQ
MA4wDAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNIADBFAiAPNldqGJHryfjPFyX3
zfHHWlO7xSDTzdyoxzroFdwy+gIhAKmZizEVvDlBiIe+3ptCArU3dbp+bzLynTcr
Ma9ayzQy
-----END CERTIFICATE-----`

const ufrag = 'libp2p+webrtc+v1/' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
const ip = '192.168.65.5';
const port = 12345;
var offerSdp = {
    "type": "offer",
    "sdp": `v=0\r\no=- 0 0 IN IP4 ${ip}\r\ns=-\r\nc=IN IP4 ${ip}\r\nt=0 0\r\na=ice-lite\r\nm=application ${port} UDP/DTLS/SCTP webrtc-datachannel\r\na=mid:0\r\na=setup:passive\r\na=ice-ufrag:${ufrag}\r\na=ice-pwd:${ufrag}\r\na=fingerprint:SHA-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\r\na=sctp-port:5000\r\na=max-message-size:16384\r\na=candidate:1467250027 1 UDP 1467250027 ${ip} ${port} typ host\r\n`
};

let peer1 = new rtc.RTCPeerConnection({
    enableIceUdpMux: true,
    skipCheckFingerprint: true,
    iceUfrag: ufrag,
    icePwd: ufrag,
    certPem: cert_pem,
    keyPem: key_pem,
    port: 60916,
    maxMessageSize: 16384
});

peer1.setRemoteDescription(offerSdp);

console.readLine();

@paullouisageneau
Copy link
Owner

        const handshakeDataChannel = peerConnection.createDataChannel('');

You shouldn't set an empty label, it is technically allowed but might cause issues with some implementations.

Today, based on the implementation of the skipCheckFingerprint option, it is possible to implement a simple Peer B.
All that is left is the stun reflection mechanism, which will allow a more complete Peer B to be implemented.

Great, nice work!

@xicilion
Copy link
Contributor Author

xicilion commented May 6, 2024

var rtc = require('rtc');

const key_pem =
    `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3bbuT2SjSlMZH/J1
vHwmF0Blb/DBc/v7f1Za9GPUXHmhRANCAATDpmYxZozjVw6xlERNjJJGgfY3bEmj
xAKFRq3nbxbDHvMEs34u9HntMZWJ0hp3GUC+Ax7JHTv3cYqSaAg2SpR4
-----END PRIVATE KEY-----`

const cert_pem =
    `-----BEGIN CERTIFICATE-----
MIIBgjCCASigAwIBAgIJAPMXEoZXOaDEMAoGCCqGSM49BAMCMEoxDzANBgNVBAMM
BmNhLmNvbTELMAkGA1UEBhMCVVMxCzAJBgNVBAcMAkNBMRAwDgYDVQQKDAdleGFt
cGxlMQswCQYDVQQIDAJDQTAeFw0yNDA1MDUxNjAzMjFaFw0yNDA4MTMxNjAzMjFa
MDExCzAJBgNVBAYTAkNOMRAwDgYDVQQKDAdiYW96LmNuMRAwDgYDVQQDDAdiYW96
Lm1lMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw6ZmMWaM41cOsZRETYySRoH2
N2xJo8QChUat528Wwx7zBLN+LvR57TGVidIadxlAvgMeyR0793GKkmgINkqUeKMQ
MA4wDAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNIADBFAiAPNldqGJHryfjPFyX3
zfHHWlO7xSDTzdyoxzroFdwy+gIhAKmZizEVvDlBiIe+3ptCArU3dbp+bzLynTcr
Ma9ayzQy
-----END CERTIFICATE-----`

let accepter = new rtc.RTCPeerConnection({
    enableIceUdpMux: true,
    stunBinding: true,
    port: 60916
});

accepter.onstunbinding = function (binding) {
    console.log('onstunbinding', binding);

    const ufrag = binding.ufrag;
    const [ip, port] = binding.address.split(':');

    let peer1 = new rtc.RTCPeerConnection({
        enableIceUdpMux: true,
        skipCheckFingerprint: true,
        iceUfrag: ufrag,
        icePwd: ufrag,
        certPem: cert_pem,
        keyPem: key_pem,
        maxMessageSize: 16384
    });

    peer1.setRemoteDescription({
        "type": "offer",
        "sdp": `v=0\r\no=- 0 0 IN IP4 ${ip}\r\ns=-\r\nc=IN IP4 ${ip}\r\nt=0 0\r\na=ice-lite\r\nm=application ${port} UDP/DTLS/SCTP webrtc-datachannel\r\na=mid:0\r\na=setup:passive\r\na=ice-ufrag:${ufrag}\r\na=ice-pwd:${ufrag}\r\na=fingerprint:SHA-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\r\na=sctp-port:5000\r\na=max-message-size:16384\r\na=candidate:1467250027 1 UDP 1467250027 ${ip} ${port} typ host\r\n`
    });
}

accepter.setRemoteDescription({
    "type": "offer",
    "sdp": `v=0\r\no=- 0 0 IN IP4 00.0.0\r\ns=-\r\nc=IN IP4 00.0.0\r\nt=0 0\r\na=ice-lite\r\nm=application 1 UDP/DTLS/SCTP webrtc-datachannel\r\na=mid:0\r\na=setup:passive\r\na=ice-ufrag:1\r\na=ice-pwd:1\r\na=fingerprint:SHA-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\r\na=sctp-port:5000\r\na=max-message-size:16384\r\na=candidate:1467250027 1 UDP 1467250027 00.0.0 1 typ host\r\n`
});

console.readLine();

After adding the stunbinding event, the full version of Peer B has established a connection. There is still an issue where the second connection handshake fails if there is a short time between connections, still working on it.

It's a bit of a shame that the implementation of the stunbinding event doesn't look very good.

@xicilion
Copy link
Contributor Author

xicilion commented May 6, 2024

I found it. It was an issue with my test code, where I was testing with Peer A bound to a port, causing Peer B to treat the same address and port as the same connection.

I thought there would be connection confusion here when udp is multiplexed, but then I figured out that this only happens when udp is multiplexed on both ends. So it's not a problem.

@xicilion
Copy link
Contributor Author

xicilion commented May 7, 2024

So far, I've made the following changes:

  • libjuice

    • agent_create support passing in ice_ufrag and ice_pwd in config.
  • libdatachannel.

    • Configuration supports passing in iceUfrag and icePwd.
    • Configuration supports passing in certPem and keyPem.
    • Configuration supports skipCheckFingerprint.
    • Disable comparing local and remote iceUfrag and icePwd in validateRemoteDescription.

I will submit pr for each of these features if you find them acceptable.

Because I don't understand many implementation details, the implementation of reflect stun in libjuice and libdatachannel is too complicated, I'm sure you will have a better design. I don't think I'll submit it.

achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 5, 2024
Adds two new optional config keys - `iceUfrag` and `icePwd` which
are passed to libjuice.

Depends on: paullouisageneau/libjuice#249

Refs: paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 5, 2024
Adds two new optional config keys - `iceUfrag` and `icePwd` which
are passed to libjuice.

Depends on: paullouisageneau/libjuice#249

Refs: paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 5, 2024
Adds two new optional config keys - `iceUfrag` and `icePwd` which
are passed to libjuice.

Refs: paullouisageneau#1166
@achingbrain
Copy link
Contributor

achingbrain commented Jun 6, 2024

This is very exciting stuff, thanks so much for picking it up @xicilion

I've just got js-libp2p successfully dialling go-libp2p over webrtc-direct from node.js using a patched version of node-datachannel (murat-dogan/node-datachannel#256) that uses libdatachannel with #1201 applied and the latest version of libjuice (so it has paullouisageneau/libjuice#243 which doesn't appear to have made it into a release yet).

Haven't quite go the listener end done yet, I get a DTLS error (logs below) but this is some nice progress!

...
2024-06-06 14:12:22.184 DEBUG [112439100] [rtc::impl::DtlsTransport::start@836] Starting DTLS transport
2024-06-06 14:12:22.184 INFO  [112439100] [rtc::impl::IceTransport::LogCallback@385] juice: Changing state to completed
2024-06-06 14:12:22.184 INFO  [112439100] [rtc::impl::PeerConnection::changeIceState@1254] Changed ICE state to completed
2024-06-06 14:12:22.184 DEBUG [112439094] [PeerConnectionWrapper::onIceStateChange@783] onIceStateChange cb received from rtc
2024-06-06 14:12:22.184 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@786] mOnIceStateChangeCallback call(1)
2024-06-06 14:12:22.184 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@795] mOnIceStateChangeCallback call(2)
2024-06-06 14:12:22.235 INFO  [112439100] [rtc::impl::IceTransport::LogCallback@385] juice: Changing state to connected
2024-06-06 14:12:22.235 INFO  [112439100] [rtc::impl::PeerConnection::changeIceState@1254] Changed ICE state to connected
2024-06-06 14:12:22.236 DEBUG [112439100] [rtc::impl::DtlsTransport::DtlsTransport@733] Initializing DTLS transport (OpenSSL)
2024-06-06 14:12:22.236 DEBUG [112439093] [PeerConnectionWrapper::onIceStateChange@783] onIceStateChange cb received from rtc
2024-06-06 14:12:22.236 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@786] mOnIceStateChangeCallback call(1)
2024-06-06 14:12:22.236 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@795] mOnIceStateChangeCallback call(2)
2024-06-06 14:12:22.236 DEBUG [112439100] [rtc::impl::DtlsTransport::start@836] Starting DTLS transport
2024-06-06 14:12:22.236 INFO  [112439100] [rtc::impl::IceTransport::LogCallback@385] juice: Changing state to completed
2024-06-06 14:12:22.236 INFO  [112439100] [rtc::impl::PeerConnection::changeIceState@1254] Changed ICE state to completed
2024-06-06 14:12:22.236 DEBUG [112439095] [PeerConnectionWrapper::onIceStateChange@783] onIceStateChange cb received from rtc
2024-06-06 14:12:22.236 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@786] mOnIceStateChangeCallback call(1)
2024-06-06 14:12:22.236 DEBUG [112439004] [PeerConnectionWrapper::onIceStateChange@795] mOnIceStateChangeCallback call(2)
2024-06-06 14:12:22.236 ERROR [112439092] [rtc::impl::DtlsTransport::InfoCallback@1047] DTLS alert: unexpected_message
2024-06-06 14:12:22.236 ERROR [112439087] [rtc::impl::DtlsTransport::InfoCallback@1047] DTLS alert: unexpected_message
2024-06-06 14:12:22.238 ERROR [112439092] [rtc::impl::DtlsTransport::doRecv@987] DTLS recv: Handshake failed: error:0A0000F4:SSL routines::unexpected message
2024-06-06 14:12:22.238 ERROR [112439087] [rtc::impl::DtlsTransport::doRecv@987] DTLS recv: Handshake failed: error:0A0003F2:SSL routines::ssl/tls alert unexpected message
2024-06-06 14:12:22.238 ERROR [112439092] [rtc::impl::DtlsTransport::doRecv@995] DTLS handshake failed
2024-06-06 14:12:22.238 INFO  [112439092] [rtc::impl::PeerConnection::changeState@1236] Changed state to failed
2024-06-06 14:12:22.238 DEBUG [112439092] [PeerConnectionWrapper::onStateChange@737] onStateChange cb received from rtc
2024-06-06 14:12:22.238 ERROR [112439087] [rtc::impl::DtlsTransport::doRecv@995] DTLS handshake failed
2024-06-06 14:12:22.238 INFO  [112439087] [rtc::impl::PeerConnection::changeState@1236] Changed state to failed

achingbrain added a commit to achingbrain/node-datachannel that referenced this issue Jun 6, 2024
paullouisageneau/libjuice#243 allows setting
the ICE ufrag and pwd fields instead of generating random ones every
time.

paullouisageneau/libdatachannel#1201 exposes
config keys to allow setting the fields in libjuice from libdatachannel.

This PR allows setting the fields in libdatachannel from the PeerConnection
constructor.

It will require the two PRs above being merged an shipped before this
is ready for merging.

Refs: paullouisageneau/libdatachannel#1166
@achingbrain
Copy link
Contributor

achingbrain commented Jun 6, 2024

I get a DTLS error

I think I've figured this out, I had the wrong DTLS roles set in the inferred SDP offers/answers, seems to work now.

@xicilion
Copy link
Contributor Author

xicilion commented Jun 6, 2024

so it has paullouisageneau/libjuice#243 which doesn't appear to have made it into a release yet.

yep, I was waiting for libjuice@243 to be released to implement this feature, glad you released it.

@xicilion
Copy link
Contributor Author

xicilion commented Jun 6, 2024

Haven't quite go the listener end done yet, I get a DTLS error (logs below) but this is some nice progress!

I have a PR at libjuice, but don't think the implementation is very nice.
paullouisageneau/libjuice#248

@achingbrain
Copy link
Contributor

glad you released it

Ah, no - nothing's been released yet, I'm running locally off patched versions. Hopefully @paullouisageneau can take a look soon.

I have a PR at libjuice but don't think the implementation is very nice.

Yes, I saw that - I ended up just opening a UDP port using node.js and decoding the incoming messages using the stun module to extract the ufrag, though I'd much rather not have to pull an additional dependency in so something like this would be better.

@xicilion
Copy link
Contributor Author

xicilion commented Jun 7, 2024

I ended up just opening a UDP port using node.js and decoding the incoming messages using the stun module to extract the ufrag

How can libdatachannel establish a connection with Peer A again on the same port in this way?

I read the code:
libp2p/js-libp2p#2583

at this line:
https://github.com/libp2p/js-libp2p/pull/2583/files#diff-d97a3ca500f9b61eaf94a65583b51eb08d155fd9aae4dd1bae7ad98ed0160778R174

It looks like that the listener is creating a new rtc connection on a different port. that may not work behind NAT I thought.

Have you tested it in the NAT environment? @achingbrain

achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Returns a vector that contains the certificate fingerprints used
by the connection to the remote peer.

Closes paullouisageneau#1203
Refs paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Returns a vector that contains the certificate fingerprints used
by the connection to the remote peer.

Closes paullouisageneau#1203
Refs paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Returns a vector that contains the certificate fingerprints used
by the connection to the remote peer.

Closes paullouisageneau#1203
Refs paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Returns a vector that contains the certificate fingerprints used
by the connection to the remote peer.

Closes paullouisageneau#1203
Refs paullouisageneau#1166
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Adds an optional second argument to `rtc::PeerConnection::setLocalDescription`
that can contain an ICE ufrag and pwd that if passed will be used in place
of the randomly generated versions.

Refs: paullouisageneau#1166
Refs: paullouisageneau#1201 (comment)
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 11, 2024
Adds an optional second argument to `rtc::PeerConnection::setLocalDescription`
that can contain an ICE ufrag and pwd that if passed will be used in place
of the randomly generated versions.

Refs: paullouisageneau#1166
Refs: paullouisageneau#1201 (comment)
@xicilion
Copy link
Contributor Author

xicilion commented Jun 11, 2024

Perfect, now the official version can be directly used for implementing webrtc direct.

@xicilion
Copy link
Contributor Author

It looks like that the listener is creating a new rtc connection on a different port. that may not work behind NAT I thought.

I did some tests and confirmed that this approach won't work.

When Peer A is behind NAT, the connection will fail because NAT detects incoming packets from another port that has not been accessed from the inside before.

In other words, if Peer B wants to support access from Peer A behind NAT, the only way is to listen for connections on the same port using UdpMux.

So, we may have to consider the feasibility of paullouisageneau/libjuice#248.

@achingbrain
Copy link
Contributor

I figured something like that might be necessary, I haven't got as far as testing behind NATs yet - thanks for looking into it.

achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 13, 2024
Adds an optional second argument to `rtc::PeerConnection::setLocalDescription`
that can contain an ICE ufrag and pwd that if passed will be used in place
of the randomly generated versions.

Refs: paullouisageneau#1166
Refs: paullouisageneau#1201 (comment)

Co-authored-by: Paul-Louis Ageneau <[email protected]>
achingbrain added a commit to achingbrain/libdatachannel that referenced this issue Jun 14, 2024
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
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

3 participants