152
Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved. Eyeball AnyFirewall Engine v10.0 Developer Guide

AnyFirewall Engine v10.0 Developer Guide

Embed Size (px)

Citation preview

Page 1: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Eyeball AnyFirewall Engine v10.0

Developer Guide

Page 2: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

1. AFE Introduction

Introduction

The Eyeball AnyFirewall™ Engine (AFE) is a software library that enables seamless traversal of NATs, firewalls and web proxies for VoIP and other communications applications and devices. It offers the following features: Figure 1 shows the internals of Eyeball AnyFirewall Engine (AFE), and how it can be used in different applications.

Page 3: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 1: Internals of AnyFirewall Engine, and 3 applications using it.

AFE works best with Eyeball AnyFirewall Server – a carrier-grade STUN and TURN server. Figure 2 illustrates two applications using Eyeball AnyFirewall Server to establish communications between them. The main purpose of Eyeball AnyFirewall Server is to help AFE in NAT/firewall discovery, and if required, relaying of signaling/media data. Although AFE works with any STUN-TURN server for standard STUN/TURN features, it is dependent on Eyeball AnyFirewall Server for traversing web-proxies using http-tunneling (due to lack of standardization for http-tunneling).

Page 4: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 2: Eyeball AnyFirewall Engine works best with Eyeball AnyFirewall Server. The server helps AFE in NAT/firewall detection and data relaying.

This document describes functionality and usage of Eyeball AnyFirewall Engine for the supported OS platforms.

Page 5: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

2. AFE v10.0 Revision Summary

AnyFirewall™ Engine v10.0 with dual-stack and IPv6 support, latest IETF extension for ICE-STUN-TURN, complete inter-operability with Microsoft Lync-2013.

Revision Summary

AFE v10 Enhanced with:

Lync 2013, including:

o MS-ICE2 v4.0, v4.01 o MS-ICE2BWM v2.0, v2.01 o MS-TURN v4.0, v4.1 o MS-TURNBWM v2.0, v2.01 o MS-SDPEXT v4.0, v5.0, v5.1 o Bandwidth management / SVC calls o Dual Stack (IPv6/IPv4) Lync 2013 ICE functionality for UDP and TCP candidates o Ability to disable exceptions in stack

IETF Standard, including:

o TURN extension for IPv6, RFC-6156 o ICE extension for IPv6, RFC-5245 o STUN extension for IPv6, RFC-5389 o TURN-TCP extension for IPv6, RFC-6062 o ICE-TCP extension for IPv6, RFC-6544

API Changes:

o How to deal with IPv6 candidate in SDP. o ProcessReceivedData

Page 7: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for Android

Android

System Requirements

Development environment:

C/C++ development environment such as Eclipse (Helios)

Android OS 3 and API level 8 are recommended

Package

The AnyFirewall™ Engine for Android is shipped in a package with the following components:

Source library:

AFE as a shared object: libAFE.so

File to link applications using C interface APIs:

libafec.a

Header files required to develop applications based on AFE:

AnyFirewallEngine_dll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

AnyFirewallEngine.h (C interface to AFE APIs)

Other supporting files:

Page 8: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

A sample SIP application based on the AnyFirewall™ Engine

This AFE Developer's Guide

The sample application is available in source code, which demonstrates how to write applications based on AnyFirewall™ Engine. The source code is ready to be compiled using Eclipse (Helios) with Android OS 3, API level 8.

Page 9: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for iOS

iOS

System Requirements

Development environment:

C/C++ development environment such as gcc (version 4.2.1 (LLVM build 2336.1.00), xcode 4.2, iOS SDK 5.0)

Package

The AnyFirewall™ Engine for iOS is shipped in a package with the following components:

Source library:

AFE as a static library

Header files required to develop applications based on AFE:

AnyFirewallEngine.h

AnyFirewallDll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

Page 10: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AnyFirewallEngine.h (C interface to AFE APIs)

Other supporting files:

A sample SIP application based on the AnyFirewall™ Engine

This documentation

The sample application is available in source code, which demonstrates how to write applications based on AnyFirewall™ Engine. The source code is ready to be compiled using gnu gcc/g++ (version 4.2.1 (LLVM build 2336.1.00), xcode 4.2, iOS SDK 5.0).

Page 11: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for Linux

Linux

System Requirements

Development environment:

C/C++ development environment such as gcc (version 4.1.2)

Package

The AnyFirewall™ Engine for Linux is shipped in a package with the following components:

Source library:

AFE as a shared object: libAFE.so

File to link applications using C interface APIs:

libafec.a

Header files required to develop applications based on AFE:

AnyFirewallEngine_dll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

AnyFirewallEngine.h (C interface to AFE APIs)

Other supporting files:

A sample SIP application based on the AnyFirewall™ Engine and a demo version of the Eyeball Audio Engine

Page 12: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

This AFE Developer's Guide

The sample application is available in source code, which demonstrates how to write applications based on AnyFirewall™ Engine. The source code is ready to be compiled using gnu gcc/g++.

Page 13: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for Mac OS X

Mac OS X

System Requirements

Development environment:

C/C++ development environment such as gcc (version 4.2.1 (LLVM build 2336.1.00))

Package

The AnyFirewall™ Engine for Mac OS X is shipped in a package with the following components:

Source library:

AFE as a dynamic library: libAFE.dylib

File to link applications using C interface APIs:

libafec.a

Header files required to develop applications based on AFE:

AnyFirewallEngine_dll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

AnyFirewallEngine.h (C interface to AFE APIs)

Other supporting files:

Page 14: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

A sample SIP application based on the AnyFirewall™ Engine and a demo version of the Eyeball Audio Engine

This AFE Developer's Guide

The sample application is available in source code, which demonstrates how to write applications based on AnyFirewall™ Engine. The source code is ready to be compiled using gnu gcc/g++.

Page 15: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for Microsoft Windows

Microsoft Windows

System Requirements

Development environment:

C/C++ development environment such as Microsoft Visual Studio

Package

The AnyFirewall™ Engine for Windows is shipped in a package with the following components:

Source library:

AFE as a dynamic link library: AnyFirewall.dll

File to link applications using C interface APIs:

AnyFirewallEngineCInterfaceToDll.lib

Header files required to develop applications based on AFE:

AnyFirewallEngine_dll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

AnyFirewallEngine.h (C interface to AFE APIs)

Other supporting files:

Page 16: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

A sample SIP application based on the AnyFirewall™ Engine and a demo version of the Eyeball Audio Engine

This AFE Developer's Guide

The sample application is available in source code, which demonstrates how to write applications based on AnyFirewall™ Engine. The source code is ready to be compiled using Visual Studio 2010.

Page 17: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AFE for VxWorks

VxWorks

System Requirements

Development environment:

C/C++ development environment such as Wind River Workbench Development Suite 3.3

Wind River Core Runtime version 6.9 is also required

Package

The AnyFirewall™ Engine for VxWorks is shipped in a package with the following components:

Source library:

AFE as a shared object: libAFE.so

File to link applications using C interface APIs:

libafec.a

Header files required to develop applications based on AFE:

AnyFirewallEngine_dll.h

AnyFirewallInterface.h (C++ interface to AFE APIs)

AnyFirewallEngine.h (C interface to AFE APIs)

Page 18: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Other supporting files:

A sample SIP application based on the AnyFirewall™ Engine

This AFE Developer's Guide

Page 19: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

4. AFE Channels: Programming with the AnyFirewall™ Engine

\

The Eyeball AnyFirewall™ Engine uses the concept of channels to simplify programming. Each channel is accessed via a set of functions similar to the socket API. Like sockets, each channel represents an endpoint for sending and receiving data. However, channels hide the underlying complexity required for the firewall traversal process, e.g. STUN, TURN, and ICE functionality. In order to add the AFE functionality to an existing application, the AFE replaces sockets with channels, and calls to the socket API are replaced with the similar calls to the AFE API.

AFE also provides access to sockets through its API.

For example, in order to receive RTP voice data using AFE, an application calls the AFE API function Recv() instead of the socket API function recv(). In order to send data, the application calls the AFE API function Send() instead of the socket API function send(). Furthermore, the AFE provides an API function Select() for channels. This function models the behavior of the socket API function select().

Figure 3: Integration of AnyFirewall Engine into an existing product.

Page 20: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5. AFE Code Examples for Windows, Linux, Mac, iOS and Android

Code Examples for Windows, Linux, Mac, iOS and Android

This section explains the relevant steps for writing a SIP-based voice application in C++ using the AnyFirewall™ Engine for Windows, Linux, Mac, iOS and Android. The necessary function calls to initialize the AnyFirewall™ Engine, to register with a SIP proxy and to send and receive media from another application are outlined.

Page 21: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.1. AFE: Initialization

Initialization

You must initialize the AnyFirewall™ Engine before any data can be sent or received. The initialization includes setting the Eyeball AnyFirewall™ Server address and credentials required to allocate any resources on the AnyFirewall™ Server. The AnyFirewall™ Server comprises two servers: STUN and TURN, which are specified separately.

AFEngine Object Instantiation

// For Windows, Linux, Mac, iOS

m_pAFEngine = new CAnyFirewallEngine;

// For Android

m_pAFEngine = new AnyFirewallEngine;

Library Instantiation

// For Windows

m_bAFEngineInit = m_pAFEngine->InitDll(AfxGetInstanceHandle(),

AF_MODE_AUTO, true);

// For Linux, Mac, iOS, Android

m_bAFEngineInit = m_pAFEngine->Init();

// Create a store to keep server settings

serverStoreID = m_pAFEngine->CreateServerStore(AF_MODE_MSOCS, true);

To use AFE in Microsoft Lync mode, use AF_MODE_ MSOCS in place of AF_MODE_ AUTO.

Page 22: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Initiate STUN and TURN ports

// Create strings describing the AnyFirewall™ Server’s addresses and ports for STUN

and TURN

string sStunHosts = m_pAFEngine->CreateHost(

AF_HOST_PUBLIC,

“70.38.102.237”,

3478,

AF_PROTOCOL_UDP,

NULL

);

sStunHosts += m_pAFEngine->CreateHost(

AF_HOST_PUBLIC,

“70.38.102.237”,

3478,

AF_PROTOCOL_TCP,

NULL

);

string sTurnHosts = m_pAFEngine->CreateHost(

AF_HOST_PUBLIC,

“70.38.102.237”,

3478,

AF_PROTOCOL_UDP,

NULL

);

sTurnHosts += m_pAFEngine->CreateHost(

AF_HOST_PUBLIC,

“70.38.102.238”,

443,

AF_PROTOCOL_TCP,

NULL

);

// Specify the AnyFirewall Server and the authentication information

m_pAFEngine->SetSTUNServer(serverStoreID, sStunHosts);

m_pAFEngine->SetTURNServer(serverStoreID, sTurnHosts);

m_pAFEngine->SetTURNUsernamePassword(serverStoreID , sTURNUsername, sTURNPassword);

The method CreateHost creates a description of the host the AnyFirewall™ Server is running on. When connecting to a server with a public IP address (“ 70.38.102.237” in this example), the first parameter should be set to AF_HOST_PUBLIC. The fourth parameter specifies AF_PROTOCOL_UDP or AF_PROTOCOL_TCP.

Note that the servers may also be specified using DNS SRV records.

Page 23: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

// Specify the STUN server using DNS SRV records.

m_pAFEngine->SetSTUNServer(serverStoreID, “dns-srv _stun._tls.eyeball.com 0 tls”);

The function SetSTUNServer sets the STUN server for binding requests. The function SetTURNServer sets the TURN server for relaying data.

In the above example, the last parameter of CreateHost function is specified as NULL. This means that AFE will use default STUN timing parameters for connecting to the specified servers. These parameters can be customized with struct AfConnectionParams. For more details, please see the reference for CreateHost function.

After the servers are set, DetectConnectivity should be called. The parameter to this function can be used to specify which checks should be performed during this phase.

struct AfFirewallDetectionParams fdp;

fdp.iDetectUdpConnectivity = 1;

fdp.iDetectTcpConnectivity = 1;

fdp.iDetectProxyConnectivity = 1;

fdp.iDetectUPnPConnectivity = 1;

fdp.iCheckTurnCredentials = 1;

fdp.iUPnPDeviceDiscoveryTimeout = 3000;

m_pAFEngine->DetectConnectivity(serverStoreID, &fdp);

Page 24: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.2. AFE: SIP Proxy Connection and Registration

SIP Proxy Connection and Registration

The AnyFirewall™ Engine can be used to establish a connection to a SIP proxy, i.e., to register with a SIP proxy using UDP, TCP, or TLS as transport protocols. For this purpose, the AnyFirewall™ Engine determines the available connection options to the SIP proxy, e.g., whether UDP can be used to connect to the SIP proxy or whether an HTTP tunnel must be setup.

Before connecting to the SIP proxy to send or receive SIP messages, it is necessary to create a channel. Channels represent communication endpoints and behave similar to sockets for an application developer. Once the channel is created, it is necessary to call Connect. Connecting a channel means setting up the internal data structures, detecting the public IP address and port and allocating ports on the AnyFirewall™ Server.

You must detect the public port in order to populate the SIP REGISTER message with the correct Contact field parameters.

The following code snippet contains the necessary function calls to create a channel and REGISTER with a SIP proxy. The sample code creates a channel for the communication with the SIP proxy and connects to the SIP proxy and exchanges SIP messages with the SIP proxy.

m_iSipChannel = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_UDP, 0, 0, 0);

if (m_iSipChannel < 0)

{

Page 25: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

// Handle errors here

}

m_bSipTransportUdp = true;

// Connect to the SIP proxy

// This function determines the best possible connection method:

// direct UDP if the firewall does not block UDP traffic,

// TCP or HTTP tunneling will be used otherwise.

if (!m_pAFEngine->Connect(m_iSipChannel, m_pAFEngine->CreateHost(

AF_HOST_PUBLIC,

sSipProxyAddress,

iSipProxyPort,

AF_PROTOCOL_UDP,

NULL)

))

{

// Handle errors here

m_pAFEngine->Close(m_iSipChannel);

}

// Retrieve the description that will be used in communicating with the

// server. This information is placed in the Contact field of the

// REGISTER message.

string sRegIPPort = m_pAFEngine->GetLocalAddress(m_iSipChannel);

if (m_sMyRaddr.empty())

{

m_sMyRaddr = m_pAFEngine->GetHostAddress(sRegIPPort);

}

if (m_iMyRport <= 0)

{

m_iMyRport = m_pAFEngine->GetHostPort(sRegIPPort);

}

// Create the SIP REGISTER message using the parameters obtained from

// calling the AFE API GetLocalAddress()

string sRegMsg = m_pSipUtil->BuildRegisterRequest(m_sUsername,

m_sMyRaddr,

m_iMyRport,

m_sSipProxyDomain,

m_iTransportType

);

// Send the SIP REGISTER message

if (m_pAFEngine->Send(m_iSipChannel, sRegMsg.c_str(),

(int)sRegMsg.length(),

AF_NON_BLOCKING) < 0

)

{

// Handle the errors

}

iRet = m_pAFEngine->Recv(m_iSipChannel,

Page 26: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

sSIPRegisterResponse,

SIPRegisterResponseLength,

1000

);

The channel used to connect to the SIP proxy is created using the method Create. This function creates a channel of type AF_CHANNEL_UDP. This channel type is used when connecting to servers or clients that support UDP.

The host description, generated by CreateHost in this case, defines that the SIP proxy should be contacted using UDP (AF_PROTOCOL_UDP). The other protocols that can be used in this context are TCP (AF_PROTOCOL_TCP) or TLS/SSL (AF_PROTOCOL_TLS).

The method Connect initiates the connection to the SIP proxy. The method determines whether the SIP proxy can be directly accessed. If this is not possible, it will try to relay SIP message through the AnyFirewall™ Server instead of attempting a direct connection (this behavior can be changed using channel option EAfOptionRelayFallbackTimeout). In many cases, SIP proxies only support UDP. In these situations, it is impossible to create a direct connection from a client in a UDP-blocked environment. Examples are corporate networks where only an HTTP proxy can be used to connect to the public Internet. In order to overcome this problem, the AnyFirewall™ Engine allocates a UDP port on the AnyFirewall™ Server and relays the SIP messages through the AnyFirewall™ Server. The AnyFirewall™ Server then translates the SIP messages received from the AnyFirewall™ Engine from TCP to UDP and forwards them to the SIP proxy using UDP. In the same way, messages received from the SIP proxy will be translated from UDP to TCP and forwarded to the AnyFirewall™ Engine.

Page 27: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.3. AFE: Making a Call

Making a Call

Overview

Making a call starts with sending a SIP INVITE message with an SDP describing on which IP address(es) and port(s) the application expects to receive audio or video packets. The format of these candidates is specified for example by the MMUSIC working group of the IETF [3]. When using the AnyFirewall™ Engine, these candidate fields are populated with parameters obtained from the AnyFirewall™ Engine. These strings can be used to populate the candidate fields in the SDP part of a SIP INVITE message.

