diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 1721848421..02979eb6b0 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Sep 19 12:32:11 EDT 2007 +Thu Oct 11 15:56:47 EDT 2007 diff --git a/libs/sofia-sip/RELEASE b/libs/sofia-sip/RELEASE index 2ccffdff3e..1bee036003 100644 --- a/libs/sofia-sip/RELEASE +++ b/libs/sofia-sip/RELEASE @@ -40,8 +40,8 @@ libsofia-sip-ua/iptsec: libsofia-sip-ua/sip: - Added SIPEXTHDRTAG_TYPEDEF() macro and tag class sipexthdrtag_class[] -- Added SIP headers Alert-Info and Reply-To. Remote-Party-ID, - P-Asserted-Identity, P-Preferred-Identity +- Added SIP headers Alert-Info, Reply-To. Remote-Party-ID, + P-Asserted-Identity, and P-Preferred-Identity - Added sip_update_default_mclass() and sip_extend_mclass() - Added macros SIP_HAVE_XXXX for extra headers, e.g., SIP_HAVE_ALERT_INFO(). @@ -102,12 +102,18 @@ Symbian Open C build and packaging (SIS) files for libsofia-sip-ua, libsofia-sip-ua-glib and for several test apps have been added under sofia-sip/open_c. -New SIP headers are not available by default. Application must enable them -with sip_update_default_mclass() and sip_extend_mclass(). +The SIP headers Alert-Info, Reply-To. Remote-Party-ID, P-Asserted-Identity, +and P-Preferred-Identity are not not available by default. Application must +enable them with sip_update_default_mclass() and sip_extend_mclass(). Bugs fixed in this release -------------------------- +- Fixed sf.net bug #1804248: nua_prack() now works. + Thanks to Fabio Margarido for sending the patch. +- Fixed sf.net bug #1810115: crash after failed outgoing request and + nta_destroy() + Thanks to Mikhail Zabaluev for reporting the problem. - Fixed sf.net bug #1804248: nua_prack() now works. Thanks to Fabio Margarido for sending the patch. - Fixed sf.net bug 1803686: nua_destroy() can now be called from inside diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 1fdc5b0c52..686ac8e4bd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -256,12 +256,6 @@ static int outgoing_recv_reliable(nta_outgoing_t *orq, msg_t *msg, sip_t *sip); /* Internal message passing */ union sm_arg_u { - struct leg_recv_s { - nta_leg_t *leg; - msg_t *msg; - tport_t *tport; - } a_leg_recv[1]; - struct outgoing_recv_s { nta_outgoing_t *orq; msg_t *msg; @@ -922,7 +916,7 @@ int agent_set_params(nta_agent_t *agent, tagi_t *tags) unsigned bad_resp_mask = agent->sa_bad_resp_mask; usize_t maxsize = agent->sa_maxsize; unsigned max_forwards = agent->sa_max_forwards->mf_count; - usize_t udp_mtu = agent->sa_udp_mtu; + unsigned udp_mtu = agent->sa_udp_mtu; unsigned sip_t1 = agent->sa_t1; unsigned sip_t2 = agent->sa_t2; unsigned sip_t4 = agent->sa_t4; @@ -6651,8 +6645,7 @@ nta_outgoing_t *nta_outgoing_tcancel(nta_outgoing_t *orq, #if HAVE_SOFIA_SRESOLV if (!orq->orq_resolved) { - if (orq->orq_resolver) - outgoing_cancel_resolver(orq); + outgoing_destroy_resolver(orq); outgoing_reply(orq, SIP_487_REQUEST_CANCELLED, 1); return NULL; /* XXX - Does anyone care about reply? */ } @@ -7742,6 +7735,9 @@ void outgoing_cut_off(nta_outgoing_t *orq) su_inline void outgoing_reclaim(nta_outgoing_t *orq) { + if (orq->orq_status2b) + *orq->orq_status2b = -1; + if (orq->orq_request) msg_destroy(orq->orq_request), orq->orq_request = NULL; if (orq->orq_response) @@ -8726,6 +8722,8 @@ int outgoing_reply(nta_outgoing_t *orq, int status, char const *phrase, a->sip = sip; a->status = status; + orq->orq_status2b = &a->status; + if (su_msg_send(su_msg) == SU_SUCCESS) { return 0; } @@ -8744,8 +8742,14 @@ void outgoing_delayed_recv(su_root_magic_t *rm, union sm_arg_u *u) { struct outgoing_recv_s *a = u->a_outgoing_recv; - if (outgoing_recv(a->orq, a->status, a->msg, a->sip) < 0 && a->msg) - msg_destroy(a->msg); + + if (a->status > 0) { + a->orq->orq_status2b = 0; + if (outgoing_recv(a->orq, a->status, a->msg, a->sip) >= 0) + return; + } + + msg_destroy(a->msg); } diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h b/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h index 65b0a7cf78..5cce3c73c0 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h @@ -257,32 +257,32 @@ struct nta_agent_s /* Statistics */ struct { - uint32_t as_recv_msg; - uint32_t as_recv_request; - uint32_t as_recv_response; - uint32_t as_bad_message; - uint32_t as_bad_request; - uint32_t as_bad_response; - uint32_t as_drop_request; - uint32_t as_drop_response; - uint32_t as_client_tr; - uint32_t as_server_tr; - uint32_t as_dialog_tr; - uint32_t as_acked_tr; - uint32_t as_canceled_tr; - uint32_t as_trless_request; - uint32_t as_trless_to_tr; - uint32_t as_trless_response; - uint32_t as_trless_200; - uint32_t as_merged_request; - uint32_t as_sent_msg; - uint32_t as_sent_request; - uint32_t as_sent_response; - uint32_t as_retry_request; - uint32_t as_retry_response; - uint32_t as_recv_retry; - uint32_t as_tout_request; - uint32_t as_tout_response; + usize_t as_recv_msg; + usize_t as_recv_request; + usize_t as_recv_response; + usize_t as_bad_message; + usize_t as_bad_request; + usize_t as_bad_response; + usize_t as_drop_request; + usize_t as_drop_response; + usize_t as_client_tr; + usize_t as_server_tr; + usize_t as_dialog_tr; + usize_t as_acked_tr; + usize_t as_canceled_tr; + usize_t as_trless_request; + usize_t as_trless_to_tr; + usize_t as_trless_response; + usize_t as_trless_200; + usize_t as_merged_request; + usize_t as_sent_msg; + usize_t as_sent_request; + usize_t as_sent_response; + usize_t as_retry_request; + usize_t as_retry_response; + usize_t as_recv_retry; + usize_t as_tout_request; + usize_t as_tout_response; } sa_stats[1]; /** Hash of dialogs. */ @@ -544,6 +544,8 @@ struct nta_outgoing_s char const *orq_branch; /**< Transaction branch */ char const *orq_via_branch; /**< @Via branch */ + int *orq_status2b; /**< Delayed response */ + nta_outgoing_t *orq_cancel; /**< CANCEL transaction */ uint32_t orq_rseq; /**< Latest incoming rseq */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c index 2426c30374..7da5f74600 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c @@ -415,7 +415,7 @@ tag_typedef_t ntatag_maxsize = USIZETAG_TYPEDEF(maxsize); * nta_agent_create(), nta_agent_set_params() * * @par Parameter type - * - #usize_t + * - unsigned * * @par Values * - Maximum size of an outgoing UDP request diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h b/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h index 832702eda0..4b2ae32854 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h +++ b/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h @@ -150,10 +150,10 @@ NTA_DLL extern tag_typedef_t ntatag_maxsize_ref; #define NTATAG_MAXSIZE_REF(x) ntatag_maxsize_ref, tag_usize_vr(&(x)) NTA_DLL extern tag_typedef_t ntatag_udp_mtu; -#define NTATAG_UDP_MTU(x) ntatag_udp_mtu, tag_usize_v((x)) +#define NTATAG_UDP_MTU(x) ntatag_udp_mtu, tag_uint_v((x)) NTA_DLL extern tag_typedef_t ntatag_udp_mtu_ref; -#define NTATAG_UDP_MTU_REF(x) ntatag_udp_mtu_ref, tag_usize_vr(&(x)) +#define NTATAG_UDP_MTU_REF(x) ntatag_udp_mtu_ref, tag_uint_vr(&(x)) NTA_DLL extern tag_typedef_t ntatag_max_forwards; #define NTATAG_MAX_FORWARDS(x) ntatag_max_forwards, tag_uint_v((x)) diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c b/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c index e95119a539..fa9f2da636 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c @@ -445,6 +445,54 @@ int api_test_deinit(agent_t *ag) END(); } +static int api_test_destroy(agent_t *ag) +{ + nta_agent_t *nta; + su_root_t *root; + su_home_t home[1]; + nta_outgoing_t *orq; + nta_leg_t *leg; + int i; + + BEGIN(); + + memset(home, 0, sizeof home); + home->suh_size = sizeof home; + su_home_init(home); + + TEST_1(root = su_root_create(NULL)); + + for (i = 0; i < 2; i++) { + TEST_1(nta = nta_agent_create(root, + (url_string_t *)"sip:*:*", + NULL, + NULL, + TAG_END())); + TEST_1(leg = nta_leg_tcreate(nta, NULL, NULL, + NTATAG_NO_DIALOG(1), + TAG_END())); + /* This creates a delayed response message */ + orq = nta_outgoing_tcreate(leg, outgoing_callback, ag, NULL, + SIP_METHOD_MESSAGE, + URL_STRING_MAKE("sip:foo.bar;transport=none"), + SIPTAG_FROM_STR(""), + SIPTAG_TO_STR(""), + TAG_END()); + TEST_1(orq); + + TEST_VOID(nta_outgoing_destroy(orq)); + TEST_VOID(nta_leg_destroy(leg)); + TEST_VOID(nta_agent_destroy(nta)); + } + + TEST_VOID(su_root_destroy(root)); + TEST_VOID(su_home_deinit(home)); + + END(); + +} + + /* Get and check parameters */ int api_test_params(agent_t *ag) { @@ -460,7 +508,7 @@ int api_test_params(agent_t *ag) unsigned blacklist = -1; unsigned debug_drop_prob = -1; unsigned max_forwards = -1; - unsigned maxsize = -1; + usize_t maxsize = -1; unsigned preload = -1; unsigned progress = -1; unsigned sip_t1 = -1; @@ -1114,22 +1162,9 @@ static int api_test_errors(agent_t *ag) TEST_P(nta_outgoing_tcancel(NONE, NULL, NULL, TAG_END()), NULL); TEST_VOID(nta_outgoing_destroy(NONE)); -#if 0 -nta_reliable_t *nta_reliable_treply(nta_incoming_t *ireq, - nta_prack_f *callback, - nta_reliable_magic_t *rmagic, - int status, char const *phrase, - tag_type_t tag, - tag_value_t value, ...); - -nta_reliable_t *nta_reliable_mreply(nta_incoming_t *irq, - nta_prack_f *callback, - nta_reliable_magic_t *rmagic, - msg_t *msg); - -void nta_reliable_destroy(nta_reliable_t *); - -#endif + TEST_P(nta_reliable_treply(NULL, NULL, NULL, 0, NULL, TAG_END()), NULL); + TEST_P(nta_reliable_mreply(NULL, NULL, NULL, NULL), NULL); + TEST_VOID(nta_reliable_destroy(NULL)); TEST_VOID(nta_agent_destroy(nta)); TEST_VOID(su_root_destroy(root)); @@ -1382,6 +1417,7 @@ int main(int argc, char *argv[]) retval |= api_test_init(ag); fflush(stdout); SINGLE_FAILURE_CHECK(); if (retval == 0) { retval |= api_test_errors(ag); SINGLE_FAILURE_CHECK(); + retval |= api_test_destroy(ag); SINGLE_FAILURE_CHECK(); retval |= api_test_params(ag); SINGLE_FAILURE_CHECK(); retval |= api_test_stats(ag); SINGLE_FAILURE_CHECK(); retval |= api_test_dialog_matching(ag); SINGLE_FAILURE_CHECK(); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c index da9428a035..beec60976a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c @@ -196,6 +196,7 @@ int nua_stack_set_from(nua_t *nua, int initial, tagi_t const *tags) sip_from_t const *from = NONE; char const *str = NONE; sip_from_t *f = NULL, f0[1]; + int set; char const *uicc_name = "default"; @@ -220,11 +221,13 @@ int nua_stack_set_from(nua_t *nua, int initial, tagi_t const *tags) f0->a_display = from->a_display; *f0->a_url = *from->a_url; f = sip_from_dup(nua->nua_home, f0); + set = 1; } else if (str && str != NONE) { f = sip_from_make(nua->nua_home, str); if (f) *f0 = *f, f = f0, f->a_params = NULL; + set = 1; } else { sip_contact_t const *m; @@ -236,11 +239,13 @@ int nua_stack_set_from(nua_t *nua, int initial, tagi_t const *tags) *f0->a_url = *m->m_url; f = sip_from_dup(nua->nua_home, f0); } + set = 0; } if (!f) return -1; - + + nua->nua_from_is_set = set; *nua->nua_from = *f; return 0; } @@ -1148,7 +1153,6 @@ int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags) url_string_t const *url = NULL; sip_to_t const *p_to = NULL; char const *to_str = NULL; - sip_from_t from[1]; sip_from_t const *p_from = NULL; char const *from_str = NULL; nua_handle_t *identity = NULL; @@ -1210,10 +1214,8 @@ int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags) ; else if (from_str) p_from = sip_from_make(tmphome, from_str); - else if (!p_from && nh->nh_nua->nua_from) - *from = *nh->nh_nua->nua_from, from->a_params = NULL, p_from = from; else - p_from = SIP_NONE; /* XXX - why? */ + p_from = SIP_NONE; if (p_to) ; @@ -1553,8 +1555,8 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, if (nh->nh_ds->ds_local) has_from = 1, *from = *nh->nh_ds->ds_local, from->a_params = NULL; - else - has_from = 0; + else /* if (nua->nua_from_is_set) */ + has_from = 1, *from = *nua->nua_from; media_params = soa_get_paramlist(nh->nh_soa, TAG_END()); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c index e93536e944..ad46787cea 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c @@ -1993,7 +1993,13 @@ int nua_client_init_request(nua_client_request_t *cr) url = (url_string_t const *)t->t_value; } - t = nh->nh_tags, sip_add_tagis(msg, sip, &t); + t = nh->nh_tags; + + /* Use the From header from the dialog */ + if (ds->ds_leg && t->t_tag == siptag_from) + t++; + + sip_add_tagis(msg, sip, &t); } if (!ds->ds_route) { diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h index 6f1f24b3d7..22e49a80f5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h @@ -222,6 +222,8 @@ struct nua_s { /* Engine state flags */ unsigned nua_shutdown_started:1; /**< Shutdown initiated */ unsigned nua_shutdown_final:1; /**< Shutdown is complete */ + + unsigned nua_from_is_set; unsigned :0; /**< Used by stop-and-wait args calls */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_100rel.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_100rel.c index 05c377bc05..651630a217 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_100rel.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_100rel.c @@ -377,6 +377,7 @@ int test_prack_auth(struct context *ctx) INVITE(c, c_call, c_call->nh, TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)), + SIPTAG_FROM(c->to), SOATAG_USER_SDP_STR(c_call->sdp), TAG_END()); @@ -420,6 +421,8 @@ int test_prack_auth(struct context *ctx) } TEST_E(e->data->e_event, nua_r_prack); TEST(e->data->e_status, 200); + TEST_1(sip = sip_object(e->data->e_msg)); + TEST_1(sip->sip_from->a_url->url_user); TEST_1(e = ei); TEST_E(e->data->e_event, nua_r_invite); TEST(e->data->e_status, 200); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c index e67253a8d8..92311cb609 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c @@ -74,6 +74,7 @@ int test_nua_init(struct context *ctx, url_t const *p_uri, *a_uri, *b_uri; /* Proxy URI */ char const *initial_route = NULL; /* Initial route towards internal proxy */ char const *a_bind, *a_bind2; + url_t *e_proxy = NULL; int err = -1; url_t b_proxy[1]; @@ -162,8 +163,13 @@ int test_nua_init(struct context *ctx, p_uri = a_uri = b_uri = test_proxy_uri(ctx->p); + if (o_proxy) { + TEST_1(e_proxy = url_hdup(ctx->home, (void *)o_proxy)); + ctx->external_proxy = e_proxy; + } + if (start_nat && p_uri == NULL) - p_uri = url_hdup(ctx->home, (void *)o_proxy); + p_uri = e_proxy; if (ctx->p) initial_route = test_proxy_route_uri(ctx->p, &ctx->lr); @@ -262,7 +268,7 @@ int test_nua_init(struct context *ctx, ctx->a.instance = nua_generate_instance_identifier(ctx->home); ctx->a.nua = nua_create(ctx->root, a_callback, ctx, - NUTAG_PROXY(a_uri ? a_uri : o_proxy), + NUTAG_PROXY(a_uri ? a_uri : e_proxy), NUTAG_INITIAL_ROUTE_STR(initial_route), SIPTAG_FROM_STR("sip:alice@example.com"), NUTAG_URL(a_bind), @@ -310,7 +316,7 @@ int test_nua_init(struct context *ctx, } ctx->b.nua = nua_create(ctx->root, b_callback, ctx, - NUTAG_PROXY(b_uri ? b_uri : o_proxy), + NUTAG_PROXY(b_uri ? b_uri : e_proxy), SIPTAG_FROM_STR("sip:bob@example.org"), NUTAG_URL("sip:0.0.0.0:*"), SOATAG_USER_SDP_STR("m=audio 5006 RTP/AVP 8 0"), @@ -350,9 +356,10 @@ int test_nua_init(struct context *ctx, /* ctx->c.instance = nua_generate_instance_identifier(ctx->home); */ + ctx->c.to = sip_from_make(ctx->home, "Charlie "); + ctx->c.nua = nua_create(ctx->root, c_callback, ctx, - NUTAG_PROXY(p_uri ? p_uri : o_proxy), - SIPTAG_FROM_STR("sip:charlie@example.net"), + NUTAG_PROXY(p_uri ? p_uri : e_proxy), NUTAG_URL("sip:0.0.0.0:*"), SOATAG_USER_SDP_STR("m=audio 5400 RTP/AVP 8 0"), NUTAG_INSTANCE(ctx->c.instance), @@ -365,15 +372,13 @@ int test_nua_init(struct context *ctx, TEST_1(e = ctx->c.specials->head); err = tl_gets(e->data->e_tags, NTATAG_CONTACT_REF(m), - SIPTAG_FROM_REF(sipaddress), SIPTAG_ALLOW_REF(allow), NUTAG_APPL_METHOD_REF(appl_method), SIPTAG_SUPPORTED_REF(supported), TAG_END()); - TEST(err, 5); TEST_1(m); + TEST(err, 4); TEST_1(m); TEST_1(ctx->c.contact = sip_contact_dup(ctx->home, m)); - TEST_1(ctx->c.to = sip_to_dup(ctx->home, sipaddress)); TEST_1(ctx->c.allow = sip_allow_dup(ctx->home, allow)); TEST_1(ctx->c.appl_method = su_strdup(ctx->home, appl_method)); TEST_1(ctx->c.supported = sip_supported_dup(ctx->home, supported)); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c index 4735caee63..4cabdefab7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c @@ -340,6 +340,8 @@ int main(int argc, char *argv[]) retval |= test_nua_destroy(ctx); SINGLE_FAILURE_CHECK(); + retval |= test_stack_errors(ctx); SINGLE_FAILURE_CHECK(); + retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat, TESTNATTAG_SYMMETRIC(o_inat_symmetric), TESTNATTAG_LOGGING(o_inat_logging), @@ -354,8 +356,6 @@ int main(int argc, char *argv[]) if (o_events_c) ctx->c.printer = print_event; - retval |= test_stack_errors(ctx); SINGLE_FAILURE_CHECK(); - retval |= test_register(ctx); if (retval == 0) diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h index feac00b8bf..0e75b799c8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h @@ -126,7 +126,8 @@ struct context int threading, proxy_tests, expensive, quit_on_single_failure, osx_runloop; int print_tags; - char const *external_proxy; + + url_t *external_proxy; int proxy_logging; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c index 5d5a60de78..d583dad96f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c @@ -198,7 +198,7 @@ int test_nua_destroy(struct context *ctx) /* ======================================================================== */ -int test_stack_errors(struct context *ctx) +int test_byecancel_without_invite(struct context *ctx) { BEGIN(); @@ -208,9 +208,6 @@ int test_stack_errors(struct context *ctx) int internal_error = 900; - if (print_headings) - printf("TEST NUA-1.2: Stack error handling\n"); - if (print_headings) printf("TEST NUA-1.2.1: CANCEL without INVITE\n"); @@ -252,8 +249,17 @@ int test_stack_errors(struct context *ctx) if (print_headings) printf("TEST NUA-1.2.2: PASSED\n"); - if (!ctx->proxy_tests) - goto nua_1_2_5; + END(); +} + + +int test_unregister_without_register(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a, *b = &ctx->b; + struct call *a_call = a->call; + struct event *e; /* -Un-register without REGISTER--------------------------------------- */ @@ -301,10 +307,22 @@ int test_stack_errors(struct context *ctx) if (print_headings) printf("TEST NUA-1.2.4: PASSED\n"); + + END(); +} - /* -terminate without notifier--------------------------------------- */ +/* -terminate without notifier--------------------------------------- */ + +int test_terminate_without_notifier(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a, *b = &ctx->b; + struct call *a_call = a->call; + struct event *e; + + int internal_error = 900; - nua_1_2_5: if (print_headings) printf("TEST NUA-1.2.5: terminate without notifier\n"); @@ -335,8 +353,108 @@ int test_stack_errors(struct context *ctx) if (print_headings) printf("TEST NUA-1.2.5: PASSED\n"); + END(); +} + +int destroy_on_503(CONDITION_PARAMS) +{ + save_event_in_list(ctx, event, ep, call); + + if (status == 503) { + assert(nh == call->nh); + nua_handle_destroy(call->nh), call->nh = NULL; + } + + return + nua_r_set_params <= event && event < nua_i_network_changed + && status >= 200; +} + + +int test_register_503(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a; + struct call *a_reg = a->reg; + struct event *e; + +/* REGISTER test + + A + |------REGISTER--\ + |<-------503-----/ + | + +*/ + + if (print_headings) + printf("TEST NUA-1.2.6: REGISTER with bad domain\n"); + + TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END())); + + REGISTER(a, a_reg, a_reg->nh, + NUTAG_REGISTRAR(URL_STRING_MAKE("sip:bad.domain")), + SIPTAG_TO_STR("sip:lissu@bad.domain"), + TAG_END()); + run_a_until(ctx, -1, destroy_on_503); + + TEST_1(e = a->events->head); + TEST_E(e->data->e_event, nua_r_register); + TEST(e->data->e_status, 503); + TEST_1(!e->next); + free_events_in_list(ctx, a->events); + + TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END())); + + REGISTER(a, a_reg, a_reg->nh, + NUTAG_REGISTRAR(URL_STRING_MAKE("sip:bad.domain")), + SIPTAG_TO_STR("sip:lissu@bad.domain"), + TAG_END()); + nua_handle_destroy(a_reg->nh), a_reg->nh = NULL; + + if (print_headings) + printf("TEST NUA-1.2.6: PASSED\n"); + + END(); +} + +int test_stack_errors(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a; + + if (print_headings) + printf("TEST NUA-1.2: Stack error handling\n"); + + TEST_1(ctx->root == NULL); + TEST_1(ctx->root = su_root_create(NULL)); + + a->nua = nua_create(ctx->root, a_callback, ctx, + NUTAG_URL("sip:0.0.0.0:*"), + TAG_IF(ctx->a.logging, TPTAG_LOG(1)), + TAG_END()); + TEST_1(a->nua); + + TEST(test_byecancel_without_invite(ctx), 0); + if (ctx->proxy_tests) + TEST(test_unregister_without_register(ctx), 0); + TEST(test_terminate_without_notifier(ctx), 0); + TEST(test_register_503(ctx), 0); + TEST(test_register_503(ctx), 0); + + nua_shutdown(a->nua); + + run_a_until(ctx, -1, until_final_response); + + TEST_VOID(nua_destroy(a->nua)); + + su_root_destroy(ctx->root), ctx->root = NULL; + if (print_headings) printf("TEST NUA-1.2: PASSED\n"); END(); } + 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 aafdb961db..9276b04582 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_register.c @@ -46,16 +46,30 @@ /* ======================================================================== */ /* Test REGISTER */ +int test_clear_registrations(struct context *ctx); +int test_outbound_cases(struct context *ctx); +int test_register_a(struct context *ctx); +int test_register_b(struct context *ctx); +int test_register_c(struct context *ctx); +int test_register_refresh(struct context *ctx); + int test_register_to_proxy(struct context *ctx) +{ + return + test_clear_registrations(ctx) || + test_outbound_cases(ctx) || + test_register_a(ctx) || + test_register_b(ctx) || + test_register_c(ctx) || + test_register_refresh(ctx); +} + +int test_clear_registrations(struct context *ctx) { BEGIN(); - struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c, *x; + struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c; struct call *a_reg = a->reg, *b_reg = b->reg, *c_reg = c->reg; - struct event *e; - sip_t const *sip; - sip_cseq_t cseq[1]; - int seen_401; if (print_headings) printf("TEST NUA-2.3.0.1: un-REGISTER a\n"); @@ -93,7 +107,8 @@ int test_register_to_proxy(struct context *ctx) printf("TEST NUA-2.3.0.3: un-REGISTER c\n"); TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END())); - UNREGISTER(c, c_reg, c_reg->nh, SIPTAG_TO(c->to), + UNREGISTER(c, c_reg, c_reg->nh, + SIPTAG_FROM(c->to), SIPTAG_TO(c->to), SIPTAG_CONTACT_STR("*"), TAG_END()); run_c_until(ctx, -1, until_final_response); @@ -105,9 +120,151 @@ int test_register_to_proxy(struct context *ctx) if (print_headings) printf("TEST NUA-2.3.0.3: PASSED\n"); + END(); +} + +int test_outbound_cases(struct context *ctx) +{ + BEGIN(); + +#if 0 + + struct endpoint *a = &ctx->a, *x; + struct call *a_reg = a->reg; + struct event *e; + sip_t const *sip; + sip_contact_t m[1]; + /* REGISTER test - A B + A R + |------REGISTER----->| + |<-------401---------| + |------REGISTER----->| + |<-------200---------| + | | + +*/ + + if (print_headings) + printf("TEST NUA-2.3.1: REGISTER a\n"); + + test_proxy_domain_set_expiration(ctx->a.domain, 5, 5, 10); + + TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END())); + + sip_contact_init(m); + m->m_display = "Lissu"; + *m->m_url = *a->contact->m_url; + m->m_url->url_user = "a"; + m->m_url->url_params = "transport=udp"; + + REGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to), + NUTAG_OUTBOUND("use-rport no-options-keepalive"), + SIPTAG_CONTACT(m), + TAG_END()); + run_a_until(ctx, -1, save_until_final_response); + + TEST_1(e = a->events->head); + TEST_E(e->data->e_event, nua_r_register); + TEST(e->data->e_status, 401); + TEST_1(sip = sip_object(e->data->e_msg)); + TEST(sip->sip_status->st_status, 401); + TEST_1(!sip->sip_contact); + TEST_1(!e->next); + free_events_in_list(ctx, a->events); + + AUTHENTICATE(a, a_reg, a_reg->nh, + NUTAG_AUTH("Digest:\"test-proxy\":alice:secret"), TAG_END()); + run_a_until(ctx, -1, save_until_final_response); + + TEST_1(e = a->events->head); + TEST_E(e->data->e_event, nua_r_register); + 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_display, "Lissu"); + TEST_S(sip->sip_contact->m_url->url_user, "a"); + TEST_1(strstr(sip->sip_contact->m_url->url_params, "transport=udp")); + + if (ctx->nat) { + TEST_1(e = a->specials->head); + } + + test_proxy_domain_set_expiration(ctx->a.domain, 600, 3600, 36000); + + if (print_headings) + printf("TEST NUA-2.3.1: PASSED\n"); + + if (print_headings) + printf("TEST NUA-2.3.4: refresh REGISTER\n"); + + if (!ctx->p) { + free_events_in_list(ctx, a->events); + return 0; + } + + /* Wait for A to refresh its registrations */ + + /* + * Avoid race condition: if X has already refreshed registration + * with expiration time of 3600 seconds, do not wait for new refresh + */ + a->next_condition = save_until_final_response; + + for (x = a; x; x = NULL) { + for (e = x->events->head; e; e = e->next) { + if (e->data->e_event == nua_r_register && + e->data->e_status == 200 && + (sip = sip_object(e->data->e_msg)) && + sip->sip_contact && + sip->sip_contact->m_expires && + strcmp(sip->sip_contact->m_expires, "3600") == 0) { + x->next_condition = NULL; + break; + } + } + } + + run_a_until(ctx, -1, a->next_condition); + + for (e = a->events->head; e; e = e->next) { + TEST_E(e->data->e_event, nua_r_register); + TEST(e->data->e_status, 200); + TEST_1(sip = sip_object(e->data->e_msg)); + TEST_1(sip->sip_contact); + if (!e->next) + break; + } + TEST_1(e); + TEST_1(sip = sip_object(e->data->e_msg)); + TEST_S(sip->sip_contact->m_expires, "3600"); + TEST_1(!e->next); + free_events_in_list(ctx, a->events); + + if (print_headings) + printf("TEST NUA-2.3.4: PASSED\n"); + + TEST_1(0); + +#endif + + END(); +} + +int test_register_a(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a; + struct call *a_reg = a->reg; + struct event *e; + sip_t const *sip; + sip_cseq_t cseq[1]; + +/* REGISTER test + + A R |------REGISTER----->| |<-------401---------| |------REGISTER----->| @@ -187,6 +344,18 @@ int test_register_to_proxy(struct context *ctx) if (print_headings) printf("TEST NUA-2.3.1: PASSED\n"); + END(); +} + +int test_register_b(struct context *ctx) +{ + BEGIN(); + + struct endpoint *b = &ctx->b; + struct call *b_reg = b->reg; + struct event *e; + sip_t const *sip; + if (print_headings) printf("TEST NUA-2.3.2: REGISTER b\n"); @@ -236,10 +405,22 @@ int test_register_to_proxy(struct context *ctx) TEST_S(sip->sip_contact->m_url->url_user, "b"); free_events_in_list(ctx, b->events); + test_proxy_domain_set_expiration(ctx->b.domain, 600, 3600, 36000); + if (print_headings) printf("TEST NUA-2.3.2: PASSED\n"); - test_proxy_domain_set_expiration(ctx->b.domain, 600, 3600, 36000); + END(); +} + +int test_register_c(struct context *ctx) +{ + BEGIN(); + + struct endpoint *c = &ctx->c; + struct call *c_reg = c->reg; + struct event *e; + sip_t const *sip; if (print_headings) printf("TEST NUA-2.3.3: REGISTER c\n"); @@ -249,7 +430,8 @@ int test_register_to_proxy(struct context *ctx) TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END())); - REGISTER(c, c_reg, c_reg->nh, SIPTAG_TO(c->to), + REGISTER(c, c_reg, c_reg->nh, SIPTAG_TO(c->to), + SIPTAG_FROM(c->to), NUTAG_OUTBOUND(NULL), NUTAG_M_DISPLAY("C"), NUTAG_M_USERNAME("c"), @@ -300,15 +482,27 @@ int test_register_to_proxy(struct context *ctx) if (print_headings) printf("TEST NUA-2.3.3: PASSED\n"); + END(); +} + +int test_register_refresh(struct context *ctx) +{ + BEGIN(); + + struct endpoint *a = &ctx->a, *b = &ctx->b, *x; + struct event *e; + sip_t const *sip; + int seen_401; + + if (print_headings) + printf("TEST NUA-2.3.4: refresh REGISTER\n"); + if (!ctx->p) { free_events_in_list(ctx, a->events); free_events_in_list(ctx, b->events); return 0; } - if (print_headings) - printf("TEST NUA-2.3.4: refresh REGISTER\n"); - /* Wait for A and B to refresh their registrations */ /* @@ -343,6 +537,7 @@ int test_register_to_proxy(struct context *ctx) break; } TEST_1(e); + TEST_1(sip = sip_object(e->data->e_msg)); TEST_S(sip->sip_contact->m_expires, "3600"); TEST_1(!e->next); free_events_in_list(ctx, a->events); @@ -569,6 +764,7 @@ int test_connectivity(struct context *ctx) TEST_1(c_call->nh = nua_handle(c->nua, c_call, SIPTAG_TO(a->to), TAG_END())); OPTIONS(c, c_call, c_call->nh, + SIPTAG_FROM(c->to), TAG_IF(!ctx->proxy_tests, NUTAG_URL(a->contact->m_url)), TAG_END()); @@ -767,7 +963,7 @@ int test_unregister(struct context *ctx) /* Unregister using another handle */ free_events_in_list(ctx, c->events); TEST_1(c->call->nh = nua_handle(c->nua, c->call, TAG_END())); - UNREGISTER(c, c->call, c->call->nh, SIPTAG_TO(c->to), + UNREGISTER(c, c->call, c->call->nh, SIPTAG_TO(c->to), SIPTAG_FROM(c->to), NUTAG_M_DISPLAY("C"), NUTAG_M_USERNAME("c"), NUTAG_M_PARAMS("c=1"), @@ -807,6 +1003,7 @@ int test_unregister(struct context *ctx) } TEST(e->data->e_status, 200); TEST_1(sip = sip_object(e->data->e_msg)); + TEST_1(sip->sip_from->a_url->url_user); TEST_1(!sip->sip_contact); TEST_1(!e->next); free_events_in_list(ctx, c->events); diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c index 20e9f1065e..61762e88d1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c @@ -286,7 +286,7 @@ int test_cache(void) if (t1.tv_nsec < t0.tv_nsec) t2.tv_sec--, t2.tv_nsec += 1000000000; printf("sres_cache: stored %u entries: %lu.%09lu sec\n", - N, (long unsigned)t2.tv_sec, t2.tv_nsec); + (unsigned)N, (long unsigned)t2.tv_sec, t2.tv_nsec); } for (i = 0, N; i < N; i++) @@ -303,7 +303,7 @@ int test_cache(void) if (t1.tv_nsec < t0.tv_nsec) t2.tv_sec--, t2.tv_nsec += 1000000000; printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n", - N, (long unsigned)t2.tv_sec, t2.tv_nsec); + (unsigned)N, (long unsigned)t2.tv_sec, t2.tv_nsec); } for (i = 0, N; i < N; i++) @@ -325,7 +325,7 @@ int test_cache(void) if (t1.tv_nsec < t0.tv_nsec) t2.tv_sec--, t2.tv_nsec += 1000000000; printf("sres_cache: stored %u entries: %lu.%09lu sec\n", - N, (long unsigned)t2.tv_sec, t2.tv_nsec); + (unsigned)N, (long unsigned)t2.tv_sec, t2.tv_nsec); } for (i = 0, N; i < N; i++) @@ -343,7 +343,7 @@ int test_cache(void) if (t1.tv_nsec < t0.tv_nsec) t2.tv_sec--, t2.tv_nsec += 1000000000; printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n", - N, (long unsigned)t2.tv_sec, t2.tv_nsec); + (unsigned)N, (long unsigned)t2.tv_sec, t2.tv_nsec); } for (i = 0, N; i < N; i++) { diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_poll_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_poll_port.c index e5e38f2cb0..9b95b28b03 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_poll_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_poll_port.c @@ -669,7 +669,7 @@ int su_poll_clone_start(su_root_t *parent, su_root_init_f init, su_root_deinit_f deinit) { - return su_pthreaded_port_start(su_default_port_create, + return su_pthreaded_port_start(su_poll_port_create, parent, return_clone, magic, init, deinit); } 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 fa61196831..6e7a16873a 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 @@ -296,8 +296,6 @@ static void *su_pthread_port_clone_main(void *varg) task->sut_port = arg->create(); if (task->sut_port) { - task->sut_port->sup_thread = 1; - task->sut_root = su_salloc(su_port_home(task->sut_port), sizeof *task->sut_root); if (task->sut_root) { @@ -346,8 +344,6 @@ static void *su_pthread_port_clone_main(void *varg) } } - task->sut_port->sup_thread = 0; - task->sut_port->sup_base->sup_vtable-> su_port_decref(task->sut_port, zap, "su_pthread_port_clone_main"); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c index 73ab7324c7..872592ec2b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c @@ -664,22 +664,30 @@ int tls_pending(tls_t const *tls) return tls && tls->con && SSL_pending(tls->con); } +/** Check if data is available in TCP connection. + * + * + * + * @retval -1 upon an error + * @retval 0 end-of-stream + * @retval 1 nothing to read + * @retval 2 there is data to read + */ int tls_want_read(tls_t *tls, int events) { if (tls && (events & tls->read_events)) { int ret = tls_read(tls); - if (ret > 0) - return 1; + return 2; else if (ret == 0) return 0; else if (errno == EAGAIN) - return 2; + return 3; /* ??? */ else return -1; } - return 0; + return 1; } ssize_t tls_write(tls_t *tls, void *buf, size_t size) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c index d25bfe34f0..2f9860dac6 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c @@ -304,12 +304,23 @@ int tport_tls_events(tport_t *self, int events) } if ((self->tp_events & SU_WAIT_IN) && !self->tp_closed) { - ret = tls_want_read(tlstp->tlstp_context, events); - if (ret > 0) - tport_recv_event(self); - else if (ret == 0) /* End-of-stream */ + for (;;) { + ret = tls_want_read(tlstp->tlstp_context, events); + if (ret > 1) { + tport_recv_event(self); + if ((events & SU_WAIT_HUP) && !self->tp_closed) + continue; + } + break; + } + + if (ret == 0) { /* End-of-stream */ + if (self->tp_msg) + tport_recv_event(self); tport_shutdown0(self, 2); - else if (ret < 0) + } + + if (ret < 0) tport_error_report(self, errno, NULL); } @@ -363,8 +374,11 @@ int tport_tls_recv(tport_t *self) SU_DEBUG_7(("%s(%p): tls_read() returned "MOD_ZD"\n", __func__, (void *)self, N)); - if (N == 0) /* End-of-stream */ + if (N == 0) { + if (self->tp_msg) + msg_recv_commit(self->tp_msg, 0, 1); /* End-of-stream */ return 0; + } else if (N == -1) { if (su_is_blocking(su_errno())) { tport_tls_set_events(self); diff --git a/libs/sofia-sip/rules/sofia.am b/libs/sofia-sip/rules/sofia.am index a69ce94dbf..771052c799 100644 --- a/libs/sofia-sip/rules/sofia.am +++ b/libs/sofia-sip/rules/sofia.am @@ -33,7 +33,7 @@ _tag.c_tag_ref.c: ../nua/libnua.la ../sdp/libsdp.la ../sip/libsip.la ../soa/libsoa.la \ ../sresolv/libsresolv.la ../stun/libstun.la ../su/libsu.la \ ../tport/libtport.la ../url/liburl.la: - $(MAKE) -C $(@D) $(@F) + cd $(@D) && $(MAKE) $(@F) INTERNAL_INCLUDES = \ -I$(srcdir)/../features -I../features \