From b7c6c0e483e45a4bebe530f7a9b49f13ab66c925 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 19 Nov 2007 18:09:15 +0000 Subject: [PATCH] Merge up to current sofia-sip darcs. Thu Nov 15 08:40:38 EST 2007 Pekka.Pessi@nokia.com * htable2.h: fixed usize_t/size_t confusion Fri Nov 16 06:38:51 EST 2007 Youness Alaoui * Added #include Fri Nov 16 10:27:58 EST 2007 Pekka.Pessi@nokia.com * auth_client.c: allow multiple challenges in auc_credentials() or auc_all_credentials() Fri Nov 16 10:29:00 EST 2007 Pekka.Pessi@nokia.com * nua/test_proxy.[hc], nua/test_register.c: test support of multiple realms. Fri Nov 16 11:17:09 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/su_alloc.h, su_alloc.c: added su_home_lock(), su_home_trylock(), su_home_unlock() Added test in torture_su_alloc.c. Using in su_pthread_port.c. Fri Nov 16 12:29:55 EST 2007 Pekka.Pessi@nokia.com * test_register.c, test_proxy.c: use realm "test-proxy" during normal tests Fri Nov 16 12:34:00 EST 2007 Pekka.Pessi@nokia.com * nua_register.c: sf.net bug #1816647: Outbound contact does not make it to dialogs Now use Contact from first registration instead of Contact generated from transport. Mon Nov 19 12:00:06 EST 2007 Pekka Pessi * su_alloc.c: silenced warnings on Sun CC git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6338 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/sofia-sip/libsofia-sip-ua/bnf/bnf.c | 1 + .../libsofia-sip-ua/http/http_extra.c | 1 + libs/sofia-sip/libsofia-sip-ua/ipt/token64.c | 1 + .../libsofia-sip-ua/iptsec/auth_client.c | 2 +- .../libsofia-sip-ua/iptsec/auth_common.c | 1 + .../libsofia-sip-ua/iptsec/auth_digest.c | 1 + libs/sofia-sip/libsofia-sip-ua/msg/msg_auth.c | 1 + .../libsofia-sip-ua/nua/nua_register.c | 27 +++-- .../libsofia-sip-ua/nua/test_basic_call.c | 16 ++- .../libsofia-sip-ua/nua/test_proxy.c | 34 ++++-- .../libsofia-sip-ua/nua/test_proxy.h | 5 +- .../libsofia-sip-ua/nua/test_register.c | 21 +++- .../sofia-sip/libsofia-sip-ua/sip/sip_event.c | 1 + .../sofia-sip/libsofia-sip-ua/sip/sip_extra.c | 1 + .../libsofia-sip-ua/sip/sip_feature.c | 1 + libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c | 1 + .../libsofia-sip-ua/sip/sip_pref_util.c | 1 + .../libsofia-sip-ua/sip/sip_reason.c | 1 + .../sofia-sip/libsofia-sip-ua/sip/sip_refer.c | 1 + .../libsofia-sip-ua/sip/sip_security.c | 1 + .../libsofia-sip-ua/sip/sip_tag_class.c | 1 + libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c | 1 + .../libsofia-sip-ua/su/sofia-sip/htable2.h | 10 +- .../libsofia-sip-ua/su/sofia-sip/su_alloc.h | 4 + libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c | 114 ++++++++++++++---- .../libsofia-sip-ua/su/su_alloc_lock.c | 39 +++--- libs/sofia-sip/libsofia-sip-ua/su/su_log.c | 1 + .../libsofia-sip-ua/su/su_pthread_port.c | 4 +- libs/sofia-sip/libsofia-sip-ua/su/su_strlst.c | 1 + .../libsofia-sip-ua/su/torture_su_alloc.c | 39 +++++- libs/sofia-sip/libsofia-sip-ua/url/url.c | 1 + 31 files changed, 264 insertions(+), 70 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/bnf/bnf.c b/libs/sofia-sip/libsofia-sip-ua/bnf/bnf.c index 0422f6bc9d..6783659050 100644 --- a/libs/sofia-sip/libsofia-sip-ua/bnf/bnf.c +++ b/libs/sofia-sip/libsofia-sip-ua/bnf/bnf.c @@ -35,6 +35,7 @@ #include "sofia-sip/bnf.h" +#include #include #define ws bnf_ws diff --git a/libs/sofia-sip/libsofia-sip-ua/http/http_extra.c b/libs/sofia-sip/libsofia-sip-ua/http/http_extra.c index 8000a7db29..f9f8fa5d8e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/http/http_extra.c +++ b/libs/sofia-sip/libsofia-sip-ua/http/http_extra.c @@ -33,6 +33,7 @@ #include "config.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/ipt/token64.c b/libs/sofia-sip/libsofia-sip-ua/ipt/token64.c index 75c737f6ca..dd7548f9bb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/ipt/token64.c +++ b/libs/sofia-sip/libsofia-sip-ua/ipt/token64.c @@ -33,6 +33,7 @@ #include "config.h" +#include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c index e336623eb6..ade683ea72 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c @@ -387,7 +387,7 @@ int ca_credentials(auth_client_t *ca, if ((scheme != NULL && strcasecmp(scheme, ca->ca_scheme)) || (realm != NULL && strcmp(realm, ca->ca_realm))) - return -1; + return 0; old_user = ca->ca_user, old_pass = ca->ca_pass; diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_common.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_common.c index 5fa4d7737e..2fd6a6e21d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_common.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_common.c @@ -37,6 +37,7 @@ #include "sofia-sip/auth_common.h" #include "sofia-sip/msg_header.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_digest.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_digest.c index 97e59d2b2f..7a45809526 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_digest.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_digest.c @@ -41,6 +41,7 @@ #include "iptsec_debug.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_auth.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_auth.c index 912b147164..c81e9f0ca5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_auth.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_auth.c @@ -35,6 +35,7 @@ #include "config.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c index 909098917f..fda891f5d3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c @@ -1426,6 +1426,7 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list, int sips_uri = remote_uri && remote_uri->url_type == url_sips; nua_registration_t const *nr, *public = NULL, *any = NULL; + nua_registration_t const *registered = NULL; nua_registration_t const *namewise = NULL, *sipswise = NULL; int ip4 = remote_uri && host_is_ip4_address(remote_uri->url_host); @@ -1444,11 +1445,15 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list, continue; if (sips_uri ? nr->nr_secure : !nr->nr_secure) return (nua_registration_t *)nr; + if (!registered && nr->nr_aor) + registered = nr; if (!public && nr->nr_public) public = nr; if (!any) any = nr; } + if (registered) + return (nua_registration_t *)registered; if (public) return (nua_registration_t *)public; if (any) @@ -1456,8 +1461,11 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list, return NULL; } - if (!sips_aor && aor) + if (!sips_aor && aor) { alt_aor = memcpy(_alt_aor, aor, sizeof _alt_aor); + alt_aor->a_url->url_type = url_sips; + alt_aor->a_url->url_scheme = "sips"; + } for (nr = list; nr; nr = nr->nr_next) { if (!nr->nr_ready || !nr->nr_contact) @@ -1468,11 +1476,12 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list, if (!namewise && alt_aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0) namewise = nr; } - else { - if (!sipswise && ((sips_aor || sips_uri) ? - nr->nr_secure : !nr->nr_secure)) - sipswise = nr; - } + + if (!sipswise && ((sips_aor || sips_uri) ? + nr->nr_secure : !nr->nr_secure)) + sipswise = nr; + if (!registered) + registered = nr; if (!public && nr->nr_public) public = nr; if (!any) @@ -1483,7 +1492,9 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list, return (nua_registration_t *)namewise; if (sipswise) return (nua_registration_t *)sipswise; - + if (registered) + return (nua_registration_t *)registered; + /* XXX - should we do some policing whether sips_aor or sips_uri can be used with sip contact? @@ -1594,7 +1605,7 @@ int nua_registration_add_contact_to_request(nua_handle_t *nh, * * @param nh * @param msg response message - * @param sip response headers + * @param sip headers in response message * @param record_route record-route from request * @param remote_contact Contact from request */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c index e355689222..689edbea05 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c @@ -457,8 +457,14 @@ int test_basic_call_2(struct context *ctx) TEST_S(sip->sip_content_type->c_type, "application/sdp"); TEST_1(sip->sip_payload); /* there is sdp in 200 OK */ TEST_1(sip->sip_contact); +#if nomore /* Test that B does not use application-specific contact */ TEST_1(!sip->sip_contact->m_url->url_user); +#else + /* sf.net bug #1816647: Outbound contact does not make it to dialogs */ + /* Now we use first registered contact if aor does not match */ + TEST_S(sip->sip_contact->m_url->url_user, "b"); +#endif TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state); TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */ TEST_1(!is_answer_recv(e->data->e_tags)); /* but it is ignored */ @@ -989,6 +995,9 @@ int change_uri_in_ack(CONDITION_PARAMS) } /* Test changing from/to within dialog */ +/* Test that a proper Contact gets selected in response + * regardless of the To URI. + */ int test_basic_call_5(struct context *ctx) { BEGIN(); @@ -1004,13 +1013,15 @@ int test_basic_call_5(struct context *ctx) a_call->sdp = "m=audio 5008 RTP/AVP 8"; b_call->sdp = "m=audio 5010 RTP/AVP 0 8"; - TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END())); + TEST_1(a_call->nh = nua_handle(a->nua, a_call, + SIPTAG_TO_STR(""), + TAG_END())); TEST_1(!nua_handle_has_active_call(a_call->nh)); TEST_1(!nua_handle_has_call_on_hold(a_call->nh)); INVITE(a, a_call, a_call->nh, - TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)), + NUTAG_URL(b->contact->m_url), SOATAG_USER_SDP_STR(a_call->sdp), NUTAG_AUTOACK(0), TAG_END()); @@ -1032,6 +1043,7 @@ int test_basic_call_5(struct context *ctx) TEST(e->data->e_status, 200); TEST_1(sip = sip_object(e->data->e_msg)); TEST_1(sip->sip_contact); + TEST_S(sip->sip_contact->m_url->url_user, "b"); TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state); TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c index a439f1af99..c6e59ac072 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c @@ -134,7 +134,7 @@ struct domain { struct { sip_time_t min_expires, expires, max_expires; int outbound_tcp; /**< Use inbound TCP connection as outbound */ - int authorize; + char const *authorize; /**< Authorization realm to use */ } prefs; tagi_t *tags; @@ -216,6 +216,7 @@ struct proxy_tr auth_mod_t *am; /* Authentication module */ auth_status_t *as; /* Authentication status */ + char const *realm; /* Authentication realm to use */ unsigned use_auth; /* Authentication method (401/407) to use */ unsigned rr:1; @@ -473,20 +474,33 @@ void test_proxy_domain_get_outbound(struct domain *d, } } -void test_proxy_domain_set_authorize(struct domain *d, int authorize) +int test_proxy_domain_set_authorize(struct domain *d, + char const *realm) { if (d) { - d->prefs.authorize = authorize; + if (realm) { + realm = su_strdup(d->home, realm); + if (!realm) + return -1; + } + + d->prefs.authorize = realm; + + return 0; } + return -1; } -void test_proxy_domain_get_authorize(struct domain *d, - int *return_authorize) +int test_proxy_domain_get_authorize(struct domain *d, + char const **return_realm) { if (d) { - if (return_authorize) - *return_authorize = d->prefs.authorize; + if (return_realm) { + *return_realm = d->prefs.authorize; + return 0; + } } + return -1; } int test_proxy_close_tports(struct proxy *p) @@ -533,7 +547,7 @@ struct domain *test_proxy_add_domain(struct proxy *p, d->prefs.expires = 3600; d->prefs.max_expires = 36000; d->prefs.outbound_tcp = 0; - d->prefs.authorize = 0; + d->prefs.authorize = NULL; if (d->uri && d->tags && !su_task_execute(su_clone_task(p->clone), _domain_init, d, &init)) { @@ -795,6 +809,7 @@ static int originating_transaction(struct proxy_tr *t) if (o && o->auth && o->prefs.authorize) { t->am = o->auth; + t->realm = o->prefs.authorize; t->use_auth = 407; } @@ -966,6 +981,7 @@ static int challenge_transaction(struct proxy_tr *t) as->as_method = sip->sip_request->rq_method_name; as->as_source = msg_addrinfo(t->msg); + as->as_realm = t->realm; as->as_user_uri = sip->sip_from->a_url; as->as_display = sip->sip_from->a_display; @@ -1110,6 +1126,8 @@ int process_register(struct proxy_tr *t) if (t->domain->auth) { t->am = t->domain->auth, t->use_auth = 401; + if (t->domain->prefs.authorize) + t->realm = t->domain->prefs.authorize; if (challenge_transaction(t)) return t->status; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h index b8b2ac6672..d8f5c0933c 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h @@ -64,8 +64,9 @@ void test_proxy_get_session_timer(struct proxy *p, sip_time_t *return_session_expires, sip_time_t *return_min_se); -void test_proxy_domain_set_authorize(struct domain *d, int authorize); -void test_proxy_domain_get_authorize(struct domain *d, int *return_authorize); +int test_proxy_domain_set_authorize(struct domain *, char const *realm); +int test_proxy_domain_get_authorize(struct domain *, + char const **return_realm); void test_proxy_domain_set_outbound(struct domain *d, int use_outbound); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c index 9276b04582..1ee17cf248 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c @@ -426,7 +426,7 @@ int test_register_c(struct context *ctx) printf("TEST NUA-2.3.3: REGISTER c\n"); test_proxy_domain_set_expiration(ctx->c.domain, 600, 3600, 36000); - test_proxy_domain_set_authorize(ctx->c.domain, 2); + test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy-0"); TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END())); @@ -453,7 +453,7 @@ int test_register_c(struct context *ctx) free_events_in_list(ctx, c->events); AUTHENTICATE(c, c_reg, c_reg->nh, - NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END()); + NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"), TAG_END()); run_abc_until(ctx, -1, save_events, -1, save_events, -1, save_until_final_response); @@ -778,6 +778,23 @@ int test_connectivity(struct context *ctx) free_events_in_list(ctx, c->events); + /* Sneakily change the realm */ + + TEST(test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy"), 0); + + AUTHENTICATE(c, c_call, c_call->nh, + NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"), + TAG_END()); + + run_abc_until(ctx, -1, NULL, -1, NULL, -1, save_until_final_response); + + /* Client events: nua_options(), nua_r_options */ + TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_options); + TEST(e->data->e_status, 407); + TEST_1(!e->next); + + free_events_in_list(ctx, c->events); + AUTHENTICATE(c, c_call, c_call->nh, NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END()); diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_event.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_event.c index d0712a16e4..cf9e1ec403 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_event.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_event.c @@ -41,6 +41,7 @@ #include "sofia-sip/sip_parser.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c index 0bc8957543..4b1e6c4e45 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c @@ -43,6 +43,7 @@ #include "sofia-sip/sip_parser.h" #include "sofia-sip/sip_extra.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c index 6030b45c2c..a072187cae 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c @@ -39,6 +39,7 @@ #include "sofia-sip/sip_parser.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c index f0938be630..ff44a6b867 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c @@ -40,6 +40,7 @@ #include "sofia-sip/sip_parser.h" #include "sofia-sip/msg_mime_protos.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_pref_util.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_pref_util.c index bbbdfb849e..bb7d9800cb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_pref_util.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_pref_util.c @@ -33,6 +33,7 @@ #include "config.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c index ee2157cdc7..86e11fd8ae 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c @@ -39,6 +39,7 @@ #include "sofia-sip/sip_parser.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_refer.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_refer.c index 057f469d88..a9b0a3b3bb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_refer.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_refer.c @@ -42,6 +42,7 @@ #include "sofia-sip/sip_parser.h" #include "sofia-sip/sip_extra.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c index cb2a1c6eab..3bd85f4676 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c @@ -57,6 +57,7 @@ #include "sofia-sip/sip_parser.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_tag_class.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_tag_class.c index 611908091e..436f25be96 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_tag_class.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_tag_class.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c index b11c636b51..5d371ea98e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c @@ -50,6 +50,7 @@ #include +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h index 54f3be3557..98cee22aef 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h @@ -138,13 +138,13 @@ HTABLE2_SCOPE int prefix##_remove(type *, entrytype const) HTABLE2_SCOPE \ int prefix##_resize(void *realloc_arg, \ type pr[1], \ - usize_t new_size) \ + size_t new_size) \ { \ entrytype *new_hash; \ entrytype *old_hash = pr->pr##table; \ - usize_t old_size; \ - usize_t i, j, i0; \ - usize_t again = 0, used = 0, collisions = 0; \ + size_t old_size; \ + size_t i, j, i0; \ + size_t again = 0, used = 0, collisions = 0; \ \ (void)realloc_arg; \ \ @@ -256,7 +256,7 @@ entrytype *prefix##_insert(type *pr, entrytype e) \ HTABLE2_SCOPE \ int prefix##_remove(type *pr, entrytype const e) \ { \ - usize_t i, j, k, size = pr->pr##size; \ + size_t i, j, k, size = pr->pr##size; \ entrytype *htable = pr->pr##table; \ \ /* Search for entry */ \ diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h index a5b2d70f8e..d4ff66559f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h @@ -107,6 +107,10 @@ SU_DLL int su_home_mutex_lock(su_home_t *home); SU_DLL int su_home_mutex_unlock(su_home_t *home); +SU_DLL int su_home_lock(su_home_t *home); +SU_DLL int su_home_trylock(su_home_t *home); +SU_DLL int su_home_unlock(su_home_t *home); + SU_DLL void *su_alloc(su_home_t *h, isize_t size) __attribute__((__malloc__)); SU_DLL void *su_zalloc(su_home_t *h, isize_t size) diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c index 948ba295ea..b54b71a7ab 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c @@ -186,6 +186,7 @@ #include "sofia-sip/su_alloc_stat.h" #include "sofia-sip/su_errno.h" +#include #include #include #include @@ -193,17 +194,18 @@ #include -void (*su_home_locker)(void *mutex); -void (*su_home_unlocker)(void *mutex); +int (*_su_home_locker)(void *mutex); +int (*_su_home_unlocker)(void *mutex); -void (*su_home_mutex_locker)(void *mutex); -void (*su_home_mutex_unlocker)(void *mutex); +int (*_su_home_mutex_locker)(void *mutex); +int (*_su_home_mutex_trylocker)(void *mutex); +int (*_su_home_mutex_unlocker)(void *mutex); -void (*su_home_destroy_mutexes)(void *mutex); +void (*_su_home_destroy_mutexes)(void *mutex); #define MEMLOCK(h) \ - (((h) && (h)->suh_lock ? su_home_locker((h)->suh_lock) : (void)0), (h)->suh_blocks) -#define UNLOCK(h) (((h) && (h)->suh_lock ? su_home_unlocker((h)->suh_lock) : (void)0), NULL) + ((void)((h) && (h)->suh_lock ? _su_home_locker((h)->suh_lock) : 0), (h)->suh_blocks) +#define UNLOCK(h) ((void)((h) && (h)->suh_lock ? _su_home_unlocker((h)->suh_lock) : 0), NULL) #ifdef NDEBUG #define MEMCHECK 0 @@ -987,7 +989,7 @@ void _su_home_deinit(su_home_t *home) home->suh_blocks = NULL; if (home->suh_lock) - su_home_destroy_mutexes(home->suh_lock); + _su_home_destroy_mutexes(home->suh_lock); } home->suh_lock = NULL; @@ -1462,42 +1464,108 @@ int su_home_is_threadsafe(su_home_t const *home) return home && home->suh_lock; } -/** Obtain exclusive lock on home (if home is threadsafe). */ +/** Increase refcount and obtain exclusive lock on home. + * + * @note The #su_home_t structure must be created with su_home_new() or + * su_home_clone(), or initialized with su_home_init() before using this + * function. + * + * In order to enable actual locking, use su_home_threadsafe(), too. + * Otherwise the su_home_mutex_lock() will just increase the reference + * count. + */ int su_home_mutex_lock(su_home_t *home) { + int error; + if (home == NULL) return su_seterrno(EFAULT); - if (home->suh_lock) { - su_home_ref(home); - su_home_mutex_locker(home->suh_lock); - } - else if (home->suh_blocks) { - if (!su_home_ref(home)) - return -1; - } + if (home->suh_blocks == NULL || !su_home_ref(home)) + return su_seterrno(EINVAL); /* Uninitialized home */ + + if (!home->suh_lock) + return 0; /* No-op */ + + error = _su_home_mutex_locker(home->suh_lock); + if (error) + return su_seterrno(error); return 0; } -/** Release exclusive lock on home (if home is threadsafe) */ +/** Release exclusive lock on home and decrease refcount (if home is threadsafe) */ int su_home_mutex_unlock(su_home_t *home) { if (home == NULL) return su_seterrno(EFAULT); if (home->suh_lock) { - su_home_mutex_unlocker(home->suh_lock); - su_home_unref(home); - } - else if (home->suh_blocks) { - su_home_unref(home); + int error = _su_home_mutex_unlocker(home->suh_lock); + if (error) + return su_seterrno(error); } + if (home->suh_blocks == NULL) + return su_seterrno(EINVAL), -1; /* Uninitialized home */ + + su_home_unref(home); + return 0; } +/** Obtain exclusive lock on home without increasing refcount. + * + * @return 0 if successful, -1 if not threadsafe, error code otherwise. + * + */ +int su_home_lock(su_home_t *home) +{ + if (home == NULL) + return EFAULT; + + if (home->suh_lock == NULL) + return -1; /* No-op */ + + return _su_home_mutex_locker(home->suh_lock); +} + + +/** Try to obtain exclusive lock on home without increasing refcount. + * + * @return 0 if successful, -1 if not threadsafe, + * EBUSY if already locked, error code otherwise. + * + */ +int su_home_trylock(su_home_t *home) +{ + if (home == NULL) + return EFAULT; + + if (home->suh_lock == NULL) + return -1; /* No-op */ + + return _su_home_mutex_trylocker(home->suh_lock); +} + + +/** Release exclusive lock on home. + * + * @return 0 if successful, -1 if not threadsafe, error code otherwise. + */ +int su_home_unlock(su_home_t *home) +{ + if (home == NULL) + return EFAULT; + + if (home->suh_lock == NULL) + return -1; /* No-op */ + + return _su_home_mutex_unlocker(home->suh_lock); +} + + /** Initialize statistics structure */ void su_home_init_stats(su_home_t *home) { diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc_lock.c b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc_lock.c index d9f4a94724..ce5a958568 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc_lock.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc_lock.c @@ -41,25 +41,32 @@ #include #include -extern void (*su_home_locker)(void *mutex); -extern void (*su_home_unlocker)(void *mutex); +extern int (*_su_home_locker)(void *mutex); +extern int (*_su_home_unlocker)(void *mutex); -extern void (*su_home_mutex_locker)(void *mutex); -extern void (*su_home_mutex_unlocker)(void *mutex); +extern int (*_su_home_mutex_locker)(void *mutex); +extern int (*_su_home_mutex_trylocker)(void *mutex); +extern int (*_su_home_mutex_unlocker)(void *mutex); -extern void (*su_home_destroy_mutexes)(void *mutex); +extern void (*_su_home_destroy_mutexes)(void *mutex); /** Mutex */ -static void mutex_locker(void *_mutex) +static int mutex_locker(void *_mutex) { pthread_mutex_t *mutex = _mutex; - pthread_mutex_lock(mutex + 1); + return pthread_mutex_lock(mutex + 1); } -static void mutex_unlocker(void *_mutex) +int mutex_trylocker(void *_mutex) { pthread_mutex_t *mutex = _mutex; - pthread_mutex_unlock(mutex + 1); + return pthread_mutex_trylock(mutex + 1); +} + +static int mutex_unlocker(void *_mutex) +{ + pthread_mutex_t *mutex = _mutex; + return pthread_mutex_unlock(mutex + 1); } static void mutex_destroy(void *_mutex) @@ -69,7 +76,6 @@ static void mutex_destroy(void *_mutex) pthread_mutex_destroy(mutex + 1); free(_mutex); } - #endif @@ -100,13 +106,14 @@ int su_home_threadsafe(su_home_t *home) #endif #if SU_HAVE_PTHREADS - if (!su_home_unlocker) { + if (!_su_home_unlocker) { /* Avoid linking pthread library just for memory management */ - su_home_mutex_locker = mutex_locker; - su_home_mutex_unlocker = mutex_unlocker; - su_home_locker = (void (*)(void *))pthread_mutex_lock; - su_home_unlocker = (void (*)(void *))pthread_mutex_unlock; - su_home_destroy_mutexes = mutex_destroy; + _su_home_mutex_locker = mutex_locker; + _su_home_mutex_trylocker = mutex_trylocker; + _su_home_mutex_unlocker = mutex_unlocker; + _su_home_locker = (int (*)(void *))pthread_mutex_lock; + _su_home_unlocker = (int (*)(void *))pthread_mutex_unlock; + _su_home_destroy_mutexes = mutex_destroy; } mutex = calloc(1, 2 * (sizeof *mutex)); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c index fd30ef9920..372f91db0d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index 6e7a16873a..0d356fa250 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -97,7 +97,7 @@ void su_pthread_port_lock(su_port_t *self, char const *who) PORT_LOCK_DEBUG(("%p at %s locking(%p)...", (void *)pthread_self(), who, self)); - su_home_mutex_lock(self->sup_base->sup_home); + su_home_lock(self->sup_base->sup_home); PORT_LOCK_DEBUG((" ...%p at %s locked(%p)...", (void *)pthread_self(), who, self)); @@ -105,7 +105,7 @@ void su_pthread_port_lock(su_port_t *self, char const *who) void su_pthread_port_unlock(su_port_t *self, char const *who) { - su_home_mutex_unlock(self->sup_base->sup_home); + su_home_unlock(self->sup_base->sup_home); PORT_LOCK_DEBUG((" ...%p at %s unlocked(%p)\n", (void *)pthread_self(), who, self)); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_strlst.c b/libs/sofia-sip/libsofia-sip-ua/su/su_strlst.c index 1bb4757dac..c94858c571 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_strlst.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_strlst.c @@ -79,6 +79,7 @@ #include "sofia-sip/su_config.h" #include "sofia-sip/su_strlst.h" +#include #include #include #include diff --git a/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c index 22126174c6..76a01b74f2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -194,6 +195,42 @@ static int test_alloc(void) END(); } +static int test_lock(void) +{ + su_home_t home[1] = { SU_HOME_INIT(home) }; + + BEGIN(); + + TEST(su_home_mutex_lock(home), -1); + TEST(su_home_mutex_unlock(home), -1); + + TEST(su_home_lock(home), -1); + TEST(su_home_trylock(home), -1); + TEST(su_home_unlock(home), -1); + + TEST(su_home_init(home), 0); + + TEST(su_home_mutex_lock(home), 0); + TEST(su_home_trylock(home), -1); + TEST(su_home_mutex_unlock(home), 0); + TEST(su_home_trylock(home), -1); + + TEST(su_home_threadsafe(home), 0); + + TEST(su_home_mutex_lock(home), 0); + TEST(su_home_trylock(home), EBUSY); + TEST(su_home_mutex_unlock(home), 0); + + TEST(su_home_lock(home), 0); + TEST(su_home_trylock(home), EBUSY); + TEST(su_home_unlock(home), 0); + + TEST(su_home_trylock(home), 0); + TEST(su_home_unlock(home), 0); + + END(); +} + static int test_strdupcat(void) { su_home_t home[1] = { SU_HOME_INIT(home) }; @@ -708,6 +745,7 @@ int main(int argc, char *argv[]) #endif retval |= test_alloc(); + retval |= test_lock(); retval |= test_strdupcat(); retval |= test_sprintf("%s.%s", "foo", "bar"); retval |= test_strlst(); @@ -716,4 +754,3 @@ int main(int argc, char *argv[]) return retval; } - diff --git a/libs/sofia-sip/libsofia-sip-ua/url/url.c b/libs/sofia-sip/libsofia-sip-ua/url/url.c index 008e55e900..a1e3f54693 100644 --- a/libs/sofia-sip/libsofia-sip-ua/url/url.c +++ b/libs/sofia-sip/libsofia-sip-ua/url/url.c @@ -40,6 +40,7 @@ #include +#include #include #include #include