From cdb0f86fac81b206ee8e260d2b344e36cb3ac0aa Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Thu, 7 Feb 2013 09:35:34 +0000 Subject: Close #1602: configurable local port range for ICE transport. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4343 74dad513-b988-da41-8d7b-12977e46ad98 --- pjnath/include/pjnath/stun_sock.h | 12 +++++++++++- pjnath/include/pjnath/turn_sock.h | 17 +++++++++++++++++ pjnath/src/pjnath/stun_sock.c | 24 ++++++++++++++---------- pjnath/src/pjnath/turn_sock.c | 31 ++++++++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 12 deletions(-) (limited to 'pjnath') diff --git a/pjnath/include/pjnath/stun_sock.h b/pjnath/include/pjnath/stun_sock.h index db7d1d04..f9e9be2e 100644 --- a/pjnath/include/pjnath/stun_sock.h +++ b/pjnath/include/pjnath/stun_sock.h @@ -238,10 +238,20 @@ typedef struct pj_stun_sock_cfg * 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. + * in #pj_stun_sock_info structure. If the port is set to zero, the + * socket will bind at any port (chosen by the OS). */ pj_sockaddr bound_addr; + /** + * Specify the port range for STUN socket binding, relative to the start + * port number specified in \a bound_addr. Note that this setting is only + * applicable when the start port number is non zero. + * + * Default value is zero. + */ + pj_uint16_t port_range; + /** * Specify the STUN keep-alive duration, in seconds. The STUN transport * does keep-alive by sending STUN Binding request to the STUN server. diff --git a/pjnath/include/pjnath/turn_sock.h b/pjnath/include/pjnath/turn_sock.h index c1250856..f756a3b8 100644 --- a/pjnath/include/pjnath/turn_sock.h +++ b/pjnath/include/pjnath/turn_sock.h @@ -141,6 +141,23 @@ typedef struct pj_turn_sock_cfg */ pj_bool_t qos_ignore_error; + /** + * 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. If the port is + * set to zero, the socket will bind at any port (chosen by the OS). + */ + pj_sockaddr bound_addr; + + /** + * Specify the port range for TURN socket binding, relative to the start + * port number specified in \a bound_addr. Note that this setting is only + * applicable when the start port number is non zero. + * + * Default value is zero. + */ + pj_uint16_t port_range; + } pj_turn_sock_cfg; diff --git a/pjnath/src/pjnath/stun_sock.c b/pjnath/src/pjnath/stun_sock.c index 7f6aacd8..725c4c8f 100644 --- a/pjnath/src/pjnath/stun_sock.c +++ b/pjnath/src/pjnath/stun_sock.c @@ -32,6 +32,8 @@ #include +enum { MAX_BIND_RETRY = 100 }; + struct pj_stun_sock { char *obj_name; /* Log identification */ @@ -162,7 +164,9 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg, pj_pool_t *pool; pj_stun_sock *stun_sock; pj_stun_sock_cfg default_cfg; + pj_sockaddr bound_addr; unsigned i; + pj_uint16_t max_bind_retry; pj_status_t status; PJ_ASSERT_RETURN(stun_cfg && cb && p_stun_sock, PJ_EINVAL); @@ -211,17 +215,17 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg, 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)); - } else { - pj_sockaddr bound_addr; - - pj_sockaddr_init(af, &bound_addr, NULL, 0); - status = pj_sock_bind(stun_sock->sock_fd, &bound_addr, - pj_sockaddr_get_len(&bound_addr)); + max_bind_retry = MAX_BIND_RETRY; + if (cfg->port_range && cfg->port_range < max_bind_retry) + max_bind_retry = cfg->port_range; + pj_sockaddr_init(af, &bound_addr, NULL, 0); + if (cfg->bound_addr.addr.sa_family == pj_AF_INET() || + cfg->bound_addr.addr.sa_family == pj_AF_INET6()) + { + pj_sockaddr_cp(&bound_addr, &cfg->bound_addr); } - + status = pj_sock_bind_random(stun_sock->sock_fd, &bound_addr, + cfg->port_range, max_bind_retry); if (status != PJ_SUCCESS) goto on_error; diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c index 919c0839..08831a4c 100644 --- a/pjnath/src/pjnath/turn_sock.c +++ b/pjnath/src/pjnath/turn_sock.c @@ -32,6 +32,10 @@ enum TIMER_DESTROY }; + +enum { MAX_BIND_RETRY = 100 }; + + #define INIT 0x1FFFFFFF struct pj_turn_sock @@ -102,6 +106,7 @@ PJ_DEF(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg) cfg->qos_ignore_error = PJ_TRUE; } + /* * Create. */ @@ -725,6 +730,8 @@ static void turn_on_state(pj_turn_session *sess, int sock_type; pj_sock_t sock; pj_activesock_cb asock_cb; + pj_sockaddr bound_addr, *cfg_bind_addr; + pj_uint16_t max_bind_retry; /* Close existing connection, if any. This happens when * we're switching to alternate TURN server when either TCP @@ -750,7 +757,29 @@ static void turn_on_state(pj_turn_session *sess, return; } - /* Apply QoS, if specified */ + /* Bind socket */ + cfg_bind_addr = &turn_sock->setting.bound_addr; + max_bind_retry = MAX_BIND_RETRY; + if (turn_sock->setting.port_range && + turn_sock->setting.port_range < max_bind_retry) + { + max_bind_retry = turn_sock->setting.port_range; + } + pj_sockaddr_init(turn_sock->af, &bound_addr, NULL, 0); + if (cfg_bind_addr->addr.sa_family == pj_AF_INET() || + cfg_bind_addr->addr.sa_family == pj_AF_INET6()) + { + pj_sockaddr_cp(&bound_addr, cfg_bind_addr); + } + status = pj_sock_bind_random(sock, &bound_addr, + turn_sock->setting.port_range, + max_bind_retry); + if (status != PJ_SUCCESS) { + pj_turn_sock_destroy(turn_sock); + 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), -- cgit v1.2.3