Skip to content

Supporting VoIP with tunnelers

Shawn Carey edited this page Mar 19, 2021 · 6 revisions

This page summarizes the tunneler/tSDK/zSDK features that will be needed to support VoIP

VoIP uses SIP to set up calls between endpoints (e.g. phones). Calls (audio, video, etc) are carried over a different protocol (typically RTP). This page focuses on the details of SIP that are directly relevant for tunneling SIP and related "media" protocols such as RTP.

Sample sequence diagram

Initialization:

  1. tunnelers (phones and SIP server) get IPs from ip-pool service
  2. phones are configured with IP
  3. phones register with SIP server
  • Phones intercept and host RDP, SIP
  • SIP server intercepts and hosts SIP
  • SIP and RTP services are configured with:
    • intercept.v1:
      • "dialOptions": { "identity": "$intercepted_ip" } <-- map intercepted IPs to terminators
      • "sourceIp": "$ip_pool[voip-ips]" <-- map egress IPs to intercepted IPs
    • host.v1:
      • "listenOptions": { "identity": "$ip_pool[voip-ips]" } <-- map terminators to intercepted IPs

SIP - Session Initiation Protocol

REGISTER

Each phone in a VoIP system registers itself with a SIP server. The registration associates the phone's "contact address" (IP address) with the owning user's SIP identity (URI). The contact address defines where the SIP server will deliver future requests (e.g. INVITE) for the SIP identity.

The phone may use one of the following methods to determine the address of the SIP server to register with:

  1. the address can be configured into the phone.
  2. using the host portion of the phone's address-of-record (SIP URI) (see RFC 3263)
  3. multicast to "sip.mcast.net" (224.0.1.75).

The REGISTER message specifies the phone's contact address in a Contact header. The value of the contact header is populated by the phone.

RFC 3665; section 2 shows several REGISTER dialogs.

INVITE

A phone initiates a call by sending an INVITE request to another phone.

Typically the INVITE request is sent to a SIP server which forwards it to the phone(s) that are associated with the recipient if the recipient is in the SIP server's domain. Otherwise, the SIP server determines the SIP server that is responsible for the call recipient and forwards the INVITE there.

The INVITE dialog only sets up a session for a call. The call itself is carried over a different protocol such as RTP. The details of the session are conveyed in the SIP INVITE dialog with Session Description Protocol.

The important point to note here is that the sender of the INVITE (the caller) selects a listen port from a configured range and includes that port in the SDP content of the INVITE request. The callee then dials the caller at that port. The hosting tunneler for the RTP service (on the caller) must dial the same port that the phone is listening on. So the intercepted port from the callee needs to be relayed to the hosting tunneler on the caller, which means we need a new server config type to support "transparent" ports.

The intercepting tunneler would need to know that it should send the intercepted address over to the hosting tunneler... or maybe the intercepted address could always be sent? Regardless, the hosting tunneler needs to know which address/port to dial... This feels very close to "network services", although how would net services work when we nat the dial address?

RFC 3665; section 3 shows several INVITE dialogs.

Tunneling VoIP

SIP Header Field Summary Relevance to Tunnelers
Via Address at which the sender expects to receive responses to this request. A Via is added by every server that has handled the packet (including the originating phone). Note that receiver of the SIP message may add received parameter to the first Via if the address in the Via is a domain name or an IP address that differs from the packet source address. When using UDP for the transport, Via allows the SIP server to send the reply to the sender. Via is also relevant when the transport is TCP and the connection that carried the request is broken. Ziti tunnelers located at all SIP endpoints (phones, servers) must intercept any address that appears in Via fields. Ziti SIP service configurations should specify sourceIp="$tunneler_id.tag[ipaddr]" to ensure that received parameters are correct.
Contact Address at which the sender would like to receive subsequent requests (e.g. INVITE). The value that a phone populates Contact fields with is configurable, but the configuration is phone-specific. For example, see the public_address setting at https://docs.genesys.com/Documentation/SP/Current/dep/Options. Ziti tunnelers on SIP servers must intercept any address that appears in Contact fields. Some phones determine the host portion of their contact address by looking at a network interface on the host. Tunnelers could assign the source IP address they they send in dial requests to the tun interface that they use for intercepting packets. In combination with the $interface_name configuration concept, this would provide a low-touch mechanism for VoIP deployments that are adopting ziti.
Route
Record-Route inserted by proxies in a request to force future requests in the dialog to be routed through the proxy

Current Ziti tunnelers can intercept only a single address (IP:port) for a given service. This model requires a distinct service to be created for each user (phone) that participates in the VoIP network. This would be impractical for even modest numbers of user agents.

A more convenient way to define Ziti services for SIP is to allow CIDR blocks (and/or multiple IPs) in the service "client" configuration. This allows a single service to provide access to every participating user agent in the network. When a connection for a service that specifies multiple IPs is intercepted, the intercepted address is used to select the targeted Ziti endpoint via Ziti dial options.

References:

Example Deployment

Participant/Group Address/CIDR
SIP server 1 10.0.0.1
South America users 10.1.0.0/16
Europe users 10.2.0.0/16
APAC users 10.3.0.0/16
North America users 10.4.0.0/16

Service Definitions

  • SIP

    intercept addresses:
      - 10.0.0.1
      - 10.1.0.0/16
      - 10.2.0.0/16
      - 10.3.0.0/16
      - 10.4.0.0/16
    ports: 5060/udp
    

    All endpoints have dial and bind permission.

  • RTP

    addresses:
      - 10.1.0.0/16
      - 10.2.0.0/16
      - 10.3.0.0/16
      - 10.4.0.0/16
    ports (udp):
      - 7222 - 7422
      - 7622 - 7822
      - 12002 - 12952
    

    Clients have dial and bind permission.

Tunneler Features

  • CIDR Intercept

  • Port Range Intercept

  • Pass intercepted port (address?) to hosting tunneler when intercept configuration includes port range or CIDR.

  • Use Ziti SDK options for identity Dial/Listen

    • ziti-sdk-c does not yet support identity dial/listen
  • Source Address Spoofing ("Transparency")