Commit 2eca488d authored by Pekka Pessi's avatar Pekka Pessi

nua: added NUTAG_INITIAL_ROUTE() and NUTAG_INITIAL_ROUTE_STR()

Added tags NUTAG_INITIAL_ROUTE() and NUTAG_INITIAL_ROUTE_STR() that can be
used to determine the route set included in the request initiating dialogs
or outside them. They can be used instead or in addition to the
NUTAG_PROXY() when determining the outbound proxy.

The URL in NUTAG_PROXY() is not added to the requests, and it affects all
the requests, including in-dialog requests. The route set in
NUTAG_INITIAL_ROUTE{_STR}() is explictly added to the requests and it is
visible in the requests, and it affects only routing of the initial
requests.

TODO: interaction with service route set returned by registrar in the
Service-Route header.

darcs-hash:20070917141542-65a35-b7e7a38d4fbcc86ed156bfe5e353d91b37a8588d.gz
parent 558d1e1b
......@@ -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),
......
......@@ -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];
......
......@@ -1996,6 +1996,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)
......
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment