summaryrefslogtreecommitdiff
path: root/pjnath/include
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-06-06 14:47:10 +0000
committerBenny Prijono <bennylp@teluu.com>2008-06-06 14:47:10 +0000
commit8ec5bd6b3d5bafb1d3ab11236a3adc45ac5f04d8 (patch)
tree75c82cf12d34d58e3ccf64e6eb08e8628e8f94cf /pjnath/include
parent77825e4c00356383e69f3fc4c63eccd0a3aa103f (diff)
Major major modifications related to ticket #485 (support for TURN-07):
- Added STUN socket transport pj_stun_sock - Integration of TURN-07 to ICE - Major refactoring in ICE stream transport to make it simpler - Major modification (i.e. API change) in almost everywhere else - Much more elaborate STUN, TURN, and ICE tests in pjnath-test git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1988 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath/include')
-rw-r--r--pjnath/include/pjnath.h1
-rw-r--r--pjnath/include/pjnath/config.h78
-rw-r--r--pjnath/include/pjnath/errno.h9
-rw-r--r--pjnath/include/pjnath/ice_session.h77
-rw-r--r--pjnath/include/pjnath/ice_strans.h695
-rw-r--r--pjnath/include/pjnath/nat_detect.h1
-rw-r--r--pjnath/include/pjnath/stun_config.h13
-rw-r--r--pjnath/include/pjnath/stun_msg.h21
-rw-r--r--pjnath/include/pjnath/stun_session.h50
-rw-r--r--pjnath/include/pjnath/stun_sock.h403
-rw-r--r--pjnath/include/pjnath/stun_transaction.h17
-rw-r--r--pjnath/include/pjnath/turn_session.h346
-rw-r--r--pjnath/include/pjnath/turn_sock.h230
-rw-r--r--pjnath/include/pjnath/types.h378
14 files changed, 1637 insertions, 682 deletions
diff --git a/pjnath/include/pjnath.h b/pjnath/include/pjnath.h
index 962aeba0..84096beb 100644
--- a/pjnath/include/pjnath.h
+++ b/pjnath/include/pjnath.h
@@ -26,6 +26,7 @@
#include <pjnath/stun_config.h>
#include <pjnath/stun_msg.h>
#include <pjnath/stun_session.h>
+#include <pjnath/stun_sock.h>
#include <pjnath/stun_transaction.h>
#include <pjnath/turn_session.h>
#include <pjnath/turn_sock.h>
diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h
index c84fe18c..e002a105 100644
--- a/pjnath/include/pjnath/config.h
+++ b/pjnath/include/pjnath/config.h
@@ -142,6 +142,84 @@
/* **************************************************************************
+ * STUN TRANSPORT CONFIGURATION
+ */
+
+/**
+ * The packet buffer size for the STUN transport.
+ */
+#ifndef PJ_STUN_SOCK_PKT_LEN
+# define PJ_STUN_SOCK_PKT_LEN 2000
+#endif
+
+
+/**
+ * The duration of the STUN keep-alive period, in seconds.
+ */
+#ifndef PJ_STUN_KEEP_ALIVE_SEC
+# define PJ_STUN_KEEP_ALIVE_SEC 15
+#endif
+
+
+/* **************************************************************************
+ * TURN CONFIGURATION
+ */
+
+/**
+ * Maximum DNS SRV entries to be processed in the DNS SRV response
+ */
+#ifndef PJ_TURN_MAX_DNS_SRV_CNT
+# define PJ_TURN_MAX_DNS_SRV_CNT 4
+#endif
+
+
+/**
+ * Maximum TURN packet size to be supported.
+ */
+#ifndef PJ_TURN_MAX_PKT_LEN
+# define PJ_TURN_MAX_PKT_LEN 3000
+#endif
+
+
+/**
+ * The TURN permission lifetime setting. This value should be taken from the
+ * TURN protocol specification.
+ */
+#ifndef PJ_TURN_PERM_TIMEOUT
+# define PJ_TURN_PERM_TIMEOUT 300
+#endif
+
+
+/**
+ * The TURN channel binding lifetime. This value should be taken from the
+ * TURN protocol specification.
+ */
+#ifndef PJ_TURN_CHANNEL_TIMEOUT
+# define PJ_TURN_CHANNEL_TIMEOUT 600
+#endif
+
+
+/**
+ * Number of seconds to refresh the permission/channel binding before the
+ * permission/channel binding expires. This value should be greater than
+ * PJ_TURN_PERM_TIMEOUT setting.
+ */
+#ifndef PJ_TURN_REFRESH_SEC_BEFORE
+# define PJ_TURN_REFRESH_SEC_BEFORE 60
+#endif
+
+
+/**
+ * The TURN session timer heart beat interval. When this timer occurs, the
+ * TURN session will scan all the permissions/channel bindings to see which
+ * need to be refreshed.
+ */
+#ifndef PJ_TURN_KEEP_ALIVE_SEC
+# define PJ_TURN_KEEP_ALIVE_SEC 15
+#endif
+
+
+/* **************************************************************************
* ICE CONFIGURATION
*/
diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h
index 56763916..3cd3320a 100644
--- a/pjnath/include/pjnath/errno.h
+++ b/pjnath/include/pjnath/errno.h
@@ -121,6 +121,15 @@
#define PJNATH_ESTUNINSERVER (PJNATH_ERRNO_START+42) /* 370042 */
+/************************************************************
+ * STUN SESSION/TRANSPORT ERROR CODES
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * STUN object has been destoyed.
+ */
+#define PJNATH_ESTUNDESTROYED (PJNATH_ERRNO_START+60) /* 370060 */
+
/************************************************************
* ICE ERROR CODES
diff --git a/pjnath/include/pjnath/ice_session.h b/pjnath/include/pjnath/ice_session.h
index 2af223f3..87b723af 100644
--- a/pjnath/include/pjnath/ice_session.h
+++ b/pjnath/include/pjnath/ice_session.h
@@ -129,6 +129,11 @@ PJ_BEGIN_DECL
*/
/**
+ * Forward declaration for checklist.
+ */
+typedef struct pj_ice_sess_checklist pj_ice_sess_checklist;
+
+/**
* This enumeration describes the type of an ICE candidate.
*/
typedef enum pj_ice_cand_type
@@ -194,6 +199,24 @@ typedef struct pj_ice_sess_comp
/**
+ * Data structure to be attached to internal message processing.
+ */
+typedef struct pj_ice_msg_data
+{
+ unsigned transport_id;
+ pj_bool_t has_req_data;
+
+ union data {
+ struct request_data {
+ pj_ice_sess *ice;
+ pj_ice_sess_checklist *clist;
+ unsigned ckid;
+ } req;
+ } data;
+} pj_ice_msg_data;
+
+
+/**
* This structure describes an ICE candidate.
* ICE candidate is a transport address that is to be tested by ICE
* procedures in order to determine its suitability for usage for
@@ -204,16 +227,34 @@ typedef struct pj_ice_sess_comp
typedef struct pj_ice_sess_cand
{
/**
+ * The candidate type, as described in #pj_ice_cand_type enumeration.
+ */
+ pj_ice_cand_type type;
+
+ /**
+ * Status of this candidate. The value will be PJ_SUCCESS if candidate
+ * address has been resolved successfully, PJ_EPENDING when the address
+ * resolution process is in progress, or other value when the address
+ * resolution has completed with failure.
+ */
+ pj_status_t status;
+
+ /**
* The component ID of this candidate. Note that component IDs starts
* with one for RTP and two for RTCP. In other words, it's not zero
* based.
*/
- pj_uint32_t comp_id;
+ pj_uint8_t comp_id;
/**
- * The candidate type, as described in #pj_ice_cand_type enumeration.
+ * Transport ID to be used to send packets for this candidate.
*/
- pj_ice_cand_type type;
+ pj_uint8_t transport_id;
+
+ /**
+ * Local preference value, which typically is 65535.
+ */
+ pj_uint16_t local_pref;
/**
* The foundation string, which is an identifier which value will be
@@ -383,7 +424,7 @@ typedef enum pj_ice_sess_checklist_state
* This structure represents ICE check list, that is an ordered set of
* candidate pairs that an agent will use to generate checks.
*/
-typedef struct pj_ice_sess_checklist
+struct pj_ice_sess_checklist
{
/**
* The checklist state.
@@ -405,7 +446,7 @@ typedef struct pj_ice_sess_checklist
*/
pj_timer_entry timer;
-} pj_ice_sess_checklist;
+};
/**
@@ -430,12 +471,14 @@ typedef struct pj_ice_sess_cb
*
* @param ice The ICE session.
* @param comp_id ICE component ID.
+ * @param transport_id Transport ID.
* @param pkt The STUN packet.
* @param size The size of the packet.
* @param dst_addr Packet destination address.
* @param dst_addr_len Length of destination address.
*/
pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id,
+ unsigned transport_id,
const void *pkt, pj_size_t size,
const pj_sockaddr_t *dst_addr,
unsigned dst_addr_len);
@@ -446,6 +489,7 @@ typedef struct pj_ice_sess_cb
*
* @param ice The ICE session.
* @param comp_id ICE component ID.
+ * @param transport_id Transport ID.
* @param pkt The whole packet.
* @param size Size of the packet.
* @param src_addr Source address where this packet was received
@@ -453,6 +497,7 @@ typedef struct pj_ice_sess_cb
* @param src_addr_len The length of source address.
*/
void (*on_rx_data)(pj_ice_sess *ice, unsigned comp_id,
+ unsigned transport_id,
void *pkt, pj_size_t size,
const pj_sockaddr_t *src_addr,
unsigned src_addr_len);
@@ -496,6 +541,7 @@ typedef struct pj_ice_rx_check
PJ_DECL_LIST_MEMBER(struct pj_ice_rx_check);
unsigned comp_id; /**< Component ID. */
+ unsigned transport_id; /**< Transport ID. */
pj_sockaddr src_addr; /**< Source address of request */
unsigned src_addr_len; /**< Length of src address. */
@@ -553,6 +599,9 @@ struct pj_ice_sess
unsigned rcand_cnt; /**< # of remote cand. */
pj_ice_sess_cand rcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */
+ /* Array of transport datas */
+ pj_ice_msg_data tp_data[4];
+
/* List of eearly checks */
pj_ice_rx_check early_check; /**< Early checks. */
@@ -582,6 +631,17 @@ PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type);
/**
+ * This is a utility function to retrieve the string name for the
+ * particular role type.
+ *
+ * @param role Role type.
+ *
+ * @return The string representation of the role.
+ */
+PJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role);
+
+
+/**
* This is a utility function to calculate the foundation identification
* for a candidate.
*
@@ -685,6 +745,8 @@ PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
*
* @param ice ICE session instance.
* @param comp_id Component ID of this candidate.
+ * @param transport_id Transport ID to be used to send packets for this
+ * candidate.
* @param type Candidate type.
* @param local_pref Local preference for this candidate, which
* normally should be set to 65535.
@@ -699,6 +761,7 @@ PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
*/
PJ_DECL(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
unsigned comp_id,
+ unsigned transport_id,
pj_ice_cand_type type,
pj_uint16_t local_pref,
const pj_str_t *foundation,
@@ -797,6 +860,9 @@ PJ_DECL(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice,
*
* @param ice The ICE session.
* @param comp_id Component ID.
+ * @param transport_id Number to identify where this packet was received
+ * from. This parameter will be returned back to
+ * application in \a on_tx_pkt() callback.
* @param pkt Incoming packet.
* @param pkt_size Size of incoming packet.
* @param src_addr Source address of the packet.
@@ -806,6 +872,7 @@ PJ_DECL(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice,
*/
PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice,
unsigned comp_id,
+ unsigned transport_id,
void *pkt,
pj_size_t pkt_size,
const pj_sockaddr_t *src_addr,
diff --git a/pjnath/include/pjnath/ice_strans.h b/pjnath/include/pjnath/ice_strans.h
index 09fedbad..8097b382 100644
--- a/pjnath/include/pjnath/ice_strans.h
+++ b/pjnath/include/pjnath/ice_strans.h
@@ -25,6 +25,8 @@
* @brief ICE Stream Transport
*/
#include <pjnath/ice_session.h>
+#include <pjnath/stun_sock.h>
+#include <pjnath/turn_sock.h>
#include <pjlib-util/resolver.h>
#include <pj/ioqueue.h>
#include <pj/timer.h>
@@ -44,137 +46,28 @@ PJ_BEGIN_DECL
* library.
*
* ICE stream transport, as represented by #pj_ice_strans structure, is an ICE
- * capable component for transporting media streams within a media session.
+ * capable class for transporting media streams within a media session.
* It consists of one or more transport sockets (typically two for RTP
* based communication - one for RTP and one for RTCP), and an
* \ref PJNATH_ICE_SESSION for performing connectivity checks among the.
* various candidates of the transport addresses.
*
- * \section PJNATH_ICE_STREAM_TRANSPORT_USING Using the ICE Stream Transport
- *
- * Application may use the ICE stream transport in two ways:
- * - it can create the ICE stream transports once during application
- * initialization and keep them alive throughout application lifetime, or
- * - it can create and destroy the ICE stream transport as needed everytime
- * a call is made and destroyed.
- *
- * Keeping the ICE stream transport alive throughout
- * application's lifetime is normally preferable, as initializing the
- * ICE stream transport may incur delay because the ICE stream transport
- * would need to communicate with the STUN/TURN server to get the
- * server reflexive and relayed candidates for the transports.
- *
- * Regardless of which usage scenario is being used, the ICE stream
- * transport is capable for restarting the ICE session being used and to
- * send STUN keep-alives for its STUN server reflexive and relayed
- * candidates. When ICE stream transport detects that the STUN mapped
- * address has changed in the keep-alive response, it will automatically
- * update its address to the new address, and notify the application via
- * \a on_addr_change() function of the #pj_ice_strans_cb callback.
- *
- * \subsection PJNATH_ICE_ST_TRA_INIT Initialization
- *
- * Application creates the ICE stream transport by calling
- * #pj_ice_strans_create() function. Among other things, application needs
- * to specify:
- * - STUN configuration (pj_stun_config), containing STUN settings
- * such as timeout values and the instances of timer heap and
- * ioqueue.
- * - Session name, useful for identifying this session in the log.
- * - Number of ICE components.
- * - Arbitrary user data, useful when associating the ICE session
- * with some application's data structure.
- * - A callback (#pj_ice_strans_cb) to receive events from the ICE
- * stream transport. Two of the most important fields in this
- * callback structure are \a on_rx_data() to notify application
- * about incoming data (perhaps RTP or RTCP packet), and
- * \a on_ice_complete() to notify application that ICE negotiation
- * has completed, either successfully or with failure.
- *
- * After the ICE stream transport is created, application may set up the
- * STUN servers to be used to obtain STUN server reflexive and relayed
- * candidate, by calling #pj_ice_strans_set_stun_domain() or
- * #pj_ice_strans_set_stun_srv().
- *
- * Application then creates each component by calling
- * #pj_ice_strans_create_comp(); this would create an actual socket
- * which listens to the specified local address, and it would also
- * perform lookup to find various transport address candidates for this
- * socket.
- *
- * Adding component may involve contacting STUN and TURN servers to get
- * STUN mapped address and allocate TURN relay channel, and this process
- * may take some time to complete. Once application has added all
- * components, it can check whether server reflexive and relayed
- * candidates have been acquired, by calling #pj_ice_strans_get_comps_status().
- *
- * \subsection PJNATH_ICE_ST_TRA_INIT_ICE Starting ICE Session
- *
- * When application is about to send an offer containing ICE capability,
- * or when it receives an offer containing ICE capability, it would
- * create the ICE session by calling #pj_ice_strans_init_ice(). This would
- * register all transport address aliases for each component to the ICE
- * session as candidates. After this application can enumerate all local
- * candidates by calling #pj_ice_strans_enum_cands(), and encode these
- * candidates in the SDP to be sent to remote agent.
- *
- * \subsection PJNATH_ICE_ST_TRA_START Starting Connectivity Checks
- *
- * Once application receives the SDP from remote, it pairs local candidates
- * with remote candidates, and can start ICE connectivity checks. This is
- * done by calling #pj_ice_strans_start_ice(), specifying
- * the remote candidate list, and remote username and password. If the
- * pairing process is successful, ICE connectivity checks will begin
- * immediately. The ICE session/transport will then notify the application
- * via the callback when ICE connectivity checks completes, either
- * successfully or with failure.
- *
- * \subsection PJNATH_ICE_ST_TRA_SEND_RECV Sending and Receiving Data
- *
- * Application can send data (normally RTP or RTCP packets) at any time
- * by calling #pj_ice_strans_sendto(). This function takes a destination
- * address as one of the arguments, and this destination address should
- * be taken from the default transport address of the component (that is
- * the address in SDP c= and m= lines, or in a=rtcp attribute).
- * If ICE negotiation is in progress, this function will send the data
- * to the destination address. Otherwise if ICE negotiation has completed
- * successfully, this function will send the data to the nominated remote
- * address, as negotiated by ICE.
- *
- * Upon receiving incoming data (that is a non-STUN message), the ICE
- * stream transport will notify the application by calling \a on_rx_data()
- * of the #pj_ice_strans_cb callback.
- *
- * \subsection PJNATH_ICE_ST_TRA_STOP Stopping ICE Session
- *
- * Once the call is terminated, application no longer needs to keep the
- * ICE session, so it should call #pj_ice_strans_stop_ice() to destroy the
- * ICE session within this ICE stream transport. Note that this WILL NOT
- * destroy the sockets/transports, it only destroys the ICE session
- * within this ICE stream transport. It is recommended that application
- * retains the ICE stream transport to speed up the process of setting up
- * the next call. The ICE stream transport will continue to send STUN
- * keep-alive packets to keep the NAT binding open and to detect change
- * in STUN mapped address.
- *
- * \subsection PJNATH_ICE_ST_TRA_RESTART Restarting ICE Session
- *
- * When a new call is made, application can repeat the above
- * #pj_ice_strans_init_ice() to #pj_ice_strans_stop_ice() cycle for
- * the new call, using this same ICE stream transport.
- *
- * \subsection PJNATH_ICE_ST_TRA_DESTROY Destroying ICE Stream Transport
- *
- * Finally, when the ICE stream transport itself is no longer needed,
- * for example when the application quits, application should call
- * #pj_ice_strans_destroy() to release back all resources allocated by this
- * ICE stream transport.
- *
*/
/** Forward declaration for ICE stream transport. */
typedef struct pj_ice_strans pj_ice_strans;
+/** Transport operation types to be reported on \a on_status() callback */
+typedef enum pj_ice_strans_op
+{
+ /** Initialization (candidate gathering) */
+ PJ_ICE_STRANS_OP_INIT,
+
+ /** Negotiation */
+ PJ_ICE_STRANS_OP_NEGOTIATION
+
+} pj_ice_strans_op;
+
/**
* This structure contains callbacks that will be called by the
* ICE stream transport.
@@ -200,195 +93,200 @@ typedef struct pj_ice_strans_cb
unsigned src_addr_len);
/**
- * This callback will be called when ICE checks have completed.
- * This callback is optional.
+ * Callback to report status.
*
* @param ice_st The ICE stream transport.
- * @param status The ICE connectivity check status.
+ * @param op The operation
+ * @param status Operation status.
*/
void (*on_ice_complete)(pj_ice_strans *ice_st,
+ pj_ice_strans_op op,
pj_status_t status);
- /**
- * This callback will be called when ICE transport has detected that
- * the STUN mapped address of a candidate has changed.
- *
- * @param ice_st The ICE stream transport.
- * @param comp_id Component ID.
- * @param cand_id Candidate ID.
- */
- void (*on_addr_change)(pj_ice_strans *ice_st,
- unsigned comp_id,
- unsigned cand_id);
-
} pj_ice_strans_cb;
/**
- * Various flags that can be specified when creating a component with
- * #pj_ice_strans_create_comp(). These options may be combined together
- * with bitmask operation.
+ * This structure describes ICE stream transport configuration. Application
+ * should initialize the structure by calling #pj_ice_strans_cfg_default()
+ * before changing the settings.
*/
-enum pj_ice_strans_option
+typedef struct pj_ice_strans_cfg
{
/**
- * If this option is specified, only a listening socket will be
- * created for the component, and no candidate will be added to
- * the component. Application must add the component manually
- * by inspecting the socket and transport address of the component.
+ * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)
+ * is supported, and this is the default value.
*/
- PJ_ICE_ST_OPT_DONT_ADD_CAND = 1,
+ int af;
/**
- * If this option is specified, then no STUN reflexive candidate
- * will be added to the component.
- */
- PJ_ICE_ST_OPT_DISABLE_STUN = 2,
-
- /**
- * If this option is specified, then no STUN relay candidate
- * will be added to the component.
- */
- PJ_ICE_ST_OPT_DISABLE_RELAY = 4,
-
- /**
- * If this option is specified, then when the function fails to
- * bind the socket to the specified port, it WILL NOT try to
- * bind the socket to the next available port.
+ * STUN configuration which contains the timer heap and
+ * ioqueue instance to be used, and STUN retransmission
+ * settings. This setting is mandatory.
*
- * If this option is NOT specified, then the function will try to
- * bind the socket to next port+2, repetitively until the socket
- * is bound successfully.
+ * The default value is all zero. Application must initialize
+ * this setting with #pj_stun_config_init().
*/
- PJ_ICE_ST_OPT_NO_PORT_RETRY = 8,
-};
+ pj_stun_config stun_cfg;
-
-/**
- * This structure describes ICE stream transport candidate. A "candidate"
- * in ICE stream transport can be viewed as alias transport address
- * for the socket.
- */
-typedef struct pj_ice_strans_cand
-{
/**
- * Candidate type.
- */
- pj_ice_cand_type type;
-
- /**
- * Status of this candidate. This status is useful for ICE reflexive
- * and relay candidate, where the address needs to be resolved
- * asynchronously by sending STUN request to STUN server.
+ * DNS resolver to be used to resolve servers. If DNS SRV
+ * resolution is required, the resolver must be set.
*
- * The value will be PJ_SUCCESS if candidate address has been resolved
- * successfully, PJ_EPENDING when the address resolution process is
- * in progress, or other value when the address resolution has
- * completed with failure.
+ * The default value is NULL.
*/
- pj_status_t status;
+ pj_dns_resolver *resolver;
/**
- * The candidate transport address.
+ * STUN and local transport settings. This specifies the
+ * settings for local UDP socket, which will be resolved
+ * to get the STUN mapped address.
*/
- pj_sockaddr addr;
+ struct {
+ /**
+ * Optional configuration for STUN transport. The default
+ * value will be initialized with #pj_stun_sock_cfg_default().
+ */
+ pj_stun_sock_cfg cfg;
+
+ /**
+ * Disable host candidates. When this option is set, no
+ * host candidates will be added.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t no_host_cands;
+
+ /**
+ * Include loopback addresses in the host candidates.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t loop_addr;
+
+ /**
+ * Specify the STUN server domain or hostname or IP address.
+ * If DNS SRV resolution is required, application must fill
+ * in this setting with the domain name of the STUN server
+ * and set the resolver instance in the \a resolver field.
+ * Otherwise if the \a resolver setting is not set, this
+ * field will be resolved with hostname resolution and in
+ * this case the \a port field must be set.
+ *
+ * The \a port field should also be set even when DNS SRV
+ * resolution is used, in case the DNS SRV resolution fails.
+ *
+ * When this field is empty, STUN mapped address resolution
+ * will not be performed. In this case only ICE host candidates
+ * will be added to the ICE transport, unless if \a no_host_cands
+ * field is set. In this case, both host and srflx candidates
+ * are disabled.
+ *
+ * The default value is empty.
+ */
+ pj_str_t server;
+
+ /**
+ * The port number of the STUN server, when \a server
+ * field specifies a hostname rather than domain name. This
+ * field should also be set even when the \a server
+ * specifies a domain name, to allow DNS SRV resolution
+ * to fallback to DNS A/AAAA resolution when the DNS SRV
+ * resolution fails.
+ *
+ * The default value is PJ_STUN_PORT.
+ */
+ pj_uint16_t port;
+
+ } stun;
/**
- * The ICE session candidate ID after this candidate has been registered
- * to an ICE session. Before ICE session is created, or after ICE
- * session has been destroyed, the value will be -1.
+ * TURN specific settings.
*/
- int ice_cand_id;
+ struct {
+ /**
+ * Specify the TURN server domain or hostname or IP address.
+ * If DNS SRV resolution is required, application must fill
+ * in this setting with the domain name of the TURN server
+ * and set the resolver instance in the \a resolver field.
+ * Otherwise if the \a resolver setting is not set, this
+ * field will be resolved with hostname resolution and in
+ * this case the \a port field must be set.
+ *
+ * The \a port field should also be set even when DNS SRV
+ * resolution is used, in case the DNS SRV resolution fails.
+ *
+ * When this field is empty, relay candidate will not be
+ * created.
+ *
+ * The default value is empty.
+ */
+ pj_str_t server;
+
+ /**
+ * The port number of the TURN server, when \a server
+ * field specifies a hostname rather than domain name. This
+ * field should also be set even when the \a server
+ * specifies a domain name, to allow DNS SRV resolution
+ * to fallback to DNS A/AAAA resolution when the DNS SRV
+ * resolution fails.
+ *
+ * Default is zero.
+ */
+ pj_uint16_t port;
+
+ /**
+ * Type of connection to the TURN server.
+ *
+ * Default is PJ_TURN_TP_UDP.
+ */
+ pj_turn_tp_type conn_type;
+
+ /**
+ * Credential to be used for the TURN session. This setting
+ * is mandatory.
+ *
+ * Default is to have no credential.
+ */
+ pj_stun_auth_cred auth_cred;
+
+ /**
+ * Optional TURN Allocate parameter. The default value will be
+ * initialized by #pj_turn_alloc_param_default().
+ */
+ pj_turn_alloc_param alloc_param;
+
+ } turn;
+
+} pj_ice_strans_cfg;
- /**
- * Local preference value, which typically is 65535.
- */
- pj_uint16_t local_pref;
-
- /**
- * Foundation associated with this candidate, which value normally will be
- * calculated by the function.
- */
- pj_str_t foundation;
-} pj_ice_strans_cand;
-
-
-/**
- * This structure describes an ICE stream transport component. A component
- * in ICE stream transport typically corresponds to a single socket created
- * for this component, and bound to a specific transport address. This
- * component may have multiple alias addresses, for example one alias
- * address for each interfaces in multi-homed host, another for server
- * reflexive alias, and another for relayed alias. For each transport
- * address alias, an ICE stream transport candidate (#pj_ice_strans_cand) will
- * be created, and these candidates will eventually registered to the ICE
- * session.
+/**
+ * Initialize ICE transport configuration with default values.
+ *
+ * @param cfg The configuration to be initialized.
*/
-typedef struct pj_ice_strans_comp
-{
- pj_ice_strans *ice_st; /**< ICE stream transport. */
- unsigned comp_id; /**< Component ID. */
- pj_uint32_t options; /**< Option flags. */
- pj_sock_t sock; /**< Socket descriptor. */
-
- pj_stun_session *stun_sess; /**< STUN session. */
- pj_uint8_t ka_tsx_id[12]; /**< ID for keep STUN alives */
-
- pj_sockaddr local_addr; /**< Local/base address. */
-
- unsigned pending_cnt; /**< Pending resolution cnt. */
- pj_status_t last_status; /**< Last status. */
-
- unsigned cand_cnt; /**< # of candidates/aliaes. */
- pj_ice_strans_cand cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */
- int default_cand; /**< Default candidate selected */
-
- pj_ioqueue_key_t *key; /**< ioqueue key. */
- pj_uint8_t pkt[1500]; /**< Incoming packet buffer. */
- pj_ioqueue_op_key_t read_op; /**< ioqueue read operation key */
- pj_ioqueue_op_key_t write_op; /**< ioqueue write op. key */
- pj_sockaddr src_addr; /**< source packet address buf. */
- int src_addr_len; /**< length of src addr. buf. */
-
-} pj_ice_strans_comp;
+PJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg);
/**
- * This structure represents the ICE stream transport.
+ * Copy configuration.
+ *
+ * @param pool Pool.
+ * @param dst Destination.
+ * @param src Source.
*/
-struct pj_ice_strans
-{
- char obj_name[PJ_MAX_OBJ_NAME]; /**< Log ID. */
-
- pj_pool_t *pool; /**< Pool used by this object. */
- void *user_data; /**< Application data. */
- pj_stun_config stun_cfg; /**< STUN settings. */
- pj_ice_strans_cb cb; /**< Application callback. */
-
- pj_ice_sess *ice; /**< ICE session. */
-
- unsigned comp_cnt; /**< Number of components. */
- pj_ice_strans_comp **comp; /**< Components array. */
-
- pj_dns_resolver *resolver; /**< The resolver instance. */
- pj_bool_t has_rjob; /**< Has pending resolve? */
- pj_sockaddr_in stun_srv; /**< STUN server address. */
- pj_sockaddr_in turn_srv; /**< TURN server address. */
-
- pj_timer_entry ka_timer; /**< STUN keep-alive timer. */
-};
+PJ_DECL(void) pj_ice_strans_cfg_copy(pj_pool_t *pool,
+ pj_ice_strans_cfg *dst,
+ const pj_ice_strans_cfg *src);
/**
- * Create the ICE stream transport containing the specified number of
- * components. After the ICE stream transport is created, application
- * may initialize the STUN server settings, and after that it has to
- * initialize each components by calling #pj_ice_strans_create_comp()
- * function.
+ * Create and initialize the ICE stream transport with the specified
+ * parameters.
*
- * @param stun_cfg The STUN settings.
* @param name Optional name for logging identification.
+ * @param cfg Configuration.
* @param comp_cnt Number of components.
* @param user_data Arbitrary user data to be associated with this
* ICE stream transport.
@@ -399,8 +297,8 @@ struct pj_ice_strans
* @return PJ_SUCCESS if ICE stream transport is created
* successfully.
*/
-PJ_DECL(pj_status_t) pj_ice_strans_create(pj_stun_config *stun_cfg,
- const char *name,
+PJ_DECL(pj_status_t) pj_ice_strans_create(const char *name,
+ const pj_ice_strans_cfg *cfg,
unsigned comp_cnt,
void *user_data,
const pj_ice_strans_cb *cb,
@@ -419,133 +317,24 @@ PJ_DECL(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st);
/**
- * Set the domain to be used when resolving the STUN servers. If application
- * wants to utillize STUN, then STUN server must be specified, either by
- * calling this function or by calling #pj_ice_strans_set_stun_srv().
- *
- * If application calls this function, then the STUN/TURN servers will
- * be resolved by querying DNS SRV records for the specified domain.
- *
- * @param ice_st The ICE stream transport.
- * @param resolver The resolver instance that will be used to
- * resolve the STUN/TURN servers.
- * @param domain The target domain.
- *
- * @return PJ_SUCCESS if DNS SRV resolution job can be
- * started. The resolution process itself will
- * complete asynchronously.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st,
- pj_dns_resolver *resolver,
- const pj_str_t *domain);
-
-/**
- * Set the STUN and TURN server addresses. If application
- * wants to utillize STUN, then STUN server must be specified, either by
- * calling this function or by calling #pj_ice_strans_set_stun_domain().
- *
- * With this function, the STUN and TURN server addresses will be
- * assigned immediately, that is no DNS resolution will need to be
- * performed.
+ * Get the user data associated with the ICE stream transport.
*
* @param ice_st The ICE stream transport.
- * @param stun_srv The STUN server address, or NULL if STUN
- * reflexive candidate is not to be used.
- * @param turn_srv The TURN server address, or NULL if STUN
- * relay candidate is not to be used.
*
- * @return PJ_SUCCESS, or the appropriate error code.
+ * @return The user data.
*/
-PJ_DECL(pj_status_t)
-pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st,
- const pj_sockaddr_in *stun_srv,
- const pj_sockaddr_in *turn_srv);
+PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st);
-/**
- * Create and initialize the specified component. This function will
- * instantiate the socket descriptor for this component, optionally
- * bind the socket to the specified address (or bind to any address/port
- * if the \a addr parameter is NULL), and start finding all alias
- * addresses for this socket. For each alias addresses that if finds,
- * it will add an ICE stream transport candidate for this component.
- *
- * After all components have been initialized, application should poll
- * the #pj_ice_strans_get_comps_status() peridically to check if STUN
- * server reflexive and relayed candidates have been obtained
- * successfully.
- *
- * @param ice_st The ICE stream transport.
- * @param comp_id The component ID, which value must be greater than
- * zero and less than or equal to the number of
- * components in this ICE stream transport.
- * @param options Options, see #pj_ice_strans_option.
- * @param addr Local address where socket will be bound to. This
- * address will be used as follows:
- * - if the value is NULL, then socket will be bound
- * to any available port.
- * - if the value is not NULL, then if the port number
- * is not zero, it will used as the starting port
- * where the socket will be bound to. If bind() to
- * this port fails, this function will try to bind
- * to port+2, repeatedly until it succeeded.
- * If application doesn't want this function to
- * retry binding the socket to other port, it can
- * specify PJ_ICE_ST_OPT_NO_PORT_RETRY option.
- * - if the value is not NULL, then if the address
- * is not INADDR_ANY, this function will bind the
- * socket to this particular interface only, and
- * no other host candidates will be added for this
- * socket.
- *
- *
- * @return PJ_SUCCESS, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_create_comp(pj_ice_strans *ice_st,
- unsigned comp_id,
- pj_uint32_t options,
- const pj_sockaddr_in *addr);
-
-/**
- * Manually add a candidate (transport address alias) for the specified
- * component. Normally application shouldn't need to use this function,
- * as candidates will be added automatically when component is created
- * with #pj_ice_strans_create_comp().
- *
- * @param ice_st ICE stream transport.
- * @param comp_id The component ID.
- * @param type The candidate type.
- * @param local_pref The local preference for this candidate
- * (typically the value is 65535).
- * @param addr The candidate address.
- * @param set_default Set to non-zero to make this candidate the
- * default candidate for this component.
- *
- * @return PJ_SUCCESS, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_add_cand(pj_ice_strans *ice_st,
- unsigned comp_id,
- pj_ice_cand_type type,
- pj_uint16_t local_pref,
- const pj_sockaddr_in *addr,
- pj_bool_t set_default);
-
-/**
- * Get the status of components in the ICE stream transports. Since
- * some IP address candidates have to be obtained asynchronously (for
- * example, the STUN reflexive or relay candidate), application can
- * use this function to know whether the address resolution has
- * completed.
- *
- * @param ice_st The ICE stream transport.
- *
- * @return PJ_SUCCESS if all candidates have been resolved
- * successfully, PJ_EPENDING if transport resolution
- * is still in progress, or other status on failure.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_get_comps_status(pj_ice_strans *ice_st);
/**
* Initialize the ICE session in the ICE stream transport.
+ * When application is about to send an offer containing ICE capability,
+ * or when it receives an offer containing ICE capability, it must
+ * call this function to initialize the internal ICE session. This would
+ * register all transport address aliases for each component to the ICE
+ * session as candidates. Then application can enumerate all local
+ * candidates by calling #pj_ice_strans_enum_cands(), and encode these
+ * candidates in the SDP to be sent to remote agent.
*
* @param ice_st The ICE stream transport.
* @param role ICE role.
@@ -560,10 +349,10 @@ PJ_DECL(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
const pj_str_t *local_passwd);
/**
- * Enumerate the local candidates. This function can only be called
- * after the ICE session has been created in the ICE stream transport.
+ * Enumerate the local candidates for the specified component.
*
* @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
* @param count On input, it specifies the maximum number of
* elements. On output, it will be filled with
* the number of candidates copied to the
@@ -573,38 +362,113 @@ PJ_DECL(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st,
+ unsigned comp_id,
unsigned *count,
pj_ice_sess_cand cand[]);
/**
+ * Get the default candidate for the specified component. When this
+ * function is called before ICE negotiation completes, the default
+ * candidate is selected according to local preference criteria. When
+ * this function is called after ICE negotiation completes, the
+ * default candidate is the candidate that forms the valid pair.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
+ * @param cand Pointer to receive the default candidate
+ * information.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_get_def_cand(pj_ice_strans *ice_st,
+ unsigned comp_id,
+ pj_ice_sess_cand *cand);
+
+/**
+ * Get the current ICE role. ICE session must have been initialized
+ * before this function can be called.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return Current ICE role.
+ */
+PJ_DECL(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st);
+
+
+/**
+ * Change session role. This happens for example when ICE session was
+ * created with controlled role when receiving an offer, but it turns out
+ * that the offer contains "a=ice-lite" attribute when the SDP gets
+ * inspected. ICE session must have been initialized before this function
+ * can be called.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param new_role The new role to be set.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st,
+ pj_ice_sess_role new_role);
+
+
+/**
* Start ICE connectivity checks. This function can only be called
- * after the ICE session has been created in the ICE stream transport.
+ * after the ICE session has been created in the ICE stream transport
+ * with #pj_ice_strans_init_ice().
*
- * This function will pair the local and remote candidates to create
- * check list. Once the check list is created and sorted based on the
- * priority, ICE periodic checks will be started. This function will
- * return immediately, and application will be notified about the
- * connectivity check status in the callback.
+ * This function must be called once application has received remote
+ * candidate list (typically from the remote SDP). This function pairs
+ * local candidates with remote candidates, and starts ICE connectivity
+ * checks. The ICE session/transport will then notify the application
+ * via the callback when ICE connectivity checks completes, either
+ * successfully or with failure.
*
* @param ice_st The ICE stream transport.
* @param rem_ufrag Remote ufrag, as seen in the SDP received from
* the remote agent.
* @param rem_passwd Remote password, as seen in the SDP received from
* the remote agent.
- * @param rem_cand_cnt Number of remote candidates.
- * @param rem_cand Remote candidate array.
+ * @param rcand_cnt Number of remote candidates in the array.
+ * @param rcand Remote candidates array.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
-PJ_DECL(pj_status_t)
-pj_ice_strans_start_ice( pj_ice_strans *ice_st,
- const pj_str_t *rem_ufrag,
- const pj_str_t *rem_passwd,
- unsigned rem_cand_cnt,
- const pj_ice_sess_cand rem_cand[]);
+PJ_DECL(pj_status_t) pj_ice_strans_start_ice(pj_ice_strans *ice_st,
+ const pj_str_t *rem_ufrag,
+ const pj_str_t *rem_passwd,
+ unsigned rcand_cnt,
+ const pj_ice_sess_cand rcand[]);
+
+/**
+ * Retrieve the candidate pair that has been nominated and successfully
+ * checked for the specified component. If ICE negotiation is still in
+ * progress or it has failed, this function will return NULL.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
+ *
+ * @return The valid pair as ICE checklist structure if the
+ * pair exist.
+ */
+PJ_DECL(const pj_ice_sess_check*)
+pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,
+ unsigned comp_id);
/**
- * Stop and destroy the ICE session inside this media transport.
+ * Stop and destroy the ICE session inside this media transport. Application
+ * needs to call this function once the media session is over (the call has
+ * been disconnected).
+ *
+ * Application MAY reuse this ICE stream transport for subsequent calls.
+ * In this case, it must call #pj_ice_strans_stop_ice() when the call is
+ * disconnected, and reinitialize the ICE stream transport for subsequent
+ * call with #pj_ice_strans_init_ice()/#pj_ice_strans_start_ice(). In this
+ * case, the ICE stream transport will maintain the internal sockets and
+ * continue to send STUN keep-alive packets and TURN Refresh request to
+ * keep the NAT binding/TURN allocation open and to detect change in STUN
+ * mapped address.
+ *
+ * If application does not want to reuse the ICE stream transport for
+ * subsequent calls, it must call #pj_ice_strans_destroy() to destroy the
+ * ICE stream transport altogether.
*
* @param ice_st The ICE stream transport.
*
@@ -614,11 +478,16 @@ PJ_DECL(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st);
/**
- * Send outgoing packet using this transport. If ICE checks have not
- * produced a valid check for the specified component ID, this function
- * send to the destination address. Otherwise it will send the packet to
- * remote destination using the nominated local candidate as have been checked
- * previously.
+ * Send outgoing packet using this transport.
+ * Application can send data (normally RTP or RTCP packets) at any time
+ * by calling this function. This function takes a destination
+ * address as one of the arguments, and this destination address should
+ * be taken from the default transport address of the component (that is
+ * the address in SDP c= and m= lines, or in a=rtcp attribute).
+ * If ICE negotiation is in progress, this function will send the data
+ * to the destination address. Otherwise if ICE negotiation has completed
+ * successfully, this function will send the data to the nominated remote
+ * address, as negotiated by ICE.
*
* @param ice_st The ICE stream transport.
* @param comp_id Component ID.
diff --git a/pjnath/include/pjnath/nat_detect.h b/pjnath/include/pjnath/nat_detect.h
index a4bc5fec..53fcceec 100644
--- a/pjnath/include/pjnath/nat_detect.h
+++ b/pjnath/include/pjnath/nat_detect.h
@@ -32,7 +32,6 @@ PJ_BEGIN_DECL
/**
* @defgroup PJNATH_NAT_DETECT NAT Classification/Detection Tool
* @brief NAT Classification/Detection Tool
- * @ingroup PJNATH_ICE
* @{
*
* This module provides one function to perform NAT classification and
diff --git a/pjnath/include/pjnath/stun_config.h b/pjnath/include/pjnath/stun_config.h
index d724ed9c..eba1fce0 100644
--- a/pjnath/include/pjnath/stun_config.h
+++ b/pjnath/include/pjnath/stun_config.h
@@ -25,6 +25,8 @@
*/
#include <pjnath/stun_msg.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
#include <pj/string.h>
@@ -103,6 +105,17 @@ PJ_INLINE(void) pj_stun_config_init(pj_stun_config *cfg,
/**
+ * Check that STUN config is valid.
+ */
+PJ_INLINE(pj_status_t) pj_stun_config_check_valid(const pj_stun_config *cfg)
+{
+ PJ_ASSERT_RETURN(cfg->ioqueue && cfg->pf && cfg->timer_heap &&
+ cfg->rto_msec && cfg->res_cache_msec, PJ_EINVAL);
+ return PJ_SUCCESS;
+}
+
+
+/**
* @}
*/
diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h
index 7c3805ea..e293f6fe 100644
--- a/pjnath/include/pjnath/stun_msg.h
+++ b/pjnath/include/pjnath/stun_msg.h
@@ -34,8 +34,8 @@ PJ_BEGIN_DECL
/* **************************************************************************/
/**
* @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing
- * @brief Low-level representation and parsing of STUN messages.
* @ingroup PJNATH_STUN
+ * @brief Low-level representation and parsing of STUN messages.
* @{
*/
@@ -955,9 +955,8 @@ typedef struct pj_stun_uint_attr pj_stun_req_addr_type;
/**
* This describes the TURN REQUESTED-PROPS attribute, encoded as
* STUN 32bit integer attribute. Few macros are provided to manipulate
- * the values in this attribute: #PJ_STUN_GET_RPP_BITS(),
- * #PJ_STUN_SET_RPP_BITS(), #PJ_STUN_GET_RPP_PORT(), and
- * #PJ_STUN_SET_RPP_PORT().
+ * the values in this attribute: #PJ_STUN_GET_PROP_TYPE(), and
+ * #PJ_STUN_SET_PROP_TYPE().
*
* This attribute allows the client to request certain properties for
* the relayed transport address that is allocated by the server. The
@@ -1164,7 +1163,7 @@ enum pj_stun_decode_options
* Disable FINGERPRINT verification. This option can be used when calling
* #pj_stun_msg_check() and #pj_stun_msg_decode() to disable the
* verification of FINGERPRINT, for example when the STUN usage says when
- * FINGERPRINT mechanism shall not * be used.
+ * FINGERPRINT mechanism shall not be used.
*/
PJ_STUN_NO_FINGERPRINT_CHECK = 8
};
@@ -1292,7 +1291,7 @@ PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,
* value, if these attributes are present in the message.
*
* If application wants to apply credential to the message, it MUST
- * include a blank MESSAGE-INTEGRITY attribute in the message, as the
+ * include a blank MESSAGE-INTEGRITY attribute in the message as the
* last attribute or the attribute before FINGERPRINT. This function will
* calculate the HMAC digest from the message using the supplied key in
* the parameter. The key should be set to the password if short term
@@ -1320,10 +1319,10 @@ PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,
*/
PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
pj_uint8_t *pkt_buf,
- unsigned buf_size,
+ pj_size_t buf_size,
unsigned options,
const pj_str_t *key,
- unsigned *p_msg_len);
+ pj_size_t *p_msg_len);
/**
* Check that the PDU is potentially a valid STUN message. This function
@@ -1345,7 +1344,7 @@ PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
* message.
*/
PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu,
- unsigned pdu_len, unsigned options);
+ pj_size_t pdu_len, unsigned options);
/**
@@ -1371,10 +1370,10 @@ PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu,
*/
PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
const pj_uint8_t *pdu,
- unsigned pdu_len,
+ pj_size_t pdu_len,
unsigned options,
pj_stun_msg **p_msg,
- unsigned *p_parsed_len,
+ pj_size_t *p_parsed_len,
pj_stun_msg **p_response);
/**
diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h
index 821e765b..896a2b58 100644
--- a/pjnath/include/pjnath/stun_session.h
+++ b/pjnath/include/pjnath/stun_session.h
@@ -213,6 +213,7 @@ struct pj_stun_rx_data
*/
struct pj_stun_tx_data
{
+ /** PJLIB list interface */
PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);
pj_pool_t *pool; /**< Pool. */
@@ -240,6 +241,21 @@ struct pj_stun_tx_data
/**
+ * These are the flags to control the message logging in the STUN session.
+ */
+typedef enum pj_stun_sess_msg_log_flag
+{
+ PJ_STUN_SESS_LOG_TX_REQ=1, /**< Log outgoing STUN requests. */
+ PJ_STUN_SESS_LOG_TX_RES=2, /**< Log outgoing STUN responses. */
+ PJ_STUN_SESS_LOG_TX_IND=4, /**< Log outgoing STUN indications. */
+
+ PJ_STUN_SESS_LOG_RX_REQ=8, /**< Log incoming STUN requests. */
+ PJ_STUN_SESS_LOG_RX_RES=16, /**< Log incoming STUN responses */
+ PJ_STUN_SESS_LOG_RX_IND=32 /**< Log incoming STUN indications */
+} pj_stun_sess_msg_log_flag;
+
+
+/**
* Create a STUN session.
*
* @param cfg The STUN endpoint, to be used to register timers etc.
@@ -258,11 +274,16 @@ PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_config *cfg,
pj_stun_session **p_sess);
/**
- * Destroy the STUN session.
+ * Destroy the STUN session and all objects created in the context of
+ * this session.
*
* @param sess The STUN session instance.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJ_EPENDING if the operation
+ * cannot be performed immediately because callbacks are
+ * being called; in this case the session will be destroyed
+ * as soon as the last callback returns.
*/
PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);
@@ -333,6 +354,14 @@ PJ_DECL(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess,
PJ_DECL(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess,
pj_stun_auth_type auth_type,
const pj_stun_auth_cred *cred);
+/**
+ * Configure message logging. By default all flags are enabled.
+ *
+ * @param sess The STUN session instance.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess,
+ unsigned flags);
/**
* Create a STUN request message. After the message has been successfully
@@ -381,7 +410,7 @@ PJ_DECL(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,
* call.
*
* @param sess The STUN session instance.
- * @param req The STUN request where the response is to be created.
+ * @param rdata The STUN request where the response is to be created.
* @param err_code Error code to be set in the response, if error response
* is to be created, according to pj_stun_status enumeration.
* This argument MUST be zero if successful response is
@@ -432,6 +461,9 @@ PJ_DECL(pj_status_t) pj_stun_session_create_res(pj_stun_session *sess,
* be sent.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_send_msg() callback.
*/
PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
void *token,
@@ -449,7 +481,7 @@ PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
*
* @param sess The STUN session instance.
* @param rdata The STUN request message to be responded.
- * @param err_code Error code to be set in the response, if error response
+ * @param code Error code to be set in the response, if error response
* is to be created, according to pj_stun_status enumeration.
* This argument MUST be zero if successful response is
* to be created.
@@ -472,6 +504,9 @@ PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
* @param addr_len Address length.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_send_msg() callback.
*/
PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess,
const pj_stun_rx_data *rdata,
@@ -496,6 +531,9 @@ PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess,
* callback. This error status MUST NOT be PJ_SUCCESS.
*
* @return PJ_SUCCESS if transaction is successfully cancelled.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_request_complete() callback.
*/
PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess,
pj_stun_tx_data *tdata,
@@ -511,6 +549,9 @@ PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess,
* @param tdata The request message previously sent.
*
* @return PJ_SUCCESS on success, or the appropriate error.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in \a on_send_msg()
+ * callback.
*/
PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,
pj_stun_tx_data *tdata);
@@ -548,6 +589,9 @@ PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,
* @param src_addr_len Length of the source address.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in one of the
+ * callback.
*/
PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
const void *packet,
diff --git a/pjnath/include/pjnath/stun_sock.h b/pjnath/include/pjnath/stun_sock.h
new file mode 100644
index 00000000..a5ac7f69
--- /dev/null
+++ b/pjnath/include/pjnath/stun_sock.h
@@ -0,0 +1,403 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJNATH_STUN_SOCK_H__
+#define __PJNATH_STUN_SOCK_H__
+
+/**
+ * @file stun_sock.h
+ * @brief STUN aware socket transport
+ */
+#include <pjnath/stun_config.h>
+#include <pjlib-util/resolver.h>
+#include <pj/ioqueue.h>
+#include <pj/sock.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJNATH_STUN_SOCK STUN aware socket transport
+ * @brief STUN aware socket transport
+ * @ingroup PJNATH_STUN
+ * @{
+ * The STUN transport provides asynchronous UDP like socket transport
+ * with the additional capability to query the publicly mapped transport
+ * address (using STUN resolution), to refresh the NAT binding, and to
+ * demultiplex internal STUN messages from application data (the
+ * application data may be a STUN message as well).
+ */
+
+/**
+ * Opaque type to represent a STUN transport.
+ */
+typedef struct pj_stun_sock pj_stun_sock;
+
+/**
+ * Types of operation being reported in \a on_status() callback of
+ * pj_stun_sock_cb. Application may retrieve the string representation
+ * of these constants with pj_stun_sock_op_name().
+ */
+typedef enum pj_stun_sock_op
+{
+ /**
+ * Asynchronous DNS resolution.
+ */
+ PJ_STUN_SOCK_DNS_OP = 1,
+
+ /**
+ * Initial STUN Binding request.
+ */
+ PJ_STUN_SOCK_BINDING_OP,
+
+ /**
+ * Subsequent STUN Binding request for keeping the binding
+ * alive.
+ */
+ PJ_STUN_SOCK_KEEP_ALIVE_OP,
+
+} pj_stun_sock_op;
+
+
+/**
+ * This structure contains callbacks that will be called by the STUN
+ * transport to notify application about various events.
+ */
+typedef struct pj_stun_sock_cb
+{
+ /**
+ * Notification when incoming packet has been received.
+ *
+ * @param stun_sock The STUN transport.
+ * @param data The packet.
+ * @param data_len Length of the packet.
+ * @param src_addr The source address of the packet.
+ * @param addr_len The length of the source address.
+ *
+ * @return Application should normally return PJ_TRUE to let
+ * the STUN transport continue its operation. However
+ * it must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback.
+ */
+ pj_bool_t (*on_rx_data)(pj_stun_sock *stun_sock,
+ void *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *src_addr,
+ unsigned addr_len);
+
+ /**
+ * Notifification when asynchronous send operation has completed.
+ *
+ * @param stun_sock The STUN transport.
+ * @param send_key The send operation key that was given in
+ * #pj_stun_sock_sendto().
+ * @param sent If value is positive non-zero it indicates the
+ * number of data sent. When the value is negative,
+ * it contains the error code which can be retrieved
+ * by negating the value (i.e. status=-sent).
+ *
+ * @return Application should normally return PJ_TRUE to let
+ * the STUN transport continue its operation. However
+ * it must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback.
+ */
+ pj_bool_t (*on_data_sent)(pj_stun_sock *stun_sock,
+ pj_ioqueue_op_key_t *send_key,
+ pj_ssize_t sent);
+
+ /**
+ * Notification when the status of the STUN transport has changed. This
+ * callback may be called for the following conditions:
+ * - the first time the publicly mapped address has been resolved from
+ * the STUN server, this callback will be called with \a op argument
+ * set to PJ_STUN_SOCK_BINDING_OP \a status argument set to
+ * PJ_SUCCESS.
+ * - anytime when the transport has detected that the publicly mapped
+ * address has changed, this callback will be called with \a op
+ * argument set to PJ_STUN_SOCK_KEEP_ALIVE_OP and \a status
+ * argument set to PJ_SUCCESS. On this case and the case above,
+ * application will get the resolved public address in the
+ * #pj_stun_sock_info structure.
+ * - for any terminal error (such as STUN time-out, DNS resolution
+ * failure, or keep-alive failure), this callback will be called
+ * with the \a status argument set to non-PJ_SUCCESS.
+ *
+ * @param stun_sock The STUN transport.
+ * @param op The operation that triggers the callback.
+ * @param status The status.
+ *
+ * @return Must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback. Application should
+ * normally destroy the socket and return PJ_FALSE
+ * upon encountering terminal error, otherwise it
+ * should return PJ_TRUE to let the STUN socket operation
+ * continues.
+ */
+ pj_bool_t (*on_status)(pj_stun_sock *stun_sock,
+ pj_stun_sock_op op,
+ pj_status_t status);
+
+} pj_stun_sock_cb;
+
+
+/**
+ * This structure contains information about the STUN transport. Application
+ * may query this information by calling #pj_stun_sock_get_info().
+ */
+typedef struct pj_stun_sock_info
+{
+ /**
+ * The bound address of the socket.
+ */
+ pj_sockaddr bound_addr;
+
+ /**
+ * IP address of the STUN server.
+ */
+ pj_sockaddr srv_addr;
+
+ /**
+ * The publicly mapped address. It may contain zero address when the
+ * mapped address has not been resolved. Application may query whether
+ * this field contains valid address with pj_sockaddr_has_addr().
+ */
+ pj_sockaddr mapped_addr;
+
+ /**
+ * Number of interface address aliases. The interface address aliases
+ * are list of all interface addresses in this host.
+ */
+ unsigned alias_cnt;
+
+ /**
+ * Array of interface address aliases.
+ */
+ pj_sockaddr aliases[PJ_ICE_ST_MAX_CAND];
+
+} pj_stun_sock_info;
+
+
+/**
+ * This describe the settings to be given to the STUN transport during its
+ * creation. Application should initialize this structure by calling
+ * #pj_stun_sock_cfg_default().
+ */
+typedef struct pj_stun_sock_cfg
+{
+ /**
+ * Packet buffer size. Default value is PJ_STUN_SOCK_PKT_LEN.
+ */
+ unsigned max_pkt_size;
+
+ /**
+ * Specify the number of simultaneous asynchronous read operations to
+ * be invoked to the ioqueue. Having more than one read operations will
+ * increase performance on multiprocessor systems since the application
+ * will be able to process more than one incoming packets simultaneously.
+ * Default value is 1.
+ */
+ unsigned async_cnt;
+
+ /**
+ * Specify the interface where the socket should be bound to. If the
+ * address is zero, socket will be bound to INADDR_ANY. If the address
+ * is non-zero, socket will be bound to this address only, and the
+ * transport will have only one address alias (the \a alias_cnt field
+ * in #pj_stun_sock_info structure.
+ */
+ pj_sockaddr bound_addr;
+
+ /**
+ * Specify the STUN keep-alive duration, in seconds. The STUN transport
+ * does keep-alive by sending STUN Binding request to the STUN server.
+ * If this value is zero, the PJ_STUN_KEEP_ALIVE_SEC value will be used.
+ * If the value is negative, it will disable STUN keep-alive.
+ */
+ int ka_interval;
+
+} pj_stun_sock_cfg;
+
+
+
+/**
+ * Retrieve the name representing the specified operation.
+ */
+PJ_DECL(const char*) pj_stun_sock_op_name(pj_stun_sock_op op);
+
+
+/**
+ * Initialize the STUN transport setting with its default values.
+ *
+ * @param cfg The STUN transport config.
+ */
+PJ_DECL(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg);
+
+
+/**
+ * Create the STUN transport using the specified configuration. Once
+ * the STUN transport has been create, application should call
+ * #pj_stun_sock_start() to start the transport.
+ *
+ * @param stun_cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this transport.
+ * @param af Address family of socket. Currently pj_AF_INET()
+ * and pj_AF_INET6() are supported.
+ * @param name Optional name to be given to this transport to
+ * assist debugging.
+ * @param cb Callback to receive events/data from the transport.
+ * @param cfg Optional transport settings.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_sock Pointer to receive the created transport instance.
+ *
+ * @restun PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_create(pj_stun_config *stun_cfg,
+ const char *name,
+ int af,
+ const pj_stun_sock_cb *cb,
+ const pj_stun_sock_cfg *cfg,
+ void *user_data,
+ pj_stun_sock **p_sock);
+
+
+/**
+ * Start the STUN transport. This will start the DNS SRV resolution for
+ * the STUN server (if desired), and once the server is resolved, STUN
+ * Binding request will be sent to resolve the publicly mapped address.
+ * Once the initial STUN Binding response is received, the keep-alive
+ * timer will be started.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default STUN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records. The recommended value for this
+ * parameter is PJ_STUN_PORT.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the allocation process will be notified
+ * to application in \a on_state() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_start(pj_stun_sock *stun_sock,
+ const pj_str_t *domain,
+ pj_uint16_t default_port,
+ pj_dns_resolver *resolver);
+
+/**
+ * Destroy the STUN transport.
+ *
+ * @param sock The STUN transport socket.
+ *
+ * @restun PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *sock);
+
+
+/**
+ * Associate a user data with this STUN transport. The user data may then
+ * be retrieved later with #pj_stun_sock_get_user_data().
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param user_data Arbitrary data.
+ *
+ * @restun PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_set_user_data(pj_stun_sock *stun_sock,
+ void *user_data);
+
+/**
+ * Retrieve the previously assigned user data associated with this STUN
+ * transport.
+ *
+ * @param stun_sock The STUN transport instance.
+ *
+ * @restun The user/application data.
+ */
+PJ_DECL(void*) pj_stun_sock_get_user_data(pj_stun_sock *stun_sock);
+
+
+/**
+ * Get the STUN transport info. The transport info contains, among other
+ * things, the allocated relay address.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param info Pointer to be filled with STUN transport info.
+ *
+ * @restun PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_get_info(pj_stun_sock *stun_sock,
+ pj_stun_sock_info *info);
+
+
+/**
+ * Send a data to the specified address. This function may complete
+ * asynchronously and in this case \a on_data_sent() will be called.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param op_key Optional send key for sending the packet down to
+ * the ioqueue. This value will be given back to
+ * \a on_data_sent() callback
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param flag pj_ioqueue_sendto() flag.
+ * @param dst_addr The remote address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_sendto(pj_stun_sock *stun_sock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *pkt,
+ unsigned pkt_len,
+ unsigned flag,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_SOCK_H__ */
+
diff --git a/pjnath/include/pjnath/stun_transaction.h b/pjnath/include/pjnath/stun_transaction.h
index c17bc359..842c8145 100644
--- a/pjnath/include/pjnath/stun_transaction.h
+++ b/pjnath/include/pjnath/stun_transaction.h
@@ -89,7 +89,9 @@ typedef struct pj_stun_tsx_cb
* @param pkt_size Size of the STUN packet.
*
* @return If return value of the callback is not PJ_SUCCESS,
- * the transaction will fail.
+ * the transaction will fail. Application MUST return
+ * PJNATH_ESTUNDESTROYED if it has destroyed the
+ * transaction in this callback.
*/
pj_status_t (*on_send_msg)(pj_stun_client_tsx *tsx,
const void *stun_pkt,
@@ -161,7 +163,8 @@ pj_stun_client_tsx_schedule_destroy(pj_stun_client_tsx *tsx,
*
* @param tsx The STUN transaction.
*
- * @return PJ_SUCCESS on success, or the appropriate error code.
+ * @return PJ_SUCCESS on success or PJ_EINVAL if the parameter
+ * is NULL.
*/
PJ_DECL(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx);
@@ -214,7 +217,10 @@ PJ_DECL(void*) pj_stun_client_tsx_get_data(pj_stun_client_tsx *tsx);
* @param pkt The STUN packet to send.
* @param pkt_len Length of STUN packet.
*
- * @return PJ_SUCCESS on success or the appropriate error code.
+ * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED
+ * when the user has destroyed the transaction in
+ * \a on_send_msg() callback, or any other error code
+ * as returned by \a on_send_msg() callback.
*/
PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,
pj_bool_t retransmit,
@@ -228,7 +234,10 @@ PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,
*
* @param tsx The STUN client transaction instance.
*
- * @return PJ_SUCCESS on success or the appropriate error code.
+ * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED
+ * when the user has destroyed the transaction in
+ * \a on_send_msg() callback, or any other error code
+ * as returned by \a on_send_msg() callback.
*/
PJ_DECL(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx);
diff --git a/pjnath/include/pjnath/turn_session.h b/pjnath/include/pjnath/turn_session.h
index 2c10387b..73be679c 100644
--- a/pjnath/include/pjnath/turn_session.h
+++ b/pjnath/include/pjnath/turn_session.h
@@ -29,12 +29,25 @@
PJ_BEGIN_DECL
+/**
+ * @defgroup PJNATH_TURN TURN Client Library
+ */
+
+
/* **************************************************************************/
/**
- * @defgroup PJNATH_TURN_SESSION TURN client session
+ * @defgroup PJNATH_TURN_SESSION Transport independent TURN client session
* @brief Transport independent TURN client session
- * @ingroup PJNATH_STUN
+ * @ingroup PJNATH_TURN
* @{
+ *
+ * This module describes the transport independent TURN client session. This
+ * interface is provided for implementors of a TURN client transport, and
+ * application usually will want to use \ref PJNATH_TURN_SOCK instead.
+ *
+ * The transport independent TURN client session is created to facilitate
+ * the creation of different types of transports between the client and the
+ * TURN server.
*/
/**
@@ -43,18 +56,6 @@ PJ_BEGIN_DECL
typedef struct pj_turn_session pj_turn_session;
-#define PJ_TURN_INVALID_CHANNEL 0xFFFF
-#define PJ_TURN_CHANNEL_MIN 0x4000
-#define PJ_TURN_CHANNEL_MAX 0xFFFE /* inclusive */
-#define PJ_TURN_NO_TIMEOUT ((long)0x7FFFFFFF)
-#define PJ_TURN_MAX_PKT_LEN 3000
-#define PJ_TURN_PERM_TIMEOUT 300 /* Must be greater than REFRESH_SEC_BEFORE */
-#define PJ_TURN_CHANNEL_TIMEOUT 600 /* Must be greater than REFRESH_SEC_BEFORE */
-#define PJ_TURN_REFRESH_SEC_BEFORE 60
-#define PJ_TURN_KEEP_ALIVE_SEC 15
-#define PJ_TURN_PEER_HTABLE_SIZE 8
-
-
/**
* TURN transport types, which will be used both to specify the connection
* type for reaching TURN server and the type of allocation transport to be
@@ -133,14 +134,21 @@ typedef enum pj_turn_state_t
} pj_turn_state_t;
-/* ChannelData header */
+#pragma pack(1)
+
+/**
+ * This structure ChannelData header. All the fields are in network byte
+ * order when it's on the wire.
+ */
typedef struct pj_turn_channel_data
{
- pj_uint16_t ch_number;
- pj_uint16_t length;
+ pj_uint16_t ch_number; /**< Channel number. */
+ pj_uint16_t length; /**< Payload length. */
} pj_turn_channel_data;
+#pragma pack()
+
/**
* Callback to receive events from TURN session.
@@ -151,18 +159,33 @@ typedef struct pj_turn_session_cb
* This callback will be called by the TURN session whenever it
* needs to send outgoing message. Since the TURN session doesn't
* have a socket on its own, this callback must be implemented.
+ *
+ * @param sess The TURN session.
+ * @param pkt The packet/data to be sent.
+ * @param pkt_len Length of the packet/data.
+ * @param dst_addr Destination address of the packet.
+ * @param addr_len Length of the destination address.
+ *
+ * @return The callback should return the status of the
+ * send operation.
*/
pj_status_t (*on_send_pkt)(pj_turn_session *sess,
const pj_uint8_t *pkt,
unsigned pkt_len,
const pj_sockaddr_t *dst_addr,
- unsigned dst_addr_len);
+ unsigned addr_len);
/**
* Notification when peer address has been bound successfully to
* a channel number.
*
- * This callback is optional.
+ * This callback is optional since the nature of this callback is
+ * for information only.
+ *
+ * @param sess The TURN session.
+ * @param peer_addr The peer address.
+ * @param addr_len Length of the peer address.
+ * @param ch_num The channel number associated with this peer address.
*/
void (*on_channel_bound)(pj_turn_session *sess,
const pj_sockaddr_t *peer_addr,
@@ -173,10 +196,16 @@ typedef struct pj_turn_session_cb
* Notification when incoming data has been received, either through
* Data indication or ChannelData message from the TURN server.
*
- * This callback is optional.
+ * @param sess The TURN session.
+ * @param pkt The data/payload of the Data Indication or ChannelData
+ * packet.
+ * @param pkt_len Length of the data/payload.
+ * @param peer_addr Peer address where this payload was received by
+ * the TURN server.
+ * @param addr_len Length of the peer address.
*/
void (*on_rx_data)(pj_turn_session *sess,
- const pj_uint8_t *pkt,
+ void *pkt,
unsigned pkt_len,
const pj_sockaddr_t *peer_addr,
unsigned addr_len);
@@ -185,26 +214,50 @@ typedef struct pj_turn_session_cb
* Notification when TURN session state has changed. Application should
* implement this callback at least to know that the TURN session is
* going to be destroyed.
+ *
+ * @param sess The TURN session.
+ * @param old_state The previous state of the session.
+ * @param new_state The current state of the session.
*/
- void (*on_state)(pj_turn_session *sess, pj_turn_state_t old_state,
+ void (*on_state)(pj_turn_session *sess,
+ pj_turn_state_t old_state,
pj_turn_state_t new_state);
} pj_turn_session_cb;
/**
- * Allocate parameter.
+ * Allocation parameter, which can be given when application calls
+ * pj_turn_session_alloc() to allocate relay address in the TURN server.
+ * Application should call pj_turn_alloc_param_default() to initialize
+ * this structure with the default values.
*/
typedef struct pj_turn_alloc_param
{
+ /**
+ * The requested BANDWIDTH. Default is zero to not request any
+ * specific bandwidth.
+ */
int bandwidth;
+
+ /**
+ * The requested LIFETIME. Default is zero to not request any
+ * explicit allocation lifetime.
+ */
int lifetime;
+
+ /**
+ * If set to non-zero, the TURN session will periodically send blank
+ * Send Indication every PJ_TURN_KEEP_ALIVE_SEC to refresh local
+ * NAT bindings. Default is zero.
+ */
int ka_interval;
+
} pj_turn_alloc_param;
/**
- * TURN session info.
+ * This structure describes TURN session info.
*/
typedef struct pj_turn_session_info
{
@@ -214,14 +267,14 @@ typedef struct pj_turn_session_info
pj_turn_state_t state;
/**
- * Type of connection to the TURN server.
+ * Last error (if session was terminated because of error)
*/
- pj_turn_tp_type tp_type;
+ pj_status_t last_status;
/**
- * The relay address
+ * Type of connection to the TURN server.
*/
- pj_sockaddr relay_addr;
+ pj_turn_tp_type conn_type;
/**
* The selected TURN server address.
@@ -229,6 +282,16 @@ typedef struct pj_turn_session_info
pj_sockaddr server;
/**
+ * Mapped address, as reported by the TURN server.
+ */
+ pj_sockaddr mapped_addr;
+
+ /**
+ * The relay address
+ */
+ pj_sockaddr relay_addr;
+
+ /**
* Current seconds before allocation expires.
*/
int lifetime;
@@ -237,67 +300,173 @@ typedef struct pj_turn_session_info
/**
- * Create default pj_turn_alloc_param.
+ * Initialize pj_turn_alloc_param with the default values.
+ *
+ * @param prm The TURN allocation parameter to be initialized.
*/
PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm);
+
/**
* Duplicate pj_turn_alloc_param.
+ *
+ * @param pool Pool to allocate memory (currently not used)
+ * @param dst Destination parameter.
+ * @param src Source parameter.
*/
PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool,
pj_turn_alloc_param *dst,
const pj_turn_alloc_param *src);
/**
- * Get TURN state name.
+ * Get string representation for the given TURN state.
+ *
+ * @param state The TURN session state.
+ *
+ * @return The state name as NULL terminated string.
*/
PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state);
/**
- * Create TURN client session.
+ * Create a TURN session instance with the specified address family and
+ * connection type. Once TURN session instance is created, application
+ * must call pj_turn_session_alloc() to allocate a relay address in the TURN
+ * server.
+ *
+ * @param cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this session.
+ * @param name Optional name to identify this session in the log.
+ * @param af Address family of the client connection. Currently
+ * pj_AF_INET() and pj_AF_INET6() are supported.
+ * @param conn_type Connection type to the TURN server.
+ * @param cb Callback to receive events from the TURN session.
+ * @param options Option flags, currently this value must be zero.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_sess Pointer to receive the created instance of the
+ * TURN session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
-PJ_DECL(pj_status_t) pj_turn_session_create(pj_stun_config *cfg,
+PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg,
const char *name,
int af,
pj_turn_tp_type conn_type,
const pj_turn_session_cb *cb,
- void *user_data,
unsigned options,
+ void *user_data,
pj_turn_session **p_sess);
-
/**
- * Shutdown TURN client session.
+ * Shutdown TURN client session. This will gracefully deallocate and
+ * destroy the client session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess);
/**
- * Forcefully destroy the TURN session.
+ * Forcefully destroy the TURN session. This will destroy the session
+ * immediately. If there is an active allocation, the server will not
+ * be notified about the client destruction.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess);
/**
- * Get TURN session info.
+ * Get the information about this TURN session and the allocation, if
+ * any.
+ *
+ * @param sess The TURN client session.
+ * @param info The structure to be initialized with the TURN
+ * session info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess,
pj_turn_session_info *info);
/**
- * Re-assign user data.
+ * Associate a user data with this TURN session. The user data may then
+ * be retrieved later with pj_turn_session_get_user_data().
+ *
+ * @param sess The TURN client session.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess,
void *user_data);
/**
- * Retrieve user data.
+ * Retrieve the previously assigned user data associated with this TURN
+ * session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return The user/application data.
*/
PJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess);
+
+/**
+ * Configure message logging. By default all flags are enabled.
+ *
+ * @param sess The TURN client session.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess,
+ unsigned flags);
+
+
/**
- * Set the server or domain name of the server.
+ * Set the server or domain name of the server. Before the application
+ * can send Allocate request (with pj_turn_session_alloc()), it must first
+ * resolve the server address(es) using this function. This function will
+ * resolve the TURN server using DNS SRV resolution if the \a resolver
+ * is set. The server resolution process will complete asynchronously,
+ * and application will be notified in \a on_state() callback with the
+ * session state set to PJ_TURN_STATE_RESOLVED.
+ *
+ * Application may call with pj_turn_session_alloc() before the server
+ * resolution completes. In this case, the operation will be queued by
+ * the session, and it will be sent once the server resolution completes.
+ *
+ * @param sess The TURN client session.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default TURN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the resolution process will be notified
+ * to application in \a on_state() callback.
*/
PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess,
const pj_str_t *domain,
@@ -306,43 +475,120 @@ PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess,
/**
- * Set credential to be used by the session.
+ * Set credential to be used to authenticate against TURN server.
+ * Application must call this function before sending Allocate request
+ * with pj_turn_session_alloc().
+ *
+ * @param sess The TURN client session
+ * @param cred STUN credential to be used.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess,
const pj_stun_auth_cred *cred);
/**
- * Create TURN allocation.
+ * Allocate a relay address/resource in the TURN server by sending TURN
+ * Allocate request. Application must first initiate the server resolution
+ * process with pj_turn_session_set_server() and set the credential to be
+ * used with pj_turn_session_set_credential() before calling this function.
+ *
+ * This function will complete asynchronously, and the application will be
+ * notified about the allocation result in \a on_state() callback. The
+ * TURN session state will move to PJ_TURN_STATE_READY if allocation is
+ * successful, and PJ_TURN_STATE_DEALLOCATING or greater state if allocation
+ * has failed.
+ *
+ * Once allocation has been successful, the TURN session will keep this
+ * allocation alive until the session is destroyed, by sending periodic
+ * allocation refresh to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param param Optional TURN allocation parameter.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,
const pj_turn_alloc_param *param);
/**
- * Relay data to the specified peer through the session.
+ * Send a data to the specified peer address via the TURN relay. This
+ * function will encapsulate the data as STUN Send Indication or TURN
+ * ChannelData packet and send the message to the TURN server. The TURN
+ * server then will send the data to the peer.
+ *
+ * The allocation (pj_turn_session_alloc()) must have been successfully
+ * created before application can relay any data.
+ *
+ * Since TURN session is transport independent, this function will
+ * ultimately call \a on_send_pkt() callback to request the application
+ * to actually send the packet containing the data to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param peer_addr The remote peer address (the ultimate destination
+ * of the data, and not the TURN server address).
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess,
const pj_uint8_t *pkt,
unsigned pkt_len,
- const pj_sockaddr_t *addr,
+ const pj_sockaddr_t *peer_addr,
unsigned addr_len);
/**
- * Bind a peer address to a channel number.
+ * Optionally establish channel binding for the specified a peer address.
+ * This function will assign a unique channel number for the peer address
+ * and request channel binding to the TURN server for this address. When
+ * a channel has been bound to a peer, the TURN client and TURN server
+ * will exchange data using ChannelData encapsulation format, which has
+ * lower bandwidth overhead than Send Indication (the default format used
+ * when peer address is not bound to a channel).
+ *
+ * This function will complete asynchronously, and application will be
+ * notified about the result in \a on_channel_bound() callback.
+ *
+ * @param sess The TURN client session.
+ * @param peer The remote peer address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated, or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess,
const pj_sockaddr_t *peer,
unsigned addr_len);
/**
- * Notify TURN client session upon receiving a packet from server.
- * The packet maybe a STUN packet or ChannelData packet.
+ * Notify TURN client session upon receiving a packet from server. Since
+ * the TURN session is transport independent, it does not read packet from
+ * any sockets, and rather relies on application giving it packets that
+ * are received from the TURN server. The session then processes this packet
+ * and decides whether it is part of TURN protocol exchange or if it is a
+ * data to be reported back to user, which in this case it will call the
+ * \a on_rx_data() callback.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The packet as received from the TURN server. This
+ * should contain either STUN encapsulated message or
+ * a ChannelData packet.
+ * @param pkt_len The length of the packet.
+ *
+ * @return The function may return non-PJ_SUCCESS if it receives
+ * non-STUN and non-ChannelData packet, or if the
+ * \a on_rx_data() returns non-PJ_SUCCESS;
*/
PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
- const pj_uint8_t *pkt,
- unsigned pkt_len,
- pj_bool_t is_datagram);
+ void *pkt,
+ unsigned pkt_len);
/**
diff --git a/pjnath/include/pjnath/turn_sock.h b/pjnath/include/pjnath/turn_sock.h
index 91bf9e20..875f6313 100644
--- a/pjnath/include/pjnath/turn_sock.h
+++ b/pjnath/include/pjnath/turn_sock.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __PJNATH_turn_sock_H__
-#define __PJNATH_turn_sock_H__
+#ifndef __PJNATH_TURN_SOCK_H__
+#define __PJNATH_TURN_SOCK_H__
/**
* @file turn_sock.h
@@ -31,46 +31,87 @@ PJ_BEGIN_DECL
/* **************************************************************************/
/**
- * @defgroup PJNATH_TURN_UDP TURN TCP client
- * @brief TURN relay using TCP client as transport protocol
- * @ingroup PJNATH_STUN
+ * @defgroup PJNATH_TURN_SOCK TURN client transport
+ * @brief Client transport utilizing TURN relay
+ * @ingroup PJNATH_TURN
* @{
+ *
+ * The TURN relay client transport can be used to relay data from the client
+ * to peer via a TURN relay. The application establishes TURN connection to
+ * the TURN server using UDP or TCP as the transport, then creates a relay
+ * address in the TURN server to be advertised to remote peer(s) as the
+ * transport address. When application sends data to a remote address via
+ * this transport, the data will be sent via the TURN relay, and vice versa.
*/
/**
- * Opaque declaration for TURN TCP client.
+ * Opaque declaration for TURN client.
*/
typedef struct pj_turn_sock pj_turn_sock;
-
+/**
+ * This structure contains callbacks that will be called by the TURN
+ * transport.
+ */
typedef struct pj_turn_sock_cb
{
/**
- * Notification when incoming data has been received, either through
- * Data indication or ChannelData message from the TURN server.
+ * Notification when incoming data has been received from the remote
+ * peer via the TURN server. The data reported in this callback will
+ * be the exact data as sent by the peer (e.g. the TURN encapsulation
+ * such as Data Indication or ChannelData will be removed before this
+ * function is called).
*
- * This callback is mandatory.
+ * @param turn_sock The TURN client transport.
+ * @param data The data as received from the peer.
+ * @param data_len Length of the data.
+ * @param peer_addr The peer address.
+ * @param addr_len The length of the peer address.
*/
void (*on_rx_data)(pj_turn_sock *turn_sock,
- const pj_uint8_t *pkt,
+ void *pkt,
unsigned pkt_len,
const pj_sockaddr_t *peer_addr,
unsigned addr_len);
/**
* Notification when TURN session state has changed. Application should
- * implement this callback to know that the TURN session is no longer
- * available.
+ * implement this callback to monitor the progress of the TURN session.
+ *
+ * @param turn_sock The TURN client transport.
+ * @param old_state Previous state.
+ * @param new_state Current state.
*/
- void (*on_state)(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
+ void (*on_state)(pj_turn_sock *turn_sock,
+ pj_turn_state_t old_state,
pj_turn_state_t new_state);
} pj_turn_sock_cb;
/**
- * Create.
+ * Create a TURN transport instance with the specified address family and
+ * connection type. Once TURN transport instance is created, application
+ * must call pj_turn_sock_alloc() to allocate a relay address in the TURN
+ * server.
+ *
+ * @param cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this transport.
+ * @param af Address family of the client connection. Currently
+ * pj_AF_INET() and pj_AF_INET6() are supported.
+ * @param conn_type Connection type to the TURN server. Both TCP and
+ * UDP are supported.
+ * @param cb Callback to receive events from the TURN transport.
+ * @param options Option flags, currently this value must be zero.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_turn_sock Pointer to receive the created instance of the
+ * TURN transport.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
int af,
@@ -81,53 +122,174 @@ PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
pj_turn_sock **p_turn_sock);
/**
- * Destroy.
+ * Destroy the TURN transport instance. This will gracefully close the
+ * connection between the client and the TURN server. Although this
+ * function will return immediately, the TURN socket deletion may continue
+ * in the background and the application may still get state changes
+ * notifications from this transport.
+ *
+ * @param turn_sock The TURN transport instance.
*/
PJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock);
+
/**
- * Set user data.
+ * Associate a user data with this TURN transport. The user data may then
+ * be retrieved later with #pj_turn_sock_get_user_data().
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_sock_set_user_data(pj_turn_sock *turn_sock,
- void *user_data);
+ void *user_data);
/**
- * Get user data.
+ * Retrieve the previously assigned user data associated with this TURN
+ * transport.
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return The user/application data.
*/
PJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock);
/**
- * Get info.
+ * Get the TURN transport info. The transport info contains, among other
+ * things, the allocated relay address.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param info Pointer to be filled with TURN transport info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock,
- pj_turn_session_info *info);
+ pj_turn_session_info *info);
+
+/**
+ * Acquire the internal mutex of the TURN transport. Application may need
+ * to call this function to synchronize access to other objects alongside
+ * the TURN transport, to avoid deadlock.
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock);
+
+
+/**
+ * Release the internal mutex previously held with pj_turn_sock_lock().
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock);
+
/**
- * Initialize.
+ * Set STUN message logging for this TURN session.
+ * See #pj_stun_session_set_log().
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
*/
-PJ_DECL(pj_status_t) pj_turn_sock_init(pj_turn_sock *turn_sock,
- const pj_str_t *domain,
- int default_port,
- pj_dns_resolver *resolver,
- const pj_stun_auth_cred *cred,
- const pj_turn_alloc_param *param);
+PJ_DECL(void) pj_turn_sock_set_log(pj_turn_sock *turn_sock,
+ unsigned flags);
/**
- * Send packet.
+ * Allocate a relay address/resource in the TURN server. This function
+ * will resolve the TURN server using DNS SRV (if desired) and send TURN
+ * \a Allocate request using the specified credential to allocate a relay
+ * address in the server. This function completes asynchronously, and
+ * application will be notified when the allocation process has been
+ * successful in the \a on_state() callback when the state is set to
+ * PJ_TURN_STATE_READY. If the allocation fails, the state will be set
+ * to PJ_TURN_STATE_DEALLOCATING or greater.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default TURN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ * @param cred The STUN credential to be used for the TURN server.
+ * @param param Optional TURN allocation parameter.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the allocation process will be notified
+ * to application in \a on_state() callback.
+ *
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock,
+ const pj_str_t *domain,
+ int default_port,
+ pj_dns_resolver *resolver,
+ const pj_stun_auth_cred *cred,
+ const pj_turn_alloc_param *param);
+
+/**
+ * Send a data to the specified peer address via the TURN relay. This
+ * function will encapsulate the data as STUN Send Indication or TURN
+ * ChannelData packet and send the message to the TURN server. The TURN
+ * server then will send the data to the peer.
+ *
+ * The allocation (pj_turn_sock_alloc()) must have been successfully
+ * created before application can relay any data.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param peer_addr The remote peer address (the ultimate destination
+ * of the data, and not the TURN server address).
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock,
const pj_uint8_t *pkt,
unsigned pkt_len,
- const pj_sockaddr_t *addr,
+ const pj_sockaddr_t *peer_addr,
unsigned addr_len);
/**
- * Bind a peer address to a channel number.
+ * Optionally establish channel binding for the specified a peer address.
+ * This function will assign a unique channel number for the peer address
+ * and request channel binding to the TURN server for this address. When
+ * a channel has been bound to a peer, the TURN transport and TURN server
+ * will exchange data using ChannelData encapsulation format, which has
+ * lower bandwidth overhead than Send Indication (the default format used
+ * when peer address is not bound to a channel).
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param peer The remote peer address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
*/
PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock,
- const pj_sockaddr_t *peer,
- unsigned addr_len);
+ const pj_sockaddr_t *peer,
+ unsigned addr_len);
/**
@@ -138,5 +300,5 @@ PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock,
PJ_END_DECL
-#endif /* __PJNATH_turn_sock_H__ */
+#endif /* __PJNATH_TURN_SOCK_H__ */
diff --git a/pjnath/include/pjnath/types.h b/pjnath/include/pjnath/types.h
index 88872dcb..66ab4cdd 100644
--- a/pjnath/include/pjnath/types.h
+++ b/pjnath/include/pjnath/types.h
@@ -35,6 +35,13 @@
PJ_BEGIN_DECL
/**
+ * This constant describes a number to be used to identify an invalid TURN
+ * channel number.
+ */
+#define PJ_TURN_INVALID_CHANNEL 0xFFFF
+
+
+/**
* Initialize pjnath library.
*
* @return Initialization status.
@@ -43,7 +50,7 @@ PJ_DECL(pj_status_t) pjnath_init(void);
/**
- * Display error to the log.
+ * Display error to the log.
*
* @param sender The sender name.
* @param title Title message.
@@ -67,167 +74,216 @@ PJ_END_DECL
/* Doxygen documentation below: */
/**
- * @mainpage PJNATH - Open Source ICE, STUN, and TURN Library
- *
- * \n
- * This is the documentation of PJNATH, an Open Source library providing
- * NAT traversal helper functionalities by using standard based protocols.
- *
- * \n
- * \section PJNATH_STUN STUN Protocol Library
- *
- * Session Traversal Utilities (STUN, or previously known as Simple
- * Traversal of User Datagram Protocol (UDP) Through Network Address
- * Translators (NAT)s), is a lightweight protocol that serves as a tool for
- * application protocols in dealing with NAT traversal. It allows a client
- * to determine the IP address and port allocated to them by a NAT and to
- * keep NAT bindings open.
- *
- * The PJNATH library provides facilities to support both the core
- * <B>STUN-bis</B> specification and the <B>TURN</B> usage of STUN,
- * as well as other STUN usages. Please see #pj_stun_attr_type for
- * list of STUN attributes supported by this library.
- *
- *
- * The following are some design principles that have been utilized
- * when implementing the STUN library in PJNATH:
- *
- * - layered architecture, with \ref PJNATH_STUN_MSG as the lowest
- * layer and \ref PJNATH_STUN_SESSION as the highest abstraction
- * layer, to accommodate various usage scenario of the library.
- *
- * - no transport -- the STUN library is pretty much transport
- * independent and all sending and receiving functionalities will
- * have to be implemented by application or higher level
- * abstraction (such as ICE). This helps facilitating an even
- * more usage scenarios of the library.
- *
- * - common functionalities for both STUN client and server
- * development. All STUN components can be used to develop both
- * STUN client and STUN server application, and in fact, in ICE,
- * both STUN client and server functionality exist in a single
- * ICE session.
- *
- * \n
- *
- * \subsection PJNATH_STUN_ARCH STUN Library Organization
- *
- * \image html stun-arch.jpg "STUN Library Architecture"
- *
- * The STUN library is organized as follows:
- *
- * - for both client and server, the highest abstraction is
- * \ref PJNATH_STUN_SESSION, which provides management of incoming
- * and outgoing messages and association of STUN credential to
- * a STUN session.
- *
- * - for client, the next layer below is \ref PJNATH_STUN_TRANSACTION,
- * which manages retransmissions of STUN request. Server side STUN
- * transaction is handled in \ref PJNATH_STUN_SESSION layer above.
- *
- * - \ref PJNATH_STUN_AUTH provides mechanism to verify STUN
- * credential in incoming STUN messages.
- *
- * - the lowest layer of the library is \ref PJNATH_STUN_MSG. This layer
- * provides STUN message representation, validation, parsing,
- * encoding MESSAGE-INTEGRITY for outgoing messages, and
- * debugging (dump to log) of STUN messages.
- *
- * All STUN library components are independent of any transports.
- * Application gives incoming packet to the STUN components for processing,
- * and it must supply the STUN components with callback to send outgoing
- * messages.
- *
- *
- * \n
- *
- * \subsection PJNATH_STUN_CLASSES PJNATH Class Diagram
- *
- *
- * \image html UML-class-diagram.png "Class Diagram"
- *
- * TBD: write descriptions.
- *
- * \subsection PJNATH_STUN_USING Using STUN Library
- *
- * [The developers guide documentation can certainly be improved here]
- *
- * For a sample STUN and TURN client, please see <tt>pjstun-client</tt>
- * project under <tt>pjnath/src</tt> directory.
- *
- * For a sample STUN and TURN server, please see <tt>pjstun-srv-test</tt>
- * project under <tt>pjnath/src</tt> directory.
- *
- *
- * \subsection PJNATH_STUN_REF STUN Reference
- *
- * References for STUN:
- *
- * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-15.txt">
- * <B>draft-ietf-behave-rfc3489bis-15</b></A>: Session Traversal
- * Utilities for (NAT) (STUN),
- * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-07.txt">
- * <B>draft-ietf-behave-turn-07</B></A>: Obtaining Relay Addresses
- * from Simple Traversal Underneath NAT (STUN)
- * - Obsoleted: <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>.
- *
- * \n
- *
- * \section PJNATH_ICE ICE Implementation
- *
- * Interactive Connectivity Establishment (ICE) is a standard based
- * methodology for traversing Network Address Translator (NAT), and
- * is described in
- * <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt">
- * <B>draft-ietf-mmusic-ice-19.txt</B></A> draft. The PJNATH ICE
- * implementation is aimed to provide a usable and generic ICE transports
- * for different types of application, including but not limited to
- * the usage of ICE in SIP/SDP offer/answer.
- *
- *
- * \subsection PJNATH_ICE_ARCH ICE Library Organization
- *
- * \image html ice-arch.jpg "ICE Architecture"
- *
- * The ICE library is organized as follows:
- *
- * - the highest abstraction is ICE media transport, which maintains
- * ICE stream transport and provides SDP translations to be used
- * for SIP offer/answer exchanges. ICE media transport is part
- * of PJMEDIA library.
- *
- * - higher in the hierarchy is \ref PJNATH_ICE_STREAM_TRANSPORT,
- * which binds ICE with UDP sockets, and provides STUN binding
- * and relay/TURN allocation for the sockets. This component can
- * be directly used by application, although normally application
- * should use the next higher abstraction since it provides
- * SDP translations and better integration with other PJ libraries
- * such as PJSIP and PJMEDIA.
- *
- * - the lowest layer is \ref PJNATH_ICE_SESSION, which provides
- * ICE management and negotiation in a transport-independent way.
- * This layer contains the state machines to perform ICE
- * negotiation, and provides the most flexibility to control all
- * aspects of ICE session. This layer normally is only usable for
- * ICE implementors.
- *
- * \subsection PJNATH_ICE_USING Using the ICE Library
- *
- * For ICE implementation that has been integrated with socket transport,
- * please see \ref PJNATH_ICE_STREAM_TRANSPORT_USING.
- *
- * For ICE implementation that has not been integrated with socket
- * transport, please see \ref pj_ice_sess_using_sec.
- *
- * \subsection PJNATH_ICE_REF Reference
- *
- * References for ICE:
- * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt">
- * <B>draft-ietf-mmusic-ice-19.txt</B></A>: Interactive Connectivity
- * Establishment (ICE): A Methodology for Network Address Translator
- * (NAT) Traversal for Offer/Answer Protocols
- */
+@mainpage PJNATH - Open Source ICE, STUN, and TURN Library
+
+\n
+This is the documentation of PJNATH, an Open Source library providing
+NAT traversal helper functionalities by using standard based protocols
+such as STUN, TURN, and ICE.
+
+\n
+\n
+
+\section lib_comps Library Components
+
+\subsection comp_stun STUN
+
+Session Traversal Utilities (STUN, or previously known as Simple
+Traversal of User Datagram Protocol (UDP) Through Network Address
+Translators (NAT)s), is a lightweight protocol that serves as a tool for
+application protocols in dealing with NAT traversal. It allows a client
+to determine the IP address and port allocated to them by a NAT and to
+keep NAT bindings open.
+
+This version of PJNATH implements the following STUN-bis draft:
+- <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-15.txt">
+ <B>draft-ietf-behave-rfc3489bis-15</b></A>: Session Traversal
+ Utilities for (NAT) (STUN),
+
+
+\subsection comp_turn TURN
+
+Traversal Using Relays around NAT (TURN) allows the host to control the
+operation of the relay and to exchange packets with its peers using the relay.
+
+This version of PJNATH implements both TCP and UDP client transport and it
+complies with the following TURN draft:
+ - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-07.txt">
+ <B>draft-ietf-behave-turn-07</B></A>: Obtaining Relay Addresses
+ from Simple Traversal Underneath NAT (STUN)
+
+
+\subsection comp_ice ICE
+
+Interactive Connectivity Establishment (ICE) is a standard based
+methodology for traversing Network Address Translator (NAT). This
+implementation is aimed to provide a usable and generic ICE transports
+for different types of application, including but not limited to
+the usage of ICE in SIP/SDP offer/answer.
+
+
+This version of PJNATH implements the following ICE draft:
+ - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt">
+ <B>draft-ietf-mmusic-ice-19.txt</B></A> draft. The PJNATH ICE
+
+
+\subsection comp_natck NAT Classification Utility
+
+The PJNATH library also provides NAT classification utility as
+described in <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>.
+While the practice to detect the NAT type to assist NAT traversal
+has been deprecated in favor of ICE, the information may still be
+useful for troubleshooting purposes, hence the utility is provided.
+
+
+\n
+\n
+
+\section lib_org Library Organization
+
+The PJNATH library consists of many components with each providing
+specific functionality that may or may not be of the interests of
+applications (or application developers). This section attempts to
+give brief overview on the components provided by PJNATH.
+
+The PJNATH components from the highest layer to the lower layer are
+as follows.
+
+
+\n
+
+\subsection user_comp High-level Transport Objects
+
+PJNATH library provides some high-level objects that may be used
+by applications:
+
+
+\subsubsection stun_sock STUN Transport
+
+The \ref PJNATH_STUN_SOCK provides asynchronous UDP like socket transport
+with the additional capability to query the publicly mapped transport
+address (using STUN resolution), to refresh the NAT binding, and to
+demultiplex internal STUN messages from application data (the
+application data may be a STUN message as well).
+
+
+\subsubsection turn_sock TURN Client Transport
+
+The \ref PJNATH_TURN_SOCK may be used by the application to send and
+receive data via TURN server. For more information please see the
+documentation of \ref PJNATH_TURN_SOCK.
+
+
+\subsubsection ice_strans ICE Stream Transport
+
+The \ref PJNATH_ICE_STREAM_TRANSPORT provides transport interface to
+send and receive data through connection that is negotiated
+with ICE protocol. The \ref PJNATH_ICE_STREAM_TRANSPORT naturally
+contains both STUN Transport and \ref PJNATH_TURN_SOCK.
+
+The \ref PJNATH_ICE_STREAM_TRANSPORT interface is suitable for both
+SIP or non-SIP use. For SIP use, application may prefer to use the
+ICE media transport in PJMEDIA instead where it has been integrated
+with the SDP offer and answer mechanism.
+
+
+\subsubsection natck NAT Classification Utility
+
+PJNATH also provides \a PJNATH_NAT_DETECT to assist troubleshooting
+of problems related to NAT traversal.
+
+
+
+\n
+
+
+\subsection sessions Transport Independent Sessions Layer
+
+Right below the high level transports objects are the transport
+independent sessions. These sessions don't have access to sockets,
+so higher level objects (such as transports) must give incoming
+packets to the sessions and provide callback to be called by
+sessions to send outgoing packets.
+
+
+\subsubsection ice_sess ICE Session
+
+The \ref PJNATH_ICE_SESSION is used by the \ref PJNATH_ICE_STREAM_TRANSPORT
+and contains the actual logic of the ICE negotiation.
+
+
+\subsubsection turn_sess TURN Session
+
+The \ref PJNATH_TURN_SESSION is used by the \ref PJNATH_TURN_SOCK
+and it contains TURN protocol logic. Implementors may implement
+other types of TURN client connection (such as TURN TLS client)
+by utilizing this session.
+
+
+\subsubsection stun_sess STUN Session
+
+The \ref PJNATH_STUN_SESSION manages STUN message exchange between
+a client and server (or vice versa). It manages \ref PJNATH_STUN_TRANSACTION
+for sending or receiving requests and \ref PJNATH_STUN_AUTH for both
+both incoming and outgoing STUN messages.
+
+The \ref PJNATH_STUN_SESSION is naturally used by the \ref PJNATH_TURN_SESSION
+and \ref PJNATH_ICE_SESSION
+
+
+\n
+
+\subsection stun_tsx STUN Transaction Layer
+
+The \ref PJNATH_STUN_TRANSACTION is a thin layer to manage retransmission
+of STUN requests.
+
+
+\n
+
+
+\subsection stun_msg STUN Messaging Layer
+
+At the very bottom of the PJNATH components is the \ref PJNATH_STUN_MSG
+layer. The API contains various representation of STUN messaging components
+and it provides API to encode and decode STUN messages.
+
+
+
+\n
+\n
+
+\section class_dia Class Diagram
+
+
+The following class diagram shows the interactions between objects in
+PJNATH:
+
+\image html UML-class-diagram.png "Class Diagram"
+\image latex UML-class-diagram.png "Class Diagram"
+
+
+
+\n
+\n
+
+\section samples Sample Applications
+
+
+Some sample applications have been provided with PJNATH, and it's available
+under <tt>pjnath/src</tt> directory:
+
+ - <b>pjturn-client</b>: this is a stand-alone, console based TURN client
+ application to be used as a demonstration for PJNATH TURN client
+ transport API and for simple testing against TURN server implementations.
+ The client supports both UDP and TCP connection to the TURN server.
+
+ - <b>pjturn-srv</b>: this is a simple TURN server to be used for testing
+ purposes. It supports both UDP and TCP connections to the clients.
+
+
+*/
/**
* @defgroup PJNATH_STUN STUN Library