ice4j Documentation

repository·master·Indexed 19 days ago

https://github.com/jitsi/ice4j

A Java-based implementation of the Interactive Connectivity Establishment (ICE) protocol. ice4j enables Offer/Answer based protocols like SIP and XMPP to traverse NATs using STUN and TURN. It includes features such as socket sharing, a Push API for reduced latency, mapping harvesters for srflx candidates (including AWS detection), and tools for candidate prioritization and connectivity checks.

Tokens
5K
Snippets
17
Records
23
Agent score
67%

What's inside ice4j

  1. Overview of ice4j

    master
    ice4j is a Java implementation of the Interactive Connectivity Establishment (ICE) protocol. It is designed to enable Offer/Answer based protocols (such as SIP and XMPP) to traverse NATs by combining various NAT traversal utilities, including STUN and TURN. The library also provides features like socket sharing.
  2. Configure mapping harvesters for srflx candidates

    master

    Mapping harvesters allow an ICE Agent to obtain srflx (server reflexive) candidates without dynamically querying a STUN server. They work by using pre-configured or dynamically discovered local/public IP address pairs.

    Note: Mapping harvesters preserve the original candidate's port number and should only be used when port numbers are preserved by the network.

    # Pre-configured mapping harvester
    org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=192.168.1.5
    org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=203.0.113.5
    
    # AWS Harvester control
    org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
    org.ice4j.ice.harvest.FORCE_AWS_HARVESTER=false
    
    # STUN server addresses for mapping harvesters
    org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=stun1.example.com:12345,stun2.example.com:23456
  3. Use the standalone Pseudo TCP project

    master
    The pseudo TCP implementation is no longer part of the ice4j repository. If you require pseudo TCP functionality, you must use the dedicated project located at https://github.com/jitsi/jitsi-pseudotcp.
  4. Enable and use the Push API in ice4j

    master

    The Push API allows ice4j to pass received payload packets directly to your application via a callback, bypassing the virtual DatagramSocket queues. This reduces latency and CPU workload by avoiding unnecessary packet copying between threads.

    Setup Steps

    1. Enable the API: Set AbstractUdpListener.USE_PUSH_API to true. This must be done before creating any SinglePortUdpHarvester instances.
    2. Configure Callbacks: For every Component, register a callback for payload packets using setBufferCallback().
    3. Send Data: Use Component.send(byte[] data, int offset, int length) to transmit data instead of using virtual sockets.

    Limitations

    • The Push API is currently only supported when using SinglePortUdpHarvester.
    • If your application uses regular HostCandidates, you must continue reading packets from a DatagramSocket. However, Component.send() remains compatible with both modes.
    // 1. Enable the API before harvester creation
    AbstractUdpListener.USE_PUSH_API = true;
    
    // 2. Configure the callback on a Component
    component.setBufferCallback(new PayloadCallback() {
        @Override
        public void onPayload(Component component, byte[] data, int offset, int length) {
            // Handle received packet
        }
    });
    
    // 3. Send data via the component
    component.send(myData, 0, myData.length);
  5. Configure buffer allocation and padding for the Push API

    master

    When using the Push API, buffers for packets are managed via BufferPool.getBuffer. By default, this allocates new memory on the Java heap, but you can provide a custom implementation.

    Buffer Ownership

    • If your application does not consume the buffer, it is automatically returned to the pool via BufferPool.returnBuffer.
    • If your application does consume the buffer, you are responsible for returning it to the pool.

    Buffer Padding Options

    You can configure specific offsets and trailing space in the buffers to optimize processing (e.g., for RTP). Use the following configuration options:

    • AbstractUdpListener.BYTES_TO_LEAVE_AT_START_OF_PACKET
    • AbstractUdpListener.BYTES_TO_LEAVE_AT_END_OF_PACKET
  6. How component socket merging works

    master

    The useComponentSocket configuration determines whether a per-component merging socket is enabled by default.

    • If enabled: You must use the socket instance provided by Component.getSocket.
    • If disabled: You must use the socket instance from the desired CandidatePair.

    Note that this default behavior can be overridden via the Agent API.

  7. Configure AWS mapping harvester behavior

    master

    Ice4j can automatically detect if it is running in an AWS network and enable the AWS mapping harvester. You can override this behavior using the following properties:

    • org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER: Set to true to explicitly disable the AWS harvester.
    • org.ice4j.ice.harvest.FORCE_AWS_HARVESTER: Set to true to force the use of the AWS harvester even if AWS is not detected.
  8. Configure UDP harvester receive buffer size

    master

    You can set the receive buffer size for the single port UDP harvester (or other AbstractUdpListener implementations) using org.ice4j.ice.harvest.AbstractUdpHarvester.SO_RCVBUF.

    If not specified, the system default is used (e.g., net.core.rmem_default on Linux). If you increase this value, ensure the system maximum (net.core.rmem_max on Linux) is also increased to accommodate the setting.

    org.ice4j.ice.harvest.AbstractUdpHarvester.SO_RCVBUF=1048576
  9. Configure ICE Agent settings

    master

    The AgentConfig class provides access to global configuration parameters for the ICE agent. These settings can be configured using two sets of keys: legacy org.ice4j.* keys and the newer ice4j.* keys. Many duration-based settings expect a Long value representing milliseconds in the configuration source.

    // Access the global configuration instance
    val config = org.ice4j.ice.AgentConfig.config
    
    // Example of accessing a property
    val softwareName = config.software
    val delay = config.terminationDelay
  10. Filter interfaces and IP addresses for candidate allocation

    master

    You can restrict which network interfaces and IP addresses ice4j uses for candidate allocations using semicolon-separated lists. This is useful for controlling network exposure or ensuring only specific networks are used for ICE connectivity.

    # Allow only specific interfaces
    org.ice4j.ice.harvest.ALLOWED_INTERFACES=eth0;wlan0
    
    # Block specific interfaces
    org.ice4j.ice.harvest.BLOCKED_INTERFACES=lo
    
    # Allow only specific IP addresses
    org.ice4j.ice.harvest.ALLOWED_ADDRESSES=192.168.1.10;10.0.0.5
    
    # Block specific IP addresses
    org.ice4j.ice.harvest.BLOCKED_ADDRESSES=172.16.0.1
    
    # Disable IPv6 binding
    org.ice4j.ipv6.DISABLED=true
  11. Reference: AbstractUdpListener Push API configuration keys

    master

    The following configuration keys are used to control buffer behavior when the Push API is enabled in AbstractUdpListener.

    AbstractUdpListener.BYTES_TO_LEAVE_AT_START_OF_PACKET
    AbstractUdpListener.BYTES_TO_LEAVE_AT_END_OF_PACKET
  12. Monitor connectivity check activity with isAlive()

    master

    The isAlive() method provides a debugging mechanism to check if the ConnectivityCheckServer has received any STUN request.

    Warning: This is strictly for debugging. A true value does not mean ICE negotiation succeeded; it only indicates that the server received a STUN request, even if it was malformed or contained incorrect credentials (e.g., wrong username or ufrag).

    boolean isAlive()