In this section, we show how to create audio channels for sending and receiving voice packets, obtaining the candidates for the SDP and sending the SIP INVITE message. Finally, the call completion with the callee is described.

Creating an audio channel

m_iAudioChannelRTP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTP, 0, 0, 0);

m_iAudioChannelRTCP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTCP, 0, 0, 0);

If client wants ICE over TCP along with UDP then the call should be,

m_iAudioChannelRTP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTP, 0, 0, -1);

m_iAudioChannelRTCP= m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTCP, 0, 0, -1);

Page 28: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The audio channels are created using the parameter AF_CHANNEL_RTP and AF_CHANNEL_RTCP, which are a specialized version of AF_CHANNEL_UDP. This describes a channel for sending and receiving RTP/RTCP packets.

Other potential types used for different purposes are AF_CHANNEL_UDP, AF_CHANNEL_LOOPBACK, AF_CHANNEL_TCP, AF_CHANNEL_DATA, AF_CHANNEL_TLS and AF_CHANNEL_BFCP. TCP and TLS channels are only used for client/server connections, e.g. in order to establish a TCP connection to a SIP proxy.

Obtaining candidate parameters of the audio channels

char sMediaStreamSpec[100];

sprintf(sMediaStreamSpec, "%s %d %d",

AF_MEDIA_STREAM_AUDIO,

m_iAudioChannelRTP,

m_iAudioChannelRTCP

);

m_iSession = m_pAFEngine->CreateSession(serverStoreID, sMediaStreamSpec, NULL);

const struct AfSessionInfo *sessionInfo = m_pAFEngine->MakeOffer(m_iSession);

Here, the method CreateSession creates a session with one media stream AF_MEDIA_STREAM_AUDIO and two audio channels in that media stream. The function returns a unique session ID that is used to call the MakeOffer API that initializes all the channels (e.g., detects public IP address and port) belonging to that session, and returns a SDP structure describing the possible IP addresses, ports and protocols that can be used to connect to the client application. This information must be transmitted to the callee.

How to deal with IPv6 candidate in SDP

AfMedia structure and AfSessionInfo structure holds the address family information of local and remote peer to let client create SDP properly.

There is a new member named as isIPv6Candidate under AfMedia structure, which holds the address family information of pcCandidate[index] local candidate.

There is a new member named as isRemotePeerSupportsIPv6 under AfSessionInfo structure, which holds the address family information of remote peer, whether remote peer supports IPv6 address or not. Remote Information will be retrieved when client receives SDP from remote peer.

Page 29: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

If isIPv6Candidate[index] value is 0, pcCandidate[index] candidate is IPv4 address.

If isIPv6Candidate[index] value is 1, pcCandidate[index] candidate is IPv6 address.

If isRemotePeerSupportsIPv6 value is 0, peer supports only IPv4 address family.

If isRemotePeerSupportsIPv6 value is 1, peer supports dual-stack or IPv6 address family.

Sending a SIP Invite

In order to initiate a call, the same channel as created for the registration is used to send the SIP INVITE message.

The SDP structure returned by MakeOffer can be used to construct the SDP string of a SIP message.

// CreateSIPINVITE must be implemented somewhere

std::string sAudioSDPInfo = CreateSdpFromStruct(sessionInfo);

string sInviteMsg = m_pSipUtil->BuildInviteRequestMsg(

m_sUsername,

sRemoteUser,

m_sMyRaddr,

m_iMyRport,

sAudioSDPInfo,

m_sSipProxyDomain,

sCalleeAddress,

sCallID,

false,

m_sBranchTag,

m_sFromTag,

"",

m_iTransportType

);

if (m_pAFEngine->Send(m_iSIPChannel, sInviteMsg.c_str(),

(int)sInviteMsg.length(),

AF_BLOCKING) < 0

)

{

// Handle errors here

}

In this particular example, the method Send blocks ( AF_BLOCKING) until the message could be inserted into the internal buffers used by the AnyFirewall™ Engine. Instead of defining AF_BLOCKING, it is also possible to set a timeout (in milliseconds) or use AF_NON_BLOCKING.

Responding to a SIP INVITE Message

Page 30: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The callee essentially follows the same steps as the caller. Upon receiving a SIP INVITE, the callee creates the channels and the session that will be used for communicating with the caller. Then the callee uses MakeAnswer() API to process the SDP received from its remote peer. Moreover, the function returns an SDP description for the callee that can be used in 200 OK responses. The call to this function also starts ICE checks [3]. m_iAudioChannelRTP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTP, 0, 0, 0);

m_iAudioChannelRTCP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTCP, 0, 0, 0);

For ICE over TCP along with UDP use:

m_iAudioChannelRTP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTP, 0, 0, -1);

m_iAudioChannelRTCP = m_pAFEngine->Create(serverStoreID, AF_CHANNEL_RTCP, 0, 0, -1);

char sMediaStreamSpec[100];

sprintf(sMediaStreamSpec, "%s %d %d",

AF_MEDIA_STREAM_AUDIO,

m_iAudioChannelRTP,

m_iAudioChannelRTCP

);

m_iSession = m_pAFEngine-> CreateSession (serverStoreID, sMediaStreamSpec,NULL);

const struct AfSessionInfo *sessionInfo = m_pAFEngine->MakeAnswer(m_iSession,

sRemoteSDP, sPeerID);

std::string sAudioSDPInfo = CreateSdpFromStruct(sessionInfo);

How to deal with insufficient bandwidth

In Microsoft® Lync™ mode, Callee side is the bandwidth management agent. For a particular offer from caller, bandwidth availability is checked in the first call to AFE's MakeAnswer() or MakeAnswerAsync() API function. This function returns a structure - AfSessionInfo.

Before constructing answerSDP, AFE client must check AfSessionInfo's data member bandwidthAvailable:

If value is 0, bandwidth is not available for any of the media included in the session. AFE client must close the session and cancel the call.

If value is 1, bandwidth is available for at least one of the media included in the session. AFE client should proceed in this case. The AFE client iterates through each of the media in the media list ppMedia of AfSessionInfo structure. Each media is represented by AfMedia structure. Bandwidth availability for each media can be checked by bandwidthAvailable data member

Page 31: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

of AfMedia structure. AFE client must iterate through each AfMedia and check the value of bandwidthAvailable:

o If value is 0, bandwidth is unavailable for this media. Client adds m line with port 0 to the SDP. The client then adds a diagnostic message indicating insufficient bandwidth. Client does not need to close the channels associated with this media because AFE handles this issue.

o If value is 1, bandwidth is available for this media. AFE client adds necessary attributes to the SDP for this media.

Establishing an Audio Call with a Callee

Once the caller receives 200 OK, it uses ProcessAnswer API to process the remote SDP and start ICE checks [3]. …

m_pAFEngine->ProcessAnswer(m_iSession, sSDP, successAnswerReceived, sPeerID);

Page 32: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.4. AFE: Receiving Media

Receiving Media

The following code example shows how to receive audio packets from a channel.

The method Select is used to wait for network events. This method works in the same way as the function select known from the socket API, but works with channels instead of socket descriptors.

while (m_dwAudioThreadID != 0)

{

// Set events of interest for an audio channel that was created earlier:

aChannels[0] = m_iControlChannel;

aChannels[1] = m_iAudioChannelRTP;

aChannels[2] = m_iAudioChannelRTCP;

aChannels[3] = m_iSession;

aInputEvents[0] = AF_SELECT_READ;

aInputEvents[1] = AF_SELECT_READ;

aInputEvents[2] = AF_SELECT_READ;

aInputEvents[3] = AF_SELECT_READ;

aOutputEvents[0] = AF_SELECT_NOEVENT;

aOutputEvents[1] = AF_SELECT_NOEVENT;

aOutputEvents[2] = AF_SELECT_NOEVENT;

aOutputEvents[3] = AF_SELECT_NOEVENT;

int iRet = m_pAFEngine->Select(4,

aChannels,

aInputEvents,

Page 33: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

aOutputEvents,

AF_TIMEOUT_INFINITE

);

if (iRet <= 0)

{

continue;

}

//Handle audio channel

if (aOutputEvents[1])

{

if (aOutputEvents[1] & AF_SELECT_READ)

{

int iRet = m_pAFEngine->Recv(m_iAudioChannelRTP,

pBuff, 2048, AF_NON_BLOCKING);

if (iRet > 0)

{

m_pAudio->HandleAudioPacket(pBuff, iRet);

}

}

if (aOutputEvents[1] & AF_SELECT_ERROR)

{

if (m_iAudioChannelRTP >= 0)

{

EndCall();

HangUp();

}

}

}// end handle audio channel

//Handle control channel

if (aOutputEvents[0])

{

if (aOutputEvents[0] & AF_SELECT_READ)

{

char dummy;

m_pAFEngine->Recv(m_iControlChannel, &dummy, 1,

AF_NON_BLOCKING);

}

if (aOutputEvents[0] & AF_SELECT_ERROR)

{

//handle error

}

}

// Handle Session event

if (aOutputEvents[3])

{

if (aOutputEvents[3] & AF_SELECT_READ)

{

unsignedlong ulEvent;

int iRet = m_pAFEngine->Recv(m_iSession,

(char*)&ulEvent,

Page 34: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

4,

AF_NON_BLOCKING

);

if (iRet > 0)

{

switch (ulEvent)

{

case EAfEventICECheckCompleted:

//Ring after the Ice Checks complete

if (!m_bCaller)

{

m_pAudio->PlayWavFile(sWavFile);

}

break;

case EAfEventICENeedUpdatedOffer:

SendReinvite();

break;

default:

break;

} //switch

} //if iRet

}

if (aOutputEvents[3] & AF_SELECT_ERROR)

{

//handle error

}

}// end handle session level event channel

} // end while

The above example assumes a separate audio engine (object m_pAudio) is used to process the packets received via the AnyFirewall™ Engine. The method Select uses an infinite timeout (AF_TIMEOUT_INFINITE). The predefined value AF_SELECT_READ is used to determine which event is of interest to the application. In addition, it is possible that the Select call returns an event of type AF_SELECT_ERROR. In the Select call, we include two additional channels along with the audio channels. One is the control channel (AF_CHANNEL_LOOPBACK), which can be used for resuming the execution blocked by the Select call, and the other is the session level event channel, used for receiving session related events fired from the AFE. Channel types are discussed in 6.1. Channels.

As an alternative to using Select, it is possible to provide a callback function that is called by AnyFirewall Engine whenever data is available for reading on a channel. The callback is provided by implementing an abstract base class IAfCallbackHandler, which defines the actual callback function HandleCallback. The callback class is set using the API function SetCallbackHandler.

Page 35: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Do not mix Select and Callback functions.

The following code snippet shows an actual implementation of the callback and how to register the callback with a channel in AnyFirewall Engine.

// callback class

class CAudioReceiver : IAfCallbackHandler

{

public:

virtual void _cdecl HandleCallback(int iChannel, char *pData,

int iLen,

const

CAfStdString& sSrcAddress,

int

iSrcPort,

const void

*pContext

);

}

// the actual callback implementation

void CAudioReceiver::HandleCallback(int iChannel, char *pData,

int iLen,

const

CAfStdString& sSrcAddress,

int

iSrcPort,

const void

*pContext))

{

// received an audio packet on channel iChannel

m_pAudio->HandleAudioPacket(pData, iLen);

}

// registering the callback with AnyFirewall Engine for an audio channel

CAudioReceiver *pAudioReceiver = new CAudioReceiver;

pAFEngine->SetCallbackHandler(m_iAudioChannelRTP, pAudioReceiver);

For more details, please refer to 7.3. Channel Management and Data Transfer.

Page 36: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.5. AFE: Sending Media

Sending Media

In order to receive and then send captured audio data from the audio engine, the instance of CNetworkHandler in the audio engine must be set to:

m_pAudio->SetNetworkController(networkHandler);

CNetworkController instance has to implement a pure virtual function from the abstract class IAudioSampleHandler:

virtual void HandleAudioSamples(char *pData, int iLen) = 0;

The implementation is shown below: void CNetworkController::HandleAudioSamples(char *pData, int iLen)

{

m_pAFEngine->Send(m_iAudioChannelRTP,

pData, iLen,

AF_NON_BLOCKING);

}

Page 37: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.6. AFE: Sending Re-INVITE with updated m/c line

Sending Re-INVITE with updated m/c line

After the ICE check is completed, the address and ports for both source and destination for the media are decided. The chosen addresses and ports may differ from the address and port in the m/c line of the SDP. ICE requires that a re-INVITE be sent with the m/c lines for each channel updated to the chosen addresses and ports.

If a mismatch exists in the addresses and ports for both the source and destination for the media chosen, the AnyFirewall™ Engine will fire an EAfEventICENeedUpdatedOffer event. The application should call MakeOffer again for the session to obtain the SDP with the updated m/c lines.

struct AfEvent stAfEvent;

int iRet = m_pAFEngine->Recv(m_iEventChannel, (char *)&stAfEvent,

8,

AF_NON_BLOCKING

);

if (iRet > 0)

{

switch (stAfEvent.uEvent)

{

//Obtain the SDP with the updated m/c line for the session

case EAfEventICENeedUpdatedOffer:

SendReinvite();

break;

}

}

void SendReinvite()

Page 38: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

{

//Obtain the SDP with the updated m/c line for the session

AfSessionInfo *sessionInfo = m_pAFEngine->MakeOffer(m_iSession);

std::string sUpdatedSDPInfo = CreateSdpFromStruct(sessionInfo);

}

Page 39: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.7. AFE: Closing Channels and De-initialization

Closing Channels and De-initialization

Channels should be closed when they are no longer required.

This method is shown in the line of code below: …

m_pAFEngine->Close(iChannel);

Closing a channel releases any resources that were allocated internally on the AnyFirewall™ Server.

Then the server store which keeps server settings for the corresponding server store id should be closed. All the sessions and channels using that store will implicitly be closed. This includes any independent channel that is not associated with a session.

m_pAFEngine->CloseServerStore(serverStoreID);

The following call releases all the resources allocated by the AnyFirewall™ Engine after the application is closed:

m_pAFEngine->Release();

Page 40: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.8. AFE: Using Host Descriptions

Using Host Descriptions

Host descriptions are required by Connect.

This section describes how to create a host description in order to connect to a server.

Host descriptions have the following formats:

“<host-type><IP address><port><protocol>”

“<host-type><IP address><port> udp <RTO><Rc><Rm>”

“<host-type><IP address><port> tcp <Ti>”

The different parts of a host description can be set using the AnyFirewall™ Engine API functions CreateHost, SetHostType, SetHostAddress, SetHostPort, SetHostProtocol. Similar functions are available to retrieve the information. For more details, please refer to section 7. C++ Function Reference.

Host descriptions are required when using Connect to connect to a server with a public IP address, e.g. a SIP proxy. In this case, CreateHost is used to create a host description of the server (see section 7. C++ Function Reference). The host description list contains only a single host description of type public (AF_HOST_PUBLIC) and the IP address, port and transport protocol of the server. It is also possible to use DNS SRV lookups to identify a suitable server to connect. In this case, the host type AF_HOST_DNS_SRV is used instead of AF_HOST_PUBLIC.

string sTarget = "_stun._udp." + sDomain;

string sDnsSrv = m_pAFEngine->CreateHost(AF_HOST_DNS_SRV,

sTarget,

0,

AF_PROTOCOL_UDP,

NULL

);

m_pAFEngine->SetSTUNServer(serverStoreID, sDnsSrv);

Page 41: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

In this case, the host description is passed to API functions defining a server to use, such as SetSTUNServer. Host descriptions can be concatenated (separated with a semicolon), which is required in case a server supports several transport protocols. For example, in order to enable TCP and UDP relaying, two host descriptions are concatenated to describe the UDP and TCP interfaces of a TURN server.

Page 42: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

5.9. AFE: Flow Diagram

Flow Diagram

The following diagram shows the sequence of relevant API calls for both caller and callee when making a call.

Page 43: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The following function ModifySession can be used to add a stream to, or remove a stream from an ongoing session. The following diagram illustrates the flow for this.

Page 44: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Page 45: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6. AFE Types and Definitions

Types and Definitions

This section lists the predefined types and enumeration values that can be used by application developers when accessing the AnyFirewall™ Engine.

6.1. AFE: Channels

6.2. AFE: EVENT Order List

6.3. AFE: Host Types

6.4. AFE: Protocols

6.5. AFE: Timeouts

6.6. AFE: Channel Options

Page 46: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.1. AFE: Channels

Channels

Channel types define the transport protocol used. They are specified when creating a channel (see section 5.2. SIP Proxy Connection and Registration).

The different channel types are outlined in the following table. The types are defined in the AnyFirewall™ Engine header file.

Type Definition Description

AF_CHANNEL_UDP

A UDP channel. This means the preferred transport protocol is UDP. In cases where UDP is blocked, the AnyFirewall™ Engine will fall back to TCP or HTTP tunneling, and the AnyFirewall™ Server will carry out the protocol mapping from TCP to UDP. In any case, the transport protocol used to communicate with the remote party will be UDP.

