diff options
author | Benny Prijono <bennylp@teluu.com> | 2009-10-25 09:02:07 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2009-10-25 09:02:07 +0000 |
commit | fdc0f2ecdb18b9176f87f55ee17f054ce107e8c7 (patch) | |
tree | 768b9507e60426fcabcc8b4ce2540ae727cf7ffa /pjnath | |
parent | 2053af19e76b9c13e8bdebb13669cf915dc49981 (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.h | 4 | ||||
-rw-r--r-- | pjnath/include/pjnath/ice_strans.h | 35 | ||||
-rw-r--r-- | pjnath/include/pjnath/stun_sock.h | 27 | ||||
-rw-r--r-- | pjnath/include/pjnath/turn_sock.h | 49 | ||||
-rw-r--r-- | pjnath/src/pjnath/ice_strans.c | 31 | ||||
-rw-r--r-- | pjnath/src/pjnath/stun_sock.c | 15 | ||||
-rw-r--r-- | pjnath/src/pjnath/turn_sock.c | 31 |
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; |