@@ -90,9 +90,8 @@ extern trace_proto_t tprot;
9090extern char * rest_id_s ;
9191
9292static CURLSH * curl_share = NULL ;
93- static gen_lock_t curl_share_locks [ CURL_LOCK_DATA_LAST ] ;
93+ static gen_lock_t * curl_socket_lock = NULL ;
9494
95- static enum curl_status status ;
9695static long timer ;
9796
9897/**
@@ -441,23 +440,31 @@ static inline int get_easy_status(CURL *handle, CURLM *multi, CURLcode *code)
441440}
442441
443442static void libcurl_share_lock (CURL * handle , curl_lock_data data , curl_lock_access access , void * clientp ) {
444- LM_DBG ("Locking libcurl share %d\n" , data );
445- lock_get (& curl_share_locks [data ]);
443+ if (data == CURL_LOCK_DATA_CONNECT ) {
444+ LM_DBG ("Locking libcurl share %d\n" , data );
445+ lock_get (curl_socket_lock );
446+ }
446447}
447448
448449static void libcurl_share_unlock (CURL * handle , curl_lock_data data , void * clientp ) {
449- LM_DBG ("Unlocking libcurl share %d\n" , data );
450- lock_release (& curl_share_locks [data ]);
450+ if (data == CURL_LOCK_DATA_CONNECT ) {
451+ LM_DBG ("Unlocking libcurl share %d\n" , data );
452+ lock_release (curl_socket_lock );
453+ }
451454}
452455
453456static CURLSH * get_curl_share (void ) {
454457 CURLSHcode src ;
455458
456459 if (!curl_share ) {
457- for (int i = 0 ; i < CURL_LOCK_DATA_LAST ; ++ i ) {
458- lock_init (& curl_share_locks [i ]);
460+ curl_socket_lock = lock_alloc ();
461+
462+ if (!curl_socket_lock ) {
463+ goto done ;
459464 }
460465
466+ lock_init (curl_socket_lock );
467+
461468 curl_share = curl_share_init ();
462469
463470 w_curl_share_setopt (curl_share , CURLSHOPT_SHARE , CURL_LOCK_DATA_CONNECT );
@@ -467,16 +474,19 @@ static CURLSH *get_curl_share(void) {
467474
468475 return curl_share ;
469476cleanup :
470- for (int i = 0 ; i < CURL_LOCK_DATA_LAST ; ++ i ) {
471- lock_destroy (& curl_share_locks [i ]);
477+ if (curl_socket_lock ) {
478+ lock_destroy (curl_socket_lock );
479+ lock_dealloc (curl_socket_lock );
480+ curl_socket_lock = NULL ;
472481 }
473482
474- curl_share_cleanup (curl_share );
483+ curl_share_cleanup (curl_share ); // Passing NULL returns early if init failed
475484 curl_share = NULL ;
485+ done :
476486 return NULL ;
477487}
478488
479- static int init_transfer (CURL * handle , char * url , unsigned long timeout_s )
489+ static int init_transfer (CURL * handle , char * url , unsigned long connect_timeout_s , unsigned long timeout_s )
480490{
481491 CURLcode rc ;
482492
@@ -491,10 +501,8 @@ static int init_transfer(CURL *handle, char *url, unsigned long timeout_s)
491501 tls_dom = NULL ;
492502 }
493503
494- w_curl_easy_setopt (handle , CURLOPT_CONNECTTIMEOUT ,
495- timeout_s && timeout_s > connection_timeout ? timeout_s : connection_timeout );
496- w_curl_easy_setopt (handle , CURLOPT_TIMEOUT ,
497- timeout_s && timeout_s > curl_timeout ? timeout_s : curl_timeout );
504+ w_curl_easy_setopt (handle , CURLOPT_CONNECTTIMEOUT , connect_timeout_s );
505+ w_curl_easy_setopt (handle , CURLOPT_TIMEOUT , curl_timeout );
498506
499507 w_curl_easy_setopt (handle , CURLOPT_VERBOSE , 1 );
500508 w_curl_easy_setopt (handle , CURLOPT_FAILONERROR , 0 );
@@ -802,7 +810,7 @@ int rest_sync_transfer(enum rest_client_method method, struct sip_msg *msg,
802810 str st = STR_NULL , res_body = STR_NULL , tbody , ttype ;
803811
804812 curl_easy_reset (sync_handle );
805- if (init_transfer (sync_handle , url , 0 ) != 0 ) {
813+ if (init_transfer (sync_handle , url , connection_timeout , curl_timeout ) != 0 ) {
806814 LM_ERR ("failed to init transfer to %s\n" , url );
807815 goto cleanup ;
808816 }
@@ -918,7 +926,7 @@ static int start_async_http_req_v1(struct sip_msg *msg, enum rest_client_method
918926 goto cleanup ;
919927 }
920928
921- if (init_transfer (handle , url , async_parm -> timeout_s ) != 0 ) {
929+ if (init_transfer (handle , url , async_parm -> timeout_s , async_parm -> timeout_s ) != 0 ) {
922930 LM_ERR ("failed to init transfer to %s\n" , url );
923931 goto cleanup ;
924932 }
@@ -1613,9 +1621,7 @@ int connect_only(preconnect_urls *precon_urls, int total_cons) {
16131621 long busy_wait , timer ;
16141622 int msgq , num_of_connections , exit_code = 0 ;
16151623
1616- curl_share = get_curl_share ();
1617-
1618- if (!curl_share ) {
1624+ if (!share_connections ) {
16191625 exit_code = -1 ;
16201626 goto done ;
16211627 }
@@ -1640,7 +1646,7 @@ int connect_only(preconnect_urls *precon_urls, int total_cons) {
16401646 handle = curl_easy_init ();
16411647 curl_multi_add_handle (multi_handle , handle );
16421648
1643- if (init_transfer (handle , url , 0 ) != 0 ) {
1649+ if (init_transfer (handle , url , curl_timeout , curl_timeout ) != 0 ) {
16441650 exit_code = -1 ;
16451651 goto cleanup ;
16461652 }
@@ -1651,7 +1657,6 @@ int connect_only(preconnect_urls *precon_urls, int total_cons) {
16511657 }
16521658
16531659 w_curl_easy_setopt (handle , CURLOPT_NOBODY , 1L );
1654- w_curl_easy_setopt (handle , CURLOPT_SHARE , curl_share );
16551660 }
16561661
16571662 start = start -> next ;
@@ -1726,7 +1731,7 @@ int start_async_http_req_v2(struct sip_msg *msg, enum rest_client_method method,
17261731 CURLMcode mrc ;
17271732 OSS_CURLM * multi_list ;
17281733 CURLM * multi_handle ;
1729- long busy_wait ;
1734+ long busy_wait , req_sz ;
17301735
17311736 handle = curl_easy_init ();
17321737
@@ -1735,7 +1740,7 @@ int start_async_http_req_v2(struct sip_msg *msg, enum rest_client_method method,
17351740 goto cleanup ;
17361741 }
17371742
1738- if (init_transfer (handle , url , async_parm -> timeout_s ) != 0 ) {
1743+ if (init_transfer (handle , url , connection_timeout , async_parm -> timeout_s ) != 0 ) {
17391744 LM_ERR ("failed to init transfer to %s\n" , url );
17401745 goto cleanup ;
17411746 }
@@ -1795,13 +1800,8 @@ int start_async_http_req_v2(struct sip_msg *msg, enum rest_client_method method,
17951800 goto cleanup ;
17961801 }
17971802
1798- w_curl_multi_setopt (multi_handle , CURLMOPT_MAXCONNECTS , (long ) max_connections );
1799-
1800- status = CURL_NONE ;
1801- w_curl_easy_setopt (handle , CURLOPT_PREREQFUNCTION , prereq_callback );
1802- w_curl_easy_setopt (handle , CURLOPT_PREREQDATA , & status );
1803-
1804- busy_wait = connect_poll_interval ;
1803+ w_curl_multi_setopt (multi_handle , CURLMOPT_MAX_HOST_CONNECTIONS , max_host_connections );
1804+ w_curl_multi_setopt (multi_handle , CURLMOPT_MAXCONNECTS , max_connections );
18051805
18061806 w_curl_multi_setopt (multi_handle , CURLMOPT_TIMERFUNCTION , timer_cb );
18071807 w_curl_multi_setopt (multi_handle , CURLMOPT_TIMERDATA , & timer );
@@ -1810,14 +1810,18 @@ int start_async_http_req_v2(struct sip_msg *msg, enum rest_client_method method,
18101810 goto cleanup ;
18111811 }
18121812
1813+ busy_wait = connect_poll_interval ;
1814+
18131815 do {
18141816 running_handles = run_multi_socket (multi_handle );
18151817
18161818 if (running_handles < 0 ) {
18171819 goto error ;
18181820 }
18191821
1820- if (status == CURL_REQUEST_SENT ) {
1822+ curl_easy_getinfo (handle , CURLINFO_REQUEST_SIZE , & req_sz );
1823+
1824+ if (req_sz > 0 ) {
18211825 goto success ;
18221826 }
18231827
0 commit comments