AF_CHANNEL_RTP

Specialized channel for sending and receiving RTP packets. In Microsoft® Lync™ mode, regular or TCP-Only mode can be set through the channel option EAfOptionTcpRegularMode.

AF_CHANNEL_RTCP

Specialized channel for sending and receiving RTCP packets.

In Microsoft® Lync™ mode, regular or TCP-Only mode can be set through the channel option EAfOptionTcpRegularMode.

AF_CHANNEL_TCP TCP channel. UDP will not be used by this channel. This channel can only be used to connect to a server, e.g., a SIP proxy.

Page 47: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AF_CHANNEL_DATA

Only TCP candidates are gathered for this type of channel. UDP will not be used by this channel. This channel can be used when only TCP candidates are needed, e.g., for BFCP channel. This type of channel is only supported in Microsoft® Lync™ mode( AF_MODE_MSOCS).

AF_CHANNEL_TLS

Specialized TCP channel used to connect to servers with SSL support. Any SSL version supported by the server will be used when establishing the connection. This channel can, for example, be used to initiate a connection to a SIP proxy using TLS.

AF_CHANNEL_LOOPBACK

The purpose of this special channel is to have a mechanism to interrupt Select (see section 7.3 Channel Management and Data Transfer) calls. Sending data to a channel of this type causes AF_SELECT_READ to be signaled, interrupting a call to Select.

AF_CHANNEL_EVENT

Applications can create this type of channel to receive event messages from the AnyFirewall™ Engine. For example, once the firewall detection is completed, the AnyFirewall™ Engine fires an EAfEventFirewallTypeDetected event to the application. Currently, the application can create only one event channel at a time.

AF_CHANNEL_DNS Applications can create this type of channel to perform DNS lookups. You can cancel a blocked DNS lookup that takes too much time.

The channel type is supplied as parameter when creating channels using Create. The channel type defines the preferred transport protocol and connection used with a channel. The actual transport protocol used with the channel depends on the environment the AnyFirewall™ Engine is implemented in. In some cases, a protocol translation may be necessary. This protocol translation is carried out on the AnyFirewall™ Server, which is able to map incoming data on a TCP connection to UDP packets and vice-versa.

For example, in a voice application, channel type AF_CHANNEL_RTP would be used for audio channels. The channel type AF_CHANNEL_UDP, AF_CHANNEL_TCP or AF_CHANNEL_TLS may be used to establish a connection to the SIP proxy, depending on whether the SIP proxy supports UDP, TCP, or TLS.

Microsoft® Lync™ mode

In Microsoft® Lync™ mode(AF_MODE_MSOCS), TCP-only mode is enabled by default; RTP and RTCP channels have only TCP candidates. In order to includeboth UDP and TCP candidates, enable TCP regular mode by setting EAfOptionTcpRegularMode.

Example:

Page 48: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

m_pAFEngine->SetChannelOption(m_iAudioChannelRTP, EAfOptionTcpRegularMode,

AF_OPTION_TRUE);

All other modes

For modes other than Microsoft® Lync™ (AF_MODE_MSOCS), AF_CHANNEL_RTP and AF_CHANNEL_RTCP are almost identical to AF_CHANNEL_UDP, but there are a few important differences.

For channels of type AF_CHANNEL_RTP and AF_CHANNEL_RTCP, the timeout is ignored in the Send and Recv calls, forcing them to be non-blocking, which is important for real-time applications. AF_CHANNEL_RTP and AF_CHANNEL_RTCP also have semantic meanings when included in an ICE session.

A channel of type AF_CHANNEL_RTP is always assigned to component 1 in a media stream.

A channel of type AF_CHANNEL_RTCP is always assigned to component 2 in a media stream.

A channel of type AF_CHANNEL_UDP is always assigned to component 1 in a media stream.

Special channels: AF_CHANNEL_LOOPBACK and AF_CHANNEL_EVENT

AF_CHANNEL_LOOPBACK can be used to interrupt CAnyFirewallInterface::Select calls.

The following code is an example for how to use loopback channels with multiple threads. The first thread creates the loopback channel and performs a select; the second thread sends data to the loopback channel and causes select to return. It is necessary to read the data from the loopback channel to clear the event AF_SELECT_READ.

Page 49: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Thread 1 Thread 2

// Create a loopback channel

int iChannel = m_pAFEngine-

>Create(AF_CHANNEL_LOOPBACK,

0,

0,

0

);

// CAnyFirewallInterface::Connect has no

// effect on loopback channels

aChannels[0] = iChannel;

aInputEvents[0] = AF_SELECT_READ;

aOutputEvents[0] = AF_SELECT_NOEVENT;

// select with infinite timeout

int iRet = m_pAFEngine->Select(1,

aChannels,

aInputEvents,

aOutputEvents,

AF_TIMEOUT_INFINITE

);

// Send dummy data to

// loopback channel m_pAFEngine-

>Send(

iChannel,

pSendBuf,

iLen,

AF_NON_BLOCKING

);

// select returns: read the data, this is just

// a dummy required to clear the select event

m_pAFEngine->Recv(iChannel, pRecvBuf,

iLen,

AF_NON_BLOCKING

);

// close channel

m_pAFEngine->Close(iChannel);

… …

Page 50: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

AF_CHANNEL_EVENT is created by the application to receive events taking place inside the AFE.

The following table lists the event types that are fired by the AFE through this event channel.

Event Type Description

EAfEventFirewallTypeDetected

This event is fired when the firewall type is detected. This event will occur if DetectConnectivity() function is called. If WaitForDetectConnectivity() function is not calledthen Connect(), MakeOffer(), MakeAnswer() functions should not be called before this is fired. See also API descriptions of DetectConnectivity and WaitForDetectConnectivity.

EAfEventHTTPProxyDetected

This event is fired when HTTP Proxy is automatically detected.

This event is available only on Windows platform.

EAfEventHTTPProxyAuthenticationFailed

This event is fired when an attempt to establish a connection through HTTP proxy fails due to proxy authentication failure.

EAfEventHTTPProxyConnectionFailed

This event is fired when an attempt to establish a connection through HTTP proxy fails due to reasons other than proxy authentication failure.

EAfEventHTTPProxyNTLMDomainEmpty

This event is fired when an attempt to authenticate with the HTTP Proxy fails because no NTLM domain was specified.

Obsolete. Not used anywhere. (Both in AFE 8.6, 9.5)

EAfEventHTTPProxyAuthenticationFailureNTLM

This event is fired when an attempt to authenticate with NTLM HTTP Proxy fails.

Obsolete. Not used anywhere. (Both in AFE 8.6, 9.5)

EAfEventUPnPDeviceDiscovered This event is fired when the presence of UPnP device(s) detected.

Page 51: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Event Type Description

EAfEventConnectionToServerLost This event is fired when AFE detects a connection loss with the server.

EAfEventNoDataReceived

This event is fired when a channel did not receive any packets for 5 seconds after calling Connect. This timeout can be configured with EAfOptionRelayFallbackTimeout.

EAfEventNoDataReceivedAfterFallbackToRelay

This event is fired when a channel did not receive any packets for 5 seconds after connecting via the TURN server.

EAfEventNetworkInterfacesChanged This event is fired when a change is detected in the local interface.

EAfEventTurnServerDnsResolutionFailed

This event is fired when AFE fails to resolve the TURN server DNS.

Now obsolete.

EAfEventTurnAllocationFailed This event is fired when TURN allocation fails.

EAfEventTurnServer ConnectionFailed This event is fired when AFE fails to connect to the TURN server.

EAfEventTurnServerAuthenticationFailed This event is fired when AFE fails to authenticate with the TURN server.

EAfEventTurnResponseFromInvalidSource

This event is fired when an allocation request is sent to the TURN server, and the response is received from an IP different from the requested TURN Server.

EAfEventPSTNFailover

This event is fired when AFE detects that PSTN Failover is allowed by the server during bandwidth reservation check. This event is fired per channel. For a given session, this event is fired before EAfEventICECheckStarted.

EAfEventConnectSuccess This event is fired when non-blocking call to Connect() succeeds.

EAfEventConnectFailure This event is fired when non-blocking call to Connect() fails.

EAfEventLookupIPv4AddressSuccess This event is fired when non-blocking call to DNS_LookupIPv4Address() succeeds.

EAfEventLookupIPv4AddressFailure This event is fired when non-blocking call to DNS_LookupIPv4Address() fails.

Page 52: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Event Type Description

EAfEventBandwidthCommitSuccessful

This event is fired when response to bandwidthcommit request is received and successfully processed. This event will not be fired before EAfEventIceCheckCompleted.

Upon receipt of this event, AFE client should call the API functions GetReservationId() and GetAllocatedBandwidth()

If the reservation ID is empty (zero) the server is not managing bandwidth due to eitherof the following reasons:

1) Both caller and callee are the same location. Therefore, the bandwidth policy is not enforced in this scenario.

2) Established media path between caller and callee is not managed by bandwidthpolicy server.

If the reservation ID has a value other than zero, Non-empty reservation ID means the bandwidthis committed and the server is managing the network resources involved in the media path.

EAfEventBandwidthCommitFailed

This event is fired in 2 cases:

1) Bandwidthcommit request could not be sent due to an error,

2) AFE did not receive bandwidthcommit response 5 seconds after sending request.

This event will not be fired before EAfEventIceCheckCompleted.

Page 53: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Event Type Description

EAfEventChannelClosedImplicitly

This event is fired in 2 cases:

1) For callee, if Bandwidth Management (BWM) is enabled for a channel and that channel gets closed due to lack of sufficient bandwidth.

2) AFE finds that peer does not include media (unwanted media excluded from the SDP or port 0 specified in the m line for the unwanted media).

Fired only when AFE internally closes a channel. This event is not fired when channel is closed by AFE client application. When a session is closed, channels that belong to that session are closed, and it is considered initiated by AFE client. This event is not fired for the closing session.

EAfEventTurnResponseUnauthorized

This event is fired – if TURN AUTHENTICATION_TOKEN is set by the AFE client and the TURN server returns an error response 401 on allocation.

This event lets the client know that TURN allocation has failed due to incorrect AUTHENTICATION_TOKEN.

Each event has a channel ID associated with it that represents the channel to that the event which it belongs to. If the channel ID is 0, then the event does not belong to any specific channel. The structure AfEvent is used to retrieve events and their associated channel numbers. The following code block shows an example for handling EAfEventNoDataReceived. struct AfEvent stAfEvent;

int iRet = m_pAFEngine->Recv(m_iEventChannel, (char *) &stAfEvent, 8,

if (iRet > 0)

{

switch (stAfEvent.uEvent)

{

case EAfEventNoDataReceived:

cout << “No data was received on channel "<<

stAfEvent.uChannel;

break;

}

}

Page 54: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.2. AFE: EVENT Order List

EVENT Order List

a) For a successful call, the events must take place in the following order to establish a session for a given caller:

Event Order

Event Notes

1 EAfEventPSTNFailover May or may not be fired.

2 EAfEventOfferSDPAvailable For non-blocking call i.e. AFE is initialized as non-blocking

3 EAfEventICECheckStarted

4 EAfEventICECheckCompleted

5 EafEventCallCompletionStatusAvailable

6 EAfEventICENeedUpdatedOffer May or may not be fired.

7 EAfEventOfferSDPAvailable If EAfEventICENeedUpdatedOffer is fired and for non-blocking call

For a given callee, the following order of events takes place in order to establish a session.

b) For a successful call which does not receive a reINVITE request from the caller, the events must take place in the following order to establish a session for a given callee:

Page 55: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Event Order

Event Notes

1 EAfEventPSTNFailover May or may not be fired.

2 EAfEventAnswerSDPAvailable

3 EAfEventICECheckStarted

4 EAfEventICECheckCompleted

5 EafEventBandwidthCommitSuccessful/

EafEventBandwidthCommitFailed

Events 5 and 6 can fire in any order. However they will always come after EafEventIceCheckCompleted.

6 EafEventCallCompletionStatusAvailable Same as above.

c) For a successful call which receives a reINVITE request from the caller, the events must take place in the following order to establish a session for a given callee:

Event Order

Event Notes

1 EAfEventPSTNFailover May or may not be fired.

2 EAfEventAnswerSDPAvailable

3 EAfEventICECheckStarted

4 EAfEventICECheckCompleted

5 EafEventBandwidthCommitSuccessful/

EafEventBandwidthCommitFailed

Events 5 to 7 can fire in any order. However they will always come after EafEventIceCheckCompleted.

6 EafEventCallCompletionStatusAvailable Same as above.

7 EAfEventAnswerSDPAvailable Same as above.

d) Irrespective to Caller or Callee the event order list for a failed call is:

Event Order Event Notes

1 EAfEventPSTNFailover May or may not be fired.

2 EAfEventOfferSDPAvailable

3 EAfEventICECheckStarted

4 EAfEventICECheckFailed

5 EafEventCallCompletionStatusAvailable

Page 56: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.3. AFE: Host Types

Host Types

Host types are included in host description strings and are used to describe the nature of an IP address or port, e.g. whether it is a public IP address and port or whether it is an IP address and port allocated on a TURN server.

Type definition Description

AF_HOST_PUBLIC Public address, to be used with Connect only when connecting to a server

AF_HOST_LOCAL Private address

AF_HOST_FIREWALL Address detected on the firewall using STUN

AF_HOST_RELAY Address allocated on a TURN server (AnyFirewall™ Server)

AF_HOST_DNS_SRV

Used to carry out DNS-SRV lookups for the remote host.

Example:

string sTarget = "_stun._udp." + sDomain;

string sDnsSrv = m_pAFEngine->CreateHost(AF_HOST_DNS_SRV,

sTarget,

0,

AF_PROTOCOL_UDP,

NULL

);

m_pAFEngine->SetSTUNServer(serverStoreID, sDnsSrv);

Page 57: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.4. AFE: Protocols

Protocols

Protocol is a segment of the host description string. This segment defines the protocol that can be used to connect to the host described in the string. For example, when specifying AF_PROTOCOL_UDP in a host description, the described host can be accessed using UDP.

The following table lists the possible types and their meaning.

Type definition Description

AF_PROTOCOL_UDP UDP is used as transport protocol.

AF_PROTOCOL_TCP TCP is used as transport protocol.

AF_PROTOCOL_TLS Specifies a TLS connection to a server, e.g., a TLS connection to a SIP proxy.

Page 58: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.5. AFE: Timeouts

Timeouts

Timeouts for Send, Recv, and Select can be specified in milliseconds.

The following special timeout values are available: #define AF_TIMEOUT_INFINITE -1

#define AF_BLOCKING -1

#define AF_NON_BLOCKING 0

A value of -1 indicates an infinite timeout. A value of 0 disables the timeout. Timeouts are specified in milliseconds.

Page 59: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

6.6. AFE: Channel Options

Channel Options

The behavior of a channel can be controlled by setting the channel option parameters. The option parameters can be set by making a call to the API SetChannelOption.

The following table lists the possible options:

Option name Description

EAfOptionAutoMode

Channels use all possible means to complete a call. Server reflexive, relay, and UPnP candidates may be retrieved for each channel. If necessary, it will try HTTP tunneling.

This is the default mode.

EAfOptionStandardMode

Channels use only standard means to enable call completion, namely STUN and TURN. Server reflexive and relay candidates may be retrieved for each channel.

EAfOptionManualMode

Channels use specified means to enable call completion. If this option is set, the programmer has to specify which options they prefer to enable when connecting to its peer.

EAfOptionEnableStun

Retrieves a server reflexive candidate for connecting to a peer.

This option is only available if the channel is set to EAfOptionManualMode.

EAfOptionEnableRelay

Retrieves relay candidate for connecting to a peer. Use HTTP proxy if necessary.

This option is only available if the channel is set to EAfOptionManualMode.

EAfOptionEnableHTTPTunneling

Uses HTTP tunneling for connecting to a peer.

This option is only available if the channel is set to EAfOptionManualMode.

Page 60: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Option name Description

EAfOptionEnableUPnP

Enables a UPnP port mapping on an Internet Gateway Device (IGD) for connecting to a peer.

This option is only available if the channel is set to EAfOptionManualMode.

EAfOptionKeepAlivePeriodSeconds

Sets the keep-alive period (in seconds) for the channel.

Timeouts are specified in milliseconds. A value of -1 indicates an infinite timeout. A value of 0 disables the timeout.

EAfOptionBandwidthKbps The peak amount of bandwidth a channel can use.

EAfOptionSocket

This option can be used to specify options for the sockets used by AFE. The value must be the address of a struct of type AfSocketOptionParams.

AFE does not support retrieving this option with GetChannelOption.

EAfOptionRelayFallbackTimeout

This option affects the behavior of the Connect function.

By default, when connecting to a destination with Connect, AFE first tries a direct connection. If no data is received within 5 seconds, AFE assumes that a direct connection is not possible, and tries to connect through the TURN server. This timeout can be configured with EAfOptionRelayFallbackTimeout. Timeouts are specified in milliseconds. If the value is negative, AFE will try a direct connection only. If the value is zero, AFE will try only through relay. In the case of TCP channel, this timeout will be effective after a direct connection has been attempted with the specified iTi timeout in CreateHost function.

