diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2010-02-25 11:58:19 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2010-02-25 11:58:19 +0000 |
commit | cd0277b8c369c89206409d767d47600d3ed38786 (patch) | |
tree | 4ea90a5de7fb5a5842fff3685ac600c93246050b /pjsip | |
parent | c80dd76f236e41c653a6e6e95c9fa44c586c6a34 (diff) |
More ticket #1032:
- Updated transport state notification callback to return void.
- Updated transport state enum to only contain connected and disconnected, no more bitmask value.
- Added direction field to SIP transport.
- Removed remote hostname hash from transport key.
- Updated cert info dump to return -1 when buffer is insufficient.
- Added new error code PJSIP_TLS_ECERTVERIF.
- Updated get_cert_name() in ssl_sock_symbian.c to use heap buffer instead of stack.
- Minors, e.g: added prefix PJ in cipher types, docs.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3110 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsip/sip_errno.h | 5 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 76 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transport_tls.h | 41 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 17 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_errno.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 43 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_loop.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_tcp.c | 3 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_tls.c | 112 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_udp.c | 3 |
10 files changed, 144 insertions, 158 deletions
diff --git a/pjsip/include/pjsip/sip_errno.h b/pjsip/include/pjsip/sip_errno.h index 802ab4a2..15f842a9 100644 --- a/pjsip/include/pjsip/sip_errno.h +++ b/pjsip/include/pjsip/sip_errno.h @@ -504,6 +504,11 @@ PJ_BEGIN_DECL * SSL negotiation has exceeded the maximum configured timeout. */ #define PJSIP_TLS_ETIMEDOUT (PJSIP_ERRNO_START_PJSIP+172) /* 171172 */ +/** + * @hideinitializer + * SSL certificate verification error. + */ +#define PJSIP_TLS_ECERTVERIF (PJSIP_ERRNO_START_PJSIP+173) /* 171173 */ /** diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h index 9f6534cd..8da4d561 100644 --- a/pjsip/include/pjsip/sip_transport.h +++ b/pjsip/include/pjsip/sip_transport.h @@ -693,17 +693,30 @@ typedef struct pjsip_transport_key long type; /** - * Hash of host name. - */ - pj_uint32_t hname; - - /** * Destination address. */ pj_sockaddr rem_addr; } pjsip_transport_key; + +/** + * Enumeration of transport direction types. + */ +typedef enum pjsip_transport_dir +{ + PJSIP_TP_DIR_NONE, /**< Direction not set, normally used by + connectionless transports such as + UDP transport. */ + PJSIP_TP_DIR_OUTGOING, /**< Outgoing connection or client mode, + this is only for connection-oriented + transports. */ + PJSIP_TP_DIR_INCOMING, /**< Incoming connection or server mode, + this is only for connection-oriented + transports. */ +} pjsip_transport_dir; + + /** * This structure represent the "public" interface of a SIP transport. * Applications normally extend this structure to include transport @@ -731,6 +744,7 @@ struct pjsip_transport pj_sockaddr local_addr; /**< Bound address. */ pjsip_host_port local_name; /**< Published name (eg. STUN). */ pjsip_host_port remote_name; /**< Remote address name. */ + pjsip_transport_dir dir; /**< Connection direction. */ pjsip_endpoint *endpt; /**< Endpoint instance. */ pjsip_tpmgr *tpmgr; /**< Transport manager. */ @@ -1130,7 +1144,7 @@ PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr, * transport is found, a new one will be created. * * This is an internal function since normally application doesn't have access - * to transport manager. Application should use pjsip_endpt_acquire_transport() + * to transport manager. Application should use pjsip_endpt_acquire_transport2() * instead. * * @param mgr The transport manager instance. @@ -1244,35 +1258,26 @@ PJ_DECL(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr, /** * Enumeration of transport state types. */ -typedef enum pjsip_transport_state_type { - - /** Transport connected. */ - PJSIP_TP_STATE_CONNECTED = (1 << 0), - - /** Transport accepted. */ - PJSIP_TP_STATE_ACCEPTED = (1 << 1), - - /** Transport disconnected. */ - PJSIP_TP_STATE_DISCONNECTED = (1 << 2), - - /** Incoming connection rejected. */ - PJSIP_TP_STATE_REJECTED = (1 << 3), - - /** TLS verification error. */ - PJSIP_TP_STATE_TLS_VERIF_ERROR = (1 << 8) - -} pjsip_transport_state_type; +typedef enum pjsip_transport_state +{ + PJSIP_TP_STATE_CONNECTED, /**< Transport connected, applicable only + to connection-oriented transports + such as TCP and TLS. */ + PJSIP_TP_STATE_DISCONNECTED /**< Transport disconnected, applicable + only to connection-oriented + transports such as TCP and TLS. */ +} pjsip_transport_state; /** - * Structure of transport state info. + * Structure of transport state info passed by #pjsip_tp_state_callback. */ typedef struct pjsip_transport_state_info { /** * The last error code related to the transport state. */ pj_status_t status; - + /** * Optional extended info, the content is specific for each transport type. */ @@ -1282,30 +1287,23 @@ typedef struct pjsip_transport_state_info { /** * Type of callback to receive transport state notifications, such as - * transport connected, disconnected or TLS verification error. + * transport connected/disconnected. Application may shutdown the transport + * in this callback. * * @param tp The transport instance. - * @param state The transport state, this may contain single or - * combination of transport state types defined in - * #pjsip_transport_state_type. + * @param state The transport state. * @param info The transport state info. - * - * @return When TLS verification fails and peer verification in - * #pjsip_tls_setting is not set, application may return - * PJ_TRUE to ignore the verification result and continue - * using the transport. On other cases, this return value - * is currently not used and will be ignored. */ -typedef pj_bool_t (*pjsip_tp_state_callback)( +typedef void (*pjsip_tp_state_callback)( pjsip_transport *tp, - pj_uint32_t state, + pjsip_transport_state state, const pjsip_transport_state_info *info); /** * Setting callback of transport state notification. The caller will be * notified whenever the state of transport is changed. The type of - * events are defined in #pjsip_transport_state_type. + * events are defined in #pjsip_transport_state. * * @param mgr Transport manager. * @param cb Callback to be called to notify caller about transport diff --git a/pjsip/include/pjsip/sip_transport_tls.h b/pjsip/include/pjsip/sip_transport_tls.h index f97414b3..ddee2bc2 100644 --- a/pjsip/include/pjsip/sip_transport_tls.h +++ b/pjsip/include/pjsip/sip_transport_tls.h @@ -122,42 +122,36 @@ typedef struct pjsip_tls_setting pj_str_t server_name; /** - * Specifies the action when verification of server TLS certificate - * resulting errors: + * Specifies TLS transport behavior on the server TLS certificate + * verification result: * - If \a verify_server is disabled (set to PJ_FALSE), TLS transport * will just notify the application via #pjsip_tp_state_callback with - * state (PJSIP_TP_STATE_CONNECTED | PJSIP_TP_STATE_TLS_VERIF_ERROR) - * whenever there is any TLS verification error, the return value of - * the callback will be used to decide whether transport should be - * shutdown. + * state PJSIP_TP_STATE_CONNECTED regardless TLS verification result. * - If \a verify_server is enabled (set to PJ_TRUE), TLS transport * will be shutdown and application will be notified with state - * (PJSIP_TP_STATE_DISCONNECTED | PJSIP_TP_STATE_TLS_VERIF_ERROR) - * whenever there is any TLS verification error. + * PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification + * error, otherwise PJSIP_TP_STATE_CONNECTED will be notified. * - * When the verification resulting success, application will be notified - * via #pjsip_tp_state_callback with state PJSIP_TP_STATE_CONNECTED. + * In any cases, application can inspect #pjsip_tls_state_info in the + * callback to see the verification detail. * * Default value is PJ_FALSE. */ pj_bool_t verify_server; /** - * Specifies the action when verification of server TLS certificate - * resulting errors: + * Specifies TLS transport behavior on the client TLS certificate + * verification result: * - If \a verify_client is disabled (set to PJ_FALSE), TLS transport * will just notify the application via #pjsip_tp_state_callback with - * state (PJSIP_TP_STATE_ACCEPTED | PJSIP_TP_STATE_TLS_VERIF_ERROR) - * whenever there is any TLS verification error, the return value of - * the callback will be used to decide whether transport should be - * shutdown. + * state PJSIP_TP_STATE_CONNECTED regardless TLS verification result. * - If \a verify_client is enabled (set to PJ_TRUE), TLS transport * will be shutdown and application will be notified with state - * (PJSIP_TP_STATE_REJECTED | PJSIP_TP_STATE_TLS_VERIF_ERROR) - * whenever there is any TLS verification error. + * PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification + * error, otherwise PJSIP_TP_STATE_CONNECTED will be notified. * - * When the verification resulting success, application will be notified - * via #pjsip_tp_state_callback with state PJSIP_TP_STATE_ACCEPTED. + * In any cases, application can inspect #pjsip_tls_state_info in the + * callback to see the verification detail. * * Default value is PJ_FALSE. */ @@ -165,7 +159,7 @@ typedef struct pjsip_tls_setting /** * When acting as server (incoming TLS connections), reject inocming - * connection if client doesn't have a valid certificate. + * connection if client doesn't supply a TLS certificate. * * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag. * Default value is PJ_FALSE. @@ -209,8 +203,9 @@ typedef struct pjsip_tls_setting /** - * This structure defines transport state extended info specifically for - * TLS transport. + * This structure defines TLS transport extended info in <tt>ext_info</tt> + * field of #pjsip_transport_state_info for the transport state notification + * callback #pjsip_tp_state_callback. */ typedef struct pjsip_tls_state_info { diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 45f07d90..451b8c9c 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -846,21 +846,8 @@ typedef struct pjsua_callback /** * This callback is called when transport state is changed. See also * #pjsip_tp_state_callback. - * - * @param tp The transport instance. - * @param state The transport state, this may contain single or - * combination of transport state types defined in - * #pjsip_transport_state_type. - * @param info The transport state info. - * - * @return When TLS verification fails and peer verification in - * #pjsip_tls_setting is not set, application may return - * PJ_TRUE to ignore the verification result and continue - * using the transport. On other cases, this return value - * is currently not used and will be ignored. - */ - pj_bool_t (*on_transport_state)(pjsip_transport *tp, pj_uint32_t state, - const pjsip_transport_state_info *info); + */ + pjsip_tp_state_callback on_transport_state; } pjsua_callback; diff --git a/pjsip/src/pjsip/sip_errno.c b/pjsip/src/pjsip/sip_errno.c index 1225dd99..0c15206a 100644 --- a/pjsip/src/pjsip/sip_errno.c +++ b/pjsip/src/pjsip/sip_errno.c @@ -131,6 +131,7 @@ static const struct PJ_BUILD_ERR( PJSIP_TLS_ESEND, "Unknown error when sending SSL data"), PJ_BUILD_ERR( PJSIP_TLS_EREAD, "Unknown error when reading SSL data"), PJ_BUILD_ERR( PJSIP_TLS_ETIMEDOUT, "SSL negotiation has timed out"), + PJ_BUILD_ERR( PJSIP_TLS_ECERTVERIF, "SSL certificate verification error"), }; diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 92fbaf4d..ecfba2c9 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -866,7 +866,7 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, /* * Register to hash table (see Trac ticket #42). */ - key_len = sizeof(tp->key.type) + sizeof(tp->key.hname) + tp->addr_len; + key_len = sizeof(tp->key.type) + tp->addr_len; pj_lock_acquire(mgr->lock); /* If entry already occupied, unregister previous entry */ @@ -916,7 +916,7 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr, /* * Unregister from hash table (see Trac ticket #42). */ - key_len = sizeof(tp->key.type) + sizeof(tp->key.hname) + tp->addr_len; + key_len = sizeof(tp->key.type) + tp->addr_len; hval = 0; entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval); if (entry == (void*)tp) @@ -1591,34 +1591,12 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr, int key_len; pjsip_transport *transport; - /* - * Find factory that can create such transport. - */ - factory = mgr->factory_list.next; - while (factory != &mgr->factory_list) { - if (factory->type == type) - break; - factory = factory->next; - } - if (factory == &mgr->factory_list) - factory = NULL; - pj_bzero(&key, sizeof(key)); - key_len = sizeof(key.type) + sizeof(key.hname) + addr_len; + key_len = sizeof(key.type) + addr_len; /* First try to get exact destination. */ key.type = type; pj_memcpy(&key.rem_addr, remote, addr_len); - if (factory && factory->create_transport2 && - tdata && tdata->dest_info.name.slen) - { - /* Only include hostname hash in the key when the factory support - * create_transport2() and tdata is supplied. - */ - key.hname = pj_hash_calc_tolower(0, - (char*)tdata->dest_info.name.ptr, - &tdata->dest_info.name); - } transport = (pjsip_transport*) pj_hash_get(mgr->table, &key, key_len, NULL); @@ -1635,7 +1613,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr, pj_sockaddr *addr = &key.rem_addr; pj_bzero(addr, addr_len); - key_len = sizeof(key.type) + sizeof(key.hname) + addr_len; + key_len = sizeof(key.type) + addr_len; transport = (pjsip_transport*) pj_hash_get(mgr->table, &key, key_len, NULL); } @@ -1648,7 +1626,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr, pj_bzero(addr, addr_len); addr->addr.sa_family = remote_addr->addr.sa_family; - key_len = sizeof(key.type) + sizeof(key.hname) + addr_len; + key_len = sizeof(key.type) + addr_len; transport = (pjsip_transport*) pj_hash_get(mgr->table, &key, key_len, NULL); } @@ -1668,8 +1646,16 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr, /* * Transport not found! + * Find factory that can create such transport. */ - if (NULL == factory) { + factory = mgr->factory_list.next; + while (factory != &mgr->factory_list) { + if (factory->type == type) + break; + factory = factory->next; + } + + if (factory == &mgr->factory_list) { /* No factory can create the transport! */ pj_lock_release(mgr->lock); TRACE_((THIS_FILE, "No suitable factory was found either")); @@ -1677,7 +1663,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr, } } - TRACE_((THIS_FILE, "Creating new transport from factory")); /* Request factory to create transport. */ diff --git a/pjsip/src/pjsip/sip_transport_loop.c b/pjsip/src/pjsip/sip_transport_loop.c index 490a7bb3..f754f7fe 100644 --- a/pjsip/src/pjsip/sip_transport_loop.c +++ b/pjsip/src/pjsip/sip_transport_loop.c @@ -381,6 +381,7 @@ PJ_DEF(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt, pjsip_transport_get_default_port_for_type((pjsip_transport_type_e) loop->base.key.type); loop->base.addr_len = sizeof(pj_sockaddr_in); + loop->base.dir = PJSIP_TP_DIR_NONE; loop->base.endpt = endpt; loop->base.tpmgr = pjsip_endpt_get_tpmgr(endpt); loop->base.send_msg = &loop_send_msg; diff --git a/pjsip/src/pjsip/sip_transport_tcp.c b/pjsip/src/pjsip/sip_transport_tcp.c index a7c7eeba..58e0ba41 100644 --- a/pjsip/src/pjsip/sip_transport_tcp.c +++ b/pjsip/src/pjsip/sip_transport_tcp.c @@ -584,6 +584,7 @@ static pj_status_t tcp_create( struct tcp_listener *listener, pj_memcpy(&tcp->base.local_addr, local, sizeof(pj_sockaddr_in)); sockaddr_to_host_port(pool, &tcp->base.local_name, local); sockaddr_to_host_port(pool, &tcp->base.remote_name, remote); + tcp->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING; tcp->base.endpt = listener->endpt; tcp->base.tpmgr = listener->tpmgr; @@ -1004,7 +1005,7 @@ static pj_bool_t on_accept_complete(pj_activesock_t *asock, pjsip_transport_state_info state_info; pj_bzero(&state_info, sizeof(state_info)); - (*state_cb)(&tcp->base, PJSIP_TP_STATE_ACCEPTED, &state_info); + (*state_cb)(&tcp->base, PJSIP_TP_STATE_CONNECTED, &state_info); } } } diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c index a135c43f..0d4ef882 100644 --- a/pjsip/src/pjsip/sip_transport_tls.c +++ b/pjsip/src/pjsip/sip_transport_tls.c @@ -557,8 +557,6 @@ static pj_status_t tls_create( struct tls_listener *listener, tls->base.key.type = PJSIP_TRANSPORT_TLS; pj_memcpy(&tls->base.key.rem_addr, remote, sizeof(pj_sockaddr_in)); - tls->base.key.hname = pj_hash_calc_tolower(0, (char*)tls->remote_name.ptr, - &tls->remote_name); tls->base.type_name = "tls"; tls->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); @@ -568,6 +566,7 @@ static pj_status_t tls_create( struct tls_listener *listener, (int)pj_ntohs(remote->sin_port)); tls->base.addr_len = sizeof(pj_sockaddr_in); + tls->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING; /* Set initial local address */ if (!pj_sockaddr_has_addr(local)) { @@ -978,10 +977,9 @@ static pj_bool_t on_accept_complete(pj_ssl_sock_t *ssock, struct tls_transport *tls; pj_ssl_sock_info ssl_info; char addr[PJ_INET6_ADDRSTRLEN+10]; - pj_status_t status; - pjsip_tp_state_callback *state_cb; - pj_bool_t tls_verif_ignored; + pj_bool_t is_shutdown; + pj_status_t status; PJ_UNUSED_ARG(src_addr_len); @@ -1021,46 +1019,54 @@ static pj_bool_t on_accept_complete(pj_ssl_sock_t *ssock, /* Set the "pending" SSL socket user data */ pj_ssl_sock_set_user_data(new_ssock, tls); - tls_verif_ignored = !listener->tls_setting.verify_client; + /* Prevent immediate transport destroy as application may access it + * (getting info, etc) in transport state notification callback. + */ + pjsip_transport_add_ref(&tls->base); + + /* If there is verification error and verification is mandatory, shutdown + * and destroy the transport. + */ + if (ssl_info.verify_status && listener->tls_setting.verify_client) { + if (tls->close_reason == PJ_SUCCESS) + tls->close_reason = PJSIP_TLS_ECERTVERIF; + pjsip_transport_shutdown(&tls->base); + } /* Notify transport state to application */ state_cb = pjsip_tpmgr_get_status_cb(tls->base.tpmgr); if (state_cb) { pjsip_transport_state_info state_info; pjsip_tls_state_info tls_info; - pj_uint32_t tp_state = 0; + pjsip_transport_state tp_state; - /* Init transport state notification callback */ + /* Init transport state info */ pj_bzero(&tls_info, sizeof(tls_info)); pj_bzero(&state_info, sizeof(state_info)); + tls_info.ssl_sock_info = &ssl_info; + state_info.ext_info = &tls_info; /* Set transport state based on verification status */ - if (ssl_info.verify_status) { - state_info.status = PJSIP_TLS_EACCEPT; - tp_state |= PJSIP_TP_STATE_TLS_VERIF_ERROR; - if (listener->tls_setting.verify_client) - tp_state |= PJSIP_TP_STATE_REJECTED; - else - tp_state |= PJSIP_TP_STATE_ACCEPTED; + if (ssl_info.verify_status && listener->tls_setting.verify_client) + { + tp_state = PJSIP_TP_STATE_DISCONNECTED; + state_info.status = PJSIP_TLS_ECERTVERIF; } else { - tp_state |= PJSIP_TP_STATE_ACCEPTED; + tp_state = PJSIP_TP_STATE_CONNECTED; + state_info.status = PJ_SUCCESS; } - tls_info.ssl_sock_info = &ssl_info; - state_info.ext_info = &tls_info; - - tls_verif_ignored = (*state_cb)(&tls->base, tp_state, &state_info); + (*state_cb)(&tls->base, tp_state, &state_info); } - /* Transport should be destroyed when there is TLS verification error - * and application doesn't want to ignore it. + /* Release transport reference. If transport is shutting down, it may + * get destroyed here. */ - if (ssl_info.verify_status && - (listener->tls_setting.verify_client || !tls_verif_ignored)) - { - tls_destroy(&tls->base, PJSIP_TLS_EACCEPT); + is_shutdown = tls->base.is_shutdown; + pjsip_transport_dec_ref(&tls->base); + if (is_shutdown) return PJ_TRUE; - } + status = tls_start_read(tls); if (status != PJ_SUCCESS) { @@ -1331,9 +1337,8 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock, struct tls_transport *tls; pj_ssl_sock_info ssl_info; pj_sockaddr_in addr, *tp_addr; - pjsip_tp_state_callback *state_cb; - pj_bool_t tls_verif_ignored; + pj_bool_t is_shutdown; tls = (struct tls_transport*) pj_ssl_sock_get_user_data(ssock); @@ -1432,7 +1437,19 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock, ssl_info.verify_status |= PJ_SSL_CERT_EIDENTITY_NOT_MATCH; } - tls_verif_ignored = !tls->verify_server; + /* Prevent immediate transport destroy as application may access it + * (getting info, etc) in transport state notification callback. + */ + pjsip_transport_add_ref(&tls->base); + + /* If there is verification error and verification is mandatory, shutdown + * and destroy the transport. + */ + if (ssl_info.verify_status && tls->verify_server) { + if (tls->close_reason == PJ_SUCCESS) + tls->close_reason = PJSIP_TLS_ECERTVERIF; + pjsip_transport_shutdown(&tls->base); + } /* Notify transport state to application */ state_cb = pjsip_tpmgr_get_status_cb(tls->base.tpmgr); @@ -1441,40 +1458,33 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock, pjsip_tls_state_info tls_info; pj_uint32_t tp_state = 0; - /* Init transport state notification callback */ + /* Init transport state info */ pj_bzero(&state_info, sizeof(state_info)); pj_bzero(&tls_info, sizeof(tls_info)); - - /* Set transport state info */ state_info.ext_info = &tls_info; tls_info.ssl_sock_info = &ssl_info; /* Set transport state based on verification status */ - if (ssl_info.verify_status) { - state_info.status = PJSIP_TLS_ECONNECT; - tp_state |= PJSIP_TP_STATE_TLS_VERIF_ERROR; - if (tls->verify_server) - tp_state |= PJSIP_TP_STATE_DISCONNECTED; - else - tp_state |= PJSIP_TP_STATE_CONNECTED; + if (ssl_info.verify_status && tls->verify_server) + { + tp_state = PJSIP_TP_STATE_DISCONNECTED; + state_info.status = PJSIP_TLS_ECERTVERIF; } else { - tp_state |= PJSIP_TP_STATE_CONNECTED; + tp_state = PJSIP_TP_STATE_CONNECTED; + state_info.status = PJ_SUCCESS; } - tls_verif_ignored = (*state_cb)(&tls->base, tp_state, &state_info); + (*state_cb)(&tls->base, tp_state, &state_info); } - /* Transport should be shutdown when there is TLS verification error - * and application doesn't want to ignore it. + /* Release transport reference. If transport is shutting down, it may + * get destroyed here. */ - if (ssl_info.verify_status && - (tls->verify_server || !tls_verif_ignored)) - { - if (tls->close_reason == PJ_SUCCESS) - tls->close_reason = PJSIP_TLS_ECONNECT; - pjsip_transport_shutdown(&tls->base); + is_shutdown = tls->base.is_shutdown; + pjsip_transport_dec_ref(&tls->base); + if (is_shutdown) return PJ_FALSE; - } + /* Mark that pending connect() operation has completed. */ tls->has_pending_connect = PJ_FALSE; diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c index 24e22945..20b15b91 100644 --- a/pjsip/src/pjsip/sip_transport_udp.c +++ b/pjsip/src/pjsip/sip_transport_udp.c @@ -736,6 +736,9 @@ static pj_status_t transport_attach( pjsip_endpoint *endpt, tp->base.remote_name.host = pj_str("::0"); tp->base.remote_name.port = 0; + /* Init direction */ + tp->base.dir = PJSIP_TP_DIR_NONE; + /* Set endpoint. */ tp->base.endpt = endpt; |