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 DefinitionDescription
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.
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_MTLS Mutual TLS or MTLS is a TLS channel which is used in a situation where both endpoints need to authenticate each other. This channel offers the self certificate, previously set by the client, to the peer during TLS handshaking.
User must set a valid certificate and private key using
SetCertificate() API before creating this channel.
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:

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.


Thread 1Thread 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);
 "" 
 "" 


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 TypeDescription
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.
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.
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.
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.
EAfEventNewConnectionAccepted This event is fired when an incoming connection is accepted on a listening channel. After getting this event user may read/write on the channel.


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;
  }             
}