Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
text: 'Networking and ICE',
collapsed: false,
items: [
{ text: 'Peer Connection Configuration', link: '/networking/peer-connection-config' },
{ text: 'Port Allocator Configuration', link: '/networking/port-allocator-config' },
],
},
Expand Down
1 change: 1 addition & 0 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This section provides detailed guides for various features of the webrtc-java li

## Networking and ICE

- [Peer Connection Configuration](/guide/networking/peer-connection-config) - Candidate gathering, ICE checks, TURN, SRTP ciphers and other connection settings
- [Port Allocator Config](/guide/networking/port-allocator-config) - Restrict ICE port ranges and control candidate gathering behavior

## Monitoring and Debugging
Expand Down
85 changes: 85 additions & 0 deletions docs/guide/networking/peer-connection-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Peer Connection Configuration

`RTCConfiguration` holds the settings a peer connection is created with: ICE servers and policies, how candidates are gathered, how ICE checks connections, and how media is protected. This guide covers the settings beyond the ICE servers, which most applications leave at their defaults, but which matter for fast connecting, restrictive networks, and mobile or multi-homed hosts.

Every setting described here is unset by default, which keeps WebRTC's default. `getConfiguration()` returns the values in effect, defaults included.

```java
RTCConfiguration config = new RTCConfiguration();
config.iceServers.add(stunServer);
config.iceCandidatePoolSize = 2;
config.continualGatheringPolicy = RTCContinualGatheringPolicy.GATHER_CONTINUALLY;

RTCPeerConnection peerConnection = factory.createPeerConnection(config, observer);
```

Some settings can be changed later with `setConfiguration()`, starting from `getConfiguration()`; those WebRTC does not allow to change make it throw. A configuration WebRTC rejects makes `createPeerConnection()` throw, with the reason in the message.

## Candidate Gathering

| Setting | Effect |
|---|---|
| `iceCandidatePoolSize` | Gathers this many candidates before a connection needs them, so that connecting is faster. Default 0. |
| `continualGatheringPolicy` | `GATHER_CONTINUALLY` keeps gathering after the first candidates, so that a network that comes up later gets candidates too, which lets a connection survive a network change. Default `GATHER_ONCE`. |
| `tcpCandidatePolicy` | `DISABLED` gathers no TCP candidates. Default `ENABLED`. |
| `candidateNetworkPolicy` | `LOW_COST` leaves out cellular networks. Default `ALL`. |
| `disableIpv6OnWifi`, `maxIpv6Networks` | Limit IPv6 candidates. Default: IPv6 on Wi-Fi allowed, at most 5 IPv6 networks. |
| `networkPreference` | A kind of network, e.g. `ETHERNET`, whose candidate pairs take precedence regardless of their priority. Default: none. |
| `vpnPreference` | Whether to use, avoid, prefer or require VPN connections. Default `DEFAULT`. |
| `surfaceIceCandidatesOnIceTransportTypeChanged` | Signals at once the candidates a change of `iceTransportPolicy` lets through. Default false. |

To restrict ports and interfaces, see [Port Allocator Configuration](/guide/networking/port-allocator-config).

## Connectivity Checks

These tune how often ICE checks candidate pairs and when it gives up on one, all in milliseconds. Shorter intervals notice failures sooner, at the cost of more traffic. WebRTC checks that they fit together; for example, the check interval under strong connectivity may not exceed `stableWritableConnectionPingInterval`.

`iceConnectionReceivingTimeout`, `iceBackupCandidatePairPingInterval`, `iceCheckIntervalStrongConnectivity`, `iceCheckIntervalWeakConnectivity`, `iceCheckMinInterval`, `iceUnwritableTimeout`, `iceUnwritableMinChecks` (a count), `iceInactiveTimeout`, `stunCandidateKeepaliveInterval`, `stableWritableConnectionPingInterval`.

`prioritizeMostLikelyIceCandidatePairs` checks the pairs most likely to work first, usually those through TURN, and `enableIceRenomination` offers ICE renomination, which lets the controlling end switch the selected pair.

## TURN