EAfOptionTcpRegularMode

Applicable only for Microsoft® Lync™ mode ( AF_MODE_MSOCS). TCP regular mode is disabled by default; RTP and RTCP channels have only TCP candidates. To include both UDP and TCP candidates, TCP regular mode must be enabled by setting EAfOptionTcpRegularMode to AF_OPTION_TRUE with the help of SetChannelOption() function.

Page 61: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Option name Description

EAfOptionEnableBWManagement

Used to enable or disable the bandwidth management in AnyFirewall™ Engine for a particular channel.

o If the value is 1 then bandwidth

management is set as true for that channel. o If the value is zero then bandwidth

management is set as false.

Before setting this Option to true, Global bandwidth management must be set as true.

EAfOptionMinSendBW Used to set the minimum bandwidth used when sending on a specific channel.

EAfOptionMaxSendBW Used to set the maximumbandwidth used when sending on a specific channel.

EAfOptionMinRecvBW Used to set the minimum bandwidth used when receiving on a specific channel.

EAfOptionMaxRecvBW Used to set the maximum bandwidth used when receiving on a specific channel.

EAfOptionMaxSendBWConfirmedP2P

Used to retrieve confirmation of the maximum bandwidth that can be used when sending from a TURN server in P2P case.

EAfOptionMaxRecvBWConfirmedP2P

Used to retrieve confirmation of the maximum bandwidth that can be used when receiving from a TURN server in P2P case.

EAfOptionMaxSendBWConfirmedRelay

Used to retrieve confirmation of the maximum bandwidth that can be used when sending from a TURN server in Relay case.

EAfOptionMaxRecvBWConfirmedRelay

Used to retrieve confirmation of the maximum bandwidth that can be used when receiving from a TURN server in Relay case.

EAfOptionMSService Quality

Indicates which service is being used: audio or video. For audio MS_SERVICE_QUALITY_AUDIO and for video MS_SERVICE_QUALITY_VIDEO is used.

EAfOptionUpdateBW Used to update the bandwidth.

EAfOptionEnableModeMsOcs

Enables or disables Microsoft® Lync™ mode on a specific channel. To enable Microsoft® Lync™ mode, set this value to true. To disable it, set this value to false.

The default value is false for this option.

EAfOptionEnablePacketFilter

Enables or disables packet filters for sockets other than the one ICE selected.

By default, this feature is enabled.

Page 62: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Option name Description

EAfOptionDontFragment

Enables or disables relaying data through SendIndication mechanism in IETF mode. By default AFE uses ChannelData mechanism to relay data TURN server.

This option will work only if related channel is in EAfOptionManualMode.

EAfOptionFingerPrint

Used to enable or disable fingerprint attribute in STUN signaling. By default this attribute is enable. If the value is less than or equal to zero then fingerprint attribute will not be added in STUN signaling.If the value is greater than zero then fingerprint attribute will be added in STUN signaling.

This option will work only if Channel ID is set as 0.

EAfOptionMessageQueueSize

Now the size of message queue is configurable. Client can change the size of the queue of AFE which is used for message buffering of channel. AFE initially sets 128 size as default. If AFE can not allocate memory while re-sizing the queue, AFE will not change anything as well as return false otherwise re-size the queue according to parameter as well as return true.

If application wants to use modified buffer size then this option needs to be set just after creating a channel. This is configurable per channel basis.

The value should be greater than 32.

The value should be the power of 2. (i.e. 64, 128, 256, 512, 1024 etc.)

EAfOptionAutoMode, EAfOptionStandardMode, and EAfOptionManualMode control four other options:

EAfOptionEnableStun,

EAfOptionEnableRelay,

EAfOptionEnableHTTPTunneling, and

EAfOptionEnableUPnP.

EAfOptionAutoMode and EAfOptionStandardMode set the values of the above four options, whereas EAfOptionManualMode allows these options to be individually configured using SetChannelOption. By default EAfOptionAutoMode mode of operation is enabled.

All of the four options are initially set to FALSE when EAfOptionManualMode mode is first set. The application can then manually configure these options to TRUE or FALSE. For boolean options such as these,

Page 63: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

TRUE = AF_OPTION_TRUE = 1

FALSE = AF_OPTION_FALSE = 0.

The table below shows the mode of operation affecting the four options:

Mode of

Operation

Options

STUN Relay HTTP Tunneling UPnP

Auto TRUE TRUE TRUE TRUE

Standard TRUE TRUE FALSE FALSE

Manual TRUE/FALSE TRUE/FALSE TRUE/FALSE TRUE/FALSE

These modes of operation and options can be set for each channel. If an option is set for channel 0, these options will be applied to all subsequent channels that are created. Since these options are channel-specific, shared services such as detecting connectivity will always use STUN and TURN servers, as well as HTTP tunneling and UPnP where necessary.

7. AFE: C++ Function Reference

C++ Function Reference

Page 64: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The Eyeball AnyFirewall™ Engine functions are grouped into 4 parts: initialization and de-initialization, configuration, channel management and data transfer, and helper functions. The C++ API defines the abstract class CAnyFirewallInterface, which contains the functions of the AnyFirewall™ Engine. The file AnyFirewallEngine_dll.h contains a wrapper class CAnyFirewallEngine, ready to be used from an application. This class internally makes use of the core AFE functions of CAnyFirewallInterface. The functions of this class are described in the following sections.

7.1. AFE: Initialization and De-Initialization

7.2. AFE Configuration

7.3. AFE: Channel Management and Data Transfer

7.4. AFE: Receiving Media Directly from Socket

7.5. AFE: Helper Functions

7.1. AFE: Initialization and De-Initialization

Initialization and De-Initialization

Page 65: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool Init();

Initializes the AnyFirewall™ Engine. This function must be called before the AnyFirewall™ Engine is used.

Return value:

bool

The function returns whether the function succeeded (true) or failed (false).

int CreateServerStore (int iMode, bool bBlocking);

Creates a store that keeps server settings. Must be called to create a server store that is required to set and get any server settings.

Parameters:

int iMode

This value can be AF_MODE_STANDARD, AF_MODE_AUTO or AF_MODE_MSOCS. bool bBlocking

Denotes whether the functions calls will be blocking or non-blocking.

Return value:

int

The function returns a unique server store id. void Release();

De-initializes the AnyFirewall™ Engine and releases resources. This function must be called when the AnyFirewall™ Engine is no longer used. It will release any allocated resources both internally and on the AnyFirewall™ Server if any port allocations were made.

Page 66: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

7.2. AFE Configuration

Configuration

Page 67: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool DetectConnectivity(int serverStoreID, const struct AfFirewallDetectionParams

*pFirewallDetectionParams);

Starts the detection and analysis of the system's local interfaces. It is used to complete the configuration of the AnyFirewall Engine by determining NAT types, the presence of UPnP enabled devices, HTTP proxies, and local and reflexive IP address(es) (more than one for multiple interfaces).

DetectConnectivity should be called after:

1. Initializing and configuring the AnyFirewall Engine. 2. Resetting the STUN, TURN, or proxy server settings. 3. Receiving an EAfEventNetworkInterfacesChanged event. 4. After setting IP address using SetInterfaceAddress(..).

In Microsoft® Lync™ mode, detection of NAT type and HTTP proxy is not done.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

const struct AfFirewallDetectionParams *pFirewallDetectionParams

This parameter can be used to customize the checks to be performed by this function. struct AfFirewallDetectionParams

{

int iDetectUdpConnectivity;

int iDetectTcpConnectivity;

int iDetectProxyConnectivity;

int iDetectUPnPConnectivity;

int iCheckTurnCredentials;

int iUPnPDeviceDiscoveryTimeout;

};

The struct members iDetectUdpConnectivity , iDetectTcpConnectivity , iDetectProxyConnectivity , iDetectUPnPConnectivity specify whether to check for UDP, TCP, proxy and UPnP connectivity respectively. A non-zero value means true and zero means false. Similarly, the member iCheckTurnCredentials indicates whether to check the validity of TURN server credentials during this phase. The default value of these parameters is 1. Finally, iUPnPDeviceDiscoveryTimeout specifies the timeout in milliseconds for UPnP device discovery. The default is 3000 ms. If pFirewallDetectionParams is NULL, the default values will be used.

Return value:

Page 68: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized.

bool SetNetworkType(const int serverStoreID, EAfNetworkType nType)

This API sets specific network type which will be used by AFE.This API can be used to set IPv4 only, IPv6 only or Dual-Stack network type. By default AFE operates in Dual-Stack mode.

DetectConnectivity() API must be invoked after invoking this API.

Parameters:

int serverStoreID

An unique server store id for individual server settings.

EAfNetworkType nType

Network Type(IPv4,IPv6 or Dual_Stack) AFE will use.

Return value:

bool

Returns true if succeeded and false if fails.

Network Type values(enum EAfNetworkType):

EAfDUAL,

EAfIPv4Only,

EAfIPv6Only

void SetInterfaceAddress(int serverStoreID, const std::string& sIPAddress);

Page 69: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

This API sets specific interface address(es) which will be used by AFE as outbound interface(s). This API can be used to set IPv4 only, IPv6 only or dual-stack address(es). API will take interface address(es) in string format. Every interface address will end with a semi-colon(;) and there must not be any white-space. For example,

SetInterfaceAddress("192.168.0.176;"); SetInterfaceAddress("192.168.0.176;2001:470:19:473::c0a8:a18;"); SetInterfaceAddress("192.168.0.176;2001:470:19:473::c0a8:a18;192.168.2.176;");

If no valid interface address is passed by this API, AFE will work with detected interface address(es) from system.

DetectConnectivity() API must be invoked after invoking this API.

Parameters:

int serverStoreID

A unique server store id for individual server settings. const std::string& sIPAddress

A string with one or more interface address, every address must end with a semi-colon.

int WaitForDetectConnectivity(int serverStoreID, int iTimeoutMillisec);

Wait a period of time for DetectConnectivity to complete. This can be used to ensure connectivity is analyzed before calling the following functions: Connect , MakeOffer , or MakeAnswer .

Parameters:

int serverStoreID

A unique server store id for individual server settings.

int iTimeoutMillisec

The amount of time in milliseconds to wait for DetectConnectivity to complete.

Page 70: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

int

0 is returned on success and 1 on timeout.

void SetRealm(int serverStoreID, const std::string& sRealm);

Sets the realm for long-term credentials for the Eyeball AnyFirewall™ Server which will be included in the allocation request. If the API is not called it will take NULL string as realm in the allocation request.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

const std::string& sRealm

The realm used on the AnyFirewall™ Server.

std::string GetRealm(int serverStoreID);

Returns the realm used on the AnyFirewall™ Server as part of long-term credentials.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value:

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized.

Page 71: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool SetTURNUsernamePassword(int serverStoreID, const std::string& sUsername, const

std::string& sPassword);

Sets the long-term credentials for the Eyeball AnyFirewall™ Server. The AnyFirewall™ Engine can connect to any other STUN and TURN compliant server as well.

Parameters: int serverStoreID

A unique server store id for individual server settings.

const std::string& sUsername

The username used on the AnyFirewall™ Server.

const std::string& sPassword

The password of the user.

Return value:

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized.

std::string GetTURNUsername(int serverStoreID);

Returns the username used on the Any-Firewall™ Server as part of long-term credentials.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Page 72: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value: std::string

The username used on the AnyFirewall™ Server.

std::string GetTURNPassword(int serverStoreID);

Returns the password used on the Any-Firewall™ Server as part of long-term credentials.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value: std::string

The password used on the AnyFirewall™ Server.

bool SetSTUNServer(int serverStoreID, const std::string& sHost);

Sets the IP address or hostname of the STUN Server of the Eyeball AnyFirewall™ Server. The AnyFirewall™ Engine can connect to any other STUN-compliant server as well. The AnyFirewall™ Engine will send binding requests to the STUN Server. The STUN server can be accessed using UDP and TCP. UDP is required to detect the firewall settings; TCP is used to check whether TCP connections can be made.

Example: “public 64.85.36.178 3478 udp; public 64.85.36.178 3478 tcp;”.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Page 73: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

const std::string& sHost

The host description of the STUN Server, created by CreateHost .

Return value:

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized.

std::string GetSTUNServer(int serverStoreID);

Returns the host description string of the STUN Server, e.g. “public 64.85.36.178 3478 udp;” . For details about host description strings please see 6.3. AFE: Host Types

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value: std::string

The description of the STUN Server.

bool SetTURNServer(int serverStoreID, const std::string& sHost);

Sets the IP address or hostname of the TURN Server of the Eyeball AnyFirewall™ Server. The AnyFirewall™ Engine can connect to any other TURN-compliant server as well. The AnyFirewall™ Engine will send TURN messages to the TURN Server. TURN can be used over UDP and TCP.

It is recommended to set both transport protocols to make full use of the relaying capabilities of AnyFirewall™ Engine.

Page 74: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Example: “public 64.85.36.178 443 udp; public 64.85.36.178 443 tcp;”.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

const std::string& sHost

The host description of the TURN Server, created by CreateHost .

Return value:

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized.

std::string GetTURNServer(int serverStoreID);

Returns the host description string of the TURN Server, e.g. “public 64.85.36.186 5070 udp; public 64.85.36.186 443 tcp;” . For details about host description strings please see 6.3. AFE: Host Types .

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value: std::string

The description of the TURN Server.

Page 75: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool SetHTTPProxy(int serverStoreID, const std::string& sHost, const std::string&

sUsername, const std::string& sPassword,const std::string& sDomain);

Sets the parameters to access an HTTP proxy. If not set, the AnyFirewall™ Engine detects the HTTP proxy using the HTTP proxy settings stored for Internet Explorer.

Parameters:

int serverStoreID

A unique server store id for individual server settings. const std::string& sHost

The host description of the HTTP proxy, created by CreateHost . Example: “public proxy.eyeball.com 8080 tcp;” const std::string& sUsername

The username used on the HTTP proxy. const std::string& sPassword

The password of the user.

const std::string& sDomain

The HTTP proxy domain. Only required for NTLM authentication.

Return value:

bool

Should return true. Returns false if the AnyFirewall™ Engine is not initialized. std::string GetHTTPProxy(int serverStoreID);

Returns the host description string of the HTTP Proxy, e.g. “public proxy.eyeball.com 8080 tcp;” . For details about host description strings please see 6.3. AFE: Host Types .

Parameters:

int serverStoreID

A unique server store id for individual server settings. Return value: std::string

The description of the HTTP proxy. std::string GetHTTPProxyUsername(int serverStoreID);

Returns the username used on the HTTP Proxy.

Page 76: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value: std::string

The username used on the HTTP proxy.

std::string GetHTTPProxyPassword(int serverStoreID);

Returns the password used on the HTTP Proxy.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Return value: std::string

The password used on the HTTP proxy.

std::string GetHTTPProxyRealm();

Returns the realm used on the HTTP Proxy for NTLM authentication.

Page 77: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

std::string

The realm used on the HTTP proxy.

unsigned long DNS_LookupIPv4Address(int iDnsChannel, const std::string& sHostName)

Resolves the hostname sHostName , and returns the IP address in network byte order.

Parameters:

int iDnsChannel

The ID of a DNS Channel

const std::string& sHostName

The hostname

Return value:

unsigned long

Resolved IP in network byte order or 0 in case of error.

std::string* DNS_LookupIPv4Addresses(const int serverStoreID, const std::string&

sHostName, int& iNumResults)

Resolves the hostname sHostName , and returns only IPv4 addresses as an array of string. The number of IPv4 addresses is returned in the iNumResults parameter.

Parameters:

Page 78: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int serverStoreID

An unique server store id for individual server settings.

const std::string& sHostName

The hostname

int &iNumResults

Reference parameter that holds the number of IPv4 addresses it discovered by resolving the hostname sHostName.

Return value:

std::string*

Array of string that holds the resolved IPv4 addresses.

std::string* DNSLookupForIPv6Addresses(const int serverStoreID, const std::string&

sHostName, int& iNumResults)

Resolves the hostname sHostName, and returns only IPv6 addresses as an array of string. The number of IPv6 addresses is returned in the iNumResults parameter.

Parameters:

int serverStoreID

An unique server store id for individual server settings.

const std::string& sHostName

The hostname

int &iNumResults

Reference parameter that holds the number of IPv6 addresses it discovered by resolving the hostname sHostName.

Return value:

std::string*

Array of string that holds the resolved IPv6 addresses.

Page 79: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

std::string* GetIPAddressesFromDNS(const int serverStoreID, const std::string&

sHostName, int& iNumResults)

Resolves the hostname sHostName, and returns both IPv4 and IPv6 addresses as an array of string. The number of IP addresses is returned in the iNumResults parameter. int serverStoreID

An unique server store id for individual server settings.

const std::string& sHostName

The hostname

int &iNumResults

