summaryrefslogtreecommitdiff
path: root/pjnath
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-10-25 09:02:07 +0000
committerBenny Prijono <bennylp@teluu.com>2009-10-25 09:02:07 +0000
commitfdc0f2ecdb18b9176f87f55ee17f054ce107e8c7 (patch)
tree768b9507e60426fcabcc8b4ce2540ae727cf7ffa /pjnath
parent2053af19e76b9c13e8bdebb13669cf915dc49981 (diff)
Initial commit for ticket #950: QoS support:
- implementation: - PJLIB (sock_qos*.*) - added QoS support in: - SIP UDP transport, - SIP TCP transport, - media UDP transport (done in pjsua-lib), - pjnath ICE stream transport, - pjnath STUN socket, - pjnath TURN client - added QoS options in pjsua-lib: - QoS fields in pjsua_transport_config - added "--set-qos" parameter in pjsua Notes: - QoS in TLS transport is not yet implemented, waiting for #957 - build ok on VS6, VS2005 (multiple targets), Carbide, and Mingw - no run-time testing yet git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2966 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath')
-rw-r--r--pjnath/include/pjnath/config.h4
-rw-r--r--pjnath/include/pjnath/ice_strans.h35
-rw-r--r--pjnath/include/pjnath/stun_sock.h27
-rw-r--r--pjnath/include/pjnath/turn_sock.h49
-rw-r--r--pjnath/src/pjnath/ice_strans.c31
-rw-r--r--pjnath/src/pjnath/stun_sock.c15
-rw-r--r--pjnath/src/pjnath/turn_sock.c31
7 files changed, 179 insertions, 13 deletions
diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h
index f265e2c7..196f2d53 100644
--- a/pjnath/include/pjnath/config.h
+++ b/pjnath/include/pjnath/config.h
@@ -250,14 +250,14 @@
* the maximum number of components (PJ_ICE_MAX_COMP) value.
*/
#ifndef PJ_ICE_COMP_BITS
-# define PJ_ICE_COMP_BITS 3
+# define PJ_ICE_COMP_BITS 1
#endif
/**
* Maximum number of ICE components.
*/
-#define PJ_ICE_MAX_COMP (2<<PJ_ICE_COMP_BITS)
+#define PJ_ICE_MAX_COMP (2<<PJ_ICE_COMP_BITS)
/**
* Use the priority value according to the ice-draft.
diff --git a/pjnath/include/pjnath/ice_strans.h b/pjnath/include/pjnath/ice_strans.h
index c021dde7..43a837da 100644
--- a/pjnath/include/pjnath/ice_strans.h
+++ b/pjnath/include/pjnath/ice_strans.h
@@ -271,6 +271,13 @@ typedef struct pj_ice_strans_cfg
*/
struct {
/**
+ * Optional TURN socket settings. The default values will be
+ * initialized by #pj_turn_sock_cfg_default(). This contains
+ * settings such as QoS.
+ */
+ pj_turn_sock_cfg cfg;
+
+ /**
* 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
@@ -324,6 +331,34 @@ typedef struct pj_ice_strans_cfg
} turn;
+ /**
+ * Component specific settings, which will override the settings in
+ * the STUN and TURN settings above. For example, setting the QoS
+ * parameters here allows the application to have different QoS
+ * traffic type for RTP and RTCP component.
+ */
+ struct {
+ /**
+ * QoS traffic type to be set on this transport. When application
+ * wants to apply QoS tagging to the transport, it's preferable to
+ * set this field rather than \a qos_param fields since this is
+ * more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a
+ * lower level operation than setting the \a qos_type field and
+ * may not be supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ } comp[PJ_ICE_MAX_COMP];
+
} pj_ice_strans_cfg;
diff --git a/pjnath/include/pjnath/stun_sock.h b/pjnath/include/pjnath/stun_sock.h
index b196b325..95625c93 100644
--- a/pjnath/include/pjnath/stun_sock.h
+++ b/pjnath/include/pjnath/stun_sock.h
@@ -28,6 +28,7 @@
#include <pjlib-util/resolver.h>
#include <pj/ioqueue.h>
#include <pj/sock.h>
+#include <pj/sock_qos.h>
PJ_BEGIN_DECL
@@ -247,6 +248,32 @@ typedef struct pj_stun_sock_cfg
*/
int ka_interval;
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if STUN socket should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
} pj_stun_sock_cfg;
diff --git a/pjnath/include/pjnath/turn_sock.h b/pjnath/include/pjnath/turn_sock.h
index f6776b83..fe034612 100644
--- a/pjnath/include/pjnath/turn_sock.h
+++ b/pjnath/include/pjnath/turn_sock.h
@@ -25,6 +25,7 @@
* @brief TURN relay using UDP client as transport protocol
*/
#include <pjnath/turn_session.h>
+#include <pj/sock_qos.h>
PJ_BEGIN_DECL
@@ -101,6 +102,48 @@ typedef struct pj_turn_sock_cb
/**
+ * This structure describes options that can be specified when creating
+ * the TURN socket. Application should call #pj_turn_sock_cfg_default()
+ * to initialize this structure with its default values before using it.
+ */
+typedef struct pj_turn_sock_cfg
+{
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are not set.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if STUN socket should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+} pj_turn_sock_cfg;
+
+
+/**
+ * Initialize pj_turn_sock_cfg structure with default values.
+ */
+PJ_DECL(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg);
+
+
+/**
* 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
@@ -114,7 +157,9 @@ typedef struct pj_turn_sock_cb
* @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 setting Optional settings to be specified to the transport.
+ * If this parameter is NULL, default values will be
+ * used.
* @param user_data Arbitrary application data to be associated with
* this transport.
* @param p_turn_sock Pointer to receive the created instance of the
@@ -127,7 +172,7 @@ PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
int af,
pj_turn_tp_type conn_type,
const pj_turn_sock_cb *cb,
- unsigned options,
+ const pj_turn_sock_cfg *setting,
void *user_data,
pj_turn_sock **p_turn_sock);
diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c
index cf79ad9d..d702c656 100644
--- a/pjnath/src/pjnath/ice_strans.c
+++ b/pjnath/src/pjnath/ice_strans.c
@@ -211,6 +211,7 @@ PJ_DEF(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg)
pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL);
pj_stun_sock_cfg_default(&cfg->stun.cfg);
pj_turn_alloc_param_default(&cfg->turn.alloc_param);
+ pj_turn_sock_cfg_default(&cfg->turn.cfg);
pj_ice_sess_options_default(&cfg->opt);
@@ -273,6 +274,17 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
stun_sock_cb.on_status = &stun_on_status;
stun_sock_cb.on_data_sent = &stun_on_data_sent;
+ /* Override component specific QoS settings, if any */
+ if (ice_st->cfg.comp[comp_id-1].qos_type) {
+ ice_st->cfg.stun.cfg.qos_type =
+ ice_st->cfg.comp[comp_id-1].qos_type;
+ }
+ if (ice_st->cfg.comp[comp_id-1].qos_params.flags) {
+ pj_memcpy(&ice_st->cfg.stun.cfg.qos_params,
+ &ice_st->cfg.comp[comp_id-1].qos_params,
+ sizeof(ice_st->cfg.stun.cfg.qos_params));
+ }
+
/* Create the STUN transport */
status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL,
ice_st->cfg.af, &stun_sock_cb,
@@ -391,10 +403,22 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
turn_sock_cb.on_rx_data = &turn_on_rx_data;
turn_sock_cb.on_state = &turn_on_state;
+ /* Override with component specific QoS settings, if any */
+ if (ice_st->cfg.comp[comp_id-1].qos_type) {
+ ice_st->cfg.turn.cfg.qos_type =
+ ice_st->cfg.comp[comp_id-1].qos_type;
+ }
+ if (ice_st->cfg.comp[comp_id-1].qos_params.flags) {
+ pj_memcpy(&ice_st->cfg.turn.cfg.qos_params,
+ &ice_st->cfg.comp[comp_id-1].qos_params,
+ sizeof(ice_st->cfg.turn.cfg.qos_params));
+ }
+
+ /* Create the TURN transport */
status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af,
ice_st->cfg.turn.conn_type,
- &turn_sock_cb, 0, comp,
- &comp->turn_sock);
+ &turn_sock_cb, &ice_st->cfg.turn.cfg,
+ comp, &comp->turn_sock);
if (status != PJ_SUCCESS) {
return status;
}
@@ -453,7 +477,8 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
if (status != PJ_SUCCESS)
return status;
- PJ_ASSERT_RETURN(comp_cnt && cb && p_ice_st, PJ_EINVAL);
+ PJ_ASSERT_RETURN(comp_cnt && cb && p_ice_st &&
+ comp_cnt <= PJ_ICE_MAX_COMP , PJ_EINVAL);
if (name == NULL)
name = "ice%p";
diff --git a/pjnath/src/pjnath/stun_sock.c b/pjnath/src/pjnath/stun_sock.c
index a0d5ff2c..6bdd77e4 100644
--- a/pjnath/src/pjnath/stun_sock.c
+++ b/pjnath/src/pjnath/stun_sock.c
@@ -136,6 +136,8 @@ PJ_DEF(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg)
cfg->max_pkt_size = PJ_STUN_SOCK_PKT_LEN;
cfg->async_cnt = 1;
cfg->ka_interval = PJ_STUN_KEEP_ALIVE_SEC;
+ cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
+ cfg->qos_ignore_error = PJ_TRUE;
}
@@ -200,6 +202,14 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
if (status != PJ_SUCCESS)
goto on_error;
+ /* Apply QoS, if specified */
+ status = pj_sock_apply_qos2(stun_sock->sock_fd, cfg->qos_type,
+ &cfg->qos_params, 2, stun_sock->obj_name,
+ NULL);
+ if (status != PJ_SUCCESS && !cfg->qos_ignore_error)
+ goto on_error;
+
+ /* Bind socket */
if (pj_sockaddr_has_addr(&cfg->bound_addr)) {
status = pj_sock_bind(stun_sock->sock_fd, &cfg->bound_addr,
pj_sockaddr_get_len(&cfg->bound_addr));
@@ -758,10 +768,7 @@ static pj_bool_t on_data_recvfrom(pj_activesock_t *asock,
/* Log socket error */
if (status != PJ_SUCCESS) {
- char errmsg[PJ_ERR_MSG_SIZE];
-
- pj_strerror(status, errmsg, sizeof(errmsg));
- PJ_LOG(2,(stun_sock->obj_name, "recvfrom() error: %s", errmsg));
+ pj_perror(2, stun_sock->obj_name, status, "recvfrom() error", 0);
return PJ_TRUE;
}
diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c
index 0c71d5cb..287b0299 100644
--- a/pjnath/src/pjnath/turn_sock.c
+++ b/pjnath/src/pjnath/turn_sock.c
@@ -46,6 +46,7 @@ struct pj_turn_sock
pj_turn_alloc_param alloc_param;
pj_stun_config cfg;
+ pj_turn_sock_cfg setting;
pj_bool_t destroy_request;
pj_timer_entry timer;
@@ -92,6 +93,14 @@ static void destroy(pj_turn_sock *turn_sock);
static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e);
+/* Init config */
+PJ_DEF(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg)
+{
+ pj_bzero(cfg, sizeof(*cfg));
+ cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
+ cfg->qos_ignore_error = PJ_TRUE;
+}
+
/*
* Create.
*/
@@ -99,21 +108,26 @@ PJ_DEF(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
int af,
pj_turn_tp_type conn_type,
const pj_turn_sock_cb *cb,
- unsigned options,
+ const pj_turn_sock_cfg *setting,
void *user_data,
pj_turn_sock **p_turn_sock)
{
pj_turn_sock *turn_sock;
pj_turn_session_cb sess_cb;
+ pj_turn_sock_cfg default_setting;
pj_pool_t *pool;
const char *name_tmpl;
pj_status_t status;
PJ_ASSERT_RETURN(cfg && p_turn_sock, PJ_EINVAL);
PJ_ASSERT_RETURN(af==pj_AF_INET() || af==pj_AF_INET6(), PJ_EINVAL);
- PJ_ASSERT_RETURN(options==0, PJ_EINVAL);
PJ_ASSERT_RETURN(conn_type!=PJ_TURN_TP_TCP || PJ_HAS_TCP, PJ_EINVAL);
+ if (!setting) {
+ pj_turn_sock_cfg_default(&default_setting);
+ setting = &default_setting;
+ }
+
switch (conn_type) {
case PJ_TURN_TP_UDP:
name_tmpl = "udprel%p";
@@ -139,6 +153,9 @@ PJ_DEF(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
/* Copy STUN config (this contains ioqueue, timer heap, etc.) */
pj_memcpy(&turn_sock->cfg, cfg, sizeof(*cfg));
+ /* Copy setting (QoS parameters etc */
+ pj_memcpy(&turn_sock->setting, setting, sizeof(*setting));
+
/* Set callback */
if (cb) {
pj_memcpy(&turn_sock->cb, cb, sizeof(*cb));
@@ -652,6 +669,16 @@ static void turn_on_state(pj_turn_session *sess,
return;
}
+ /* Apply QoS, if specified */
+ status = pj_sock_apply_qos2(sock, turn_sock->setting.qos_type,
+ &turn_sock->setting.qos_params,
+ (turn_sock->setting.qos_ignore_error?2:1),
+ turn_sock->pool->obj_name, NULL);
+ if (status != PJ_SUCCESS && !turn_sock->setting.qos_ignore_error) {
+ pj_turn_sock_destroy(turn_sock);
+ return;
+ }
+
/* Create active socket */
pj_bzero(&asock_cb, sizeof(asock_cb));
asock_cb.on_data_read = &on_data_read;