| Setting | Effect |
|---|---|
| `presumeWritableWhenFullyRelayed` | Presumes TURN-to-TURN pairs work before a check succeeds, so that DTLS starts at once, which speeds up connecting through TURN. |
| `turnPortPrunePolicy` | Prunes TURN ports: `PRUNE_BASED_ON_PRIORITY` or `KEEP_FIRST_READY` per network. Default `NO_PRUNE`. |
| `turnLoggingId` | An identifier sent to TURN servers, to tie their logs to the application's. |

## Media

| Setting | Effect |
|---|---|
| `enableDscp` | Marks media packets with DSCP values. Default true. |
| `enableCpuAdaptation` | Lowers the resolution or frame rate of video when the CPU is overused. Default true. |
| `suspendBelowMinBitrate` | Stops sending video when the bitrate falls below its minimum. Default false. |
| `screencastMinBitrate` | The bitrate screen share video is padded up to, in kbps. Default 100. |

## Security

`cryptoOptions` selects the SRTP cipher suites a peer connection offers. A new `RTCCryptoOptions` holds WebRTC's defaults, to change from:

```java
RTCCryptoOptions crypto = new RTCCryptoOptions();
crypto.preferGcmCryptoSuites = true;
crypto.cryptexPolicy = RTCCryptexPolicy.NEGOTIATE;

config.cryptoOptions = crypto;
```

`cryptexPolicy` encrypts the RTP header extensions and CSRCs as a whole (RFC 9335) where the peer supports it (`NEGOTIATE`) or always (`REQUIRE`).

## Signaling

| Setting | Effect |
|---|---|
| `offerExtmapAllowMixed` | Allows one- and two-byte header extensions to be mixed in offers. Default true. |
| `enableImplicitRollback` | Rolls a pending local offer back when a remote offer arrives, as perfect negotiation needs. Default false. |
| `alwaysNegotiateDataChannels` | Includes data channels in offers before any is created. Default false. |

## Related API

- `RTCConfiguration` — the configuration of a peer connection.
- `RTCPeerConnection.getConfiguration()`, `setConfiguration()` — read and change it.
- `RTCCryptoOptions` — the SRTP cipher suites.
- `PortAllocatorConfig` — ports and interfaces, see [Port Allocator Configuration](/guide/networking/port-allocator-config).
35 changes: 35 additions & 0 deletions webrtc-jni/src/main/cpp/include/api/RTCConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ namespace jni
{
namespace RTCConfiguration
{
// The position of an adapter type in RTCAdapterType.
enum class AdapterTypeOrdinal : int {};

class JavaRTCConfigurationClass : public JavaClass
{
public:
Expand All @@ -44,6 +47,38 @@ namespace jni
jfieldID audioJitterBufferMaxPackets;
jfieldID audioJitterBufferFastAccelerate;
jfieldID audioJitterBufferMinDelayMs;
jfieldID iceCandidatePoolSize;
jfieldID tcpCandidatePolicy;
jfieldID candidateNetworkPolicy;
jfieldID continualGatheringPolicy;
jfieldID disableIpv6OnWifi;
jfieldID maxIpv6Networks;
jfieldID vpnPreference;
jfieldID surfaceIceCandidatesOnIceTransportTypeChanged;
jfieldID iceConnectionReceivingTimeout;
jfieldID iceBackupCandidatePairPingInterval;
jfieldID iceCheckIntervalStrongConnectivity;
jfieldID iceCheckIntervalWeakConnectivity;
jfieldID iceCheckMinInterval;
jfieldID iceUnwritableTimeout;
jfieldID iceUnwritableMinChecks;
jfieldID iceInactiveTimeout;
jfieldID stunCandidateKeepaliveInterval;
jfieldID stableWritableConnectionPingInterval;
jfieldID prioritizeMostLikelyIceCandidatePairs;
jfieldID enableIceRenomination;
jfieldID presumeWritableWhenFullyRelayed;
jfieldID turnPortPrunePolicy;
jfieldID enableDscp;
jfieldID enableCpuAdaptation;
jfieldID suspendBelowMinBitrate;
jfieldID screencastMinBitrate;
jfieldID offerExtmapAllowMixed;
jfieldID enableImplicitRollback;
jfieldID alwaysNegotiateDataChannels;
jfieldID networkPreference;
jfieldID turnLoggingId;
jfieldID cryptoOptions;
};

JavaLocalRef<jobject> toJava(JNIEnv * env, const webrtc::PeerConnectionInterface::RTCConfiguration & config);
Expand Down
54 changes: 54 additions & 0 deletions webrtc-jni/src/main/cpp/include/api/RTCCryptoOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2026 Alex Andres
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef JNI_WEBRTC_API_RTC_CRYPTO_OPTIONS_H_
#define JNI_WEBRTC_API_RTC_CRYPTO_OPTIONS_H_

#include "JavaClass.h"
#include "JavaRef.h"

#include "api/crypto/crypto_options.h"

#include <jni.h>

namespace jni
{
namespace RTCCryptoOptions
{
class JavaRTCCryptoOptionsClass : public JavaClass
{
public:
explicit JavaRTCCryptoOptionsClass(JNIEnv * env);

jclass cls;
jmethodID ctor;
jfieldID enableGcmCryptoSuites;
jfieldID preferGcmCryptoSuites;
jfieldID enableAes128Sha1_32CryptoCipher;
jfieldID enableAes128Sha1_80CryptoCipher;
jfieldID enableEncryptedRtpHeaderExtensions;
jfieldID cryptexPolicy;
};

JavaLocalRef<jobject> toJava(JNIEnv * env, const webrtc::CryptoOptions & options);

// Converts the SRTP options; the SFrame options, which this library
// does not expose, keep their defaults.
webrtc::CryptoOptions toNative(JNIEnv * env, const JavaRef<jobject> & options);
}
}

#endif
11 changes: 10 additions & 1 deletion webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,15 @@ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_PeerConnectionFactory_createPee
auto result = factory->CreatePeerConnectionOrError(configuration, std::move(dependencies));

if (!result.ok()) {
// No peer connection took the observer.
delete observer;

// The type is a string_view, which is not terminated and cannot be
// passed through varargs as it is.
const std::string type(ToString(result.error().type()));

env->Throw(jni::JavaRuntimeException(env, "Create PeerConnection failed: %s %s",
ToString(result.error().type()), result.error().message()));
type.c_str(), result.error().message()));

return nullptr;
}
Expand All @@ -401,6 +408,8 @@ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_PeerConnectionFactory_createPee
return javaPeerConnection.release();
}