Reference parameter that holds the number of IPv4 and IPv6 addresses it discovered by resolving the hostname sHostName.

Return value:

std::string*

Array of string that holds the resolved IPv4 and IPv6 addresses.

std::string DNS_SRV_Lookup(int iDnsChannel, const std::string& sTarget, const

std::string& sProtocol)

Performs DNS-SRV query and returns the discovered hosts as a list of hosts, delimited by semicolons. Each host is in the form of “<host-type><IP address><port><transport>” . The different parts of the host descriptions and their meanings are described in detail in 6.3. AFE: Host Types .

Parameters:

int iDnsChannel

The ID of a DNS Channel

const std::string& sTarget

The DNS SRV entry e.g. “_sip._udp.eyeball.com”

Page 80: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

const std::string& sProtocol

The protocol e.g. AF_PROTOCOL_TLS

Return value:

std::string

Host list of discovered hosts

bool SetPortRange(int iBottomRange, int iTopRange, const std::string& socketType)

This function can be used to specify a range of ports to be used by AFE. Whenever AFE needs to bind a port, it will try to use a port from this range.

This function affects all channels created.

In Microsoft® Lync™ mode, if a fixed TCP port is desired, the port number can be provided for both the bottom and the top range. If a fixed port is specified, only one media stream can be used in the session. According to MS-ICE2, multiplexing occurs with TCP candidates for RTP and RTCP components. Hence, one port is enough for TCP candidates of one media stream. If another media stream attempts to use the same port, it can gather host candidates, but fails to gather server reflexive and relayed candidates since allocation has already been made for that port for the first media stream.

In Microsoft® Lync™ mode, for a fixed TCP port specified by this function, with one media stream, the call should establish for both P2P and relay cases. For two media streams, the call should establish for only the P2P case as relayed candidates cannot be gathered for the second media stream.

Parameters:

int iBottomRange

The lower limit of the port range.

int iTopRange

The upper limit of the port range.

Page 81: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

const std::string& socketType

This can be either AF_PROTOCOL_UDP or AF_PROTOCOL_TCP.

Return value:

bool

The function returns whether it succeeded (true) or failed (false).

bool SetMediaPortRange(int iBottomRange, int iTopRange, const std::string& socketType)

This function can be used to specify a range of ports to be used for media channels by AFE. Whenever AFE needs to bind a media port, it will try to use a port from this range. AFE will not use any port from this port range for its internal usage.

This function affects all channels created. If the port is not specified while creating a channel, AFE will bind any available port from the system even though media port range has been set. So, it is recommended to use specific port when the media port range is set.

Parameters:

int iBottomRange

The lower limit of the port range.

int iTopRange

The upper limit of the port range.

const std::string& socketType

This can be either AF_PROTOCOL_UDP or AF_PROTOCOL_TCP.

Return value:

bool

The function returns whether it succeeded (true) or failed (false).

Page 82: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool SetBandwidthManagement(int serverStoreID, int bEnable);

This function is used to set bandwidth management globally. If global bandwidth management is true then we can enable or disable bandwidth management on specified channels.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

int bEnable

set 1 to set true,0 to set false.

The default value is false.

Return value:

bool

The function returns whether it succeeded (true) or failed (false).

int GetAllocatedBandwidth(int iChannel);

This API is used to get the allocated bandwidth for a specific channel.

Parameters:

int iChannel

Specifies the channel number

Page 83: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

int

The function returns the allocated bandwidth.

std::string GetReservationId(int iChannel);

This function returns the reservation ID of 16 bytes from the TURN server.

Parameters:

int iChannel

Specifies the channel number

Return value:

std::string

Returns the reservation ID

void SetDefaultCandidatePreferenceOrder(enum CandidateType

defaultCandidatePreferenceOrder[], int sizeOfPreferenceOrderList, bool

forceReInviteDisabled)

Configures the order of preference for default candidate in offer or answer SDP.

Once configured, the order remain in effect for every subsequent SDP. To change the order, use the function ResetDefaultCandidatePreferenceOrder().

If no preference order is set, the default preference order is:

For MS-ICE2 Regular mode: UDP host candidate, UDP server reflexive candidate, UDP relayed candidate, TCP relayed candidate, TCP server reflexive candidate.

For MS-ICE2 TCP-only mode: TCP host candidate, TCP relayed candidate, TCP server reflexive candidate.

Page 84: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

This function is applicable only for Microsoft® Lync™ mode.

It is RECOMMENDED that the default candidate be chosen in the following order - relayed candidate, server reflexive candidate, host candidate (Ref: ICE Protocol).

Parameters:

enum CandidateType defaultCandidatePreferenceOrder[ ]

List of values from enumeration CandidateType .

int sizeOfPreferenceOrderList

Number of CandidateType values present in the list

bool forceReInviteDisabled

False if reINVITE is to be sent always, true otherwise

If SetDefaultCandidatePreferenceOrder function is not configured then reINVITE will always occur.

void ResetDefaultCandidatePreferenceOrder()

Resets the preference order if it was set by SetDefaultCandidatePreferenceOrder(). This function is applicable only for Microsoft® Lync™ mode.

Default preference order will be enforced:

For MS-ICE2 Regular mode: UDP host candidate, UDP server reflexive candidate, UDP relayed candidate, TCP relayed candidate, TCP server reflexive candidate.

Page 85: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

For MS-ICE2 TCP-only mode: TCP host candidate, TCP relayed candidate, TCP server reflexive candidate.

std::string GetLocalInterfaceIPs()

Returns interface IP address (es) of the system. If there is more than one interface IP address then the addresses will be space separated.

Return value:

std::string

The function returns the local interface address (es). typedef int (*custom_cert_verify_callback)(void *x509_store_ctx, void *arg)

A function pointer type used by SetCertificateVerificationCallback API. Clients must define function that conform this function signature. When set by client, this function will be invoked by AFE to verify the peer certificate during TLS connection attempt.

Parameters:

void *x509_store_ctx

Client will receive an instance of X509_STORE_CTX structure that is the certificate store of the other peer AFE attempting to connect. Using this certificate store client can verify the peer certificate.

void *arg

Currently provides channel ID pointer.

Return value:

Client callback must return 1 when certificate is verified successfully. Otherwise client should return 0. Returning 1 will make AFE continue the TLS connection process. Returning 0 will cause AFE abort the TLS connection process.

void SetCertificateVerificationCallback(custom_cert_verify_callback callback)

Page 86: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The API to set the client callback that will be invoked to verify peer certificate during TLS connection process.

Parameters:

custom_cert_verify_callback callback

The client callback function’s pointer.

Sample code:

static int custom_callback(void *ctx, void *arg)

{

X509_STORE_CTX

store_ctx = X509_STORE_CTX(*(X509_STORE_CTX*)ctx);

int ret = X509_verify_cert(&store_ctx);

//do more verification

return ret;

}

m_pAFEngine->SetCertificateVerificationCallback(custom_callback);

bool SetLocationProfile(int sessionID, EAfLocation peerLocation, EAfLocation

selfLocation, EAfFederation federationType)

7.3. AFE: Channel Management and Data Transfer

Channel Management and Data Transfer

Page 87: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int Create(int serverStoreID, const std::string& channelType, int iUdpHostPort, int

iUdpServerConnectionPort, int iTcpPort);

Creates a channel and returns the channel ID. The channel type can be configured and may be set to force certain protocols or connectivity checks. This function must be called before any network activity or connectivity checks can be made.

If positive values are specified for iUdpHostPort, iUdpServerConnectionPort and iTcpPort, AFE will try to bind to those ports. If the first two parameters are zero or negative, AFE will try to use any available port.

In IETF mode, If client application sets specific port value then make sure that next port value of iUdpServerConnectionPort is also available for AFE use. As per RFC, TURN client must use separate set of 5 tuple to gather IPv6 relay candidate. So AFE uses (iUdpServerConnectionPort + 1) port value to gather IPv6 relay candidates.

The parameter iTcpPort is for TCP candidate port. For RTP/RTCP channel, giving zero in this parameter will not gather TCP candidates. Specifying -1 will try to bind to any available ports.

For a fixed TCP port, a positive integer value (> 1023) can be provided to iTcpPort. In Microsoft® Lync™ mode, TCP candidates are multiplexed for RTP and RTCP components. So the same port can be used for both RTP and RTCP channels of a media stream. In IETF mode different ports must be used for both RTP and RTCP channels to gather TCP candidates.

For channels with type AF_CHANNEL_DATA, no UDP candidates will be gathered and for channels with type AF_CHANNEL_UDP, no TCP candidates will be gathered. If the binding fails, the function will return a negative value.

The two UDP port parameters should not be specified the same positive value when operating in Microsoft® Lync™ mode ( AF_MODE_MSOCS). While AFE provides a way of specifying the exact ports to be used in a channel with parameters iUdpHostPort, iUdpServerConnectionPort and iTcpPort, it is strongly recommended that the user does not specify fixed ports like this. Instead, the user may consider specifying a range of ports to be used by AFE with the SetPortRange function.

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Page 88: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

const std::string&

channelType

This string describes the type of the channel. Currently, the following channel types are available and defined in the header file supplied with the library:

AF_CHANNEL_TCP

AF_CHANNEL_UDP

AF_CHANNEL_RTP

AF_CHANNEL_RTCP

AF_CHANNEL_DATA

AF_CHANNEL_TLS

AF_CHANNEL_LOOPBACK

AF_CHANNEL_EVENT

AF_CHANNEL_DNS

The channel types and their meaning are described in detail in 6.1. Channels.

int iUdpHostPort

The port to be used as host candidate in ICE checks. int iUdpServerConnectionPort

The port to be used for connecting to the TURN server. This should be different from iUdpHostPort when operating in Microsoft® Lync™ mode ( AF_MODE_MSOCS). int iTcpPort

The port to be used for TCP connections. The same port will be used for host, relay connection, active and passive types.

Return value:

int

The function returns the channel ID of the created channel, or a negative value to indicate an error.

Page 89: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool Connect(int iChannel, const std::string& sHost);

The function initializes the local channel endpoint and obtains its transport information. Then it connects the channel to an endpoint specified in the host description list sHost. This is a host description of the host to connect to.

By default, this function first tries to connect directly with the host. If no data is received within 5 seconds, it assumes that direct connection is not possible, and automatically retries through relay. This behavior can be modified with the help of channel option EAfOptionRelayFallbackTimeout (see 6.6. Channel Options).

DetectConnectivity should be complete before calling Connect (please see WaitForDetectConnectivity (see 6.6. Channel Options)). Parameters: int iChannel

The ID of the channel (created by Create) to connect. const std::string& sHost

The description of the host to connect to. This is a string with the format as described in detail in 6.3. Host Types.

Return value:

bool

The function returns whether it succeeded (true) or failed (false). If false, call GetLastError for the error code.

bool Close(int iChannel);

Closes a channel. All allocations made by this channel will be removed. Not recommended to invoke this API for a channel associated with a session.

Parameters:

int iChannel

The ID of the channel (created by Create) to close.

Return value:

bool

Page 90: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The function returns whether it succeeded ( true) or failed ( false).

int Send(int iChannel, const char pData[], int iLen, int iTimeoutMillisec);

Sends data on a channel. It is necessary to call Connect/ CreateSession (depending on the destination, whether it is a server or a peer) before sending data. The function will return after the data is sent. If the whole amount of bytes ( iLen) can not be sent, the function will return after iTimeoutMillisec milliseconds. The function will read at most iLen bytes from the buffer.

Parameters:

int iChannel

The ID of the channel (created by Create) to be closed.

const char pData[]

The source buffer that contains the data to be sent. int iLen

The size in bytes of the data in the buffer. int iTimeoutMillisec

A timeout in milliseconds. Predefined values are AF_BLOCKING or AF_NON_BLOCKING.

Return value:

int

The function returns the number of bytes sent or -1 if an error occurred or the channel is already closed.

int Recv(int iChannel, char pBuff[], int iLen, int iTimeoutMillisec);

Receives data from a channel. It is necessary to call Connect/CreateSession (depending on the destination, whether it is a server or a peer), before data can be received. The function will return if no data could be read after iTimeoutMillisec milliseconds. The function will write at most iLen bytes to the buffer. It is the developer’s responsibility to allocate and free the buffer.

Parameters:

int iChannel

Page 91: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The ID of the channel (created by Create) to close. char pBuff[]

The buffer that will contain the data to be sent. int iLen

The size in bytes of the data in the buffer. int iTimeoutMillisec

A timeout in milliseconds. If omitted, this parameter will be set to AF_TIMEOUT_INFINITE.

Return value:

int

The function returns the number of bytes written to the buffer or -1 if an error occurred or the channel is already closed.

int Select(int iNumChannels, int aChannels[], int aInputEvents[], int aOutputEvents[],

int iTimeoutMillisec);

Waits until data on any of the channels given in input_events and output_events is available for sending or receiving. This function operates similar to the socket function select.

Parameters:

int iNumChannels

The number of channels given in the parameters aChannels. int aChannels[]

The array of channel IDs to monitor for incoming or outgoing data. int aInputEvents[]

An array defining the input events of interest for each channel. Possible input events are AF_SELECT_READ, AF_SELECT_WRITE, AF_SELECT_NO_EVENT and AF_SELECT_ERROR. int aOutputEvents[]

An array defining the output events of interest for each channel. Possible output events are AF_SELECT_READ, AF_SELECT_WRITE, AF_SELECT_NO_EVENT and AF_SELECT_ERROR. int iTimeoutMillisec

A timeout in milliseconds. Predefined values are AF_BLOCKING or AF_NON_BLOCKING.

Return value:

int

The function returns the number of channels with an event signaled. It returns 0 on timeout and negative value on error.

Page 92: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool SetCallbackHandler(int iChannel, IAfCallbackHandler* pHandler);

This function allows specifying a callback function that handles received packets. The callback function will be called when data is received on the given channel.

Parameters:

int iChannel

The channel for which the callback is installed. IAfCallbackHandler* pHandler

Specifies the callback. IAfCallbackHandler is an abstract base class: class IAfCallbackHandler

{

public:

virtual void _cdecl HandleCallback(

int iChannel, char *pData, int iLen,

const CAfStdString& sSrcAddress, int iSrcPort,

const void *pContext) = 0;

};

An implementation of this base class and the function HandleCallback must be provided by the application developer. HandleCallback is called by AnyFirewall Engine and gets the actual channel number, a pointer to the data, the length of the data, the source address, the source port and the context pointer associated with the session.

Return value:

bool

The function returns true on success, false otherwise.

std::string GetLocalAddress(int iChannel);

Returns the host description of the local party when a channel is connected. This represents the local endpoint of the channel which has been finally selected, which can be on the host machine, on the firewall, or on the TURN server. This information is available after Connect was called (for channels not used in a session) or after ICE check completes (for channels used in a session).

Parameters:

int iChannel

The ID of the channel (created by Create).

Page 93: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

std::string

The function returns the host description of the local channel in the form of “<host-type><IP address><port><transport>”. The different parts of the host descriptions and their meanings are described in detail in 6.3. Host Types. This address will be used by the host, specified in Connect call, to send data to this channel.

std::string GetLocalAddressBase(int iChannel);

Returns a host description string with the actual host address and port being used by a channel. This address and port represents the actual address and port on the client machine. If the finally selected candidate is relay, this contains the address and port being used for the TURN server connection. This information is available after Connect was called (for channels not used in a session) or after ICE check completes (for channels used in a session).

Parameters:

int iChannel

The ID of the channel (created by Create).

Return value:

std::string

The function returns the host description of the local endpoint in the form of “<host-type><IP address><port><transport>”. The different parts of the host descriptions and their meanings are described in detail in 6.3. Host Types.

bool IsClosed(int iChannel);

Returns whether a channel was closed or not. In contrast to ChannelExists, this function also checks whether the channel was closed by the remote end.

Parameters:

Page 94: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int iChannel

The ID of the channel to check.

Return value:

bool

The function returns whether the channel was closed (true) or not (false).

std::string GetRemoteAddress(int iChannel);

Returns the host description of the remote party. It returns the host which was specified in Connect() (if called). Once ICE check is completed, it returns the confirmed remote candidate.

Parameters:

int iChannel

The ID of the channel (created by Create).

Return value:

std::string

The function returns the host description of the remote candidate in the form of “<host-type><IP address><port><transport>”. The different parts of the host descriptions and their meanings are described in detail in 6.3. Host Types. This address will be used by the channel to send data to.

bool ChannelExists(int iChannel)

Returns whether a channel was created or not.

Parameters:

int iChannel

The ID of the channel to check.

Page 95: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

bool

The function returns whether the channel exists (true) or not (false).

EAfDetectedFirewallType GetFirewallType(const int serverStoreID)

Parameters:

int serverStoreID

A unique server store id for individual server settings.

Returns the detected firewall type.

The firewall type is in the form of enumeration as listed in the following table:

Firewall Type

Description

EAfFirewallTypeUnknown

Firewall type is not known yet

EAfFirewallTypeNone

Firewall type is unknown

EAfFirewallTypeNAT

