3131#include <pj/guid.h>
3232#include <pj/assert.h>
3333#include <pj/ctype.h>
34+ #include <pj/lock.h>
3435
3536
3637#if defined(PJ_HAS_SSL_SOCK ) && PJ_HAS_SSL_SOCK != 0 && \
@@ -105,6 +106,20 @@ const pjsip_auth_algorithm pjsip_auth_algorithms[] = {
105106# define AUTH_TRACE_ (expr )
106107#endif
107108
109+ #define DO_ON_PARENT_LOCKED (sess , call ) \
110+ do { \
111+ pj_status_t on_parent; \
112+ pj_bool_t with_parent = PJ_FALSE; \
113+ if (sess->parent) { \
114+ pj_lock_acquire(sess->parent->lock); \
115+ with_parent = PJ_TRUE; \
116+ on_parent = call; \
117+ pj_lock_release(sess->parent->lock); \
118+ } \
119+ if (with_parent) { \
120+ return on_parent; \
121+ } \
122+ } while(0)
108123
109124static void dup_bin (pj_pool_t * pool , pj_str_t * dst , const pj_str_t * src )
110125{
@@ -712,6 +727,17 @@ static pjsip_cached_auth *find_cached_auth( pjsip_auth_clt_sess *sess,
712727 const pj_str_t * realm ,
713728 pjsip_auth_algorithm_type algorithm_type )
714729{
730+ pj_bool_t with_parent = PJ_FALSE ;
731+ pjsip_cached_auth * pauth = NULL ;
732+ if (sess -> parent ) {
733+ pj_lock_acquire (sess -> parent -> lock );
734+ pauth = find_cached_auth (sess -> parent , realm , algorithm_type );
735+ pj_lock_release (sess -> parent -> lock );
736+ }
737+ if (pauth != NULL ) {
738+ return pauth ;
739+ }
740+
715741 pjsip_cached_auth * auth = sess -> cached_auth .next ;
716742 while (auth != & sess -> cached_auth ) {
717743 if (pj_stricmp (& auth -> realm , realm ) == 0
@@ -734,6 +760,17 @@ static const pjsip_cred_info* auth_find_cred( const pjsip_auth_clt_sess *sess,
734760
735761 PJ_UNUSED_ARG (auth_scheme );
736762
763+ pj_bool_t with_parent = PJ_FALSE ;
764+ const pjsip_cred_info * ptr = NULL ;
765+ if (sess -> parent ) {
766+ pj_lock_acquire (sess -> parent -> lock );
767+ ptr = auth_find_cred (sess -> parent , realm , auth_scheme , algorithm_type );
768+ pj_lock_release (sess -> parent -> lock );
769+ }
770+ if (ptr != NULL ) {
771+ return ptr ;
772+ }
773+
737774 for (i = 0 ; i < sess -> cred_cnt ; ++ i ) {
738775 switch (sess -> cred_info [i ].data_type ) {
739776 case PJSIP_CRED_DATA_PLAIN_PASSWD :
@@ -795,6 +832,21 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
795832 sess -> cred_info = NULL ;
796833 pj_list_init (& sess -> cached_auth );
797834
835+ sess -> parent = NULL ;
836+ sess -> lock = NULL ;
837+ return PJ_SUCCESS ;
838+ }
839+
840+ PJ_DEF (pj_status_t ) pjsip_auth_clt_set_parent (pjsip_auth_clt_sess * sess ,
841+ const pjsip_auth_clt_sess * parent )
842+ {
843+ PJ_ASSERT_RETURN (sess && parent , PJ_EINVAL );
844+ if (parent -> lock == NULL ) {
845+ pj_lock_create_simple_mutex ( parent -> pool ,
846+ "auth_clt_parent_lock" ,
847+ & parent -> lock );
848+ }
849+ sess -> parent = parent ;
798850 return PJ_SUCCESS ;
799851}
800852
@@ -812,7 +864,12 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_deinit(pjsip_auth_clt_sess *sess)
812864 auth = auth -> next ;
813865 }
814866
815- return PJ_SUCCESS ;
867+ sess -> parent = NULL ;
868+ if (sess -> lock ) {
869+ return pj_lock_destroy (sess -> lock );
870+ } else {
871+ return PJ_SUCCESS ;
872+ }
816873}
817874
818875
@@ -849,6 +906,21 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
849906 }
850907 }
851908
909+ pj_status_t status ;
910+ if (sess -> parent ) {
911+ pj_lock_acquire (sess -> parent -> lock );
912+ sess -> parent = PJ_POOL_ZALLOC_T (pool , pjsip_auth_clt_sess );
913+ if (sess -> parent == NULL ) {
914+ status = PJ_ENOMEM ;
915+ } else {
916+ status = pjsip_auth_clt_clone (pool , sess -> parent , rhs -> parent );
917+ }
918+ pj_lock_release (sess -> parent -> lock );
919+ }
920+ if (status != PJ_SUCCESS ) {
921+ return status ;
922+ }
923+
852924 /* TODO note:
853925 * Cloning the full authentication client is quite a big task.
854926 * We do only the necessary bits here, i.e. cloning the credentials.
@@ -868,6 +940,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
868940 const pjsip_cred_info * c )
869941{
870942 PJ_ASSERT_RETURN (sess && c , PJ_EINVAL );
943+ DO_ON_PARENT_LOCKED (sess , pjsip_auth_clt_set_credentials (sess -> parent , cred_cnt , c ));
871944
872945 if (cred_cnt == 0 ) {
873946 sess -> cred_cnt = 0 ;
@@ -943,6 +1016,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
9431016 const pjsip_auth_clt_pref * p )
9441017{
9451018 PJ_ASSERT_RETURN (sess && p , PJ_EINVAL );
1019+ DO_ON_PARENT_LOCKED (sess , pjsip_auth_clt_set_prefs (sess -> parent , p ));
9461020
9471021 pj_memcpy (& sess -> pref , p , sizeof (* p ));
9481022 pj_strdup (sess -> pool , & sess -> pref .algorithm , & p -> algorithm );
@@ -960,7 +1034,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
9601034 pjsip_auth_clt_pref * p )
9611035{
9621036 PJ_ASSERT_RETURN (sess && p , PJ_EINVAL );
963-
1037+ DO_ON_PARENT_LOCKED ( sess , pjsip_auth_clt_get_prefs ( sess -> parent , p ));
9641038 pj_memcpy (p , & sess -> pref , sizeof (pjsip_auth_clt_pref ));
9651039 return PJ_SUCCESS ;
9661040}
@@ -1197,6 +1271,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
11971271 PJ_ASSERT_RETURN (tdata -> msg -> type == PJSIP_REQUEST_MSG ,
11981272 PJSIP_ENOTREQUESTMSG );
11991273
1274+
1275+ DO_ON_PARENT_LOCKED (sess , pjsip_auth_clt_init_req (sess -> parent , tdata ));
12001276 /* Init list */
12011277 pj_list_init (& added );
12021278
@@ -1548,6 +1624,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
15481624 rdata -> msg_info .msg -> line .status .code == 407 ,
15491625 PJSIP_EINVALIDSTATUS );
15501626
1627+ DO_ON_PARENT_LOCKED (sess , pjsip_auth_clt_reinit_req (sess -> parent , rdata , old_request , new_request ));
1628+
15511629 tdata = old_request ;
15521630 tdata -> auth_retry = PJ_FALSE ;
15531631
0 commit comments