diff options
author | Riza Sulistyo <riza@teluu.com> | 2014-06-19 05:07:12 +0000 |
---|---|---|
committer | Riza Sulistyo <riza@teluu.com> | 2014-06-19 05:07:12 +0000 |
commit | 727da5e28aa110f7931b696f1b1ba74e805bb9b4 (patch) | |
tree | f512a06809c4607bc07cd0c877f549a1ba09e580 /pjlib/src | |
parent | 97ebde15f373555da8309c7ebe657a2492b818b6 (diff) |
Re #1771: Implement run-time configuration to set specific socket option.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4860 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src')
-rw-r--r-- | pjlib/src/pj/sock_bsd.c | 44 | ||||
-rw-r--r-- | pjlib/src/pj/sock_linux_kernel.c | 30 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_common.c | 2 | ||||
-rw-r--r-- | pjlib/src/pj/ssl_sock_ossl.c | 27 |
4 files changed, 102 insertions, 1 deletions
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c index 107f5247..1688668b 100644 --- a/pjlib/src/pj/sock_bsd.c +++ b/pjlib/src/pj/sock_bsd.c @@ -26,6 +26,8 @@ #include <pj/errno.h> #include <pj/unicode.h> +#define THIS_FILE "sock_bsd.c" + /* * Address families conversion. * The values here are indexed based on pj_addr_family. @@ -765,14 +767,54 @@ PJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sock, const void *optval, int optlen) { + int status; PJ_CHECK_STACK(); - if (setsockopt(sock, level, optname, (const char*)optval, optlen) != 0) + +#if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_SUNOS) && PJ_SUNOS) + /* Some opt may still need int value (e.g:SO_EXCLUSIVEADDRUSE in win32). */ + status = setsockopt(sock, + level, + ((optname&0xff00)==0xff00)?(int)optname|0xffff0000:optname, + (const char*)optval, optlen); +#else + status = setsockopt(sock, level, optname, (const char*)optval, optlen); +#endif + + if (status != 0) return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); else return PJ_SUCCESS; } /* + * Set socket option. + */ +PJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd, + const pj_sockopt_params *params) +{ + unsigned int i = 0; + pj_status_t retval = PJ_SUCCESS; + PJ_CHECK_STACK(); + PJ_ASSERT_RETURN(params, PJ_EINVAL); + + for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) { + pj_status_t status = pj_sock_setsockopt(sockfd, + (pj_uint16_t)params->options[i].level, + (pj_uint16_t)params->options[i].optname, + params->options[i].optval, + params->options[i].optlen); + if (status != PJ_SUCCESS) { + retval = status; + PJ_PERROR(4,(THIS_FILE, status, + "Warning: error applying sock opt %d", + params->options[i].optname)); + } + } + + return retval; +} + +/* * Connect socket. */ PJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock, diff --git a/pjlib/src/pj/sock_linux_kernel.c b/pjlib/src/pj/sock_linux_kernel.c index 89c2f0e0..899b486e 100644 --- a/pjlib/src/pj/sock_linux_kernel.c +++ b/pjlib/src/pj/sock_linux_kernel.c @@ -36,6 +36,8 @@ #include <asm/ioctls.h> /* FIONBIO */ #include <linux/utsname.h> /* for pj_gethostname() */ +#define THIS_FILE "sock_linux_kernel.c" + /* * Address families conversion. * The values here are indexed based on pj_addr_family-0xFF00. @@ -626,6 +628,34 @@ PJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd, } /* + * Set socket option. + */ +PJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd, + const pj_sockopt_params *params) +{ + unsigned int i = 0; + pj_status_t retval = PJ_SUCCESS; + PJ_CHECK_STACK(); + PJ_ASSERT_RETURN(params, PJ_EINVAL); + + for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) { + pj_status_t status = pj_sock_setsockopt(sockfd, + params->options[i].level, + params->options[i].optname, + params->options[i].optval, + params->options[i].optlen); + if (status != PJ_SUCCESS) { + retval = status; + PJ_PERROR(4,(THIS_FILE, status, + "Warning: error applying sock opt %d", + params->options[i].optname)); + } + } + + return retval; +} + +/* * Shutdown socket. */ #if PJ_HAS_TCP diff --git a/pjlib/src/pj/ssl_sock_common.c b/pjlib/src/pj/ssl_sock_common.c index 67a8d63c..60248372 100644 --- a/pjlib/src/pj/ssl_sock_common.c +++ b/pjlib/src/pj/ssl_sock_common.c @@ -41,6 +41,8 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param) param->qos_type = PJ_QOS_TYPE_BEST_EFFORT; param->qos_ignore_error = PJ_TRUE; + param->sockopt_ignore_error = PJ_TRUE; + /* Security config */ param->proto = PJ_SSL_SOCK_PROTO_DEFAULT; } diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index 7c7b6d00..3aa85b0d 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -1650,6 +1650,14 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock, if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) goto on_return; + /* Apply socket options, if specified */ + if (ssock->param.sockopt_params.cnt) { + status = pj_sock_setsockopt_params(ssock->sock, + &ssock->param.sockopt_params); + if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error) + goto on_return; + } + /* Update local address */ ssock->addr_len = src_addr_len; status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, @@ -2452,9 +2460,19 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock, status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type, &ssock->param.qos_params, 2, ssock->pool->obj_name, NULL); + if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) goto on_error; + /* Apply socket options, if specified */ + if (ssock->param.sockopt_params.cnt) { + status = pj_sock_setsockopt_params(ssock->sock, + &ssock->param.sockopt_params); + + if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error) + goto on_error; + } + /* Bind socket */ status = pj_sock_bind(ssock->sock, localaddr, addr_len); if (status != PJ_SUCCESS) @@ -2537,6 +2555,15 @@ PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock, if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) goto on_error; + /* Apply socket options, if specified */ + if (ssock->param.sockopt_params.cnt) { + status = pj_sock_setsockopt_params(ssock->sock, + &ssock->param.sockopt_params); + + if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error) + goto on_error; + } + /* Bind socket */ status = pj_sock_bind(ssock->sock, localaddr, addr_len); if (status != PJ_SUCCESS) |