Firewall type is NAT

Page 96: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

EAfFirewallTypeTCPOnly

Firewall blocks UDP traffic. However, it allows TCP connection.

EAfFirewallTypeProxy

Firewall only allows traffic through proxy

EAfFirewallTypeBlocked

Firewall blocks both UDP and TCP traffic

Return value:

EAfDetectedFirewallType

The type of the detected firewall.

bool SetChannelOption(int iChannel, EAfOptionName eOptionName, void *vpOptionValue)

Sets the channel option eOptionName, for the channel iChannel, to the value vpOptionValue. The possible options are discussed in 6.6. Channel Options. If 0 is specified in place of iChannel, this option will be in effect for all channels that will be created in future. Otherwise, the option will be specific to that channel only.

Parameters:

int iChannel

The ID of the channel to check.

Return value:

Page 97: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool

The function returns whether the channel exists (true) or not (false).

int CreateSession(int serverStoreID, const std::string& sMediaDescription, const void

*pContext)

Creates a session with the channels as specified in the string sMediaDescription. The media description is a list of strings having the format <Media type><Channel list>, and separated by ;. Currently AFE supports two types of media type as listed in the following table. Therefore, “ AF_MEDIA_STREAM_AUDIO 1 2; AF_MEDIA_STREAM_VIDEO 3 4” will create a session with two streams. The audio stream with channel 1 and 2, and the video stream with channel 3 and 4. The function returns the ID representing the session.

Media Type

Description

AF_MEDIA_STREAM_AUDIO

Represents audio stream

AF_MEDIA_STREAM_VIDEO

Represents video stream

Parameters:

int serverStoreID

A unique server store id for individual server settings. const std::string& sMediaDescription

The media specification in the format described above const void *pContext

The context pointer associated to the session

Return value:

Page 98: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int

An unique session ID representing the session

The session ID can also be used as a channel ID where all the session level events, fired from the AFE, can be received. The following table summarizes the session level events:

Session Level Event Type

Description

EAfEventOfferSDPAvailable

Fired when non-blocking call to MakeOffer() returns and offer SDP becomes available for AFE client to retrieve. EAfEventAnswerSDPAvailable

Fired when non-blocking call to MakeAnswer() returns and Answer SDP becomes available for AFE client to retrieve. EAfEventICECheckStarted

Fired when ICE check is started. EAfEventICECheckCompleted

Fired when ICE check is completed. EAfEventCallCompletionStatusAvailable

Fired when determination of call completion type for the whole session is complete and BW commit (Microsoft® Lync™ mode) is complete. IceCheckCompleted event is always followed by CallCompletionStatusAvailable. EAfEventICENeedUpdatedOffer

Fired when the candidate pairs confirmed by ICE check is different from the candidate pairs that was used in the m/c line of the most recent offer/answer messages. reINVITE should be sent to the peer when this event is received. EAfEventICECheckFailed

Indicates the failure of ICE check. A context pointer can be associated with a session, when creating the session. AFE will return this context pointer as a parameter of the callback function pertaining to the session.

bool ModifySession(int iSessionID, const std::string& sMediaDescription)

Modifies the session iSessionID with the new media specification described in sMediaDescription. This function can be used to add or remove audio/video streams to the current session. Please see Flow Diagram for an illustration of this. To remove a media from a session don't call Close(iChannel) for

Page 99: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

channels, provide new media description as sMediaDescription, AFE will close channels associated with that media implicitly.

Parameters:

int serverStoreID

A unique server store id for individual server settings. const std::string& sMediaDescription

The media specification in the format described above

Return value:

bool

True in case of success, and false in case of failure

bool CloseSession(int iSessionID)

Closes the session iSessionID. Closes all channels in that session along with all the resources that were allocated to that session.

Parameters:

int iSessionID

The session ID

Return value:

bool

True in case of success, and false in case of failure

const struct AfSessionInfo *MakeOffer(int iSessionID)

Initializes all the channels in the session iSessionID, gathers candidates for the channels, and returns the candidate list in the form of a SDP structure.

Page 100: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

DetectConnectivity should be complete before calling MakeOffer (please see WaitForDetectConnectivity).

Parameters:

int iSessionID

The session ID

Return value:

const struct AfSessionInfo*

The offer SDP in a structured format

const struct AfSessionInfo *MakeAnswer(int iSessionID, const std::string& sOfferSDP,

const std::string& sPeerID)

Initializes all the channels in the session iSessionID, gathers candidates for the channels, and returns the candidate list in the form of a SDP structure. Moreover, it parses the SDP received from its peer and starts ICE checking. DetectConnectivity should be complete before calling MakeAnswer (please see WaitForDetectConnectivity).

Parameters:

int iSessionID

The session ID

const std::string& sOfferSDP

The SDP received from its peer

const std::string& sPeerID

The tag value parsed from peer's SDP

Return value:

Page 101: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

const struct AfSessionInfo*

The answer SDP in a structured format

bool SetSipIdentifier(const int sessionID, const std::string& callIdentifier, const

std::string& dialogIdentifier)

Applicable only for MS-Lync mode and when CAC policy is enabled in callee end. Invoke this API before calling MakeAnswer() API. Length of Sip Call Identifier and Sip Dialog Identifier must not exceed 256 bytes.

Parameters:

int sessionID

The session ID const std::string& callIdentifier

Sip Call Identifier value. const std::string& dialogIdentifier

Sip Dialog Identifier value.

Return value: bool

Returns true if succeeded and false if fails.

bool SetLocationProfile(int sessionID, EAfLocation peerLocation, EAfLocation

selfLocation, EAfFederation federationType)

Applicable only for MS-Lync mode and when CAC policy is enabled in callee end. Invoke this API before calling MakeAnswer() API. If not invoked then AFE will use default values like Intranet for self and peer location with no federation.

Parameters:

int sessionID

The session ID EAfLocation peerLocation

The Peer Location.

Page 102: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

EAfLocation selfLocation

The Self Location. EAfFederation federationType

Federation Type.

Return value:

bool

Returns true if succeeded and false if fails.

Local & Peer location values(enum EAfLocation):

EAfLocationUnknown,

EAfLocationInternet,

EAfLocationIntranet

Federation type values(enum EAfFederation):

EAfNoFederation,

EAfEnterprizeFederation,

EAfPublicCloudFederation

void MarkSuccessAnswerSent(int sessionId)

Start the ICE check timer by signaling the AFE. It's used only after calling MakeAnswer(). For example, if an application needs to wait for an arbitrary period of time to accept a call, then it must call this API after sending 200 Ok INVITE response, not after sending any provisional response like 183 session progress.

Parameter:

int iSessionID

Session ID for whom success answer sent event to be marked.

std::string GetSessionDescription(int iSessionID)

Returns the session description string of the given session.

Parameter:

int iSessionID

The session ID of the session.

Page 103: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return:

std::string

On success, returns the session description string, otherwise it returns empty string.

int GetSessionProperty(int iSessionID, EAfSessionProperty eSessionProperty)

Returns the value for the given property for the given session.

Parameters:

int iSessionID

ID of the session whose property to get. EAfSessionProperty eSessionProperty

The property whose value to get.

Return:

int

Returns the property value as an integer.

const struct AfSessionInfo *GetSessionSDP(int iSessionID)

Returns the SDP structure of the session iSessionID. This function is mainly useful in the case of non-blocking calls of MakeOffer and MakeAnswer. This function should be called after the event EAfEventOfferSDPAvailable or EAfEventAnswerSDPAvailable.

Parameters:

int iSessionID

The session ID

Return value:

const struct AfSessionInfo*

The SDP in a structured format

Page 104: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool ProcessAnswer(int iSessionID, const std::string& sAnswerSDP, bool

successAnswerReceived, const std::string& sPeerID)

Parses the SDP received from its peer and starts ICE checking.

Parameters:

int iSessionID

The session ID

const std::string& sAnswerSDP

The SDP received from its peer bool successAnswerReceived

Set as true if the answer SDP is retrieved from a 200 OK INVITE response. Set false for 1xx responses. For non-Microsoft® Lync™ mode this value should be always true. const std::string sPeerID

The tag value parsed from peer's SDP

Return value:

bool

true on success, and false on failure

7.4. AFE: Receiving Media Directly from Socket

Receiving Media Directly from Socket

Page 105: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Some applications may prefer to receive media data directly from socket, instead of using the AFE Recv API. AFE provides three functions to facilitate this:

GetSelectedSocket- the user application can get the selected socket descriptor of a channel after ICE checks are complete for the corresponding session (EAfEventICECheckCompleted event). After this, the socket descriptor can be used to receive data using Berkeley socket API (select and recvfrom)

IsSTUNMessage- Checks if STUN/TURN packet, returns true if STUN/TURN packet and application should ignore that packet. Should be used for peer-to-peer cases.

ProcessReceivedData - the received data should be processed using this AFE function in order to handle any STUN/TURN packets. Should be used for Relay cases.

DeleteUserData - any user data extracted with ProcessReceivedData must be freed with this function.

Please note that this mechanism is only applicable for media channels belonging to an ICE session. Also, the socket may only be used for receiving data, not for sending data. Data should be sent with the AFE Send API. After fetching the socket, the user application should first receive all data accumulated in the AFE buffer using the AFE Recv API, and then start using the data received by direct socket API ( recvfrom). The data received directly from socket should be considered to have arrived later than the data from AFE Recv API.

int GetSelectedSocket(int iChannel)

This function returns the socket descriptor of the selected candidate after ICE checks are complete. It may be called only after getting EAfEventCallCompletionStatusAvailable ( EAfEventIceCheckCompleted event is always followed by EAfEventCallCompletionStatusAvailable for the relevant session). The returned descriptor should only be used for receiving data, not for sending data. Data should be sent using the AFESend function. Data directly received using the socket must be processed with ProcessReceivedData, so that STUN/TURN messages are used appropriately.

When TCP candidates are selected for media after ICE checks in Microsoft® Lync™ mode, GetSelectedSocket will return the same socket descriptor for both RTP and RTCP channels because of multiplexing. In this case, the received data from the socket needs to be processed only once with the RTP channel (ProcessReceivedData).

Parameters:

int iChannel

The ID of the channel

Return value:

int

The socket descriptor corresponding to the selected candidate after ICE checks. The returned value is negative in case of error.

Page 106: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

bool IsSTUNMessage(const char pBuffer[], int iLen)

This function is used to check keep-alive messages. It checks the data received directly with a socket descriptor which returned from GetSelectedSocket API.

Parameters:

const char pBuffer[]

Received data buffer.

int iLen

Number of bytes written in data buffer.

Return value:

bool

Returns true if STUN message is given as input, false otherwise.

int ProcessReceivedData(int iChannel, const char *pRawData, int nRawDataLen, const

std::string& ipAddress, unsigned short uPort, struct UserData **ppUserData)

This function is used for processing the data received directly with a socket descriptor returned from GetSelectedSocket.

Parameters:

int iChannel

The ID of the channel.

const char *pRawData

The buffer containing the raw data received from socket.

int nRawDataLen

The length of data in pRawData.

const std::string& ipAddress

Page 107: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The IP address of the source as reported by recvfrom.

unsigned short uPort

The port of the source as reported by recvfrom.

struct UserData **ppUserData

The address of a pointer to structUserData. Any user data extracted from TURN messages can be accessed with this pointer as the head of a linked list, after the function returns. The output parameter is described below: struct UserData

{

char *pData;

int nDataLen;

struct UserData *pNextUserData;

};

pData is a pointer to the user data extracted from TURN packet. nDataLen is the length of the data. pNextUserData points to the next node in the linkedlist, with NULL indicating end of the list.

Return value:

int

An integer indicating the result of processing:

A negative value indicates error.

Zero means data was found to be UDP user data. In this case, no modification is done by AFE and the data in pRawData can be directly used by the user. *ppUserData should be ignored.

If the returned value is positive, it means data was found to be a STUN/TURN packet. User should make use of *ppUserData to read any user data extracted from the raw data. User should also free *ppUserData with DeleteUserData.

void DeleteUserData(struct UserData *pUserData)

This function is used for freeing the linked list returned by ProcessReceivedData.

Parameters:

struct UserData *pUserData

The head of the linked list to be freed.

Page 108: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

7.5. AFE: Helper Functions

Helper Functions

EAfErrorType GetLastError(int iChannelOrSession);

Page 109: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

This function returns the last error associated with a channel or session that occurred.

Parameters:

int iChannelOrSession

The channel or session ID.

Return value:

EAfErrorType

The error code.

EAfError Type

Description

EAfErrNone

No error has occurred

EAfErrUnknown

An unknown error occurred

Page 110: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

EAfErrNotAValidChannel

A channel operation was performed on the session

EAfErrNotAValidSession

A session operation was performed on the channel

EAfErrNotAValidObject

Not a valid session or channel id

EAfErrInvalidParameter

An invalid parameter was passed to the function

EAfErrClosedChannel

This operation cannot be performed on a closed channel

std::string GetHostType(const std::string& sHost);

This function returns the host type found in a given host description string sHost. For example, for the host description string “public sip.eyeball.com 5060 tcp” this function will return AF_HOST_PUBLIC.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHost

The host description to parse.

Page 111: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

std::string

The function returns the host type.

std::string SetHostType(std::string& sHost, const std::string& sType);

This function adds a host type (valid host types are AF_HOST_PUBLIC, AF_HOST_RELAY, AF_HOST_FIREWALL, AF_HOST_LOCAL, AF_HOST_DNS_SRV) to the host description found in sHost.

For further details about host descriptions please see .6.3. AFE: Host Types

Parameters:

std::string& sHost

An existing host description. This parameter also holds the result after the function returns.

const std::string& sType

The host type, e.g., AF_HOST_LOCAL or AF_HOST_RELAY

Return value:

std::string

The function returns the updated host description list.

std::string GetHostAddress(const std::string& sHost);

This function returns the address found in a given host description string sHost. For example, for the host description string “ public sip.eyeball.com 5060 tcp” this function will return “ sip.eyeball.com”.

Page 112: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHost

The host description to parse.

Return value:

std::string

The function returns the host address.

std::string SetHostAddress(std::string& sHost, const std::string& sAddress);

This function adds a host address to the host description found in sHost. The function does not check for correct syntax of the existing host description sHost, e.g. it does not check whether a host address is already set.

For details about host description strings please see 6.3. AFE: Host Types

Parameters:

std::string& sHost

An existing host description. This parameter also holds the result after the function returns.

const std::string& sAddress

The host type, e.g. “sip.eyeball.com” or “192.168.0.101”

Return value:

Page 113: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

std::string

The function returns the updated host description list.

int GetHostPort(const std::string& sHost);

This function returns the port found in a given host description string sHost. For example, for the host description string “ public sip.eyeball.com 5060 tcp” this function will return “ 5060”.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHost

The host description to parse.

Return value:

int

The function returns the port.

std::string SetHostPort(std::string& sHost, int iPort);

This function adds a port to the host description found in sHost. The function does not check for correct syntax of the existing host description sHost, e.g. it does not check whether a host port is already set.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

std::string& sHost

An existing host description. This parameter also holds the result after the function returns.

int iPort

The host port.

Page 114: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Return value:

std::string

The function returns the updated host description list.

std::string GetHostProtocol(const std::string& sHost);

This function returns the protocol found in a given host description string sHost. For example, for the host description string “ public sip.eyeball.com 5060 tcp” this function will return AF_PROTOCOL_TCP (“ tcp”).

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHost

The host description to parse.

Return value:

std::string

The function returns the host protocol.

std::string SetHostProtocol(std::string& sHost, const std::string& sProtocol);

This function adds a host protocol to the host description found in sHost. The function does not check for correct syntax of the existing host description sHost, e.g. it does not check whether a host protocol is already set.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

Page 115: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

std::string& sHost

An existing host description. This parameter also holds the result after the function returns.

const std::string& sProtocol

The host protocol, e.g. AF_PROTOCOL_UDP or AF_PROTOCOL_TCP

Return value:

std::string

The function returns the updated host description list.

int GetHostListSize(const std::string& sHostList);

This function returns the number of host descriptions in a host description list. For example, for the host list string “ local 192.168.0.2 5060 UDP; firewall 64.85.36.112 1234 UDP; relay 64.85.36.33 9876 UDP” it will return 3. The function performs only a basic syntax check of sHostList, it should not be used to check whether a list of host descriptions has a valid syntax.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHostList

A string with a list of host descriptions, separated by semi-colon.

Return value:

int

The function returns the number of host descriptions in the host description list.

Page 116: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

std::string GetHostFromList(const std::string& sHostList, int iIndex);

This function returns the host description at a given (zero-based) position in a host description list. For example, for the host list string “ local 192.168.0.2 5060 UDP; firewall 64.85.36.112 1234 UDP; relay 64.85.36.33 9876 UDP” and given iIndex=1 the function will return “ firewall 64.85.36.112 1234 UDP”.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

const std::string& sHostList

A string with a list of host descriptions.

int iIndex

The position (zero-based) of the desired host description.

Return value:

std::string

