Commit 9f3c22c5 authored by Pekka Pessi's avatar Pekka Pessi
Browse files

Updated nua_register() and NUTAG_OUTBOUND() documentation.

Taking NUTAG_OUTBOUND() options correctly into account in outbound.c.
Improved the contact validation process in outbound.c, too.

darcs-hash:20060512121142-65a35-edfd08a2b72659bfca3a3640c735effee369313b.gz
parent 3741f217
...@@ -261,8 +261,8 @@ outbound_owner_vtable nua_stack_outbound_callbacks = { ...@@ -261,8 +261,8 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* nothing * nothing
* *
* @par Related tags: * @par Related tags:
* NUTAG_REGISTRAR(), NUTAG_KEEPALIVE(), NUTAG_KEEPALIVE_STREAM(), * NUTAG_REGISTRAR(), NUTAG_INSTANCE(), NUTAG_OUTBOUND(),
* NUTAG_OUTBOUND() * NUTAG_KEEPALIVE(), NUTAG_KEEPALIVE_STREAM(),
* *
* @par Events: * @par Events:
* #nua_r_register, #nua_i_outbound * #nua_r_register, #nua_i_outbound
...@@ -273,13 +273,13 @@ outbound_owner_vtable nua_stack_outbound_callbacks = { ...@@ -273,13 +273,13 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* nua_register() will generate one and start a protocol engine for outbound * nua_register() will generate one and start a protocol engine for outbound
* connections used for NAT and firewall traversal and connectivity checks. * connections used for NAT and firewall traversal and connectivity checks.
* *
* First, nua_register() will probe for NATs in between UA and * First, nua_register() will probe for NATs in between UA and registrar. It
* registrar. It will send a REGISTER request as usual. Upon receiving the * will send a REGISTER request as usual. Upon receiving the response it
* response it checks for the presence of valid "received" and "rport" parameters in * checks for the presence of valid "received" and "rport" parameters in the
* the Via header returned by registrar. The presence of NAT is determined * Via header returned by registrar. The presence of NAT is determined from
* from the "received" parameter in a Via header. When a REGISTER request * the "received" parameter in a Via header. When a REGISTER request was
* was sent, the stack inserted the source IP address in the Via header: if * sent, the stack inserted the source IP address in the Via header: if that
* that is different from the source IP address seen by the registrar, the * is different from the source IP address seen by the registrar, the
* registrar inserts the source IP address it sees into the "received" * registrar inserts the source IP address it sees into the "received"
* parameter. * parameter.
* *
...@@ -289,14 +289,20 @@ outbound_owner_vtable nua_stack_outbound_callbacks = { ...@@ -289,14 +289,20 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* *
* The response to the initial REGISTER should also include feature tags * The response to the initial REGISTER should also include feature tags
* indicating whether registrar supports various SIP extensions: @e * indicating whether registrar supports various SIP extensions: @e
* outbound, @e pref, @e path, @e gruu. If the @e outbound extension is * outbound, @e pref, @e path, @e gruu.
* supported, and it is not explicitly disabled by application, the *
* nua_register() will use it. Basically, @e outbound means that instead of * Basically, @e outbound means that instead of registering its contact URI
* registering its contact URI with a particular address-of-record URI, the * with a particular address-of-record URI, the user-agent registers a
* user-agent registers a transport-level connection. Such a connection is * transport-level connection. Such a connection is identified on the
* identified on the Contact header field with a @ref NUTAG_INSTANCE() * Contact header field with an instance identifier, application-provided
* "unique string" identifying the user-agent instance and a numeric index * @ref NUTAG_INSTANCE() "unique string" identifying the user-agent instance
* identifying the transport-level connection. * and a stack-generated numeric index identifying the transport-level
* connection.
*
* If the @e outbound extension is supported, NUTAG_OUTBOUND() contains
* option string "outbound" and the application has provided an instance
* identifer to the stack with NUTAG_INSTANCE(), the nua_register() will try
* to use outbound.
* *
* If @e outbound is not supported, nua_register() has to generate a URI * If @e outbound is not supported, nua_register() has to generate a URI
* that can be used to reach it from outside. It will check for public * that can be used to reach it from outside. It will check for public
...@@ -306,6 +312,11 @@ outbound_owner_vtable nua_stack_outbound_callbacks = { ...@@ -306,6 +312,11 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* the "received" and "rport" parameters found in the Via header of the * the "received" and "rport" parameters found in the Via header of the
* response message. * response message.
* *
* @todo Actually generate public addresses.
*
* You can disable this kind of NAT traversal by setting "no-natify" into
* NUTAG_OUTBOUND() options string.
*
* @par GRUU and Service-Route * @par GRUU and Service-Route
* *
* After a successful response to the REGISTER request has been received, * After a successful response to the REGISTER request has been received,
...@@ -330,16 +341,26 @@ outbound_owner_vtable nua_stack_outbound_callbacks = { ...@@ -330,16 +341,26 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* application using nua_i_outbound event, and start unregistration * application using nua_i_outbound event, and start unregistration
* procedure (unless that has been explicitly disabled). * procedure (unless that has been explicitly disabled).
* *
* You can disable validation by inserting "no-validate" into
* NUTAG_OUTBOUND() string.
*
* The keepalive mechanism depends on the network features detected earlier. * The keepalive mechanism depends on the network features detected earlier.
* If @a outbound extension is used, the STUN keepalives will be used. * If @a outbound extension is used, the STUN keepalives will be used.
* Otherwise, NUA stack will repeatedly send OPTIONS requests to itself. In * Otherwise, NUA stack will repeatedly send OPTIONS requests to itself. In
* order to save bandwidth, it will include Max-Forwards: 0 in the * order to save bandwidth, it will include Max-Forwards: 0 in the
* keep-alive requests, however. The keepalive interval is determined by two * keep-alive requests, however. The keepalive interval is determined by
* parameters: NUTAG_KEEPALIVE() and NUTAG_KEEPALIVE_STREAM(). If the * NUTAG_KEEPALIVE() parameter. If the interval is 0, no keepalive messages
* interval is 0, no keepalive messages is sent. The value of * is sent.
* NUTAG_KEEPALIVE_STREAM(), if specified, is used to indicate the desired *
* transport-layer keepalive interval for stream-based transports like TLS * You can disable keepalive OPTIONS by inserting "no-options-keepalive"
* and TCP. * into NUTAG_OUTBOUND() string. Currently there are no other keepalive
* mechanisms available.
*
* The value of NUTAG_KEEPALIVE_STREAM(), if specified, is used to indicate
* the desired transport-layer keepalive interval for stream-based
* transports like TLS and TCP.
*
* @sa NUTAG_OUTBOUND() and tags.
*/ */
/** @var nua_event_e::nua_r_register /** @var nua_event_e::nua_r_register
......
...@@ -72,11 +72,12 @@ struct outbound { ...@@ -72,11 +72,12 @@ struct outbound {
char ob_cookie[32]; /**< Our magic cookie */ char ob_cookie[32]; /**< Our magic cookie */
struct outbound_prefs { struct outbound_prefs {
unsigned dgram_interval; /**< Default keepalive interval for datagram */ unsigned interval; /**< Default keepalive interval for datagram */
unsigned stream_interval; /**< Default keepalive interval for streams */ unsigned stream_interval; /**< Default keepalive interval for streams */
unsigned gruuize:1; /**< Establish a GRUU */ unsigned gruuize:1; /**< Establish a GRUU */
unsigned outbound:1; /**< Try to use outbound */ unsigned outbound:1; /**< Try to use outbound */
unsigned natify:1; /**< Try to detect NAT */ unsigned natify:1; /**< Try to detect NAT */
unsigned okeepalive:1; /**< Connection keepalive with OPTIONS */
unsigned validate:1; /**< Validate registration with OPTIONS */ unsigned validate:1; /**< Validate registration with OPTIONS */
/* How to detect NAT binding or connect to outbound: */ /* How to detect NAT binding or connect to outbound: */
unsigned use_connect:1; /**< Use HTTP connect */ unsigned use_connect:1; /**< Use HTTP connect */
...@@ -138,6 +139,8 @@ struct outbound { ...@@ -138,6 +139,8 @@ struct outbound {
msg_t *msg; /**< Keep-alive OPTIONS message */ msg_t *msg; /**< Keep-alive OPTIONS message */
nta_outgoing_t *orq; /**< Keep-alive OPTIONS transaction */ nta_outgoing_t *orq; /**< Keep-alive OPTIONS transaction */
auth_client_t *auc[1]; /**< Authenticator for OPTIONS */ auth_client_t *auc[1]; /**< Authenticator for OPTIONS */
/** Progress of registration validation */
unsigned validating:1, validated:1,:0;
} ob_keepalive; /**< Keepalive informatio */ } ob_keepalive; /**< Keepalive informatio */
}; };
...@@ -241,32 +244,39 @@ void outbound_unref(outbound_t *ob) ...@@ -241,32 +244,39 @@ void outbound_unref(outbound_t *ob)
#include <sofia-sip/bnf.h> #include <sofia-sip/bnf.h>
/** Set various outbound and nat-traversal related options. */
int outbound_set_options(outbound_t *ob, int outbound_set_options(outbound_t *ob,
char const *options, char const *options,
unsigned dgram_interval, unsigned interval,
unsigned stream_interval) unsigned stream_interval)
{ {
struct outbound_prefs prefs[1] = {{ 0 }}; struct outbound_prefs prefs[1] = {{ 0 }};
char *s; char const *s;
prefs->dgram_interval = dgram_interval; prefs->interval = interval;
prefs->stream_interval = stream_interval; prefs->stream_interval = stream_interval;
prefs->gruuize = 1; prefs->gruuize = 1;
prefs->outbound = 0; prefs->outbound = 0;
prefs->natify = 1; prefs->natify = 1;
prefs->okeepalive = 1;
prefs->validate = 1; prefs->validate = 1;
prefs->use_rport = 1; prefs->use_rport = 1;
#define MATCH(v) (len == sizeof(#v) - 1 && strncasecmp(#v, s, len) == 0) #define MATCH(v) (len == sizeof(#v) - 1 && strncasecmp(#v, s, len) == 0)
for (s = (char *)options; s && s[0]; ) { for (s = options; s && s[0]; ) {
int len = span_token(s); int len = span_token(s);
int value = 1; int value = 1;
if (len > 3 && strncasecmp(s, "no-", 3) == 0) if (len > 3 && strncasecmp(s, "no-", 3) == 0)
value = 0, s += 3, len -= 3; value = 0, s += 3, len -= 3;
else if (len > 4 && strncasecmp(s, "not-", 4) == 0)
value = 0, s += 4, len -= 4;
else if (len > 3 && strncasecmp(s, "no_", 3) == 0) else if (len > 3 && strncasecmp(s, "no_", 3) == 0)
value = 0, s += 3, len -= 3; value = 0, s += 3, len -= 3;
else if (len > 4 && strncasecmp(s, "not_", 4) == 0)
value = 0, s += 4, len -= 4;
if (len == 0) if (len == 0)
break; break;
...@@ -274,7 +284,10 @@ int outbound_set_options(outbound_t *ob, ...@@ -274,7 +284,10 @@ int outbound_set_options(outbound_t *ob,
else if (MATCH(outbound)) prefs->outbound = value; else if (MATCH(outbound)) prefs->outbound = value;
else if (MATCH(natify)) prefs->natify = value; else if (MATCH(natify)) prefs->natify = value;
else if (MATCH(validate)) prefs->validate = value; else if (MATCH(validate)) prefs->validate = value;
else if (MATCH(use-connect) || MATCH(use_connect)) prefs->use_connect = value; else if (MATCH(options-keepalive)) prefs->okeepalive = value;
else if (MATCH(options_keepalive)) prefs->okeepalive = value;
else if (MATCH(use-connect)) prefs->use_connect = value;
else if (MATCH(use_connect)) prefs->use_connect = value;
else if (MATCH(use-rport) || MATCH(use_rport)) prefs->use_rport = value; else if (MATCH(use-rport) || MATCH(use_rport)) prefs->use_rport = value;
else if (MATCH(use-socks) || MATCH(use_socks)) prefs->use_socks = value; else if (MATCH(use-socks) || MATCH(use_socks)) prefs->use_socks = value;
else if (MATCH(use-upnp) || MATCH(use_upnp)) prefs->use_upnp = value; else if (MATCH(use-upnp) || MATCH(use_upnp)) prefs->use_upnp = value;
...@@ -419,30 +432,6 @@ int outbound_check_for_nat(outbound_t *ob, ...@@ -419,30 +432,6 @@ int outbound_check_for_nat(outbound_t *ob,
int binding_changed; int binding_changed;
sip_contact_t *m = ob->ob_rcontact; sip_contact_t *m = ob->ob_rcontact;
#if 0
if (host_is_domain(v->v_host)) {
/*
* If we use domain name in Via, we assume that application
* knows something we don't.
* Just use ordinary contact unless domain name ends with ".invalid"
*/
char const *invalid = strcasestr(v->v_host, ".invalid");
if (invalid)
invalid += (sizeof ".invalid") - 1;
if (invalid && invalid[0] == '.') /* ... or .invalid. */
invalid++;
if (!invalid || invalid[0] != '\0') {
if (!ob->ob_rcontact)
...
if (!ob->ob_rcontact)
return -1;
return 0;
}
}
#endif
/* Update NAT information */ /* Update NAT information */
binding_changed = outbound_nat_detect(ob, request, response); binding_changed = outbound_nat_detect(ob, request, response);
...@@ -453,6 +442,10 @@ int outbound_check_for_nat(outbound_t *ob, ...@@ -453,6 +442,10 @@ int outbound_check_for_nat(outbound_t *ob,
if (!ob->ob_by_stack) if (!ob->ob_by_stack)
return ob_no_nat; return ob_no_nat;
/* Application does not want us to do any NAT traversal */
if (!ob->ob_prefs.natify)
return ob_no_nat;
/* We have detected NAT. Now, what to do? /* We have detected NAT. Now, what to do?
* 1) do nothing - register as usual and let proxy take care of it? * 1) do nothing - register as usual and let proxy take care of it?
* 2) try to detect our public nat binding and use it * 2) try to detect our public nat binding and use it
...@@ -648,27 +641,26 @@ static void keepalive_timer(su_root_magic_t *root_magic, ...@@ -648,27 +641,26 @@ static void keepalive_timer(su_root_magic_t *root_magic,
su_timer_t *t, su_timer_t *t,
su_timer_arg_t *ob_as_timer_arg); su_timer_arg_t *ob_as_timer_arg);
/** Start OPTIONS keepalive or contact validation process */
void outbound_start_keepalive(outbound_t *ob, void outbound_start_keepalive(outbound_t *ob,
nta_outgoing_t *register_transaction) nta_outgoing_t *register_transaction)
{ {
tport_t *tport; unsigned interval = 0;
unsigned interval; int need_to_validate;
if (!ob) if (!ob)
return; return;
if (!ob->ob_nat_detected || !register_transaction) { if (ob->ob_prefs.natify && ob->ob_prefs.okeepalive)
interval = ob->ob_prefs.interval;
need_to_validate = ob->ob_prefs.validate && !ob->ob_validated;
if (!ob->ob_nat_detected || !register_transaction ||
!(need_to_validate || interval != 0)) {
outbound_stop_keepalive(ob); outbound_stop_keepalive(ob);
return; return;
} }
tport = nta_outgoing_transport(register_transaction);
if (tport_is_dgram(tport))
interval = ob->ob_prefs.dgram_interval;
else
interval = ob->ob_prefs.stream_interval;
tport_unref(tport);
if (ob->ob_keepalive.timer) if (ob->ob_keepalive.timer)
su_timer_destroy(ob->ob_keepalive.timer), ob->ob_keepalive.timer = NULL; su_timer_destroy(ob->ob_keepalive.timer), ob->ob_keepalive.timer = NULL;
...@@ -721,6 +713,8 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip) ...@@ -721,6 +713,8 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip)
char const *p1 = ob->ob_instance; char const *p1 = ob->ob_instance;
char const *p2 = ob->ob_features; char const *p2 = ob->ob_features;
unsigned d = ob->ob_keepalive.interval;
assert(regsip); assert(regsip->sip_request); assert(regsip); assert(regsip->sip_request);
if (p1 || p2) { if (p1 || p2) {
...@@ -731,10 +725,9 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip) ...@@ -731,10 +725,9 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip)
msg_header_insert(msg, NULL, (void *)ac); msg_header_insert(msg, NULL, (void *)ac);
} }
if ( if (0 >
/* Duplicate essential headers from REGISTER request: */
sip_add_tl(msg, osip, sip_add_tl(msg, osip,
/* Duplicate essential headers from REGISTER request:
From/To, Route */
SIPTAG_TO(regsip->sip_to), SIPTAG_TO(regsip->sip_to),
SIPTAG_FROM(regsip->sip_from), SIPTAG_FROM(regsip->sip_from),
/* XXX - we should only use loose routing here */ /* XXX - we should only use loose routing here */
...@@ -743,11 +736,11 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip) ...@@ -743,11 +736,11 @@ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip)
*/ */
SIPTAG_ROUTE(regsip->sip_route), SIPTAG_ROUTE(regsip->sip_route),
/* Add Max-Forwards 0 */ /* Add Max-Forwards 0 */
SIPTAG_MAX_FORWARDS_STR("0"), TAG_IF(d, SIPTAG_MAX_FORWARDS_STR("0")),
SIPTAG_SUBJECT_STR("KEEPALIVE"), TAG_IF(d, SIPTAG_SUBJECT_STR("KEEPALIVE")),
SIPTAG_CALL_ID_STR(ob->ob_cookie), SIPTAG_CALL_ID_STR(ob->ob_cookie),
SIPTAG_ACCEPT_STR(outbound_content_type), SIPTAG_ACCEPT_STR(outbound_content_type),
TAG_END()) < 0 || TAG_END()) ||
/* Create request-line, Call-ID, CSeq */ /* Create request-line, Call-ID, CSeq */
nta_msg_request_complete(msg, nta_msg_request_complete(msg,
nta_default_leg(ob->ob_nta), nta_default_leg(ob->ob_nta),
...@@ -772,7 +765,7 @@ static int keepalive_options(outbound_t *ob) ...@@ -772,7 +765,7 @@ static int keepalive_options(outbound_t *ob)
if (ob->ob_keepalive.orq) if (ob->ob_keepalive.orq)
return 0; return 0;
if (ob->ob_registered && !ob->ob_validated) if (ob->ob_prefs.validate && ob->ob_registered && !ob->ob_validated)
return keepalive_options_with_registration_probe(ob); return keepalive_options_with_registration_probe(ob);
req = msg_copy(ob->ob_keepalive.msg); req = msg_copy(ob->ob_keepalive.msg);
...@@ -858,24 +851,49 @@ static int response_to_keepalive_options(outbound_t *ob, ...@@ -858,24 +851,49 @@ static int response_to_keepalive_options(outbound_t *ob,
} }
} }
if (status == 408) { if (binding_check <= 1 && ob->ob_registered && ob->ob_keepalive.validating) {
SU_DEBUG_1(("outbound(%p): keepalive timeout\n", ob->ob_owner)); int failed = 0, loglevel = 3;
ob->ob_oo->oo_probe_error(ob->ob_owner, ob, status, phrase, TAG_END());
return 0;
}
if (challenged > 0 && credentials > 0) { if (challenged > 0 && credentials > 0) {
keepalive_options_with_registration_probe(ob); keepalive_options_with_registration_probe(ob);
return 0; return 0;
} }
if (binding_check <= 1 && status < 300 && ob->ob_registered) { if (status < 300 && ob->ob_keepalive.validated) {
if (!ob->ob_validated) loglevel = 5;
SU_DEBUG_1(("outbound(%p): validated contact " URL_PRINT_FORMAT "\n", if (ob->ob_validated)
ob->ob_owner, URL_PRINT_ARGS(ob->ob_rcontact->m_url))); loglevel = 99; /* only once */
ob->ob_validated = ob->ob_once_validated = 1; ob->ob_validated = ob->ob_once_validated = 1;
} }
else if (status == 401 || status == 407 || status == 403)
loglevel = 5, failed = 1;
else
loglevel = 3, failed = 1;
loglevel = 1; /* XXX ... for now */
if (loglevel >= SU_LOG->log_level) {
su_llog(SU_LOG, loglevel,
"outbound(%p): %s <" URL_PRINT_FORMAT ">\n",
ob->ob_owner, failed ? "FAILED to validate" : "validated",
URL_PRINT_ARGS(ob->ob_rcontact->m_url));
if (failed)
su_llog(SU_LOG, loglevel, "outbound(%p): FAILED with %u %s\n",
ob->ob_owner, status, phrase);
}
if (failed)
ob->ob_oo->oo_probe_error(ob->ob_owner, ob, status, phrase, TAG_END());
}
else if (status == 408) {
SU_DEBUG_1(("outbound(%p): keepalive timeout\n", ob->ob_owner));
ob->ob_oo->oo_keepalive_error(ob->ob_owner, ob, status, phrase, TAG_END());
return 0;
}
ob->ob_keepalive.validating = 0;
if (ob->ob_keepalive.timer)
su_timer_set(ob->ob_keepalive.timer, keepalive_timer, ob); su_timer_set(ob->ob_keepalive.timer, keepalive_timer, ob);
return 0; return 0;
...@@ -934,6 +952,9 @@ static int keepalive_options_with_registration_probe(outbound_t *ob) ...@@ -934,6 +952,9 @@ static int keepalive_options_with_registration_probe(outbound_t *ob)
if (!ob->ob_keepalive.orq) if (!ob->ob_keepalive.orq)
return msg_destroy(req), -1; return msg_destroy(req), -1;
ob->ob_keepalive.validating = 1;
ob->ob_keepalive.validated = 0;
return 0; return 0;
} }
...@@ -957,6 +978,12 @@ int outbound_process_request(outbound_t *ob, ...@@ -957,6 +978,12 @@ int outbound_process_request(outbound_t *ob,
if (strcmp(sip->sip_call_id->i_id, ob->ob_cookie)) if (strcmp(sip->sip_call_id->i_id, ob->ob_cookie))
return 0; return 0;
if (ob->ob_keepalive.validating) {
SU_DEBUG_1(("outbound(%p): registration check OPTIONS received\n",
ob->ob_owner));
ob->ob_keepalive.validated = 1;
}
nta_incoming_treply(irq, SIP_200_OK, nta_incoming_treply(irq, SIP_200_OK,
SIPTAG_CONTENT_TYPE_STR(outbound_content_type), SIPTAG_CONTENT_TYPE_STR(outbound_content_type),
SIPTAG_PAYLOAD_STR(ob->ob_cookie), SIPTAG_PAYLOAD_STR(ob->ob_cookie),
......
...@@ -772,6 +772,23 @@ SOFIAPUBVAR tag_typedef_t nutag_registrar; ...@@ -772,6 +772,23 @@ SOFIAPUBVAR tag_typedef_t nutag_registrar;
SOFIAPUBVAR tag_typedef_t nutag_registrar_ref; SOFIAPUBVAR tag_typedef_t nutag_registrar_ref;
/** Outbound option string. /** Outbound option string.
*
* The outbound option string can specify how the NAT traversal is handled.
* The option tokens are as follows:
* - "gruuize": try to generate a GRUU
* - "outbound": use SIP outbound extension (off by default)
* - "validate": validate registration behind a NAT by sending OPTIONS to self
* - "natify": try to traverse NAT
* - "use-rport": use rport to traverse NAT
* - "options-keepalive": send periodic OPTIONS requests as keepalive messages
*
* An option token with "no-" or "not-" prefix turns the option off. For
* example, if you want to try to traverse NATs but not to use OPTIONS
* keepalive, use NUTAG_OUTBOUND("natify no-options-keepalive").
*
* @note
* Options string is used so that no new tags need to be added when the
* outbound functionality changes.
* *
* @par Used with * @par Used with
* nua_register() \n * nua_register() \n
...@@ -793,6 +810,8 @@ SOFIAPUBVAR tag_typedef_t nutag_outbound; ...@@ -793,6 +810,8 @@ SOFIAPUBVAR tag_typedef_t nutag_outbound;
#define NUTAG_OUTBOUND_REF(x) nutag_outbound_ref, tag_str_vr(&(x)) #define NUTAG_OUTBOUND_REF(x) nutag_outbound_ref, tag_str_vr(&(x))
SOFIAPUBVAR tag_typedef_t nutag_outbound_ref; SOFIAPUBVAR tag_typedef_t nutag_outbound_ref;
#if notyet
/** Outbound proxy set 1. /** Outbound proxy set 1.
* *
* @par Used with * @par Used with
...@@ -881,6 +900,8 @@ SOFIAPUBVAR tag_typedef_t nutag_outbound_set4; ...@@ -881,6 +900,8 @@ SOFIAPUBVAR tag_typedef_t nutag_outbound_set4;
#define NUTAG_OUTBOUND_SET4_REF(x) nutag_outbound_set4_ref, tag_str_vr(&(x)) #define NUTAG_OUTBOUND_SET4_REF(x) nutag_outbound_set4_ref, tag_str_vr(&(x))
SOFIAPUBVAR tag_typedef_t nutag_outbound_set4_ref; SOFIAPUBVAR tag_typedef_t nutag_outbound_set4_ref;
#endif /* ...notyet */
/** Pointer to SIP parser structure /** Pointer to SIP parser structure
* *
* @par Used with * @par Used with
...@@ -967,6 +988,8 @@ SOFIAPUBVAR tag_typedef_t nutag_keepalive_ref; ...@@ -967,6 +988,8 @@ SOFIAPUBVAR tag_typedef_t nutag_keepalive_ref;
* *
* Corresponding tag taking reference parameter is * Corresponding tag taking reference parameter is
* NUTAG_KEEPALIVE_STREAM_REF() * NUTAG_KEEPALIVE_STREAM_REF()
*
* @todo Actually pass NUTAG_KEEPALIVE_STREAM() to transport layer.
*/ */
#define NUTAG_KEEPALIVE_STREAM(x) nutag_keepalive_stream, tag_uint_v(x) #define NUTAG_KEEPALIVE_STREAM(x) nutag_keepalive_stream, tag_uint_v(x)
SOFIAPUBVAR tag_typedef_t nutag_keepalive_stream; SOFIAPUBVAR tag_typedef_t nutag_keepalive_stream;
......
...@@ -1648,7 +1648,9 @@ int test_register(struct context *ctx) ...@@ -1648,7 +1648,9 @@ int test_register(struct context *ctx)
TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END())); TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END()));
REGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to), NUTAG_KEEPALIVE(1000), REGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to),
NUTAG_OUTBOUND("no-natify options-keepalive validate"),
NUTAG_KEEPALIVE(1000),
TAG_END()); TAG_END());
run_a_until(ctx, -1, save_until_final_response); run_a_until(ctx, -1, save_until_final_response);
......
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