delete observer;

return nullptr;
}

Expand Down
8 changes: 8 additions & 0 deletions webrtc-jni/src/main/cpp/src/WebRTCContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "WebRTCContext.h"
#include "api/DataBufferFactory.h"
#include "api/RTCConfiguration.h"
#include "api/RTCStats.h"
#include "Exception.h"
#include "JavaClassLoader.h"
Expand Down Expand Up @@ -85,6 +86,13 @@ namespace jni
JavaEnums::add<webrtc::PeerConnectionInterface::SignalingState>(env, PKG"RTCSignalingState");
JavaEnums::add<webrtc::PeerConnectionInterface::TlsCertPolicy>(env, PKG"TlsCertPolicy");
JavaEnums::add<webrtc::RtpTransceiverDirection>(env, PKG"RTCRtpTransceiverDirection");
JavaEnums::add<webrtc::PeerConnectionInterface::TcpCandidatePolicy>(env, PKG"RTCTcpCandidatePolicy");
JavaEnums::add<webrtc::PeerConnectionInterface::CandidateNetworkPolicy>(env, PKG"RTCCandidateNetworkPolicy");
JavaEnums::add<webrtc::PeerConnectionInterface::ContinualGatheringPolicy>(env, PKG"RTCContinualGatheringPolicy");
JavaEnums::add<webrtc::PortPrunePolicy>(env, PKG"RTCPortPrunePolicy");
JavaEnums::add<webrtc::VpnPreference>(env, PKG"RTCVpnPreference");
JavaEnums::add<jni::RTCConfiguration::AdapterTypeOrdinal>(env, PKG"RTCAdapterType");
JavaEnums::add<webrtc::CryptoOptions::Srtp::CryptexPolicy>(env, PKG"RTCCryptexPolicy");
JavaEnums::add<webrtc::Priority>(env, PKG"RTCPriorityType");
JavaEnums::add<webrtc::DegradationPreference>(env, PKG"RTCDegradationPreference");
JavaEnums::add<webrtc::SdpType>(env, PKG"RTCSdpType");
Expand Down
Loading
Loading