The function returns the host descriptions at the position given by iIndex in the host description list.

std::string AddHostToList(std::string& sHostList, const std::string& sHost);

This function adds a host description (created by CreateHost) to an existing host description list. For example, when adding the host “ relay 64.85.36.33 9876 UDP” to the existing list “ local 192.168.0.2 5060 UDP; firewall 64.85.36.112 1234 UDP” the function will return “ local 192.168.0.2 5060 UDP; firewall 64.85.36.112 1234 UDP; relay 64.85.36.33 9876 UDP”. When sHostList is empty, the function returns sHost.

For details about host description strings please see 6.3. AFE: Host Types.

Parameters:

std::string& sHostList

A string with a list of host descriptions.

const std::string& sHost

Page 117: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

The host description to add.

Return value:

std::string

The function returns the updated host description list.

std::string CreateHost(const std::string& sType, const std::string& sAddress, int

iPort, const std::string& sProtocol, const struct AfConnectionParams

*pConnectionParams);

This function creates a new host description from the given parameters. The function checks whether the port is in the range 0-65535.

For details about host description strings please see section 6.3. AFE: Host Types.

Parameters:

const std::string& sType

The host type such as AF_HOST_LOCAL or AF_HOST_PUBLIC.

const std::string& sAddress

The IP address or hostname.

int iPort

The port.

const std::string& sProtocol

The protocol such as AF_PROTOCOL_UDP or AF_PROTOCOL_TCP.

const struct

AfConnectionParams

*pConnectionParams

This can be used to customize the STUN UDP and TCP timing parameters. It can also be used to specify TCP timeout value for proxy server and for the server to communicate with the Connect API.

Page 118: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

struct AfConnectionParams

{

int iRTO;

int iRc;

int iRm;

int iTi;

};

The members iRTO, iRc, iRm and iTi are described in STUN RFC 5389. These are used for configuring STUN UDP retransmission mechanism and TCP timeout. iRTO and iTi are specified in milliseconds.The parameter iTi is the timeout for TCP and can be used for configuring the timeout for connecting to the proxy server or other TCP servers.

When pConnectionParams is NULL, the default timing parameters are used with iRTO = 500, iRc = 7, iRm = 16, and iTi = 39500.

Return value:

std::string&

The function returns the created host description.

void SetLogFilePath(const char* filePath)

The purpose of this API is to enable/set logging path, to facilitate AFE logging on non-jailbroken iPhones/iPads. This API should be called after initialization of AFE.

Parameter:

const char* filepath

Expected logging path.

void SetLogFileOptions(const int sizeInMB, const int noOfLogFile);

This function sets the number of log files to be created and size of the each log files.

This API should be called after initialization of AnyFirewallEngine.

Page 119: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Every time when the application is started it writes log in the first log file. i.e in AFEngine0.log. If the size of the current log file exceeds maximum size, it will write logs in the next log file. When the size of the last log file exceeds maximum size, it will clean the first log file and start writing logs in the first log file.

If second parameter is set to 0 or less than 0, it will take default number of log files. If this API is not called, AFE will take default log file size and default number of log files. Here default number of log files is set to 2 (two) and default log file size is set to 1MB.

Parameter:

const int sizeInMB

Size of each log file in megabytes.

const int noOfLogFile

Number of log files to be created.

void Log(const std::string& sMessage)

This function prints the message given in sMessage into AFE log.

Enable logging option in different platform:

AFE Log for Windows

In order to enable logging, EnableAfeLogging.reg available in the installation directory is used. It inserts the key LogAF into registry. The log file, AFEngineX.log, will be created in following directory:

C:\EyeballSDKLogs

AFE Log for Linux and Mac

In order to enable logging, create a file named 'LogAF.cfg' in \etc directory and copy the following text:

loglevel =10

Page 120: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

LogAll

The log file, AFEngineX.log, will be created on following directory:

On Linux, it will be available in /root/.

On Mac, log file will be available in tmp folder.

AFE Log for iOS

In order to enable logging, create a file named 'LogAF.cfg' in /etc directory and copy the following text:

loglevel=10

LogAll

The log file, AFEngineX.log, will be created on following directory:

/var/EyeballSDKLogs/

A jailbroken device is needed for enabling logs. If the directory path is not available 'EyeballSDKLog' directory need to create within /var/ and the directory should have proper permission.

File will be accessible via 'WinSCP' of 'ssh'

AFE Log for Android

In order to enable logging, create a file named 'EyeballSDK.cfg' in /sdcard/ directory and copy the following text:

loglevel=10

LogAll

The log file, AFEngineX.log, will be created on following directory:

/sdcard/EyeballSDKLogs/

Parameters:

String sMessage

The message that we want to print in log

Page 121: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int GetChannelOption(int iChannel, EAfOptionName eOptionName)

This function returns the value for the given channel option for the given channel.

Parameters:

int iChannel

Channels ID whose option name value to get

EafOptionName eOptionName

Name of the channel option whose value to get.

Return Value:

int

Returns the option name value in integer.

bool ClearLoopbackRecvBuffer(int iChannel)

This function clears all the contents of the message buffer for the given loopback channel.

Parameter:

int iChannel

The channel ID whose control channel should be cleared

Return:

Returns true on success, false if the channel is not a loopback channel or a non-existent channel.

Page 122: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

void SetCallbackForNewTurnPort(callback_function &cb, int iChannel)

AFE client can specify a fixed local port to use for TURN allocation.

Please see function "Create" for details. If the client specifies a fixed local port to use for TURN allocation, then the client must use this callback function so that AFE can obtain new local port in case of failure.

If the server sends error response with code 437 when AFE attempts to allocate relayed candidate, then the client provides a new local port by this callback function.

Please see corresponding TURN RFC for error code 437: (http://tools.ietf.org/html/rfc5766#section-6.4)

Parameters:

callback_function &cb:

This function is a pointer which takes input from a function reference in the following format:

In C++:

int AfeClient::GetNewLocalPortForTurn(int oldLocalPort, int isTransportTypeUDP)

{

return newLocalPort;

}

callback_function callback=&(AfeClient::GetNewLocalPortForTurn);

SetCallbackForNewTurnPort(callback, channelId);

Function GetNewLocalPortForTurn must be a static member

In C:

int GetNewLocalPortForTurn(int oldLocalPort, int isTransportTypeUDP)

{

return newLocalPort;

}

callback_function callback = &(GetNewLocalPortForTurn);

af_set_callback_for_new_turn_port(callback, channelId);

GetNewLocalPortForTurn Function description:

int oldLocalPort is the port used by AFE previously.

int isTransportTypeUDP is the value which determines if the transport is UDP or TCP.

Page 123: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

If 1 then UDP, if 0 then TCP.

Return value:

int new Local Port for turn

Return value:

int iChannel

ID of the associated channel

bool SetTurnAuthenticationToken(const int serverStoreID, const CAfStdString&

authenticationToken)

This function is applicable only for AFE initialized with IETF mode. If AFE client wants to useIBM SameTimeserver as its TURN server, then it can specify AUTHENTICATION_TOKEN through this function. Long term credential required for standard TURN allocation will not be used then.

This function is part of configuring AFE, so, it SHOULD be called before the function DetectConnectivity.

Parameters:

const int serverStoreID

A unique server store id for individual server settings.

const CAfStdString&

authenticationToken

A string which takes input in the following format:

CAfStdString authenticationToken;

SetTURNAuthenticationToken(authenticationToken);

Page 124: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Returns:

bool

True if it is set successfully, otherwise False.

CAfStdString* GetTURNAuthenticationToken(const int serverStoreID)

AFE client can retrieve AUTHENTICATION_TOKEN later if it was set by client earlier.

Parameters:

const int serverStoreID

A unique server store id for individual server settings.

Returns:

CAfStdString*

This function returns CAfStdString AUTHENTICATION_TOKEN value.

bool DisableAllTurnAuthentication(const int serverStoreID)

This function is applicable only for AFE initialized with IETF mode.

It disables all types of TURN authentication - long-term credential mechanism (username, password) of standard TURN protocol and authentication token mechanism of IBM SameTime server.

If the client application invokes function SetTURNUsernamePassword or SetTurnAuthenticationToken later, authentication mechanism will be enabled and enforced then.

This function is part of configuring AFE. So it SHOULD be called before the function DetectConnectivity.

Parameters:

const int serverStoreID

Page 125: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

A unique server store id for individual server settings.

Returns:

bool

True if all TURN authentication mechanism disable successfully, otherwise False.

8. AFE: C Interface for AFE APIs

C Interface for AFE APIs

The AnyFirewall™ package comes with a C programming interface for AFE APIs as well. The function descriptions are similar to their C++ counterparts. For more information on the “C” AFE APIs, please see the AnyFirewallEngine.h file that is provided with the package.

Page 126: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

9. AFE: Sample Application

Sample Application

The AnyFirewall™ package contains two sample applications to demonstrate the main features and capabilities of the AnyFirewall™ Engine. The VoIPApp project is the primary project with executable

Page 127: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

binary. It uses reSIProcate as SIP stack. The SimpleVoIPApp project is a simpler demonstration of AnyFirewall™ Engine. It does not use a complete SIP stack.

The requirement and structure of the VoIPApp project is described below.

System Requirements

The sample application is ready to compile with Microsoft Visual Studio 2005, Red Hat Enterprise Linux 4.4, or Mac OS X 10.5.

OpenSSL (0.9.7a) and GCC 3.4.6 (or greater) is required for the Linux and Mac OS X versions.

Structure

Windows Structure

The application project (VoIPApp) for Windows consists of the following subdirectories: Bin/

Redistributable libraries from Visual Studio 2005 and AnyFirewall™ Engine dll, Audio Engine dll, and the pre-compiled sample program (in the Bin/Release sub-directory).

Libs/

Eyeball AnyFirewall™ Engine and Eyeball Audio Engine header files.

Network/

Management of SIP messages and audio packets, interface to AnyFirewall™ Engine.

The files NetworkController.cpp/NetworkController.h in the Network subdirectory contain the code that interacts with the AnyFirewall™ Engine. In particular, the class NetworkController controls the application, i.e., creates and handles SIP messages and sends and receives audio packets.

VoipAppGUI/

Page 128: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Application user interface. It uses a couple of MFC classes to display the main application windows and to handle window messages.

The application project is located in the src/VoipApp subdirectory of the package.There are also three more directories included in this project for reSIProcate. They are resip, rutil and ares. The resip folder has two subdirectories: stack and dum. They are described in Integration with reSIProcate in Section 10.4. SIP Stack Integration.

Linux and Mac OS X Structure

The application project for Linux and Mac OS X consists of the following subdirectories: lib/

Contains the AnyFirewall™ Engine shared object (Linux) or dynamic library (Mac OS X).

include/

Eyeball AnyFirewall™ Engine header files.

voipphone/

The sample application for AnyFirewall™ Engine, including a command-line user interface and a network handling class.

The networkhandler.cpp/networkhandler.h files contain the code that interacts with the AnyFirewall™ Engine. The NetworkHandler class controls the application, i.e., creates and handles SIP messages and sends and receives audio packets.

voipphone/SipUtil/

The class SipUtil is used to construct and parse SIP messages. It plays the role of a basic SIP stack.

voipphone/Audio/

Page 129: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

A library that contains the Linux playback and recording functions.

voipphone/Codec/

Contains the g711 codec used by the application.

Compilation and execution instructions can be found in the README file in the voipphone directory.

Certain issues must be ensured before you run the sample application on Linux platform:

The lib directory must exist in the VoipAppLinux directory. If you see the lib as a file and you cannot open it, delete it and make a lib directory in VoipAppLinux directory. Then you can manually copy the AFE shared library libAFE.so from the directory AFE_Shared_Library.

The selinux must be disabled. Make sure it is disabled.

You must run the executable file through the shell script(voipphone.sh).

If you cannot hear voice or your peer cannot hear your voice, make sure that the audio capture is ON from the volume control. You can go there by System->preference->volume control. If the problem persists, you can try with installing creative sound card.

You can increase the verbosity of the voipphone.sh by removing 2> /dev/null from the voipphone.sh file. Error messages will be printed in the shell now.

Functionality

The application exemplifies the usage of the AnyFirewall™ Engine API. The application allows making SIP calls to SIP softphones, gateways and devices. The source code of the sample application contains the functionality to generate SIP messages and in particular demonstrates how to generate SIP messages with SDP part compliant with the ICE RFC [3]. The application can also be used to call non-ICE compliant devices.

The application supports sending DTMF using the keyboard shortcut ALT-0, ALT-1, ALT-2, etc.

Page 130: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

10. AFE: Integration with 3rd Party Software

Integration with 3rd Party Software

In this section, we describe the steps to integrate AnyFirewall™ Engine with existing 3rd party software such as existing softclients, media engines and SIP stacks.

Page 131: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Eyeball AnyFirewall™ Engine supports two modes of integration: media (M) and signaling (S). Media mode is the basic mode of operation. In this mode, AnyFirewall™ Engine is used to transmit media (audio and video) across firewalls and NATs. Integration with SIP stacks in this mode requires only exchange of information about ICE candidates with the SIP stack. In the signaling mode, AnyFirewall™ Engine is used to send and receive SIP messages generated by the SIP stack. The signaling mode allows an application to traverse firewalls, NATs, and HTTP proxies for SIP signaling.

When signaling mode is used, it is typically used together with media mode, in what we refer to as “signaling (S) and media (M)” mode. In “S and M” mode, all SIP and media packets are sent and received using the AnyFirewall™ Engine. It is possible for the application to remove dependencies to a socket library and use the AnyFirewall™ Engine exclusively for all network functionality.

10.1. AFE: Media Mode

Media Mode

Page 132: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 4: Media mode

As outlined in Figure 4, in the media mode, AnyFirewall™ Engine is only used to transmit audio and video. Integration with SIP stacks in this mode is limited to creating media sessions (i.e. setup RTP and RTCP sockets for audio or video) and exchanging ICE candidates (i.e., IPs and ports that the AnyFirewall™ Engine is listening on for media packets sent from the remote SIP endpoint). AnyFirewall™ Engine handles firewall and NAT traversal for audio and video RTP and RTCP packets. AnyFirewall™ Engine API functions, namely MakeOffer, MakeAnswer and ProcessAnswer, are used to obtain an SDP description that includes the local ICE candidates, and parse the SDP description received from the remote SIP endpoint. The usage of these API functions is described in section 5. Code Examples for Windows, Linux, Mac, iOS of this guide and the sample application.

The integration of AnyFirewall™ Engine with media engines is described below.

Media Engine Integration

In order to integrate the AnyFirewall™ Engine with media engines, it is necessary to pass RTP packets received by AnyFirewall™ Engine to the media engine and to send RTP packets generated by the media engine to AnyFirewall™ Engine. Some media engines, such as TeamSpirt® Voice and Video Engine, also generate and process RTCP packets. In this case, the RTCP packets must also be sent and received via AnyFirewall™ Engine. Most media engines provide APIs to pass received RTP and RTCP packets to the media engine. In order to send RTP and RTCP packets generated by the media engine,

Page 133: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

callback functions are provided. These functions are called by the media engine and pass the RTP and RTCP data to the AnyFirewall™ Engine.

The process of sending and receiving media is outlined in section 5. Code Examples for Windows, Linux, Mac, iOS and the relevant source code is also available in the sample application.

Example: TeamSpirit® Voice and Video Engine - Sending

In order to use the AFE functions to send RTP and RTCP packets generated by TeamSpirit® Voice and Video Engine, the following callback function must be implemented: void SPIRIT_STDCALL TS_Transport_SendPacket(void *pInst, TS_tePacketType PacketType,

const void *pData, uint32 DataSize, TS_tChannelHandle Channel);

In order to use this function, an instance of the structure TSVoice_tChannelParams must be initialized as described below: class CMyTransport {…};

CMyTransport myTransport;

TSVoice_tChannelParams ChannelParams;

ChannelParams .Transport.Type = ts_trans_external;

ChannelParams .Transport.Ext.SendData = TS_Transport_SendPacket;

ChannelParams .Transport.Ext.Release = 0;

ChannelParams .Transport.Ext.pInst = &myTransport;

and then passed to the TeamSpirit® Voice and Video engine function ts_error SPIRIT_STDCALL TSVoice_StartChannel(TS_tChannelHandle Channel, const

TSVoice_tChannelParams *pParams);

This function is called for each voice channel.

The function TS_Transport_SendPacket simply needs to call the respective AnyFirewall™ Engine function Send as outlined in the following sample: void SPIRIT_STDCALL TS_Transport_SendPacket(void *pInst, TS_tePacketType PacketType,

const void *pData,

uint32 DataSize,

TS_tChannelHandle Channel

)

{

CMyTransport* pTransport = (CMyTransport*)pInst;

CAnyFirewallEngine* pMyAFE = pTransport->GetAFE();

int iChannel = pTransport->GetChannelByHandle(Channel, PacketType);

pMyAFE->Send(iChannel, pData, DataSize, AF_NON_BLOCKING);

}

For each voice channel generated in TeamSpirit® Voice and Video, two AnyFirewall™ Engine channels are required, one for RTP and one for RTCP packets.

Page 134: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Example: TeamSpirit® Voice and Video Engine - Receiving

RTP and RTCP packets received through the AnyFirewall™ Engine interface function Recv are passed on to TeamSpirit® Voice and Video Engine via the function call: ts_error SPIRIT_STDCALL TSVoice_PushMediaPacket(TS_tChannelHandle Channel,

TS_tePacketType PacketType, const void *pData, uint32 DataSize);

This can be done in a receiver function as outlined in the following sample code:

while (!stop)

{

len = myAFE.Recv(RTPchannel, data, len, AF_BLOCKING);

if (len > 0)

{

TSVoice_PushMediaPacket(channel[RTPchannel],ts_packet_rtp, data,

len);

}

}

while (!stop)

{

len = myAFE.Recv(RTCPchannel, data, len, AF_BLOCKING);

if (len > 0)

{

TSVoice_PushMediaPacket(channel[RTCPchannel], ts_packet_rtcp, data, len);

}

}

In the receiving functions, it is necessary to distinguish channels created by TeamSpirt® Voice and Video Engine and AnyFirewall™ Engine channels and maintain them separately.

Example: Global IP Sound VoiceEngine™ - Sending

In order to use the AFE functions to send RTP and RTCP packets generated by Global IP Sound VoiceEngine™, the following class must be implemented: class GIPS_transport

{

public:

virtual void SendPacket(int channel, const void *data, int len);

virtual void SendRTCPPacket(int channel, const void *data,int len);

};

Page 135: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

In order to use the functions of this class, an instance of the class is passed to the VoiceEngine™ function. int GIPSVE_SetSendTransport(int channel, GIPS_transport&transport);

This function is called for each voice channel.

The functions SendPacket and SendRTCPPacket simply need to call the respective AnyFirewall™ Engine function Send as outlined in the following sample:

void GIPS_transport::SendPacket(int channel, const void *data, int len)

{

myAFE.Send(RTPchannel[channel],data,len,AF_NON_BLOCKING);

}

void GIPS_transport::SendRTCPPacket(int channel, const void *data, int len)

{

myAFE.Send(RTCPchannel[channel],data,len,AF_NON_BLOCKING);

}

For each voice channel generate in Global IP Sound VoiceEngine™, two AnyFirewall™ Engine channels are required, one for RTP and one for RTCP packets.

Example: Global IP Sound VoiceEngine™ - Receiving

RTP and RTCP packets received through the AnyFirewall™ Engine interface function Recv are passed on to Global IP Sound VoiceEngine™ via the two function calls: int GIPSVE_ReceivedRTPPacket(int channel, const void *data, int len);

int GIPSVE_ReceivedRTCPPacket(int channel, const void *data, int len);

This can be done in a receiver function as outlined in the following sample code: …

while (!stop)

{

len = myAFE.Recv(RTPchannel,data,len,AF_BLOCKING);

if (len>0)

{

GIPSVE_ReceivedRTPPacket(channel[RTPchannel],data,len);

}

}

while (!stop)

{

len = myAFE.Recv(RTCPchannel,data,len,AF_BLOCKING);

if (len>0)

{

GIPSVE_ReceivedRTPPacket(channel[RTCPchannel],data,len);

}

}

Page 136: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

In the receiving functions, it is necessary to distinguish channels created by Global IP Sound VoiceEngine™ and AnyFirewall™ Engine channels and maintain them separately.

10.2. AFE: Signaling and Media Mode

Signaling and Media Mode

In order to use AnyFirewall™ Engine to send SIP messages and establish the connection to the SIP server, it is necessary to replace the SIP stack’s socket functions with those of AnyFirewall™ Engine. The actual steps to achieve this differ depending on the SIP stack. Some SIP stacks allow replacing the lower layer functions and even provide an API for that; in other cases the source code of the SIP stack must be

Page 137: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

modified and socket calls must be replaced with the functions from the connection management and data transfer APIs of AnyFirewall™ Engine, such as Connect, Send, and Receive.

Figure 5: Signaling and Media Mode

For the connection to a server, the API function Connect is used. It takes the IP, port, and protocol (UDP, TCP, TLS) of the SIP server as parameter and connects using the most suitable transport. It is also possible to traverse HTTP proxies in this mode.

Page 138: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

10.3. AFE: Interoperability with 3rd Party SIP endpoints

Interoperability with 3rd Party SIP endpoints

Page 139: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Interoperability with 3 rd party endpoints not supporting ICE, such as PSTN gateways or soft switches, usually does not require additional integration work. An SDP description that does not contain any ICE candidates or contains ICE candidates in a format that does not comply with ICE RFC will still be parsed and processed by AnyFirewall™ Engine, using the IP address and port information found in the m/c line of the SDP received from the 3 rd party end point.

10.4. AFE: SIP Stack Integration

SIP Stack Integration

Eyeball AnyFirewall™ Engine can work with any standard 3 rd Party SIP stacks. The basic idea of integrating AnyFirewall™ Engine with a SIP stack is to replace sockets with AnyFirewall™ Engine channels. Following is the brief description of how it can be integrated with two of the most popular open source SIP stacks of the industry.

Page 140: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Integration with oSIP

In this section, we describe oSIP’s high level architecture and changes required to integrate it with AnyFirewall™ Engine. Then we will show the procedure of making a call using the integrated solution.

oSIP

The GNU oSIP library is a popular open source implementation of SIP. The library provides support for multimedia and telecom software developers with an easy and powerful interface to use SIP based sessions in their applications. The high level architecture of oSIP is as following:

Page 141: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 6: oSIP Architecture

One way to integrate oSIP with AnyFirewall™ Engine is to use SIP factory, SIP parser and SIP transaction libraries from oSIP only. The user application uses a network controller class which communicates with the SIP stack and AnyFirewall™ Engine. The network controller maintains the call state and uses AnyFirewall™ Engine’s recv() and send() functions to receive and send messages. AnyFirewall™ Engine’s internal functions take care of DNS resolving. In short, the integration steps are as follows:

Network controller asks oSIP to prepare the SIP message.

oSIP prepares the message and sends it back to the network controller.

Network controller sends the message using AnyFirewall™ Engine.

Network controller checks if any SIP message is received.

When received, it sends the message to oSIP for parsing.

Page 142: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 7: oSIP architecture integrated with AnyFirewall™ Engine

Initializing oSIP

To handle incoming events, oSIP provides some handler functions. We have to set these callback functions during the oSIP initialization. The initialization function is as follows: void InitoSIPCallback()

{ ...

// initial request received callback

osip_set_message_callback(m_osip ,OSIP_IST_INVITE_RECEIVED,

&RequestMessageCallback);

...

// set other call back messages

}

In this code fragment RequestMessageCallback function is set as the handler function for the OSIP_IST_INVITE_RECEIVED event. The structure of RequestMessageCallback function will be described later.

Page 143: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Making a Call

Making a call starts with creating audio channels. It is similar to the process described in Creating an audio channel. m_iAudioChannelRTP = m_pAFEngine->Create(AF_CHANNEL_RTP);

m_iAudioChannelRTCP = m_pAFEngine->Create(AF_CHANNEL_RTCP);

Then candidate parameters of the audio channels are obtained. The CreateSession API creates a session with one media stream and two audio channels. It returns a unique session ID. Then the MakeOffer API is used to initialize all the channels. This returns the SDP structure. char sMediaStreamSpec[100];

sprintf(sMediaStreamSpec, "%s %d %d",

AF_MEDIA_STREAM_AUDIO,

m_iAudioChannelRTP,

m_iAudioChannelRTCP

);

m_iSession = m_pAFEngine->CreateSession(sMediaStreamSpec);

std::string sAudioSDPInfo = m_pAFEngine->MakeOffer(m_iSession);

...

osip_message_t*msg = BuildInviteRequest(

sCallerUri,

sCalleeUri,

sAudionSDPInfo);

SendSipMessage(msg)

);

