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 e12e0bc012..f730596285 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c @@ -160,7 +160,7 @@ int ca_challenge(auth_client_t *ca, if (!ca || !ch) return -1; - if (strcmp(ca->ca_scheme, scheme)) + if (strcasecmp(ca->ca_scheme, scheme)) return 0; if (strcmp(ca->ca_realm, realm)) return 0; @@ -433,7 +433,7 @@ int auc_copy_credentials(auth_client_t **dst, continue; if (AUTH_CLIENT_IS_EXTENDED(ca) && ca->ca_clear) continue; - if (!ca->ca_scheme[0] || strcmp(ca->ca_scheme, d->ca_scheme)) + if (!ca->ca_scheme[0] || strcasecmp(ca->ca_scheme, d->ca_scheme)) continue; if (!ca->ca_realm[0] || strcmp(ca->ca_realm, d->ca_realm)) continue; @@ -1012,6 +1012,8 @@ auth_client_t *ca_create(su_home_t *home, break; } + /* XXX - should report error if the auth scheme is not known? */ + aucsize = auc ? (size_t)auc->auc_size : (sizeof *ca); size = aucsize + realmlen; if (!auc) diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c index aceebc8c73..b86779e4cd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c @@ -484,7 +484,7 @@ int test_digest_client() "From:surf3.ims3.so.noklab.net ;tag=I8hFdg0H3OK\r\n" "To:\r\n" "Via:SIP/2.0/UDP 10.21.36.70:23800;branch=z9hG4bKJjKGu9vIHqf;received=10.21.36.70;rport\r\n" - "WWW-Authenticate:Digest algorithm=MD5,nonce=\"h7wIpP+atU+/+Zau5UwLMA==\",realm=\"ims3.so.noklab.net\"\r\n" + "WWW-Authenticate:DIGEST algorithm=MD5,nonce=\"h7wIpP+atU+/+Zau5UwLMA==\",realm=\"ims3.so.noklab.net\"\r\n" "Content-Length:0\r\n" "Security-Server:digest\r\n" "r\n"; @@ -526,11 +526,13 @@ int test_digest_client() TEST_1(m1 = read_message(MSG_DO_EXTRACT_COPY, challenge)); TEST_1(sip = sip_object(m1)); + TEST_1(aucs == NULL); TEST(auc_challenge(&aucs, home, sip->sip_www_authenticate, sip_authorization_class), 1); + TEST_1(aucs != NULL); msg_destroy(m1); - - TEST(auc_all_credentials(&aucs, "Digest", "\"ims3.so.noklab.net\"", + + TEST(auc_all_credentials(&aucs, "DIGEST", "\"ims3.so.noklab.net\"", "surf3.private@ims3.so.noklab.net", "1234"), 1); TEST_1(m2 = read_message(MSG_DO_EXTRACT_COPY, request)); diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_generic.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_generic.c index e73d19f2c8..bd4cb5c7b1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_generic.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_generic.c @@ -112,10 +112,13 @@ issize_t msg_numeric_d(su_home_t *home, char *s, isize_t slen) { + msg_numeric_t *x = (msg_numeric_t *)h; uint32_t value = 0; issize_t retval = msg_uint32_d(&s, &value); - h->sh_numeric->x_value = value; + assert(x->x_common->h_class->hc_size >= sizeof *x); + + x->x_value = value; if (*s) return -1; @@ -125,12 +128,14 @@ issize_t msg_numeric_d(su_home_t *home, issize_t msg_numeric_e(char b[], isize_t bsiz, msg_header_t const *h, int flags) { - uint32_t value = h->sh_numeric->x_value; + msg_numeric_t *x = (msg_numeric_t *)h; - if (h->sh_numeric->x_value > 0xffffffff) + assert(x->x_common->h_class->hc_size >= sizeof *x); + + if (x->x_value > 0xffffffffU) return -1; - return snprintf(b, bsiz, "%lu", (unsigned long)value); + return snprintf(b, bsiz, "%lu", x->x_value); } /* ====================================================================== */ diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_types.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_types.h index e0eb60ecf9..e8f061ec4d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_types.h +++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_types.h @@ -134,7 +134,8 @@ struct msg_pub_s { /** Numeric header. * - * A numeric header has a 32-bit integer as its value. + * A numeric header has value range of a 32-bit, 0..4294967295. The @a + * x_value field is unsigned long, however. */ struct msg_numeric_s { msg_common_t x_common[1]; /**< Common fragment info */ diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c b/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c index b30f2c4992..e458bfb777 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c @@ -193,6 +193,14 @@ char *msg_status_dup_one(msg_header_t *dst, msg_header_t const *src, return b; } +msg_hclass_t test_numeric_class[] = + MSG_HEADER_CLASS(msg_, numeric, "Numeric", "", x_common, + single, msg_generic, msg_generic); + +msg_hclass_t test_auth_class[] = + MSG_HEADER_CLASS(msg_, auth, "Auth", "", au_params, + append, msg_auth, msg_generic); + /** Extract the message body, including separator line. * * @param[in,out] msg message object @@ -411,3 +419,4 @@ int tst_add_tl(msg_t *msg, msg_test_t *tst, return t ? -1 : 0; } + diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/test_class.h b/libs/sofia-sip/libsofia-sip-ua/msg/test_class.h index d39a34af0d..ef8a8f182a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/test_class.h +++ b/libs/sofia-sip/libsofia-sip-ua/msg/test_class.h @@ -110,6 +110,9 @@ typedef struct msg_test_s { msg_content_encoding_t *msg_content_encoding; /**< Content-Encoding */ msg_content_length_t *msg_content_length; /**< Content-Length */ + + msg_auth_t *msg_auth; /**< Auth (testing) */ + msg_numeric_t *msg_numeric; /**< Numeric (testing) */ /* === Headers end here */ msg_unknown_t *msg_unknown; @@ -160,6 +163,17 @@ msg_test_t *msg_test_public(msg_t *msg) return (msg_test_t *)msg_public(msg, MSG_TEST_PROTOCOL_TAG); } +#define msg_auth_class test_auth_class + +#define msg_numeric_class test_numeric_class + +enum { + msg_auth_hash = 22894, + msg_numeric_hash = 24435 +}; + +SOFIAPUBVAR msg_hclass_t test_auth_class[1], test_numeric_class[1]; + SOFIA_END_DECLS #endif /* !defined(TEST_CLASS_H) */ diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/test_msg.c b/libs/sofia-sip/libsofia-sip-ua/msg/test_msg.c index 66f9af8290..9efcd7eef6 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/test_msg.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/test_msg.c @@ -127,7 +127,7 @@ static int msg_time_test(void) char *s; msg_numeric_t x[1]; - memset(x, 0, sizeof (x)); + memset(x, 0, sizeof (x)); x->x_common->h_class = test_numeric_class; TEST_1(msg_numeric_d(NULL, (msg_header_t *)x, s = error1, strlen(error1)) < 0); } 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 25458c799b..da9428a035 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c @@ -287,6 +287,8 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * NUTAG_ENABLEINVITE() \n * NUTAG_ENABLEMESSAGE() \n * NUTAG_ENABLEMESSENGER() \n + * NUTAG_INITIAL_ROUTE() \n + * NUTAG_INITIAL_ROUTE_STR() \n * NUTAG_INSTANCE() \n * NUTAG_INVITE_TIMER() \n * NUTAG_KEEPALIVE() \n @@ -404,6 +406,8 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * NUTAG_ENABLEINVITE() \n * NUTAG_ENABLEMESSAGE() \n * NUTAG_ENABLEMESSENGER() \n + * NUTAG_INITIAL_ROUTE() \n + * NUTAG_INITIAL_ROUTE_STR() \n * NUTAG_INSTANCE() \n * NUTAG_INVITE_TIMER() \n * NUTAG_KEEPALIVE() \n @@ -635,10 +639,10 @@ static int nhp_set_tags(su_home_t *home, } /* Set copy of header to handle pref structure */ -#define NHP_SET_HEADER(nhp, name, v) \ +#define NHP_SET_HEADER(nhp, name, hdr, v) \ if ((v) != 0) { \ - sip_##name##_t const *_value = (sip_##name##_t const *)(v); \ - sip_##name##_t *_new = NULL; \ + sip_##hdr##_t const *_value = (sip_##hdr##_t const *)(v); \ + sip_##hdr##_t *_new = NULL; \ if (_value != SIP_NONE) \ _new = sip_##name##_dup(home, _value); \ if (NHP_ISSET(nhp, name)) \ @@ -649,10 +653,10 @@ static int nhp_set_tags(su_home_t *home, } /* Set header made of string to handle pref structure */ -#define NHP_SET_HEADER_STR(nhp, name, v) \ +#define NHP_SET_HEADER_STR(nhp, name, hdr, v) \ if ((v) != 0) { \ char const *_value = (char const *)(v); \ - sip_##name##_t *_new = NULL; \ + sip_##hdr##_t *_new = NULL; \ if (_value != SIP_NONE) \ _new = sip_##name##_make(home, _value); \ if (NHP_ISSET(nhp, name)) \ @@ -662,6 +666,26 @@ static int nhp_set_tags(su_home_t *home, return -1; \ } +/* Append copy of header to handle pref structure */ +#define NHP_APPEND_HEADER(nhp, name, hdr, is_str, next, v) \ + { \ + sip_##hdr##_t const *_value = (sip_##hdr##_t const *)(v); \ + char const *_str = (char const *)(v); \ + sip_##hdr##_t *_new = NULL; \ + sip_##hdr##_t **_end = &nhp->nhp_##name; \ + if (_value != SIP_NONE && _value != NULL) { \ + _new = (is_str) \ + ? sip_##hdr##_make(home, _str) \ + : sip_##hdr##_dup(home, _value); \ + if (_new == NULL) return -1; \ + } \ + if (NHP_ISSET(nhp, name)) \ + while(*_end) \ + _end = next(*_end); \ + nhp->nhp_set.nhb_##name = 1; \ + *_end = _new; \ + } + /* Set copy of string from header to handle pref structure */ #define NHP_SET_STR_BY_HEADER(nhp, name, v) \ if ((v) != 0) { \ @@ -894,6 +918,15 @@ static int nhp_set_tags(su_home_t *home, NHP_SET(nhp, appl_method, (sip_allow_t *)appl_method); } } + else if (tag == nutag_initial_route || + tag == nutag_initial_route_str) { +#define next_route(r) (&(r)->r_next) + NHP_APPEND_HEADER(nhp, initial_route, route, + (tag == nutag_initial_route_str), + next_route, + t->t_value); + sip_route_fix(nhp->nhp_initial_route); + } /* SIPTAG_USER_AGENT(user_agent) */ else if (tag == siptag_user_agent) { NHP_SET_STR_BY_HEADER(nhp, user_agent, value); @@ -1079,6 +1112,14 @@ nua_handle_preferences_t *nhp_move_params(su_home_t *home, NHP_ZAP_OVERRIDEN(tbf, dst, m_features); NHP_ZAP_OVERRIDEN(tbf, dst, outbound); +#define NHP_ZAP_OVERRIDEN_HDR(tbf, nhp, pref) \ + (((tbf)->nhp_set.nhb_##pref \ + && (tbf)->nhp_##pref != (nhp)->nhp_##pref \ + ? msg_header_free(home, (void *)(tbf)->nhp_##pref) : (void)0), \ + (void)(!(nhp)->nhp_set.nhb_##pref ? (nhp)->nhp_##pref = NULL : NULL)) + + NHP_ZAP_OVERRIDEN_HDR(tbf, dst, initial_route); + return dst; } @@ -1399,6 +1440,8 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags) * NUTAG_ENABLEINVITE() \n * NUTAG_ENABLEMESSAGE() \n * NUTAG_ENABLEMESSENGER() \n + * NUTAG_INITIAL_ROUTE() \n + * NUTAG_INITIAL_ROUTE_STR() \n * NUTAG_INSTANCE() \n * NUTAG_INVITE_TIMER() \n * NUTAG_KEEPALIVE() \n @@ -1523,15 +1566,16 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, TAG_IF(nhp->nhp_set.nhb_##pref, TAG(nhp->nhp_##pref)) /* Include tag in the list returned to user - * if it has been earlier set (by user) returning default parameters */ + * if it has been earlier set (by user) + * but always include in the default parameters */ #define TIFD(TAG, pref) \ TAG_IF(nh == dnh || nhp->nhp_set.nhb_##pref, TAG(nhp->nhp_##pref)) /* Include string tag made out of SIP header * if it has been earlier set (by user) */ #define TIF_STR(TAG, pref) \ - TAG_IF(nhp->nhp_set.nhb_##pref, \ - TAG(nhp->nhp_set.nhb_##pref && nhp->nhp_##pref \ + TAG_IF(nhp->nhp_set.nhb_##pref, \ + TAG(nhp->nhp_set.nhb_##pref && nhp->nhp_##pref \ ? sip_header_as_string(tmphome, (void *)nhp->nhp_##pref) : NULL)) /* Include header tag made out of string @@ -1597,6 +1641,9 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, TIF_SIP(SIPTAG_ORGANIZATION, organization), TIF(SIPTAG_ORGANIZATION_STR, organization), + TIF(NUTAG_INITIAL_ROUTE, initial_route), + TIF_STR(NUTAG_INITIAL_ROUTE_STR, initial_route), + TIF(NUTAG_REGISTRAR, registrar), TIF(NUTAG_KEEPALIVE, keepalive), TIF(NUTAG_KEEPALIVE_STREAM, keepalive_stream), diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h index ae531f0844..ff63b420e2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h @@ -108,7 +108,7 @@ typedef struct nua_handle_preferences /* Subscriber state, i.e. nua_substate_pending */ unsigned nhp_substate; - /* REGISTER Keepalive intervals */ + /* REGISTER keepalive intervals */ unsigned nhp_keepalive, nhp_keepalive_stream; char const *nhp_registrar; @@ -124,14 +124,17 @@ typedef struct nua_handle_preferences char const *nhp_m_features; char const *nhp_instance; - /**< Outbound OPTIONS */ + /** Outbound OPTIONS */ char const *nhp_outbound; - /**< Network detection: NONE, INFORMAL, TRY_FULL */ + /** Network detection: NONE, INFORMAL, TRY_FULL */ int nhp_detect_network_updates; sip_allow_t *nhp_appl_method; + /** Initial route set */ + sip_route_t *nhp_initial_route; + union { struct { /* A bit for each feature set by application */ unsigned nhb_retry_count:1; @@ -182,6 +185,7 @@ typedef struct nua_handle_preferences unsigned nhb_outbound:1; unsigned nhb_detect_network_updates:1; unsigned nhb_appl_method:1; + unsigned nhb_initial_route:1; unsigned :0; } set_bits; unsigned set_unsigned[2]; 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 d16b4e378c..81b5aba837 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c @@ -245,7 +245,6 @@ static void nua_register_connection_closed(tp_stack_t *sip_stack, sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, su_home_t *home, int in_dialog, - char const *extra_username, sip_via_t const *v, char const *transport, char const *m_param, @@ -268,12 +267,12 @@ static int nua_stack_outbound_credentials(nua_handle_t *, auth_client_t **auc); outbound_owner_vtable nua_stack_outbound_callbacks = { sizeof nua_stack_outbound_callbacks, - nua_handle_contact_by_via, - nua_stack_outbound_refresh, - nua_stack_outbound_status, - nua_stack_outbound_failed, - nua_stack_outbound_failed, - nua_stack_outbound_credentials + /* oo_contact */ nua_handle_contact_by_via, + /* oo_refresh */ nua_stack_outbound_refresh, + /* oo_status */ nua_stack_outbound_status, + /* oo_probe_error */ nua_stack_outbound_failed, + /* oo_keepalive_error */ nua_stack_outbound_failed, + /* oo_credentials */ nua_stack_outbound_credentials }; /**@fn void nua_register(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...); @@ -1364,7 +1363,7 @@ int nua_registration_from_via(nua_registration_t **list, v2[1].v_next = NULL; - contact = nua_handle_contact_by_via(nh, home, 0, NULL, v2, protocol, NULL); + contact = nua_handle_contact_by_via(nh, home, 0, v2, protocol, NULL); v = sip_via_dup(home, v2); @@ -1780,7 +1779,7 @@ int nua_registration_set_contact(nua_handle_t *nh, if (nr0 && nr0->nr_via) { char const *tport = nr0->nr_via->v_next ? NULL : nr0->nr_via->v_protocol; m = nua_handle_contact_by_via(nh, nh->nh_home, 0, - NULL, nr0->nr_via, tport, NULL); + nr0->nr_via, tport, NULL); } } @@ -1918,7 +1917,6 @@ static int nua_stack_outbound_credentials(nua_handle_t *nh, sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, su_home_t *home, int in_dialog, - char const *extra_username, sip_via_t const *v, char const *transport, char const *m_param, @@ -1926,11 +1924,12 @@ sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, { su_strlst_t *l; char const *s; - char const *scheme = "sip:", *host, *port, *maddr, *comp; + char const *host, *port, *maddr, *comp; int one = 1; char _transport[16]; va_list va; sip_contact_t *m; + url_t url = URL_INIT_AS(sip); if (!v) return NULL; @@ -1946,7 +1945,7 @@ sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, if (sip_transport_has_tls(v->v_protocol) || sip_transport_has_tls(transport)) { - scheme = "sips:"; + url.url_type = url_sips; if (port && strcmp(port, SIPS_DEFAULT_SERV) == 0) port = NULL; if (port || host_is_ip_address(host)) @@ -1974,6 +1973,25 @@ sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, } } + s = NH_PGET(nh, m_username); + if (s) + url.url_user = s; + url.url_host = host; + url.url_port = port; + url.url_params = su_strdup(home, NH_PGET(nh, m_params)); + if (transport) { + url.url_params = url_strip_param_string((char*)url.url_params, "transport"); + url_param_add(home, &url, su_sprintf(home, "transport=%s", transport)); + } + if (maddr) { + url.url_params = url_strip_param_string((char*)url.url_params, "maddr"); + url_param_add(home, &url, su_sprintf(home, "maddr=%s", maddr)); + } + if (comp) { + url.url_params = url_strip_param_string((char*)url.url_params, "comp"); + url_param_add(home, &url, su_sprintf(home, "comp=%s", comp)); + } + l = su_strlst_create(NULL); s = NH_PGET(nh, m_display); @@ -1984,25 +2002,9 @@ sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, su_strlst_append(l, s); su_strlst_append(l, quote ? "\" " : " "); } + su_strlst_append(l, "<"); - su_strlst_append(l, scheme); - s = NH_PGET(nh, m_username); - if (s) su_strlst_append(l, s); - if (extra_username) su_strlst_append(l, s); - if (s || extra_username) - su_strlst_append(l, "@"); - su_strlst_append(l, host); - if (port) - su_strlst_append(l, ":"), su_strlst_append(l, port); - if (transport) - su_strlst_append(l, ";transport="), su_strlst_append(l, transport); - if (maddr) - su_strlst_append(l, ";maddr="), su_strlst_append(l, maddr); - if (comp) - su_strlst_append(l, ";comp="), su_strlst_append(l, comp); - s = NH_PGET(nh, m_params); - if (s) - s[0] == ';' ? "" : su_strlst_append(l, ";"), su_strlst_append(l, s); + su_strlst_append(l, url_as_string(home, &url)); su_strlst_append(l, ">"); va_start(va, m_param); 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 498b5e011b..e52a08dc4f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c @@ -1997,6 +1997,12 @@ int nua_client_init_request(nua_client_request_t *cr) t = nh->nh_tags, sip_add_tagis(msg, sip, &t); } + if (!ds->ds_route) { + sip_route_t *initial_route = NH_PGET(nh, initial_route); + if (initial_route) + sip_add_dup(msg, sip, (sip_header_t *)initial_route); + } + for (t = cr->cr_tags; t; t = t_next(t)) { if (t->t_tag == siptag_contact || t->t_tag == siptag_contact_str) diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c index c320348bf1..e2cce845b4 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c @@ -103,6 +103,10 @@ tag_typedef_t nutag_sips_url = URLTAG_TYPEDEF(sips_url); tag_typedef_t nutag_certificate_dir = STRTAG_TYPEDEF(certificate_dir); tag_typedef_t nutag_certificate_phrase = STRTAG_TYPEDEF(certificate_phrase); +extern msg_hclass_t sip_route_class[]; +tag_typedef_t nutag_initial_route = SIPEXTHDRTAG_TYPEDEF(initial_route, route); +tag_typedef_t nutag_initial_route_str = STRTAG_TYPEDEF(inital_route_str); + tag_typedef_t nutag_registrar = URLTAG_TYPEDEF(registrar); tag_typedef_t nutag_identity = PTRTAG_TYPEDEF(identity); tag_typedef_t nutag_m_display = STRTAG_TYPEDEF(m_display); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c b/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c index 94189d92ea..0f45fd5f20 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c @@ -581,7 +581,10 @@ int outbound_gruuize(outbound_t *ob, sip_t const *sip) return 0; } - gruu = (char *)msg_header_find_param(m->m_common, "gruu="); + gruu = (char *)msg_header_find_param(m->m_common, "pub-gruu="); + + if (gruu == NULL || gruu[0] == '\0') + gruu = (char *)msg_header_find_param(m->m_common, "gruu="); if (gruu == NULL || gruu[0] == '\0') return 0; @@ -1004,14 +1007,14 @@ int outbound_contacts_from_via(outbound_t *ob, sip_via_t const *via) v = v0; *v0 = *via; v0->v_next = NULL; - dcontact = ob->ob_oo->oo_contact(ob->ob_owner, home, 1, - NULL, v, v->v_protocol, NULL); + dcontact = ob->ob_oo->oo_contact(ob->ob_owner, home, 1, + v, v->v_protocol, NULL); if (ob->ob_instance && ob->ob_reg_id != 0) snprintf(reg_id_param, sizeof reg_id_param, ";reg-id=%u", ob->ob_reg_id); rcontact = ob->ob_oo->oo_contact(ob->ob_owner, home, 0, - NULL, v, v->v_protocol, + v, v->v_protocol, ob->ob_instance, reg_id_param, NULL); v = sip_via_dup(home, v); @@ -1112,7 +1115,7 @@ int outbound_set_contact(outbound_t *ob, char reg_id_param[20]; dcontact = ob->ob_oo->oo_contact(ob->ob_owner, home, 1, - NULL, v, tport, NULL); + v, tport, NULL); if (!dcontact) return -1; @@ -1120,7 +1123,7 @@ int outbound_set_contact(outbound_t *ob, snprintf(reg_id_param, sizeof reg_id_param, ";reg-id=%u", ob->ob_reg_id); rcontact = ob->ob_oo->oo_contact(ob->ob_owner, home, 0, - NULL, v, v->v_protocol, + v, v->v_protocol, ob->ob_instance, reg_id_param, NULL); if (!rcontact) return -1; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/outbound.h b/libs/sofia-sip/libsofia-sip-ua/nua/outbound.h index ef9d1d4cc3..175e81b293 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/outbound.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/outbound.h @@ -119,7 +119,6 @@ struct outbound_owner_vtable sip_contact_t *(*oo_contact)(outbound_owner_t *, su_home_t *home, int used_in_dialog, - char const *extra_username, sip_via_t const *v, char const *transport, char const *m_param, diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h index 7ef53d290e..e3d76792e3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h @@ -1086,6 +1086,85 @@ SOFIAPUBVAR tag_typedef_t nutag_sips_url_ref; #define NUTAG_PROXY_REF(x) NTATAG_DEFAULT_PROXY_REF(x) #define nutag_proxy ntatag_default_proxy + +/** Specify initial route set. + * + * The initial route set is used instead or or in addition to the outbound + * proxy URL given by NUTAG_PROXY(). The NUTAG_INITIAL_ROUTE() accepts a + * list of parsed @Route header structures, NUTAG_INITIAL_ROUTE_STR() an + * unparsed string. + * + * If a tag list contains multiple NUTAG_INITIAL_ROUTE() or + * NUTAG_INITIAL_ROUTE_STR() tags, the route set is constructed from them + * all. + * + * @par Used with + * nua_set_params() \n + * nua_set_hparams() \n + * any handle-specific nua call + * + * @par Parameter type + * sip_route_t const * + * + * @par Values + * Linked list of #sip_route_t structures + * + * Corresponding tag taking reference parameter is NUTAG_INITIAL_ROUTE_REF(). + * + * @since @NEW_1_12_7. + */ +#define NUTAG_INITIAL_ROUTE(x) nutag_initial_route, siptag_route_v(x) +SOFIAPUBVAR tag_typedef_t nutag_initial_route; + +#define NUTAG_INITIAL_ROUTE_REF(x) nutag_initial_route_ref, siptag_route_vr(&(x)) +SOFIAPUBVAR tag_typedef_t nutag_initial_route_ref; + + +/** Specify initial route set. + * + * The initial route set is used instead or or in addition to the outbound + * proxy URL given by NUTAG_PROXY(). The NUTAG_INITIAL_ROUTE() accepts a + * list of parsed @Route header structures, NUTAG_INITIAL_ROUTE_STR() a + * unparsed string containing route URIs, quoted with <> and separated by + * commas. + * + * Please note that the syntax requires <> around the @Route URIs if they + * contain parameters, e.g., "lr". + * + * If a tag list contains multiple NUTAG_INITIAL_ROUTE() or + * NUTAG_INITIAL_ROUTE_STR() tags, the route set is constructed from them + * all. + * + * The initial route set can be reset with NUTAG_INITIAL_ROUTE(NULL). + * + * If a tag list of a request contains SIPTAG_ROUTE() or + * SIPTAG_ROUTE_STR() tags, the resulting route set will contain first the + * initial route entries followed by the route URIs given with the + * SIPTAG_ROUTE()/SIPTAG_ROUTE_STR() tags. + * + * @par Used with + * nua_set_params() \n + * nua_set_hparams() \n + * any handle-specific nua call + * + * @par Parameter type + * sip_route_t const * + * + * @par Values + * Linked list of #sip_route_t structures + * + * Corresponding tag taking reference parameter is NUTAG_INITIAL_ROUTE_STR_REF(). + * + * @since @NEW_1_12_7. + */ +#define NUTAG_INITIAL_ROUTE_STR(x) nutag_initial_route_str, tag_str_v(x) +SOFIAPUBVAR tag_typedef_t nutag_initial_route_str; + +#define NUTAG_INITIAL_ROUTE_STR_REF(x) nutag_initial_route_str_ref, tag_str_vr(&(x)) +SOFIAPUBVAR tag_typedef_t nutag_initial_route_str_ref; + + + /** Registrar URL * * @par Used with @@ -1461,7 +1540,7 @@ SOFIAPUBVAR tag_typedef_t nutag_m_username_ref; /**URL parameters for @Contact. * - * Specify URL parameters for the Contact header URI generated for + * Specify URL parameters for the @Contact header URI generated for * registration request and dialog-creating requests/responses. * * Please note that some proxies may remove even the non-transport 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 836e35e92f..e355689222 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 @@ -1436,12 +1436,13 @@ int test_basic_call_6(struct context *ctx) struct endpoint *a = &ctx->a, *b = &ctx->b; struct call *a_call = a->call, *b_call = b->call; struct event *e; + sip_route_t *r, rb[1]; sip_t *sip; sip_contact_t ma[1], mb[1]; if (print_headings) - printf("TEST NUA-3.1: Basic call\n"); + printf("TEST NUA-3.6: Basic call\n"); a_call->sdp = "m=audio 5008 RTP/AVP 8"; b_call->sdp = "m=audio 5010 RTP/AVP 0 8"; @@ -1460,9 +1461,17 @@ int test_basic_call_6(struct context *ctx) mb->m_url->url_user = "b++b"; contact_for_b = mb; - + + sip_route_init(rb)->r_url[0] = b->contact->m_url[0]; + rb->r_url->url_user = "bob+0"; + url_param_add(nua_handle_home(a_call->nh), rb->r_url, "lr"); + INVITE(a, a_call, a_call->nh, - TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)), + NUTAG_URL("sip:bob@example.org"), /* Expanded by proxy */ + SIPTAG_ROUTE_STR("B2 ;bar=foo"), /* Last in list */ + NUTAG_INITIAL_ROUTE(ctx->lr), /* Removed by proxy (if any) */ + NUTAG_INITIAL_ROUTE(rb), /* Used to route request to b (not removed) */ + NUTAG_INITIAL_ROUTE_STR("B1 ;foo=bar"), /* Next in list */ SOATAG_USER_SDP_STR(a_call->sdp), SIPTAG_CONTACT(ma), TAG_END()); @@ -1517,6 +1526,14 @@ int test_basic_call_6(struct context *ctx) TEST_1(sip->sip_contact); TEST_S(sip->sip_contact->m_display, "Alice B."); TEST_S(sip->sip_contact->m_url->url_user, "a++a"); + TEST_1(r = sip->sip_route); + TEST_S(r->r_url->url_user, "bob+0"); + TEST_1(r = r->r_next); + TEST_S(r->r_url->url_user, "bob+1"); + TEST_1(r = r->r_next); + TEST_S(r->r_url->url_user, "bob+2"); + TEST_1(!r->r_next); + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state); TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */ TEST_1(is_offer_recv(e->data->e_tags)); @@ -1598,7 +1615,7 @@ int test_basic_call_6(struct context *ctx) nua_handle_destroy(b_call->nh), b_call->nh = NULL; if (print_headings) - printf("TEST NUA-3.1: PASSED\n"); + printf("TEST NUA-3.6: PASSED\n"); END(); } 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 e8f67d94c3..e67253a8d8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c @@ -72,6 +72,7 @@ int test_nua_init(struct context *ctx, sip_supported_t const *supported = NULL; char const *appl_method = NULL; 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; int err = -1; url_t b_proxy[1]; @@ -164,6 +165,9 @@ int test_nua_init(struct context *ctx, if (start_nat && p_uri == NULL) p_uri = url_hdup(ctx->home, (void *)o_proxy); + if (ctx->p) + initial_route = test_proxy_route_uri(ctx->p, &ctx->lr); + if (start_nat && p_uri != NULL) { int family = 0; su_sockaddr_t su[1]; @@ -259,6 +263,7 @@ int test_nua_init(struct context *ctx, ctx->a.nua = nua_create(ctx->root, a_callback, ctx, NUTAG_PROXY(a_uri ? a_uri : o_proxy), + NUTAG_INITIAL_ROUTE_STR(initial_route), SIPTAG_FROM_STR("sip:alice@example.com"), NUTAG_URL(a_bind), TAG_IF(a_bind != a_bind2, NUTAG_SIPS_URL(a_bind2)), 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 a77c7f54ee..fee43e1fc3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h @@ -180,6 +180,7 @@ struct context } a, b, c; struct proxy *p; + sip_route_t const *lr; struct nat *nat; }; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c index 4cd3aee053..6d9b035d58 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c @@ -43,6 +43,8 @@ #define __func__ "test_nua_params" #endif +sip_route_t *GLOBAL_ROUTE; + int test_tag_filter(void) { BEGIN(); @@ -104,7 +106,6 @@ int test_nua_params(struct context *ctx) ctx->root = su_root_create(NULL); TEST_1(ctx->root); - /* Disable threading by command line switch? */ su_root_threading(ctx->root, ctx->threading); ctx->a.nua = nua_create(ctx->root, a_callback, ctx, @@ -153,7 +154,6 @@ int test_nua_params(struct context *ctx) SIPTAG_ALLOW_EVENTS_STR("reg"), SIPTAG_USER_AGENT_STR("test_nua/1.0"), - SIPTAG_ORGANIZATION_STR("Open Laboratory"), NUTAG_M_DISPLAY("XXX"), @@ -163,6 +163,12 @@ int test_nua_params(struct context *ctx) NUTAG_INSTANCE("urn:uuid:3eb007b1-6d7f-472e-8b64-29e482795da8"), NUTAG_OUTBOUND("bar"), + NUTAG_INITIAL_ROUTE(NULL), + NUTAG_INITIAL_ROUTE(sip_route_make(tmphome, "")), + NUTAG_INITIAL_ROUTE_STR(""), + NUTAG_INITIAL_ROUTE_STR("sip:str2@example.net;lr=foo"), + NUTAG_INITIAL_ROUTE_STR(NULL), + TAG_END()); run_a_until(ctx, nua_r_set_params, until_final_response); @@ -221,6 +227,12 @@ int test_nua_params(struct context *ctx) SIPTAG_ALLOW_EVENTS(sip_allow_events_make(tmphome, "presence")), NUTAG_ALLOW_EVENTS("presence.winfo"), + NUTAG_INITIAL_ROUTE(NULL), + NUTAG_INITIAL_ROUTE(sip_route_make(nua_handle_home(nh), "")), + NUTAG_INITIAL_ROUTE_STR(""), + /* Check for sip_route_fix() */ + NUTAG_INITIAL_ROUTE_STR("sip:3@example.com;lr=foo"), + NUTAG_INITIAL_ROUTE_STR(NULL), SIPTAG_USER_AGENT(sip_user_agent_make(tmphome, "test_nua")), @@ -287,6 +299,9 @@ int test_nua_params(struct context *ctx) sip_organization_t const *organization = NONE; char const *organization_str = "NONE"; + sip_route_t *initial_route = NONE; + char const *initial_route_str = NONE; + char const *outbound = "NONE"; char const *m_display = "NONE"; char const *m_username = "NONE"; @@ -352,6 +367,9 @@ int test_nua_params(struct context *ctx) SIPTAG_ORGANIZATION_REF(organization), SIPTAG_ORGANIZATION_STR_REF(organization_str), + NUTAG_INITIAL_ROUTE_REF(initial_route), + NUTAG_INITIAL_ROUTE_STR_REF(initial_route_str), + NUTAG_REGISTRAR_REF(registrar), NUTAG_KEEPALIVE_REF(keepalive), NUTAG_KEEPALIVE_STREAM_REF(keepalive_stream), @@ -364,7 +382,7 @@ int test_nua_params(struct context *ctx) NUTAG_INSTANCE_REF(instance), TAG_END()); - TEST(n, 48); + TEST(n, 50); TEST_S(sip_header_as_string(tmphome, (void *)from), Alice); TEST_S(from_str, Alice); @@ -414,6 +432,17 @@ int test_nua_params(struct context *ctx) "Pussy Galore's Flying Circus"); TEST_S(organization_str, "Pussy Galore's Flying Circus"); + TEST_1(initial_route); TEST_1(initial_route != (void *)-1); + TEST_S(initial_route->r_url->url_user, "1"); + TEST_1(url_has_param(initial_route->r_url, "lr")); + TEST_1(initial_route->r_next); + TEST_S(initial_route->r_next->r_url->url_user, "2"); + TEST_1(url_has_param(initial_route->r_next->r_url, "lr")); + TEST_1(initial_route->r_next->r_next); + TEST_S(initial_route->r_next->r_next->r_url->url_user, "3"); + TEST_1(url_has_param(initial_route->r_next->r_next->r_url, "lr")); + TEST_1(!initial_route->r_next->r_next->r_next); + TEST_S(url_as_string(tmphome, registrar->us_url), "sip:sip.wonderland.org"); TEST(keepalive, 66); @@ -473,6 +502,9 @@ int test_nua_params(struct context *ctx) sip_organization_t const *organization = NONE; char const *organization_str = "NONE"; + sip_route_t *initial_route = NONE; + char const *initial_route_str = "NONE"; + url_string_t const *registrar = NONE; char const *outbound = "NONE"; @@ -585,6 +617,9 @@ int test_nua_params(struct context *ctx) TEST_P(organization, NONE); TEST_S(organization_str, "NONE"); + TEST_1(initial_route == (void *)-1); + TEST_S(initial_route_str, "NONE"); + TEST_S(outbound, "NONE"); TEST_S(m_display, "NONE"); TEST_S(m_username, "NONE"); 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 e2b169a66b..999daf0e6a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c @@ -100,6 +100,8 @@ struct proxy { nta_agent_t *agent; url_t const *uri; + sip_route_t *lr; + char const *lr_str; url_t const *rr_uri; nta_leg_t *defleg; @@ -326,7 +328,12 @@ test_proxy_init(su_root_t *root, struct proxy *proxy) return -1; proxy->uri = nta_agent_contact(proxy->agent)->m_url; - + proxy->lr_str = su_sprintf(proxy->home, "<" URL_PRINT_FORMAT ";lr>", URL_PRINT_ARGS(proxy->uri)); + proxy->lr = sip_route_make(proxy->home, proxy->lr_str); + + if (!proxy->lr) + return -1; + return 0; } @@ -391,6 +398,19 @@ url_t const *test_proxy_uri(struct proxy const *p) return p ? p->uri : NULL; } +/* Return the proxy route URI */ +char const *test_proxy_route_uri(struct proxy const *p, + sip_route_t const **return_route) +{ + if (p == NULL) + return NULL; + + if (return_route) + *return_route = p->lr; + + return p->lr_str; +} + void test_proxy_domain_set_expiration(struct domain *d, sip_time_t min_expires, sip_time_t expires, @@ -796,8 +816,9 @@ static int validate_transaction(struct proxy_tr *t) /* Remove our routes */ while (t->sip->sip_route && - url_has_param(t->sip->sip_route->r_url, "lr") && - url_cmp(t->proxy->rr_uri, t->sip->sip_route->r_url) == 0) { + url_has_param(t->sip->sip_route->r_url, "lr") && + (url_cmp(t->proxy->lr->r_url, t->sip->sip_route->r_url) == 0 || + url_cmp(t->proxy->rr_uri, t->sip->sip_route->r_url) == 0)) { sip_route_remove(t->msg, t->sip); /* add record-route also to the forwarded request */ t->rr = 1; 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 fa433eca2a..b8b2ac6672 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h @@ -39,6 +39,9 @@ void test_proxy_destroy(struct proxy *); url_t const *test_proxy_uri(struct proxy const *); +char const *test_proxy_route_uri(struct proxy const *p, + sip_route_t const **return_route); + struct domain *test_proxy_add_domain(struct proxy *, url_t const *domain, tag_type_t, tag_value_t, ...); diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sofia-sip/sdp.h b/libs/sofia-sip/libsofia-sip-ua/sdp/sofia-sip/sdp.h index b2eb5682fc..56d9abe7f4 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sofia-sip/sdp.h +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sofia-sip/sdp.h @@ -320,7 +320,7 @@ struct sdp_rtpmap_s { unsigned rm_predef : 1; /**< is this entry well-known? */ unsigned rm_pt : 7; /**< Payload type */ unsigned rm_any : 1; /**< Wildcard entry */ - int :0; + unsigned :0; }; SOFIAPUBVAR sdp_rtpmap_t const * const sdp_rtpmap_well_known[128]; diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip.doxyaliases b/libs/sofia-sip/libsofia-sip-ua/sip/sip.doxyaliases index b9866c8564..11b9733b09 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip.doxyaliases +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip.doxyaliases @@ -65,6 +65,8 @@ ALIASES += \ "WWWAuthenticate=@ref sip_www_authenticate \"WWW-Authenticate\"" \ "Warning=@ref sip_warning \"Warning\"" \ "ReferSub=@ref sip_refer_sub \"Refer-Sub\"" \ + "AlertInfo=@ref sip_alert_info \"Alert-Info\"" \ + "ReplyTo=@ref sip_reply_to \"Reply-To\"" \ "SuppressBodyIfMatch=@ref sip_suppress_body_if_match \"Suppress-Body-If-Match\"" \ "SuppressNotifyIfMatch=@ref sip_suppress_notify_if_match \"Suppress-Notify-If-Match\"" \ diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c index 162f6412f9..7ed394d311 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c @@ -1484,13 +1484,18 @@ issize_t sip_content_length_d(su_home_t *home, char *s, isize_t slen) { - return sip_numeric_d(home, h, s, slen); + sip_content_length_t *l = (sip_content_length_t *)h; + issize_t retval = msg_uint32_d(&s, &l->l_length); + if (*s) + retval = -1; + return retval; } issize_t sip_content_length_e(char b[], isize_t bsiz, sip_header_t const *h, int flags) { + sip_content_length_t const *l = (sip_content_length_t const *)h; assert(sip_is_content_length(h)); - return sip_numeric_e(b, bsiz, h, flags); + return snprintf(b, bsiz, "%lu", (unsigned long)l->l_length); } /**@ingroup sip_content_length 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 2b76376916..611908091e 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 @@ -48,6 +48,28 @@ #include #include +/** Tag class for tags containing SIP headers. @HIDE + * + * Tags in this class are not automatically added to the message with + * sip_add_tl() or sip_add_tagis(). + */ +tag_class_t sipexthdrtag_class[1] = + {{ + sizeof(siphdrtag_class), + /* tc_next */ NULL, + /* tc_len */ NULL, + /* tc_move */ NULL, + /* tc_xtra */ msghdrtag_xtra, + /* tc_dup */ msghdrtag_dup, + /* tc_free */ NULL, + /* tc_find */ NULL, + /* tc_snprintf */ msghdrtag_snprintf, + /* tc_filter */ siptag_filter, + /* tc_ref_set */ t_ptr_ref_set, + /* tc_scan */ msghdrtag_scan, + }}; + + /** Tag class for SIP header tags. @HIDE */ tag_class_t siphdrtag_class[1] = {{ diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_tag_class.h b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_tag_class.h index 02bdd39309..774eb7652a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_tag_class.h +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_tag_class.h @@ -65,6 +65,22 @@ SOFIA_BEGIN_DECLS {{ TAG_NAMESPACE, #t, sipmsgtag_class, \ (tag_value_t)SIP_PROTOCOL_TAG }} +/** Tag class for SIP headers */ +SOFIAPUBVAR tag_class_t siphdrtag_class[1]; +/** Tag class for string values of SIP headers */ +SOFIAPUBVAR tag_class_t sipstrtag_class[1]; +/** Tag class for SIP message */ +SOFIAPUBVAR tag_class_t sipmsgtag_class[1]; + +/** Define a named tag type using structure of SIP header @a t. */ +#define SIPEXTHDRTAG_TYPEDEF(n, t) \ +{{ TAG_NAMESPACE, #n, sipexthdrtag_class, \ + (tag_value_t)sip_##t##_class }} + +/** Tag class using SIP header structure */ +SOFIAPUBVAR tag_class_t sipexthdrtag_class[1]; + + /**@internal Filter SIP header tag items. */ SOFIAPUBFUN tagi_t *siptag_filter(tagi_t *dst, tagi_t const f[], tagi_t const *src, diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h index 277caad6bd..e8872b14bd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h @@ -293,6 +293,9 @@ SOFIAPUBFUN int su_setblocking(su_socket_t s, int blocking); SOFIAPUBFUN int su_setreuseaddr(su_socket_t s, int reuse); /** Get the error code associated with the socket. */ SOFIAPUBFUN int su_soerror(su_socket_t s); +/** Get the socket type. */ +SOFIAPUBFUN int su_getsocktype(su_socket_t s); + /** Get size of message available in socket. */ SOFIAPUBFUN issize_t su_getmsgsize(su_socket_t s); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c index ed48cb9994..4ee9fe4a85 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c @@ -337,6 +337,17 @@ int su_soerror(su_socket_t s) return error; } +int su_getsocktype(su_socket_t s) +{ + int socktype = 0; + socklen_t intlen = sizeof(socktype); + + if (getsockopt(s, SOL_SOCKET, SO_TYPE, (void *)&socktype, &intlen) < 0) + return -1; + + return socktype; +} + int su_setreuseaddr(su_socket_t s, int reuse) { return setsockopt(s, SOL_SOCKET, SO_REUSEADDR, diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/agent.pem b/libs/sofia-sip/libsofia-sip-ua/tport/agent.pem index 1e92b556be..c955748fd6 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/agent.pem +++ b/libs/sofia-sip/libsofia-sip-ua/tport/agent.pem @@ -1,35 +1,34 @@ -----BEGIN CERTIFICATE----- -MIIDPjCCAqegAwIBAgIHJQIBAZACBjANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQG -EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxDjAM -BgNVBAoTBXNpcGl0MSkwJwYDVQQLEyBTaXBpdCBUZXN0IENlcnRpZmljYXRlIEF1 -dGhvcml0eTAeFw0wMzEyMDMxODMwMjJaFw0wNjEyMDIxODMwMjJaMGUxCzAJBgNV +MIIDIjCCAougAwIBAgIJAPHSWjotpO2kMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEO -MAwGA1UEChMFc2lwaXQxHjAcBgNVBAMTFXBla2thLm5va2lhLnNpcGl0Lm5ldDCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsdJn/O6JoIC1I2iXOVJLQypmt9sN -HmvB84853Qx9KS+xqP3U2nqNMnDQby6ZmTsRHNGAK5QuGugU11wocmYNP0/TQFaz -KNLhNt0pMBOfpAV9vG6pCSkocObsUo2XFULPTEB/SzGcvE1G1em3XmwRfPA178y9 -L2+sVNT5Vtt5KfMCAwEAAaOB7DCB6TAgBgNVHREEGTAXghVwZWtrYS5ub2tpYS5z -aXBpdC5uZXQwCQYDVR0TBAIwADAdBgNVHQ4EFgQU1OjdL9cdA0NNbxPDQ9xZUZG6 -NnIwgZoGA1UdIwSBkjCBj4AUa0YXFOqUdiWAVG4TVNqh41QUobahdKRyMHAxCzAJ -BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9z -ZTEOMAwGA1UEChMFc2lwaXQxKTAnBgNVBAsTIFNpcGl0IFRlc3QgQ2VydGlmaWNh -dGUgQXV0aG9yaXR5ggEAMA0GCSqGSIb3DQEBBQUAA4GBADCO35LJqgiK5OUR+DuT -N4CfUhsn9T5kDSf2rikna4ZFbuS7smc/oVu4g26HHjt6DKs4UEx9OmyXFslSENZ+ -tFNeVClpHJrPsNwjk/uyjhfeW1NezhXMIi6q8DYcwE5I7r+Uz2XST+jWCTb4obPY -10ysI7e7/rgCoITe+qO2U35D +MAwGA1UEChMFc2lwaXQxKTAnBgNVBAsTIFNpcGl0IFRlc3QgQ2VydGlmaWNhdGUg +QXV0aG9yaXR5MB4XDTA3MDkxNzIwMDMzOVoXDTA5MDkxNjIwMDMzOVowNzE1MDMG +A1UEAxMsQz1GSSwgTD1IZWxzaW5raSwgTz1zb2ZpYS1zaXAsIENOPXRwb3J0IHRl +c3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUlg4LStE/8WEjUny7Edpl1 +M0HCdE9Tfu8bHfcbCBDhlSQfQkAl0NilfB8tkX8Uz8LnTTsmtz76tDEORNEQRVng +FSyg2ugryDxNKURCsdq5WyMUh1XFnu0TLAdD8z5/hqAn6+jo5gcoT92uxNsXYA79 +6qctdS8WMGuaRPsUUbRBAgMBAAGjgfwwgfkwCQYDVR0TBAIwADAdBgNVHQ4EFgQU +12vA8bvBkE0q8hrFrvmE033MLq4wgZoGA1UdIwSBkjCBj4AUa0YXFOqUdiWAVG4T +VNqh41QUobahdKRyMHAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MREwDwYDVQQHEwhTYW4gSm9zZTEOMAwGA1UEChMFc2lwaXQxKTAnBgNVBAsTIFNp +cGl0IFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggEAMCMGA1UdEQQcMBqCGHRw +b3J0LXRlc3Quc29maWEtc2lwLm9yZzALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEF +BQADgYEAiJ2FvB4RUOieuiqy3m3SbVtVeUJ9cLbPMF/MGKMGhxgCm61GTteQHW6y +f7gg2UkDeFoWclzqJam677fy+1IzVhpna6611vNow71w344eFBzg4GRBPhzR+qNn +X5CcWPWME2olV64dngtFsECdYnW58gGVuXhPW2CYiZ8nPq1gu18= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQCx0mf87omggLUjaJc5UktDKma32w0ea8HzjzndDH0pL7Go/dTa -eo0ycNBvLpmZOxEc0YArlC4a6BTXXChyZg0/T9NAVrMo0uE23SkwE5+kBX28bqkJ -KShw5uxSjZcVQs9MQH9LMZy8TUbV6bdebBF88DXvzL0vb6xU1PlW23kp8wIDAQAB -AoGAVtICT64vqBvvVPB2FVimwo5rRI1BJH88XSyq9dBpM7jDp1z3lgyL7/rA6ef4 -uqXqPwXS7HQW5rA1rMikPuawxE5UG31OG3U0+H/OGl0xwAq57mEtRDR8464jSUPY -l9bzkRpjnEgdUtkLnogm8F4mALexdc3KxIgg3uo/OOg0N5ECQQDZon1JBNEYWxEF -GBNbEvQthPy7rRLmxontgcsfhRvm5lSbuC+VP1uRHibwwIrXOUZD8uuEVdVZNzfV -bGPdh70HAkEA0Ss6HyAWczRBzrvC8eVvPmkI9XihdLqUFLTDL0R1sMCISwW/FEeH -X9yFqOY+y6EJAitzhxtol+0k+UsIJl5ctQJAXU0L6QHnokloQobPxXuasukQcGUC -dW0oNGowapLmI1cbbqbHv3QqDUyf5Rambx5ewUKjNViW3miNxzFwnshSgQJAINuQ -gskwnaJM4CPgqM0o333yeVUcz9BraKFItAkmD8D+6AIcFRxzaJykpnac0LIYTy3y -NPwaPxtynnKp8hUKrQJBAM1i5051UzJVFuRedwtPdGDrfkNwoJm27fwWozSQcBC6 -G5VnTrQ6V8VCJglNzVhy9b2WqlqfWV3D5BCgxyuH984= +MIICXQIBAAKBgQC1JYOC0rRP/FhI1J8uxHaZdTNBwnRPU37vGx33GwgQ4ZUkH0JA +JdDYpXwfLZF/FM/C5007Jrc++rQxDkTREEVZ4BUsoNroK8g8TSlEQrHauVsjFIdV +xZ7tEywHQ/M+f4agJ+vo6OYHKE/drsTbF2AO/eqnLXUvFjBrmkT7FFG0QQIDAQAB +AoGAU6lrv7QIyxhEvf5VNohOLjnO3oQsq6ZobY4cnM/DPeixtOkq8+2DM0vas5uc +IxE9k0q4hKUw5MltB2sLpXLaVAz3d9GjouKhMyzIv1UcHZli6OStSIVl458usfAy +SnJLvCP12fp4S4cSAc7Q+z5v83ztGHqPvl7GOXaiNL5BNfECQQDfo8ElGtBZtUKu +MPw/+07dPoMX4DHZ6Q9+4g3gfMoxkM+1RrFItDtkZx7W5aiWzcRrHlSB+2k/33Q1 +XyxyDnaHAkEAz1uxknSlLn//WwD5kwqPVOscWoQMHWNPG34H4Ktx/8IQ3WZGaECh +g/09XViIM4t5l1xDLZaWymcXBNqdRTXo9wJBAJDzBSO0fmg2eJKIQ2aAzvvNIZCf +ChCP4zA8+fuPRknb7xQyToOt9XS89ZsZXSzpDy7SiLl6pxv0C9Dv79G5GA8CQQCi +L5oIb2vznvHgADc1J4FMbkjTE41WPyLU4hLPS8nyvZvrT9+qE0NBtYWVyXVeu6zz +EpsIwUxYK6H5jfSM+cmpAkBRoE3KPkKJzqMYW2jNNk1CrE9YbHPcdWxsqh8+86CG +oK1ABCIX/PA4t1i0KWi0gJ3DQFr+c77XOhtChE0P2kA0 -----END RSA PRIVATE KEY----- diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/certificates-update b/libs/sofia-sip/libsofia-sip-ua/tport/certificates-update new file mode 100644 index 0000000000..86cdfc079b --- /dev/null +++ b/libs/sofia-sip/libsofia-sip-ua/tport/certificates-update @@ -0,0 +1,100 @@ +#! /bin/sh +# +# Generate agent.pem +# +# Copyright (C) 2007 Nokia Corporation +# +# Author: Pekka Pessi +# Based on Mikko Haataja's perl script +# + +CN='C=FI, L=Helsinki, O=sofia-sip, CN=tport test' +ALTNAME=DNS:tport-test.sofia-sip.org +#ALTNAME=URI:sips:tport-test.sofia-sip.org +DAYS=730 + +umask 077 + +T=${TMPDIR:-/tmp}/sofia-sip-certs-${USER}-$$-`date +%N` +CA=${T}/CA + +mkdir $T || exit 1 +mkdir $T/CA || exit 1 + +cat > $CA/cakey.pem < $CA/cacert.pem < $T/a.cnf <tp_ping >= 4) tport_tcp_pong(self); else + self->tp_ping += (unsigned short)i; if (i == iovec->siv_len && veclen == 1) { diff --git a/libs/sofia-sip/libsofia-sip-ua/url/url.c b/libs/sofia-sip/libsofia-sip-ua/url/url.c index 68a5bb5faa..008e55e900 100644 --- a/libs/sofia-sip/libsofia-sip-ua/url/url.c +++ b/libs/sofia-sip/libsofia-sip-ua/url/url.c @@ -337,8 +337,8 @@ char *url_canonize(char *d, char const *s, size_t n, return url_canonize2(d, s, n, syn33, mask32, mask64, mask96); } -#define SYN33(c) (1 << (c - 33)) -#define IS_SYN33(syn33, c) ((syn33 & (1 << (c - 33))) != 0) +#define SYN33(c) (1U << (c - 33)) +#define IS_SYN33(syn33, c) ((syn33 & (1U << (c - 33))) != 0) /** Canonize a URL component (with precomputed mask) */ static diff --git a/libs/sofia-sip/utils/sip-options.c b/libs/sofia-sip/utils/sip-options.c index 494c12fc5f..bc0b70cac8 100644 --- a/libs/sofia-sip/utils/sip-options.c +++ b/libs/sofia-sip/utils/sip-options.c @@ -61,6 +61,10 @@ *
--method=s
*
Specify the request method (defaults to OPTIONS). *
+ *
--extra | -x/dt> + *
Read extra headers (and optionally a message body) from the standard + * input + *
* * * @section return Return Codes