Then to initiate a call, a SIP INVITE message is to be sent. The BuildInviteRequest will build the message with the SDP structure and SendSipMessage will send it. This is also similar to the code given in Sending a SIP INVITE. These two functions will have oSIP functions in them. Following is the sample code of these two functions: osip_message_t*BuildInviteRequest(

const string& sCallerUri,

const string& sCalleeUri,

const string& sAudionSDPInfo)

{

osip_message_t* msg = NULL;

osip_message_init(&msg);

osip_message_set_method(msg, _strdup(METHOD_INVITE));

...

// Set uri, version, via, to, from, contact, call-id,

// cseq, max-forward etc. fields with osip functions here

...

//add SDP

osip_message_set_content_type(msg, SDP_CONTENT_TYPE);

osip_message_set_content_length(msg,

itoa(sAudionSDPInfo.size()).c_str());

osip_message_set_body(msg,

sAudionSDPInfo.c_str(),sBody.length()

);

return msg;

}

SendSipMessage(osip_message_t* message)

{

Page 144: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

int iLen;

char *szMsg = NULL;

osip_message_to_str(message, &szMsg, (size_t*)&iLen);

if (m_pAFEngine->Send(m_iSipChannel, szMsg, (int)iLen, AF_ BLOCKING) < 0)

{

//handle errors here

}

}

To receive incoming messages to a SIP channel we need a thread.

NetworkThread(void *arg)

{

for (;;)

{

int iSelect = m_pAFEngine->Select(NUM_CHANNEL, aChannels,

aInputEvents,

aOutputEvents,

NETWORK_WAIT_TIME

);

if (iSelect>0 && aOutputEvents[sipChannelIndex]==1)

{

iRet = m_pAFEngine->Recv (m_iSipChannel,

m_pNetworkBuffer.get(),BUFFER_SIZE, AF_NON_BLOCKING);

//save the message for parsing and

// call event handler functions

}

}

}

The handler functions initialization as described in Initializing oSIP, ensures that when there is an incoming event in the network, it will call the respective function.

If set, the RequestMessageCallback function will decide the response based on the event. For example response to an invite message will be 100TRYING and 180RINGING. So the RequestMessageCallback code will be as follows:

case OSIP_IST_INVITE_RECEIVED:

response = BuildInviteResponse(request, 100, "Trying");

SendSipMessage(response);

response = BuildInviteResponse(request, 180, "Ringing");

SendSipMessage(response);

When responding to a call, user will send a 200OK response.

Page 145: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

response = BuildInviteResponse(request, 200, "OK");

SendSipMessage(response);

In this section we showed how to send SIP INVITE message and receive responses to establish a call using oSIP integrated with AnyFirewall™ Engine. Similarly other SIP messages and responses can be sent and received.

Integration with reSIProcate

In this section, we describe the high level architecture of reSIProcate and changes required to integrate it with AnyFirewall™ Engine. Then we show the procedure of initializing reSIProcate and making a call using the integrated solution.

reSIProcate

reSIProcate is another popular open source SIP implementation. The reSIProcate SIP stack is now used in many commercial and open source products. It is a high performance, object oriented C++ SIP stack. It supports variety of operating systems (Windows, UNIX) with TCP, UDP and TLS transports. Following is the high level architecture of reSIProcate:

Page 146: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 8: reSIProcate architecture

After integrating reSIProcate with AnyFirewall™ Engine it will have following structure:

Page 147: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Figure 9: reSIProcate architecture after integration

InitializingDUM

At first the DUM object needs to be initialized with handlers.

reSIProcate has InviteSessionHandler, ClientRegistrationHandler and OutOfDialogHandler.

Page 148: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

We design a common handler (AFEUa) for these three handlers that uses AnyFirewall™ Engine API.

Figure 10: DUM handlers

The initialization is as following: DialogUsageManager* dumUa = new DialogUsageManager(m_SipStack);

// here AFEUa is a common handler for DUM which inherits the reSIProcate

// handler classes

AFEUa ua = new AFEUa();

//init handlers

dumUa->setInviteSessionHandler(&ua);

dumUa->setClientRegistrationHandler(&ua);

dumUa->addOutOfDialogHandler(OPTIONS, &ua);

...

Making a call

To make a call, audio channels need to be created as shown in Creating an audio channel. m_iAudioChannelRTP = m_pAFEngine->Create(AF_CHANNEL_RTP);

m_iAudioChannelRTCP = m_pAFEngine->Create(AF_CHANNEL_RTCP);

Then, candidate parameters are obtained as shown in Obtaining candidate parameters of the audio channels. AnyFirewall™ Engine APIs CreateSession and MakeOffer are also used here. char sMediaStreamSpec[100];

sprintf(sMediaStreamSpec, "%s %d %d",

AF_MEDIA_STREAM_AUDIO,

m_iAudioChannelRTP,

m_iAudioChannelRTCP

);

Page 149: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

m_iSession = m_pAFEngine->CreateSession(sMediaStreamSpec);

std::string sAudioSDPInfo = m_pAFEngine->MakeOffer(m_iSession);

To send an INVITE message, the SDP message is added to the DUM handler. Then makeInviteSession will create the message. Send function will put the message in queue to transport. ua.txt = (new Data(sAudioSDPInfo));

ua.hfv = new HeaderFieldValue(ua.txt->data(), ua.txt->size());

// Mime is a resiprocate object for assigning types. Mime type("application", "sdp");

ua.sdp = new SdpContents(ua.hfv, type);

inviteMessage = dumUa->makeInviteSession(uacAor, ua.sdp,

new AFEAppDialogSet(*dumUa, "UA(INVITE)"));

dumUa->send(inviteMessage);

The SIP message will be sent through AnyFirewall™ Engine function. CAFEConnection::write( const char *buf, const int count )

{

...

CAFETransport::pAFEngine->Send(getChannel(),

buf,count,AF_NON_BLOCKING);

...

}

To receive messages reSIProcate can have single or multiple threads for SIP stack or DUM. Here in this example, a single thread is shown: while (1)

{

// updates timer queue and transaction classes m_SipStack.process();

// process goes on until Transaction User’s(SIP stack) FIFO is empty

while(dumUa->process());

//take decision as the uas status

}

Similar AnyFirewall™ Engine function is used for reading SIP messages: int CAFEConnection::read( char* buf, int count )

{

...

CAFETransport::pAFEngine->Recv(getChannel(),buf, count,AF_NON_BLOCKING);

...

}

Also the AFEUa handler classes have to be defined with their functions. For example: when an INVITE message is received and processed, it generates onNewSession and onOffer event. Receiving these events we call respective AnyFirewall™ Engine functions from the onNewSession and onOffer functions. To send 180 Ringing and 200OK, following codes could be used for the handler: virtual void onNewSession()

{

...

serverInviteSession->provisional(180);

}

virtual void onOffer()

{

offered = true;

...

m_iSession = m_pAfe->CreateSession(mediaDescription);

const std::string callerTag = m_pSipUtil->GetTagOfFromLine(msg);

Page 150: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

string sAudioSDPInfo = m_pAfe->MakeAnswer(m_iSession, remoteSDP, callerTag);

txt = (new Data(sAudioSDPInfo));

hfv = new HeaderFieldValue(txt->data(), txt->size());

Mime type("application", "sdp");

Sdp1 = new SdpContents(hfv, type);

...

}

In this section we showed how to implement the common DUM handler that uses AnyFirewall™ Engine methods. Then we showed how to send SIP INVITE message and receive responses using reSIProcate integrated with AnyFirewall™ Engine. Using the same procedure other messages can be sent and received.

Page 151: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

11. AFE: References

References

1. J. Rosenberg, R. Mahy, P. Matthews and D. Wing: Session Traversal Utilities for NAT (STUN), RFC 5389, October 2008.

2. R. Mahy, P. Matthews and J. Rosenberg: Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN), RFC 5766, April 2010.

3. J. Rosenberg: Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols, RFC 5245, April 2010.

4. S. Perreault Ed, J. Rosenberg: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations, RFC 6062, November 2010.

5. J. Rosenberg, A. Keranen, B. B. Lowekamp, A. B. Roach: TCP Candidates with Interactive Connectivity Establishment (ICE), RFC 6544, March 2012.

Page 152: AnyFirewall Engine v10.0 Developer Guide

Copyright © 2002-2014 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

12. AFE: Legal and Contact Information

Legal and Contact Information

Copyright © 2002-2013 Eyeball Networks Inc. Patented and patents pending. All rights reserved.

Confidential Information: This document contains confidential and proprietary information. The document has been provided to you in your capacity as a customer or evaluator of Eyeball Networks Inc.'s products. Unauthorized reproduction and distribution is prohibited unless specifically approved by Eyeball Networks Inc.

Eyeball, Eyeball.com, its logos, AnyBandwidth™ and AnyFirewall™ are trademarks of Eyeball Networks Inc. All other referenced companies and product names may or may not be trademarks of their respective owners.

For more information visit Eyeball Networks at www.eyeball.com.

Department E-mail

Sales [email protected]

Technical Support [email protected]

Corporate Headquarters:

730 - 1201 West Pender Street Vancouver, B.C. V6E 2V2 Canada

Tel. +1 604.921.5993 Fax +1 604.921.5909