-Sat Jan 19 01:47:55 GMT 2008
+Wed Jan 23 13:36:34 EST 2008
Jacobs, Remeres <first.surname@nokia.com>
Jalava, Teemu <first.surname@nokia.com>
Jerris, Michael <mike -at jerris -dot com>
-Legostayev Denis <legostayev -at neic -dot nsk -dot su>
+Legostayev, Denis <legostayev -at neic -dot nsk -dot su>
+Leuenberger, Stefan <first.surname -at netmodule -dot com>
Prado, Dimitri E. <dprado -at e3c -dot com -dot br>
Puolakka, Petteri <first.surname@nokia.com>
Puustinen, Ismo <first.surname@nokia.com>
Rinne-Rahkola, Pasi <first.surname@nokia.com>
+Rondina, Daniele <geaary -at gmail -dot com>
Saari, Mika <first.surname@nokia.com>
Selin, Jari <first.surname@nokia.com>
+Suttner, Bernhard <suttner -at comdasys -dot com>
Underwood, Steve <steveu -at coppice -dot org>
Urpalainen, Jari <first.surname@nokia.com>
Whittaker, Colin <colinw -at occamnetworks -dot com>
SUBDIRS = libsofia-sip-ua $(GLIB_SUBDIRS) utils packages tests
DIST_SUBDIRS = libsofia-sip-ua libsofia-sip-ua-glib utils packages \
- win32 open_c
+ tests win32 open_c
# note: when glib devel files are not available, make should not
# enter the libsofia-sip-ua-glib subdir at all
docs/devel_platform_notes.txt \
docs/release_management.txt
-EXTRA_DIST += scripts/lcov-report scripts/uncovered
+EXTRA_DIST += scripts/lcov-report scripts/uncovered \
+ scripts/hide_emails.sh
dist_man_MANS = man/man1/sip-date.1 man/man1/sip-options.1 \
man/man1/localinfo.1 man/man1/addrinfo.1 \
Changes since last release
--------------------------
-<changes since last written in freshmeat.net "Changes:" style;
- and in less than 10 lines, written in 3rd person English, with
- complete sentences />
+Beside bugfixes, a server graylisting was added to nta and a few
+improvements in event handling were made in nua interface.
-Bugs in blaa and foo have been fixed. The stack now supports
-use of foobar...
+A check-based test program was added, too.
API/ABI changes and versioning
------------------------------
-<see previous release notes at
- http://sofia-sip.sourceforge.net/relnotes/ for examples ;
- - should include all changes to public headers, and
- other important information to developers;
- - and should be updated _continuously_! />
-
-**template**: New features in API are marked with Doxytag macro @VERSION_1_XX_X.
+New features in API are marked with Doxytag macro @NEW_1_12_8 or
+@VERSION_1_12_8.
libsofia-sip-ua:
-- **template**: Added foobar() function (sofia-sip/foobar.h).
+- Added nta_sip_is_internal(), nta_msg_is_internal() function in
+ <sofia-sip/nta.h>. Deprecating nta_is_internal_msg().
+- Added su_msg_new(), su_msg_send_to() and su_msg_deinitializer() for more
+ robust and light-weight message passing in <sofia-sip/su_wait.h>
+- Added su_home_lock(), su_home_trylock(), and su_home_unlock() in
+ <sofia-sip/su_alloc.h>
+- Added type-neutral template macros for hash tables HTABLE2_DECLARE2(), HTABLE2_PROTOS2(),
+ and HTABLE2_BODIES2().
+- Added sres_cache_set_srv_priority() in <sofia-resolv/sres_cache.h> and
+ sres_set_cached_srv_priority() <sofia-resolv/sres.h> for graylisting
+ SRV records for inresponsive servers.
+- nua_create()/nta_agent_create()/tport_bind() now joins to multicast group
+ if "maddr" parameter is specified
- This release is ABI/API compatible with applications linked against
any 1.12.x release. However, applications built against this release won't
work against an older library. The ABI has been tested with the nua module
Contributors to this release
----------------------------
-<list of people who contributed to _this_ release
- - update as people's patches are added, or when you commit stuff
- - current development team members (see AUTHORS) may be omitted,
- or listed at the end of the contribur list (depending on the scope
- of the work done since the last release)
- - name of the contributor should be enough (email addresses in AUTHORS),
- plus a _brief_ description of what was contributed
- - roughly sorted by number of patches accepted
-/>
-
-- **template**: First Surname (patch to nua/soa/msg)
-
+- Bernhard Suttner contributed patch to soa for using a=inactive attribute
+ with call hold
+- Stefan Leuenberger from Netmodule contributed the hack for changing
+ priority of SRV records if a SIP server was inresponsive
+- Daniele Rondina contributed patches fixing crash in STUN discovery cleanup
+ and for transport handling with nta_outgoing_*create()
+- Youness Alaoui sent a iPhone build fix
+- Michael Jerris and Stefan Knoblich from Freeswitch project reported
+ numerous bugs and contributed fixes
+
See the AUTHORS file in the distribution package.
Notes on new features
---------------------
-<information about major new features
- - new/changed/removed functionality
- - links to further documentation
- - section may be omitted for minor releases
-/>
+SIP Server Graylisting
+----------------------
+
+The hack contributed by Stefan Leuenberger from Netmodule changes the
+priority of SRV records which are used when SIP URI is resolved.
+
+If your domain has multiple servers, you can define separate SRV records for
+them. If any of them becomes unresponsive, a SIP request sent to it times
+out or gets rejected because of network error and Sofia SIP automatically
+retries with another server. However, as Sofia SIP does not keep track of
+failed servers with the next request it may again try first the failed
+server. The graylisting repriotizes the SRV records so that the priority of
+the failed server gets reduced and it won't be tried again until all other
+servers have failed, too. Note that the SIP URI resolver may get confused
+when using this kind of repriotizing if a single SRV record corresponds to
+multiple servers or servers with multiple addresses.
+
+You can disable the reprioritizing hack by including tag NTATAG_GREYLIST(0)
+with nua_create(), nua_set_params(), nta_agent_create() or
+nta_agent_set_params().
Bugs fixed in this release
--------------------------
+* Fixed su_home_init not initializing suh_lock.
+* Fixed memory leak when increasing hash table size
+* Fixed problems with multiple authentication challenges.
+* Fixed sf.net bug #1816647: Outbound contact does not make it to dialogs.
+* Fixed problem with tagargs, amd64 and Sun CC.
+* Fixed nta_outgoing_*create() not using NTATAG_TPORT() if
+ NTATAG_DEFAULT_PROXY() was set.
+* Fixed memory leak from nua operations.
+* Fixed crash when INVITE destroyed session before UPDATE or PRACK completed
+* Fixed crash in stun when destroying stun context during discovery callback
+* Fixed nta timer interval calculation ignoring some transactions
+* Fixed request merging when client is RFC 2543 proxy
+* Fixed request matching and merging if To/From URI does not match
+* Fixed problem with soa and overlapping INVITEs
+* Fixed handling of RFC 2848 subscriptions (without Event header)
+* Fixed problems with expiration time calculations if NOTIFY is sent before
+ SUBSCRIBE has been responded
+* Fixed su_getaddrinfo() with ephemeral (NULL or "0") service
+* Fixed IPv6 build with Vista SDK
+* Fixed sf.net bug #1867753 (avoid duplicating initial route set
+* Fixed SCTP receive
+* Using tport_log and su_llog() when logging TLS warnings and errors
+* Removed asserts on hairy dialog shutdown cases.
+* Using remote activity mode derived from O/A result rather than mode based on remote
+ offer
+* Fixed mode in SDP offer while on hold
+* Fixed handling of REFER in nua when it gets redirected or challenged
+* Fixed memory corruption when sending of ACK request failed.
+
< notable bugs fixed in this release
- check the sf.net bug tracker; see closed bugs,
sorted by closing date
#!/bin/sh
set -x
+AUTOMAKE=${AUTOMAKE:-automake-1.9} ACLOCAL=${ACLOCAL:-aclocal-1.9}
+export AUTOMAKE ACLOCAL
${AUTORECONF:-autoreconf} -i
find . \( -name 'run*' -o -name '*.sh' \) -a -type f | xargs chmod +x
chmod +x scripts/*
"VERSION_1_12_7=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
"NEW_1_12_7=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
"EXP_1_12_7=@since Experimental in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>, available if --enable-experimental configuration option is given" \
+ "VERSION_1_12_8=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.8.txt\">1.12.8</a>" \
+ "NEW_1_12_8=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.8.txt\">1.12.8</a>" \
+
docguide.docs \
mainpage.docs \
conformance.docs \
- hide_emails.sh \
ChangeLog \
pictures/SIP_basic_incoming_operation.eps \
pictures/SIP_basic_incoming_operation.gif \
print "RFC"i"=\"<a href="q site i type q">RFC "i"</a>\" "b; \
}}' \
site=http://www.faqs.org/rfcs/rfc type=.html \
- from=700 to=4800 \
+ from=700 to=5500 \
/dev/null > $@
CLEANFILES = Doxyfile.rfc *.doxytags
<a href="#4168">RFC 4168</a> <br>
<a href="#4320">RFC 4320</a> <br>
<a href="#4488">RFC 4488</a> <br>
+<a href="#5057">RFC 5057</a> <br>
</td><td>
<a href="#4566">RFC 4566</a> <br>
<a href="#2327">RFC 2327</a> <br>
</td>
</tr>
+<a name="5057"></a>
+<tr valign=top>
+ <th align="left">
+ @RFC5057: Multiple Dialog Usages in SIP
+ </th>
+ <td>
+ Sofia-SIP provides function sip_response_terminates_dialog() that
+ can be used to determine the effect of error response with dialog.
+
+ The nua UA engine uses sip_response_terminates_dialog().
+ </td>
+ <td>
+ The client application must either use NUA or
+ sip_response_terminates_dialog().
+ </td>
+</tr>
+
</table>
<table border=1 cellpadding=4 cellspacing=0>
sip_www_authenticate_class,
sip_authentication_info_class
}};
+ auth_challenger_t pach[1] =
+ {{ 407, "Proxy Authorization required",
+ sip_proxy_authenticate_class,
+ sip_proxy_authentication_info_class
+ }};
TEST_1(home = su_home_new(sizeof(*home)));
TEST(as->as_status, 0);
auth_mod_destroy(am); aucs = NULL;
+ /* Test empty realm */
+ TEST_1(am = auth_mod_create(root,
+ AUTHTAG_METHOD("Digest"),
+ AUTHTAG_REALM(""),
+ AUTHTAG_DB(testpasswd),
+ TAG_END()));
+ reinit_as(as);
+ auth_mod_check_client(am, as, NULL, ach); TEST(as->as_status, 401);
+ TEST(auc_challenge(&aucs, home, (msg_auth_t *)as->as_response,
+ sip_authorization_class), 1);
+ reinit_as(as);
+
+ TEST(auc_all_credentials(&aucs, "Digest", "\"\"", "user1", "secret"), 1);
+ msg_header_remove(m2, (void *)sip, (void *)sip->sip_authorization);
+ TEST(auc_authorization(&aucs, m2, (msg_pub_t*)sip, rq->rq_method_name,
+ (url_t *)"sip:surf3@ims3.so.noklab.net",
+ sip->sip_payload), 1);
+ TEST_1(sip->sip_authorization);
+
+ auth_mod_check_client(am, as, sip->sip_authorization, ach);
+ TEST(as->as_status, 0);
+ aucs = NULL;
+ reinit_as(as);
+ auth_mod_check_client(am, as, NULL, pach); TEST(as->as_status, 407);
+ TEST(auc_challenge(&aucs, home, (msg_auth_t *)as->as_response,
+ sip_proxy_authorization_class), 1);
+ reinit_as(as);
+
+ TEST(auc_credentials(&aucs, as->as_home, "Digest:\"\":user1:secret"), 1);
+ msg_header_remove(m2, (void *)sip, (void *)sip->sip_proxy_authorization);
+ TEST(auc_authorization(&aucs, m2, (msg_pub_t*)sip, rq->rq_method_name,
+ (url_t *)"sip:surf3@ims3.so.noklab.net",
+ sip->sip_payload), 1);
+ TEST_1(sip->sip_proxy_authorization);
+
+ auth_mod_check_client(am, as, sip->sip_proxy_authorization, pach);
+ TEST(as->as_status, 0);
+
+ auth_mod_destroy(am); aucs = NULL;
+
/* Test Basic authentication scheme */
TEST_1(am = auth_mod_create(root,
AUTHTAG_METHOD("Basic"),
url_t const *request_uri,
sip_call_id_t const *i,
char const *from_tag,
- url_t const *from_uri,
- char const *to_tag,
- url_t const *to_uri);
+ char const *to_tag);
static nta_leg_t *dst_find(nta_agent_t const *sa, url_t const *u0,
char const *method);
static void leg_recv(nta_leg_t *, msg_t *, sip_t *, tport_t *);
* NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
* NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
* NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
- * NTATAG_EXTRA_100(),
+ * NTATAG_EXTRA_100(), NTATAG_GRAYLIST(),
* NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
* NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
* NTATAG_REL100(),
agent->sa_t4 = NTA_SIP_T4;
agent->sa_t1x64 = 64 * NTA_SIP_T1;
agent->sa_timer_c = 185 * 1000;
+ agent->sa_graylist = 600;
agent->sa_drop_prob = 0;
agent->sa_is_a_uas = 0;
agent->sa_progress = 60 * 1000;
* NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
* NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
* NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
- * NTATAG_EXTRA_100(),
+ * NTATAG_EXTRA_100(), NTATAG_GRAYLIST(),
* NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
* NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
* NTATAG_REL100(),
unsigned sip_t4 = agent->sa_t4;
unsigned sip_t1x64 = agent->sa_t1x64;
unsigned timer_c = agent->sa_timer_c;
+ unsigned graylist = agent->sa_graylist;
unsigned blacklist = agent->sa_blacklist;
int ua = agent->sa_is_a_uas;
unsigned progress = agent->sa_progress;
NTATAG_DEBUG_DROP_PROB_REF(drop_prob),
NTATAG_DEFAULT_PROXY_REF(proxy),
NTATAG_EXTRA_100_REF(extra_100),
+ NTATAG_GRAYLIST_REF(graylist),
NTATAG_MAXSIZE_REF(maxsize),
NTATAG_MAX_PROCEEDING_REF(max_proceeding),
NTATAG_MAX_FORWARDS_REF(max_forwards),
outgoing_queue_adjust(agent, agent->sa_out.inv_proceeding, timer_c);
}
+ if (graylist > 24 * 60 * 60)
+ graylist = 24 * 60 * 60;
+ agent->sa_graylist = graylist;
+
+ if (blacklist > 24 * 60 * 60)
+ blacklist = 24 * 60 * 60;
agent->sa_blacklist = blacklist;
if (progress == 0)
* NTATAG_CANCEL_2543_REF(), NTATAG_CANCEL_487_REF(),
* NTATAG_CLIENT_RPORT_REF(), NTATAG_CONTACT_REF(),
* NTATAG_DEBUG_DROP_PROB_REF(), NTATAG_DEFAULT_PROXY_REF(),
- * NTATAG_EXTRA_100_REF(),
+ * NTATAG_EXTRA_100_REF(), NTATAG_GRAYLIST_REF(),
* NTATAG_MAXSIZE_REF(), NTATAG_MAX_FORWARDS_REF(), NTATAG_MCLASS_REF(),
* NTATAG_MERGE_482_REF(), NTATAG_MAX_PROCEEDING_REF(),
* NTATAG_PASS_100_REF(), NTATAG_PASS_408_REF(), NTATAG_PRELOAD_REF(),
NTATAG_DEBUG_DROP_PROB(agent->sa_drop_prob),
NTATAG_DEFAULT_PROXY(agent->sa_default_proxy),
NTATAG_EXTRA_100(agent->sa_extra_100),
+ NTATAG_GRAYLIST(agent->sa_graylist),
NTATAG_MAXSIZE(agent->sa_maxsize),
NTATAG_MAX_PROCEEDING(agent->sa_max_proceeding),
NTATAG_MAX_FORWARDS(agent->sa_max_forwards->mf_count),
if ((leg = leg_find(agent,
method_name, url,
sip->sip_call_id,
- sip->sip_from->a_tag, sip->sip_from->a_url,
- sip->sip_to->a_tag, sip->sip_to->a_url))) {
+ sip->sip_from->a_tag,
+ sip->sip_to->a_tag))) {
/* Try existing dialog */
SU_DEBUG_5(("nta: %s (%u) %s\n",
method_name, cseq, "going to existing leg"));
id->i_hash = msg_hash_string(id->i_id = rp->rp_call_id);
- leg = leg_find(sa, NULL, NULL, id, from_tag, NULL, to_tag, NULL);
+ leg = leg_find(sa, NULL, NULL, id, from_tag, to_tag);
if (leg == NULL && strcmp(from_tag, "0") == 0)
- leg = leg_find(sa, NULL, NULL, id, NULL, NULL, to_tag, NULL);
+ leg = leg_find(sa, NULL, NULL, id, NULL, to_tag);
if (leg == NULL && strcmp(to_tag, "0") == 0)
- leg = leg_find(sa, NULL, NULL, id, from_tag, NULL, NULL, NULL);
+ leg = leg_find(sa, NULL, NULL, id, from_tag, NULL);
}
return leg;
* @param call_id if non-NULL, must match with @CallID header contents
* @param remote_tag if there is remote tag
* associated with dialog, @a remote_tag must match
- * @param remote_uri if there is no remote tag, the remote URI must match
+ * @param remote_uri ignored
* @param local_tag if non-NULL and there is local tag associated with leg,
* it must math
- * @param local_uri if there is no local tag, the local URI must match
+ * @param local_uri ignored
*
+ * @note
+ * If @a remote_tag or @a local_tag is an empty string (""), the tag is
+ * ignored when matching legs.
*/
nta_leg_t *nta_leg_by_dialog(nta_agent_t const *agent,
url_t const *request_uri,
char const *local_tag,
url_t const *local_uri)
{
- void *to_be_freed = NULL, *tbf2 = NULL, *tbf3 = NULL;
+ void *to_be_freed = NULL;
url_t *url;
url_t url0[1];
nta_leg_t *leg;
agent_aliases(agent, url, NULL); /* canonize url */
}
- if (remote_uri && URL_IS_STRING(remote_uri))
- request_uri = tbf2 = url_hdup(NULL, remote_uri);
+ if (remote_tag && remote_tag[0] == '\0')
+ remote_tag = NULL;
+ if (local_tag && local_tag[0] == '\0')
+ local_tag = NULL;
- if (local_uri && URL_IS_STRING(local_uri))
- local_uri = tbf3 = url_hdup(NULL, local_uri);
-
leg = leg_find(agent,
NULL, url,
call_id,
- remote_tag, remote_uri,
- local_tag, local_uri);
+ remote_tag,
+ local_tag);
if (to_be_freed) su_free(NULL, to_be_freed);
- if (tbf2) su_free(NULL, tbf2);
- if (tbf3) su_free(NULL, tbf3);
return leg;
}
* Find a leg corresponding to the request message.
*
* A leg matches to message if leg_match_request() returns true ("Call-ID",
- * "To", and "From" match).
+ * "To"-tag, and "From"-tag match).
*/
static
nta_leg_t *leg_find(nta_agent_t const *sa,
url_t const *request_uri,
sip_call_id_t const *i,
char const *from_tag,
- url_t const *from_uri,
- char const *to_tag,
- url_t const *to_uri)
+ char const *to_tag)
{
hash_value_t hash = i->i_hash;
leg_htable_t const *lht = sa->sa_dialogs;
(leg = *ll);
ll = leg_htable_next(lht, ll)) {
sip_call_id_t const *leg_i = leg->leg_id;
- url_t const *remote_uri = leg->leg_remote->a_url;
char const *remote_tag = leg->leg_remote->a_tag;
- url_t const *local_uri = leg->leg_local->a_url;
char const *local_tag = leg->leg_local->a_tag;
+
url_t const *leg_url = leg->leg_url;
char const *leg_method = leg->leg_method;
continue;
if (strcmp(leg_i->i_id, i->i_id) != 0)
continue;
+
/* Do not match if the incoming To has tag, but the local does not */
if (!local_tag && to_tag)
continue;
/* Do not match if incoming From has no tag but remote has a tag */
if (remote_tag && !from_tag)
continue;
+
/* Avoid matching with itself */
if (!remote_tag != !from_tag && !local_tag != !to_tag)
continue;
- if (local_tag && to_tag ?
- strcasecmp(local_tag, to_tag) : addr_cmp(local_uri, to_uri))
+ if (local_tag && to_tag && strcasecmp(local_tag, to_tag) && to_tag[0])
continue;
- if (remote_tag && from_tag ?
- strcasecmp(remote_tag, from_tag) : addr_cmp(remote_uri, from_uri))
+ if (remote_tag && from_tag && strcasecmp(remote_tag, from_tag) && from_tag[0])
continue;
if (leg_url && request_uri && url_cmp(leg_url, request_uri))
char const *timer,
su_duration_t now);
-static void outgoing_ack(nta_outgoing_t *orq, msg_t *msg, sip_t *sip);
+static void outgoing_ack(nta_outgoing_t *orq, sip_t *sip);
static msg_t *outgoing_ackmsg(nta_outgoing_t *, sip_method_t, char const *,
tagi_t const *tags);
static void outgoing_retransmit(nta_outgoing_t *orq);
if (outgoing_is_queued(orq))
outgoing_remove(orq);
+ assert(orq->orq_next == NULL);
assert(*queue->q_tail == NULL);
orq->orq_timeout = set_timeout(orq->orq_agent, queue->q_timeout);
if ((*orq->orq_prev = orq->orq_next))
orq->orq_next->orq_prev = orq->orq_prev;
else
- orq->orq_queue->q_tail = orq->orq_prev, assert(!*orq->orq_queue->q_tail);
+ orq->orq_queue->q_tail = orq->orq_prev;
orq->orq_queue->q_length--;
orq->orq_next = NULL;
else {
/* Final response */
if (status >= 300 && !internal)
- outgoing_ack(orq, msg, sip);
+ outgoing_ack(orq, sip);
if (!orq->orq_completed) {
if (outgoing_complete(orq))
/** @internal ACK to a final response (300..699).
* These messages are ACK'ed via the original URL (and tport)
*/
-void outgoing_ack(nta_outgoing_t *orq, msg_t *msg, sip_t *sip)
+void outgoing_ack(nta_outgoing_t *orq, sip_t *sip)
{
nta_outgoing_t *ack;
msg_t *ackmsg;
TAG_END())))
;
else
- msg_destroy(msg);
+ msg_destroy(ackmsg);
}
}
char const *sq_proto;
char const *sq_domain;
char sq_port[6]; /* port number */
-
- uint16_t sq_type;
+ uint16_t sq_otype; /* origin type of query data (0 means request) */
+ uint16_t sq_type; /* query type */
uint16_t sq_priority; /* priority or preference */
uint16_t sq_weight; /* preference or weight */
};
outgoing_reset_timer(orq);
outgoing_queue(orq->orq_agent->sa_out.resolving, orq);
+ if (orq->orq_status > 0)
+ /* PP: don't hack priority if a preliminary response has been received */
+ ;
+ else if (orq->orq_agent->sa_graylist == 0)
+ /* PP: priority hacking disabled */
+ ;
+ /* NetModule hack:
+ * Move server that did not work to end of queue in sres cache
+ *
+ * the next request does not try to use the server that is currently down
+ *
+ * @TODO: fix cases with only A or AAAA answering, or all servers down.
+ */
+ else if (sr && sr->sr_target) {
+ struct sipdns_query *sq;
+
+ /* find latest A/AAAA record */
+ sq = sr->sr_head;
+ if (!sq || (sr->sr_a_aaaa1 != sr->sr_a_aaaa2 && sq->sq_type == sr->sr_a_aaaa1))
+ sq = sr->sr_done;
+
+ if (sq && sq->sq_otype == sres_type_srv) {
+ char const *target = sq->sq_domain, *proto = sq->sq_proto;
+ unsigned prio = sq->sq_priority, maxprio = prio;
+
+ SU_DEBUG_5(("nta: no response from %s:%s;transport=%s\n", target, sq->sq_port, proto));
+
+ for (sq = sr->sr_head; sq; sq = sq->sq_next)
+ if (sq->sq_otype == sres_type_srv && sq->sq_priority > maxprio)
+ maxprio = sq->sq_priority;
+
+ for (sq = sr->sr_done; sq; sq = sq->sq_next)
+ if (sq->sq_otype == sres_type_srv && sq->sq_priority > maxprio)
+ maxprio = sq->sq_priority;
+
+ for (sq = sr->sr_done; sq; sq = sq->sq_next) {
+ int modified;
+
+ if (sq->sq_type != sres_type_srv || strcmp(proto, sq->sq_proto))
+ continue;
+
+ /* modify the SRV record(s) corresponding to the latest A/AAAA record */
+ modified = sres_set_cached_srv_priority(
+ orq->orq_agent->sa_resolver,
+ sq->sq_domain,
+ target,
+ sq->sq_port[0] ? (uint16_t)strtoul(sq->sq_port, NULL, 10) : 0,
+ orq->orq_agent->sa_graylist,
+ maxprio + 1);
+
+ if (modified >= 0)
+ SU_DEBUG_3(("nta: reduced priority of %d %s SRV records (increase value to %u)\n",
+ modified, sq->sq_domain, maxprio + 1));
+ else
+ SU_DEBUG_3(("nta: failed to reduce %s SRV priority\n", sq->sq_domain));
+ }
+ }
+ }
+
return outgoing_resolve_next(orq);
}
sq = su_zalloc(home, (sizeof *sq) + rlen);
*tail = sq, tail = &sq->sq_next;
+ sq->sq_otype = sres_type_naptr;
sq->sq_priority = na->na_prefer;
sq->sq_weight = j;
sq->sq_type = type;
if (sq) {
*tail = sq, tail = &sq->sq_next;
+ sq->sq_otype = sres_type_srv;
sq->sq_type = sr->sr_a_aaaa1;
sq->sq_proto = sq0->sq_proto;
sq->sq_domain = memcpy(sq + 1, srv->srv_target, tlen);
snprintf(sq->sq_port, sizeof(sq->sq_port), "%u", srv->srv_port);
-
sq->sq_priority = srv->srv_priority;
sq->sq_weight = srv->srv_weight;
}
if ((leg = leg_find(irq->irq_agent,
method_name, url,
sip->sip_call_id,
- sip->sip_from->a_tag, sip->sip_from->a_url,
- sip->sip_to->a_tag, sip->sip_to->a_url))) {
+ sip->sip_from->a_tag,
+ sip->sip_to->a_tag))) {
/* Use existing dialog */
SU_DEBUG_5(("nta: %s (%u) %s\n",
method_name, sip->sip_cseq->cs_seq,
/** SIP timer C - interval between provisional responses receivedxs */
unsigned sa_timer_c;
+ /** Graylisting period */
+ unsigned sa_graylist;
/** Blacklisting period */
unsigned sa_blacklist;
*/
tag_typedef_t ntatag_timer_c = UINTTAG_TYPEDEF(timer_c);
+/**@def NTATAG_GRAYLIST(x)
+ *
+ * Avoid failed servers.
+ *
+ * The NTATAG_GRAYLIST() provides the time that the servers are avoided
+ * after a request sent to them has been failed. Avoiding means that if a
+ * domain provides multiple servers, the failed servers are tried last.
+ *
+ * @par Used with
+ * nua_create(), nua_set_params(),
+ * nta_agent_create(), nta_agent_set_params()
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Number of seconds that server is kept in graylist, from 0 to 86400.
+ *
+ * @par Default Value
+ * - 600 (graylist server for 10 minutes)
+ *
+ * @sa NTATAG_BLACKLIST(), NTATAG_TIMEOUT_408()
+ */
+tag_typedef_t ntatag_graylist = UINTTAG_TYPEDEF(graylist);
+
/**@def NTATAG_BLACKLIST(x)
*
* Add Retry-After header to error responses returned to application.
* unsigned int
*
* @par Values
- * - Value of delta-seconds in @RetryAfter header
+ * - Value of @i delta-seconds in @RetryAfter header, from 0 to 86400
*
* @par Default Value
* - 0 (no Retry-After is included)
NTA_DLL extern tag_typedef_t ntatag_timer_c_ref;
#define NTATAG_TIMER_C_REF(x) ntatag_timer_c_ref, tag_uint_vr(&(x))
+NTA_DLL extern tag_typedef_t ntatag_graylist;
+#define NTATAG_GRAYLIST(x) ntatag_graylist, tag_uint_v((x))
+
+NTA_DLL extern tag_typedef_t ntatag_graylist_ref;
+#define NTATAG_GRAYLIST_REF(x) ntatag_graylist_ref, tag_uint_vr(&(x))
+
NTA_DLL extern tag_typedef_t ntatag_blacklist;
#define NTATAG_BLACKLIST(x) ntatag_blacklist, tag_uint_v((x))
return 200;
}
+static client_check_f client_check_to_tag;
-static client_check_f * const default_checks[];
+static client_check_f * const default_checks[] = {
+ client_check_to_tag,
+ NULL
+};
+
+static client_check_f * const no_default_checks[] = {
+ NULL
+};
int outgoing_callback(client_t *ctx,
nta_outgoing_t *orq,
}
-static client_check_f * const default_checks[] = {
- client_check_to_tag,
- NULL
-};
-
-static client_check_f * const no_default_checks[] = {
- NULL
-};
/* Test transports */
END();
}
-/* Test merging */
+static ssize_t recv_udp(agent_t *ag, void *b, size_t size)
+{
+ ssize_t n;
+ memset(b, size, 0);
+
+ for (;;) {
+ su_root_step(ag->ag_root, 10L);
+ if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
+ n = su_recv(ag->ag_sink_socket, b, size, MSG_TRUNC);
+ if (n > 0)
+ return n;
+ }
+ }
+}
+
+/* Test merging */
int test_merging(agent_t *ag)
{
BEGIN();
size_t len, l1, l2;
su_sockaddr_t *su = ag->ag_su_nta;
socklen_t sulen = ag->ag_su_nta_len;
- int n;
+
+#ifndef MSG_TRUNC
+#define MSG_TRUNC 0
+#endif
/* Empty sink socket */
- while (su_wait(ag->ag_sink_wait, 1, 0) == 0)
- su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC);
+ su_setblocking(ag->ag_sink_socket, 0);
+ while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0)
+ ;
+ su_wait(ag->ag_sink_wait, 1, 0);
+ su_wait(ag->ag_sink_wait, 1, 0);
{
/* RFC 3261 8.2.2.2 Merged Requests:
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1);
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2);
- for (n = 0; n < 2; ) {
- su_root_step(ag->ag_root, 10L);
- if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
- if (n == 0)
- su_recv(ag->ag_sink_socket, r1, sizeof r1, MSG_TRUNC);
- else
- su_recv(ag->ag_sink_socket, r2, sizeof r2, MSG_TRUNC);
- n++;
- }
- }
+ recv_udp(ag, r1, sizeof r1);
+ recv_udp(ag, r2, sizeof r2);
+
len = strlen("SIP/2.0 200 ");
TEST_1(memcmp(r1, "SIP/2.0 200 ", len) == 0);
TEST_1(memcmp(r2, "SIP/2.0 482 ", len) == 0);
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
}
+ while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0)
+ ;
+
{
/*
* Check that request with same call-id, cseq and from-tag
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1);
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2);
- for (n = 0; n < 2; ) {
- su_root_step(ag->ag_root, 10L);
- if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
- if (n == 0)
- su_recv(ag->ag_sink_socket, r1, sizeof r1, MSG_TRUNC);
- else
- su_recv(ag->ag_sink_socket, r2, sizeof r2, MSG_TRUNC);
- n++;
- }
- }
+ recv_udp(ag, r1, sizeof r1);
+ recv_udp(ag, r2, sizeof r2);
len = strlen("SIP/2.0 200 ");
TEST_1(memcmp(r1, "SIP/2.0 200 ", len) == 0);
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
}
+ while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0)
+ ;
+
{
/* test with rfc2543 */
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1);
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2);
- for (n = 0; n < 2; ) {
- su_root_step(ag->ag_root, 10L);
- if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
- if (n == 0)
- su_recv(ag->ag_sink_socket, r1, sizeof r1, MSG_TRUNC);
- else
- su_recv(ag->ag_sink_socket, r2, sizeof r2, MSG_TRUNC);
- n++;
- }
- }
+ recv_udp(ag, r1, sizeof r1);
+ recv_udp(ag, r2, sizeof r2);
+
l1 = strlen("SIP/2.0 200 ");
TEST_1(memcmp(r1, "SIP/2.0 200 ", l1) == 0);
TEST_1(memcmp(r2, "SIP/2.0 482 ", l1) == 0);
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
}
+ while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0)
+ ;
+
{
/* test with to-tag */
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1);
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2);
- for (n = 0; n < 2; ) {
- su_root_step(ag->ag_root, 10L);
- if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
- if (n == 0)
- su_recv(ag->ag_sink_socket, r1, sizeof r1, MSG_TRUNC);
- else
- su_recv(ag->ag_sink_socket, r2, sizeof r2, MSG_TRUNC);
- n++;
- }
- }
+ recv_udp(ag, r1, sizeof r1);
+ recv_udp(ag, r2, sizeof r2);
+
l1 = strlen("SIP/2.0 200 ");
TEST_1(memcmp(r1, "SIP/2.0 200 ", l1) == 0);
TEST_1(memcmp(r2, "SIP/2.0 482 ", l1) != 0);
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
}
+ while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0)
+ ;
+
{
/* test with rfc2543 and to-tag */
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1);
TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2);
- for (n = 0; n < 2; ) {
- su_root_step(ag->ag_root, 10L);
- if (su_wait(ag->ag_sink_wait, 1, 0) == 0) {
- if (n == 0)
- su_recv(ag->ag_sink_socket, r1, sizeof r1, MSG_TRUNC);
- else
- su_recv(ag->ag_sink_socket, r2, sizeof r2, MSG_TRUNC);
- n++;
- }
- }
+ recv_udp(ag, r1, sizeof r1);
+ recv_udp(ag, r2, sizeof r2);
+
l1 = strlen("SIP/2.0 200 ");
TEST_1(memcmp(r1, "SIP/2.0 200 ", l1) == 0);
TEST_1(memcmp(r2, "SIP/2.0 482 ", l1) != 0);
TEST_P(leg = nta_leg_by_dialog(nta, (url_t *)"sip:pc.al.us", i,
"xyzzy", a2->a_url, a1->a_tag, a1->a_url),
dialog1);
+#if nomore
/* remote url is required */
TEST_P(leg = nta_leg_by_dialog(nta, (url_t *)"sip:pc.al.us", i,
a2->a_tag, a1->a_url, a1->a_tag, a1->a_url),
NULL);
+#endif
TEST_P(leg = nta_leg_by_dialog(nta, (url_t *)"sip:pc.al.us", i,
a2->a_tag, NULL, a1->a_tag, a1->a_url),
dialog1);
- /* local url is used if there is no local tag */
+ /* local url is used if there is no local tag */ /* XXX - not really */
TEST_P(leg = nta_leg_by_dialog(nta, (url_t *)"sip:pc.al.us", i,
a2->a_tag, a2->a_url, NULL, NULL),
NULL);
}
}
+/** Remove dialog information. */
+int nua_dialog_zap(nua_owner_t *own,
+ nua_dialog_state_t *ds)
+{
+ /* zap peer info */
+ nua_dialog_store_peer_info(own, ds, NULL);
+ /* Local Contact */
+ msg_header_free(own, (msg_header_t *)ds->ds_ltarget), ds->ds_ltarget = NULL;
+ /* Leg */
+ nta_leg_destroy(ds->ds_leg), ds->ds_leg = NULL;
+ /* Remote tag */
+ su_free(own, (void *)ds->ds_remote_tag), ds->ds_remote_tag = NULL;
+ /* Ready to set route/remote target */
+ ds->ds_route = 0;
+
+ return 0;
+}
+
/** Remove dialog (if there is no other usages). */
int nua_dialog_remove(nua_owner_t *own,
nua_dialog_state_t *ds,
nua_dialog_usage_t *usage)
{
if (ds->ds_usage == usage && (usage == NULL || usage->du_next == NULL)) {
- nua_dialog_store_peer_info(own, ds, NULL); /* zap peer info */
- msg_header_free(own, (msg_header_t *)ds->ds_ltarget), ds->ds_ltarget = NULL;
- nta_leg_destroy(ds->ds_leg), ds->ds_leg = NULL;
- su_free(own, (void *)ds->ds_remote_tag), ds->ds_remote_tag = NULL;
- ds->ds_route = 0;
+ return nua_dialog_zap(own, ds);
}
return 0;
}
-
/** @internal Get dialog usage slot. */
nua_dialog_usage_t **
nua_dialog_usage_at(nua_dialog_state_t const *ds,
sip_t const *sip, int rtag);
void nua_dialog_store_peer_info(nua_owner_t *, nua_dialog_state_t *ds,
sip_t const *sip);
+int nua_dialog_zap(nua_owner_t *own,
+ nua_dialog_state_t *ds);
int nua_dialog_remove(nua_owner_t *own,
nua_dialog_state_t *ds,
nua_dialog_usage_t *usage);
int nua_client_init_request(nua_client_request_t *cr);
+msg_t *nua_client_request_template(nua_client_request_t *cr);
+
int nua_client_restart_request(nua_client_request_t *cr,
int terminating,
tagi_t const *tags);
nua_stack_event(nua, nh, NULL, e, SIP_200_OK, NULL);
}
else {
- nua_stack_event(nua, nh, NULL, e, NUA_INTERNAL_ERROR, NULL);
+ nua_stack_event(nua, nh, NULL, e, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
}
}
return;
}
- nua_stack_tevent(nh->nh_nua, nh, NULL, e, NUA_INTERNAL_ERROR,
+ nua_stack_tevent(nh->nh_nua, nh, NULL, e, NUA_ERROR_AT(__FILE__, __LINE__),
NUTAG_SUBSTATE(nua_substate_terminated),
TAG_END());
if (!ex || ex->ex_delta == 0)
SET_STATUS(900, "Received Invalid Expiration Time");
else
- SET_STATUS1(NUA_INTERNAL_ERROR);
+ SET_STATUS1(NUA_ERROR_AT(__FILE__, __LINE__));
}
else
nua_dialog_usage_set_refresh(du, ex->ex_delta);
}
nua_stack_event(nh->nh_nua, nh, NULL,
- nua_r_publish, NUA_INTERNAL_ERROR,
+ nua_r_publish, NUA_ERROR_AT(__FILE__, __LINE__),
NULL);
nua_dialog_usage_remove(nh, ds, du);
}
/* Report that we have de-registered */
- nua_stack_event(nua, nh, NULL, nua_r_register, NUA_INTERNAL_ERROR, NULL);
+ nua_stack_event(nua, nh, NULL, nua_r_register, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
nua_dialog_usage_remove(nh, ds, du);
}
assert(cr->cr_orq);
+
if (!ds->ds_leg) {
- nta_outgoing_destroy(cr->cr_orq);
- return -1;
+ /* XXX - fix nua_dialog_usage_remove_at() instead! */
+ nta_outgoing_destroy(cr->cr_orq);
+ return -1;
}
+ assert(ds->ds_leg);
msg = nta_outgoing_getrequest(cr->cr_orq);
sip = sip_object(msg);
}
if (error < 0) {
- nua_stack_event(nh->nh_nua, nh, NULL, event, NUA_INTERNAL_ERROR, NULL);
+ nua_stack_event(nh->nh_nua, nh, NULL, event, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
}
su_msg_destroy(nua->nua_signal);
cr->cr_waiting = cr->cr_wait_for_cred = 0;
if (status < 0)
- nua_client_response(cr, 900, "Cannot add credentials", NULL);
+ nua_client_response(cr, 900, "Operation cannot add credentials", NULL);
else
- nua_client_response(cr, 904, "No matching challenge", NULL);
+ nua_client_response(cr, 904, "Operation has no matching challenge ", NULL);
}
else if (status < 0) {
nua_stack_event(nua, nh, NULL, e, 900, "Cannot add credentials", NULL);
return nua_stack_event(nh->nh_nua, nh,
NULL,
event,
- NUA_INTERNAL_ERROR,
+ NUA_ERROR_AT(__FILE__, __LINE__),
NULL);
}
}
if (du->du_cr && cr != du->du_cr) {
-
+ /* This should never happen (but it does):
+ assert(!nua_client_is_queued(du->du_cr));
+ */
if (nua_client_is_queued(du->du_cr))
return -1;
if (nua_client_is_reporting(du->du_cr)) {
int error = 0;
if (!cr->cr_method_name)
- return nua_client_return(cr, NUA_INTERNAL_ERROR, NULL);
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
if (cr->cr_msg)
return nua_client_request_try(cr);
}
if (!cr->cr_methods->crm_template ||
- !cr->cr_methods->crm_template(cr, &msg, cr->cr_tags))
- msg = nta_msg_create(nua->nua_nta, 0);
+ cr->cr_methods->crm_template(cr, &msg, cr->cr_tags) == 0)
+ msg = nua_client_request_template(cr);
sip = sip_object(msg);
if (!sip)
- return nua_client_return(cr, NUA_INTERNAL_ERROR, msg);
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
+
+ if (nh->nh_tags) {
+ for (t = nh->nh_tags; t; t = t_next(t)) {
+ if (t->t_tag == siptag_contact ||
+ t->t_tag == siptag_contact_str)
+ has_contact = 1;
+ else if (t->t_tag == nutag_url)
+ url = (url_string_t const *)t->t_value;
+ }
+ }
/**@par Populating SIP Request Message with Tagged Arguments
*
* However, if a tag value is #SIP_NONE (-1 casted as a void pointer),
* the values from previous tags are ignored.
*/
- if (nh->nh_tags) {
- for (t = nh->nh_tags; t; t = t_next(t)) {
- if (t->t_tag == siptag_contact ||
- t->t_tag == siptag_contact_str)
- has_contact = 1;
- else if (t->t_tag == nutag_url)
- url = (url_string_t const *)t->t_value;
- }
-
- 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) {
- 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)
if ((t = cr->cr_tags)) {
if (sip_add_tagis(msg, sip, &t) < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
}
/**
if (!ds->ds_leg) {
if (ds->ds_remote_tag && ds->ds_remote_tag[0] &&
sip_to_tag(nh->nh_home, sip->sip_to, ds->ds_remote_tag) < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
if (sip->sip_from == NULL &&
sip_add_dup(msg, sip, (sip_header_t *)nua->nua_from) < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
if (cr->cr_dialog) {
ds->ds_leg = nta_leg_tcreate(nua->nua_nta,
SIPTAG_CSEQ(sip->sip_cseq),
TAG_END());
if (!ds->ds_leg)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
if (!sip->sip_from->a_tag &&
sip_from_tag(msg_home(msg), sip->sip_from,
nta_leg_tag(ds->ds_leg, NULL)) < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
}
}
else {
}
if (url && nua_client_set_target(cr, (url_t *)url) < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
cr->cr_has_contact = has_contact;
if (error < -1)
msg = NULL;
if (error < 0)
- goto error;
+ return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
if (error != 0)
return error;
}
return nua_client_request_try(cr);
- error:
- return nua_client_return(cr, NUA_INTERNAL_ERROR, msg);
+}
+
+msg_t *nua_client_request_template(nua_client_request_t *cr)
+{
+ nua_handle_t *nh = cr->cr_owner;
+ nua_t *nua = nh->nh_nua;
+ nua_dialog_state_t *ds = nh->nh_ds;
+
+ msg_t *msg = nta_msg_create(nua->nua_nta, 0);
+ sip_t *sip = sip_object(msg);
+
+ if (!sip)
+ return NULL;
+
+ if (nh->nh_tags) {
+ tagi_t const *t = nh->nh_tags;
+
+ /* Use the From header from the dialog.
+ From is always first tag in the handle */
+ if (ds->ds_leg && t->t_tag == siptag_from)
+ t++;
+
+ /* When the INVITE message (or any other SIP message) is
+ * created, the tagged values saved with nua_handle() are used first. */
+ sip_add_tagis(msg, sip, &t);
+ }
+
+ return msg;
}
return nua_client_request_try(cr);
}
+
return 0;
}
}
if (error < 0)
- error = nua_client_response(cr, NUA_INTERNAL_ERROR, NULL);
+ error = nua_client_response(cr, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
assert(error > 0);
return error;
while (sip->sip_route)
sip_route_remove(msg, sip);
}
+ else if (!ds->ds_route) {
+ sip_route_t *initial_route = NH_PGET(nh, initial_route);
+
+ if (initial_route) {
+ initial_route = sip_route_dup(msg_home(msg), initial_route);
+ if (!initial_route) return -1;
+ msg_header_prepend(msg, (msg_pub_t*)sip,
+ /* This should be
+ (msg_header_t **)&sip->sip_route
+ * but directly casting pointer &sip->sip_route gives
+ * spurious type-punning warning */
+ (msg_header_t **)((char *)sip + offsetof(sip_t, sip_route)),
+ (msg_header_t *)initial_route);
+ }
+ }
+
/**
* For in-dialog requests, the request URI is taken from the @Contact
switch (status) {
case 302:
- if (nua_client_set_target(cr, sip->sip_contact->m_url) >= 0)
+ if (nua_dialog_zap(nh, nh->nh_ds) == 0 &&
+ nua_client_set_target(cr, sip->sip_contact->m_url) >= 0)
return nua_client_restart(cr, 100, "Redirected");
break;
case 305:
sip_route_init(r);
*r->r_url = *sip->sip_contact->m_url;
- if (sip_add_dup(cr->cr_msg, cr->cr_sip, (sip_header_t *)r) >= 0)
+ if (nua_dialog_zap(nh, nh->nh_ds) == 0 &&
+ sip_add_dup(cr->cr_msg, cr->cr_sip, (sip_header_t *)r) >= 0)
return nua_client_restart(cr, 100, "Redirected via a proxy");
break;
int status, char const *phrase)
{
nua_handle_t *nh = cr->cr_owner;
+ nua_dialog_state_t *ds = nh->nh_ds;
nta_outgoing_t *orq;
int error = -1, terminated, graceful;
- msg_t *msg;
- sip_t *sip;
+ msg_t *msg = NULL;
+ sip_t *sip = NULL;
if (cr->cr_retry_count > NH_PGET(nh, retry_count))
return 0;
orq = cr->cr_orq, cr->cr_orq = NULL; assert(orq);
terminated = cr->cr_terminated, cr->cr_terminated = 0;
graceful = cr->cr_graceful, cr->cr_graceful = 0;
+ cr->cr_offer_sent = cr->cr_answer_recv = 0;
+ cr->cr_offer_recv = cr->cr_answer_sent = 0;
- msg = msg_copy(cr->cr_msg);
- sip = sip_object(msg);
+ if (!ds->ds_leg && cr->cr_dialog) {
+ sip_t const *sip = cr->cr_sip;
+ ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta,
+ nua_stack_process_request, nh,
+ SIPTAG_CALL_ID(sip->sip_call_id),
+ SIPTAG_FROM(sip->sip_from),
+ SIPTAG_TO(sip->sip_to),
+ SIPTAG_CSEQ(sip->sip_cseq),
+ TAG_END());
+ }
+
+ if (ds->ds_leg || !cr->cr_dialog) {
+ msg = msg_copy(cr->cr_msg);
+ sip = sip_object(msg);
+ }
if (msg && sip) {
cr->cr_restarting = 1;
extern char const nua_internal_error[];
#define NUA_INTERNAL_ERROR 900, nua_internal_error
+#define NUA_ERROR_AT(file, line) 900, "Internal error at " file ":" #line
struct nua_s {
su_home_t nua_home[1];
if (!eu->eu_unsolicited)
nua_stack_tevent(nh->nh_nua, nh, NULL,
- nua_i_notify, NUA_INTERNAL_ERROR,
+ nua_i_notify, NUA_ERROR_AT(__FILE__, __LINE__),
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_EVENT(du->du_event),
TAG_END());
tagi_t const *tags)
{
nua_handle_t *nh = cr->cr_owner;
- nua_dialog_usage_t *du = cr->cr_usage;
+ nua_dialog_usage_t *du, *du0 = cr->cr_usage;
struct event_usage *eu;
sip_event_t *event;
int error;
cr->cr_usage = NULL;
- if (du)
- nua_dialog_usage_remove(nh, nh->nh_ds, du);
-
event = sip_event_format(nh->nh_home, "refer;id=%u", sip->sip_cseq->cs_seq);
if (!event)
return -1;
- du = nua_dialog_usage_add(nh, nh->nh_ds, nua_subscribe_usage, event);
- if (!du)
- return -1;
+
+ if (du0 == NULL ||
+ du0->du_event == NULL ||
+ du0->du_event->o_id == NULL ||
+ strcmp(du0->du_event->o_id, event->o_id)) {
+ du = nua_dialog_usage_add(nh, nh->nh_ds, nua_subscribe_usage, event);
+ if (!du)
+ return -1;
+ }
+ else {
+ du = du0, du0 = NULL;
+ }
+
+ if (du0)
+ nua_dialog_usage_remove(nh, nh->nh_ds, du0);
eu = nua_dialog_usage_private(cr->cr_usage = du);
eu ->eu_refer = 1;
END();
}
+
+int test_update_failure(struct context *ctx)
+{
+ BEGIN();
+#if 0
+ struct endpoint *a = &ctx->a, *b = &ctx->b;
+ struct call *a_call = a->call, *b_call = b->call;
+ struct event *e, *eu, *ei;
+ enum nua_callstate ustate, istate;
+
+ if (print_headings)
+ printf("TEST NUA-10.4.1: UPDATE failure terminating session\n");
+
+/* Test UPDATE failing:
+
+ A B
+ |-------INVITE------>|
+ |<----100 Trying-----|
+ | |
+ |<-------183---------|
+ |-------PRACK------->|
+ |<-------200---------|
+ | |
+ |<-------180---------|
+ | |
+ +------------------------+
+ |<------200 OK-------|
+ |-------UPDATE------>|
+ | |
+ |<-------481---------|
+ | |
+ |--------ACK-------->|
+ | |
+ |<-------BYE---------|
+ |-------200 OK-------|
+ | |
+
+*/
+
+ a_call->sdp = "m=audio 5008 RTP/AVP 8";
+ b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
+
+ nua_set_params(ctx->a.nua,
+ NUTAG_EARLY_MEDIA(1),
+ SIPTAG_SUPPORTED_STR("100rel, precondition, timer"),
+ TAG_END());
+ run_a_until(ctx, nua_r_set_params, until_final_response);
+
+ nua_set_params(ctx->b.nua,
+ NUTAG_EARLY_MEDIA(1),
+ NUTAG_ONLY183_100REL(1),
+ SIPTAG_SUPPORTED_STR("100rel, precondition, timer"),
+ NUTAG_APPL_METHOD("UPDATE"),
+ TAG_END());
+ run_b_until(ctx, nua_r_set_params, until_final_response);
+
+ TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
+
+ INVITE(a, a_call, a_call->nh,
+ TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
+ SOATAG_USER_SDP_STR(a_call->sdp),
+ SIPTAG_SUPPORTED_STR("100rel"),
+ TAG_END());
+
+ run_ab_until(ctx, -1, save_until_final_response, -1, until_pracked);
+
+ /* Client transitions:
+ INIT -(C1)-> CALLING: nua_invite(), nua_i_state
+ CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state
+ PROCEEDING -(C3+C4)-> READY: nua_r_invite, nua_i_state
+ */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
+ TEST_1(is_offer_sent(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 183);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ /* Offer is sent in PRACK */
+ TEST_1(is_offer_sent(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_prack);
+ TEST(e->data->e_status, 200);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST_1(!is_offer_sent(e->data->e_tags));
+
+ /* Send UPDATE */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
+ TEST_1(!is_answer_recv(e->data->e_tags));
+ TEST_1(is_offer_sent(e->data->e_tags));
+
+ /* The final response to the UPDATE and INVITE can be received in any order */
+ eu = event_by_type(e->next, nua_r_update);
+ ei = event_by_type(e->next, nua_r_invite);
+
+ TEST_1(e = eu); TEST_E(e->data->e_event, nua_r_update);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ ustate = callstate(e->data->e_tags);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST_1(!is_offer_sent(e->data->e_tags));
+
+ TEST_1(e = ei); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 180);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ /* Final response to INVITE */
+ TEST_1(ei = event_by_type(ei->next, nua_r_invite));
+
+ TEST_E(ei->data->e_event, nua_r_invite); TEST(ei->data->e_status, 200);
+ TEST_1(e = ei->next); TEST_E(e->data->e_event, nua_i_state);
+ istate = callstate(e->data->e_tags);
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ if (eu == e->next) {
+ /* 200 OK to UPDATE is received after 200 OK to INVITE */
+ TEST(ustate, nua_callstate_ready);
+ TEST(istate, nua_callstate_completing);
+ }
+ else {
+ /* 200 OK to UPDATE is received before 200 OK to INVITE */
+ TEST(ustate, nua_callstate_proceeding);
+ TEST(istate, nua_callstate_ready);
+ }
+
+ free_events_in_list(ctx, a->events);
+
+ /*
+ Server transitions:
+ INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
+ RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
+ EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
+ COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
+ TEST(e->data->e_status, 100);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
+
+ /* Responded with 183 Session Progress */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_answer_sent(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_prack);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_offer_recv(e->data->e_tags));
+ TEST_1(is_answer_sent(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_update);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_offer_recv(e->data->e_tags));
+ TEST_1(is_answer_sent(e->data->e_tags));
+
+ /* Responded with 180 Ringing */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ /* Responded with 200 OK */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ if (print_headings)
+ printf("TEST NUA-10.4.1: PASSED\n");
+
+ if (print_headings)
+ printf("TEST NUA-10.4.2: terminate call\n");
+
+ BYE(b, b_call, b_call->nh, TAG_END());
+ run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
+
+ /* B transitions:
+ READY --(T2)--> TERMINATING: nua_bye()
+ TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_bye);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ /* A: READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_bye);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, a->events);
+
+ nua_handle_destroy(a_call->nh), a_call->nh = NULL;
+ nua_handle_destroy(b_call->nh), b_call->nh = NULL;
+
+ if (print_headings)
+ printf("TEST NUA-10.4.2: PASSED\n");
+#endif
+ END();
+}
int cancel_when_pracked(CONDITION_PARAMS);
int alert_call(CONDITION_PARAMS);
END();
}
+int redirect_pracked(CONDITION_PARAMS);
+
+int test_180rel_redirected(struct context *ctx)
+{
+ BEGIN();
+
+ struct endpoint *a = &ctx->a, *b = &ctx->b;
+ struct call *a_call = a->call, *b_call = b->call;
+ struct event *e, *ep, *ei;
+ sip_t *sip;
+
+ if (print_headings)
+ printf("TEST NUA-10.8.1: Call with 100rel and 180\n");
+
+/* Test for 100rel:
+
+ A B
+ |-------INVITE------>|
+ |<----100 Trying-----|
+ | |
+ |<-------180---------|
+ |-------PRACK------->|
+ |<-------200---------|
+ | |
+ |<----302 Moved------|
+ |--------ACK-------->|
+ | |
+ |-------INVITE------>|
+ |<----100 Trying-----|
+ | |
+ |<-------180---------|
+ |-------PRACK------->|
+ |<-------200---------|
+ | |
+ |<------200 OK-------|
+ |--------ACK-------->|
+ | |
+ |<-------BYE---------|
+ |-------200 OK-------|
+ | |
+
+*/
+
+ a_call->sdp = "m=audio 5008 RTP/AVP 8";
+ b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
+
+ nua_set_params(ctx->a.nua,
+ NUTAG_EARLY_MEDIA(1),
+ TAG_END());
+ run_a_until(ctx, nua_r_set_params, until_final_response);
+
+ nua_set_params(ctx->b.nua,
+ NUTAG_EARLY_MEDIA(1),
+ NUTAG_SESSION_TIMER(180),
+ TAG_END());
+ run_b_until(ctx, nua_r_set_params, until_final_response);
+
+ TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
+
+ INVITE(a, a_call, a_call->nh,
+ TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
+ SOATAG_USER_SDP_STR(a_call->sdp),
+ TAG_END());
+
+ run_ab_until(ctx, -1, until_ready, -1, redirect_pracked);
+
+ /* Client transitions:
+ INIT -(C1)-> CALLING: nua_invite(), nua_i_state
+ CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state, nua_r_prack
+ PROCEEDING->(redirected)->CALLING: nua_r_invite, nua_i_state
+ CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state, nua_r_prack
+ PROCEEDING -(C3+C4)-> READY: nua_r_invite, nua_i_state
+ */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
+ TEST_1(is_offer_sent(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 180);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST_1(!is_offer_sent(e->data->e_tags));
+
+ ei = event_by_type(e->next, nua_r_invite); /* 302 */
+ ep = event_by_type(e->next, nua_r_prack); /* 200 */
+ if (!ep) {
+ run_a_until(ctx, -1, save_until_final_response);
+ ep = event_by_type(e->next, nua_r_prack);
+ }
+
+ TEST_1(e = ep); TEST_E(e->data->e_event, nua_r_prack);
+ TEST(e->data->e_status, 200);
+
+ TEST_1(e = ei); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 100);
+ TEST_1(sip = sip_object(e->data->e_msg));
+ TEST(sip->sip_status->st_status, 302);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 180);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST_1(!is_offer_sent(e->data->e_tags));
+
+ ei = event_by_type(e->next, nua_r_invite);
+ ep = event_by_type(e->next, nua_r_prack);
+ if (!ep) {
+ run_a_until(ctx, -1, save_until_final_response);
+ ep = event_by_type(e->next, nua_r_prack);
+ }
+
+ TEST_1(e = ep); TEST_E(e->data->e_event, nua_r_prack);
+ TEST(e->data->e_status, 200);
+
+ TEST_1(e = ei); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 200);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ TEST_1(!e->next || !ep->next);
+ free_events_in_list(ctx, a->events);
+
+ /*
+ Server transitions:
+ INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
+ RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
+ EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
+ COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
+ TEST(e->data->e_status, 100);
+ 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));
+
+ /* Responded with 180 Ringing */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_answer_sent(e->data->e_tags));
+
+ /* 180 is PRACKed */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_prack);
+ /* 302 terminates call */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* Terminated */
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_invite);
+ TEST(e->data->e_status, 100);
+ 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));
+
+ /* Responded with 180 Ringing */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_answer_sent(e->data->e_tags));
+
+ /* 180 is PRACKed */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_prack);
+ /* Does not have effect on call state */
+
+ /* Respond with 200 OK */
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!is_offer_answer_done(e->data->e_tags));
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ if (print_headings)
+ printf("TEST NUA-10.8.1: PASSED\n");
+
+ if (print_headings)
+ printf("TEST NUA-10.8.2: terminate call\n");
+
+ BYE(b, b_call, b_call->nh, TAG_END());
+ run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
+
+ /* B transitions:
+ READY --(T2)--> TERMINATING: nua_bye()
+ TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_bye);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ /* A: READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_bye);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, a->events);
+
+ nua_handle_destroy(a_call->nh), a_call->nh = NULL;
+ nua_handle_destroy(b_call->nh), b_call->nh = NULL;
+
+ if (print_headings)
+ printf("TEST NUA-10.8.2: PASSED\n");
+
+ END();
+}
+
+int redirect_pracked(CONDITION_PARAMS)
+{
+ if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
+ return 0;
+
+ save_event_in_list(ctx, event, ep, call);
+
+ if (event == nua_i_prack) {
+ if (!ep->flags.bit0) {
+ sip_contact_t m[1];
+
+ ep->flags.bit0 = 1;
+
+ *m = *ep->contact;
+ m->m_url->url_user = "302";
+ RESPOND(ep, call, nh, SIP_302_MOVED_TEMPORARILY, SIPTAG_CONTACT(m), TAG_END());
+ return 0;
+ }
+ else {
+ RESPOND(ep, call, nh, SIP_200_OK,
+ TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
+ TAG_END());
+ }
+ }
+
+
+ switch (callstate(tags)) {
+ case nua_callstate_received:
+ RESPOND(ep, call, nh, SIP_180_RINGING,
+ TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
+ TAG_END());
+ return 0;
+ case nua_callstate_ready:
+ return 1;
+ case nua_callstate_terminated:
+ if (call)
+ nua_handle_destroy(call->nh), call->nh = NULL;
+ return 0;
+ default:
+ return 0;
+ }
+}
int test_100rel(struct context *ctx)
{
int retval = 0;
-
+
retval = test_180rel(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_prack_auth(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_183rel(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_preconditions(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_preconditions2(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_update_by_uas(ctx); RETURN_ON_SINGLE_FAILURE(retval);
+ retval = test_update_failure(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_180rel_cancel1(ctx); RETURN_ON_SINGLE_FAILURE(retval);
retval = test_180rel_cancel2(ctx); RETURN_ON_SINGLE_FAILURE(retval);
+ retval = test_180rel_redirected(ctx); RETURN_ON_SINGLE_FAILURE(retval);
nua_set_params(ctx->a.nua,
NUTAG_EARLY_MEDIA(0),
int test_refer0(struct context *ctx, char const *tests,
int refer_with_id, int notify_by_appl);
-
int notify_until_terminated(CONDITION_PARAMS);
+int test_challenge_refer(struct context *ctx);
int test_refer(struct context *ctx)
{
/* test twice, once without id and once with id */
return
+ test_challenge_refer(ctx) ||
test_refer0(ctx, "NUA-9.1", 0, 0) ||
test_refer0(ctx, "NUA-9.2", 1, 0) ||
test_refer0(ctx, "NUA-9.3", 0, 1) ||
return 0;
}
}
+
+int authenticate_refer(CONDITION_PARAMS);
+int reject_refer_after_notified(CONDITION_PARAMS);
+
+int test_challenge_refer(struct context *ctx)
+{
+ BEGIN();
+
+ struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
+ struct call *a_call = a->call, *c_call = c->call;
+ struct event *e;
+ sip_t const *sip;
+
+ sip_refer_to_t r0[1];
+
+ if (!ctx->proxy_tests)
+ return 0;
+
+ if (print_headings)
+ printf("TEST NUA-9.0.1: challenge REFER\n");
+
+ nua_set_params(ctx->a.nua, NUTAG_APPL_METHOD("REFER"), TAG_END());
+ run_a_until(ctx, nua_r_set_params, until_final_response);
+
+ *sip_refer_to_init(r0)->r_url = *b->contact->m_url;
+ r0->r_url->url_headers = "subject=referred";
+ r0->r_display = "B";
+
+ TEST_1(c_call->nh = nua_handle(c->nua, c_call, SIPTAG_TO(a->to), TAG_END()));
+
+ REFER(c, c_call, c_call->nh,
+ SIPTAG_FROM(c->to),
+ SIPTAG_REFER_TO(r0),
+ TAG_END());
+
+ run_abc_until(ctx, -1, reject_refer_after_notified, -1, NULL, -1, authenticate_refer);
+
+ /*
+ Events in A:
+ nua_i_refer
+ */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_refer);
+ TEST(e->data->e_status, 100);
+ TEST_1(sip = sip_object(e->data->e_msg));
+ TEST_1(sip->sip_refer_to);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify);
+ TEST(e->data->e_status, 200);
+ TEST_1(!e->next);
+ /*
+ Events in C after nua_refer():
+ nua_r_refer
+ */
+ TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_refer);
+ TEST(e->data->e_status, 100);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_refer);
+ TEST(e->data->e_status, 407);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_refer);
+ TEST(e->data->e_status, 100);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify);
+ TEST(e->data->e_status, 200);
+
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_refer);
+ TEST(e->data->e_status, 480);
+
+ TEST_1(!e->next);
+
+ free_events_in_list(ctx, a->events);
+ free_events_in_list(ctx, c->events);
+
+ nua_handle_destroy(a_call->nh), a_call->nh = NULL;
+ nua_handle_destroy(c_call->nh), c_call->nh = NULL;
+
+ nua_set_params(ctx->a.nua,
+ NUTAG_APPL_METHOD(NULL),
+ NUTAG_APPL_METHOD("INVITE, REGISTER, PUBLISH, SUBSCRIBE"),
+ TAG_END());
+ run_a_until(ctx, nua_r_set_params, until_final_response);
+
+ if (print_headings)
+ printf("TEST NUA-9.0.1: PASSED\n");
+
+ END();
+}
+
+int reject_refer_after_notified(CONDITION_PARAMS)
+{
+ if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
+ return 0;
+
+ save_event_in_list(ctx, event, ep, call);
+
+ if (event == nua_i_refer) {
+ }
+
+ if (event == nua_r_notify) {
+ /* Respond to refer only after initial notify has been responded */
+ struct eventlist *list;
+ struct event *e;
+
+ if (call->events)
+ list = call->events;
+ else
+ list = ep->events;
+
+ for (e = list->head; e; e = e->next)
+ if (e->data->e_event == nua_i_refer)
+ break;
+
+ if (e) {
+ RESPOND(ep, call, nh, SIP_480_TEMPORARILY_UNAVAILABLE,
+ NUTAG_WITH(e->data->e_msg),
+ TAG_END());
+ return 1;
+ }
+ return 0;
+ }
+
+ return 0;
+}
+
+int authenticate_refer(CONDITION_PARAMS)
+{
+ if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
+ return 0;
+
+ save_event_in_list(ctx, event, ep, call);
+
+ if (status == 401 || status == 407) {
+ AUTHENTICATE(ep, call, nh,
+ NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"),
+ TAG_END());
+ }
+
+ return status == 480;
+}
*
* The parsed Alert-Info header is stored in #sip_alert_info_t structure.
*
- * @NEW_1_12_7. In order to use @b Alert-Info header,
- * initialize the SIP parser with, e.g.,
- * sip_update_default_mclass(sip_extend_mclass(NULL))
+ * @NEW_1_12_7. In order to use @b Alert-Info header, initialize the SIP
+ * parser before calling nta_agent_create() or nua_create() with, e.g.,
+ * sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * The #sip_t structure does not contain a @a sip_alert_info field, but
+ * sip_alert_info() function should be used for accessing the @b Alert-Info
+ * header structure.
*/
/**@ingroup sip_alert_info
* @sa sip_update_default_mclass()
*
* @NEW_1_12_7. In order to use @b Reply-To header,
- * initialize the SIP parser with, e.g.,
+ * initialize the SIP parser before calling nta_agent_create() or
+ * nua_create() with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t structure does not contain a @a sip_reply_to field, but
+ * sip_reply_to() function should be used for accessing the @b Reply-To
+ * header structure.
*/
/**@ingroup sip_reply_to
*
* @sa @RFC3265, draft-niemi-sip-subnot-etags-01.txt
*
- * @EXP_1_12_5. Note that #sip_t does not contain @a
+ * @EXP_1_12_5.
+ * In order to use @b Suppress-Body-If-Match header,
+ * initialize the SIP parser with, e.g.,
+ * sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t structure does not contain a @a
* sip_suppress_body_if_match field, but sip_suppress_body_if_match()
* function should be used for accessing the @b Suppress-Body-If-Match
* header structure.
*
* @sa @RFC3265, draft-niemi-sip-subnot-etag-01
*
- * @EXP_1_12_5. Note that #sip_t does not contain @a
- * sip_suppress_notify_if_match field, but sip_suppress_notify_if_match()
- * function should be used for accessing the @b Suppress-Notify-If-Match
- * header structure.
+ * @EXP_1_12_5.
+ * In order to use @b Suppress-Notify-If-Match header,
+ * initialize the SIP parser with, e.g.,
+ * sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t struct does not contain @a sip_suppress_notify_if_match field,
+ * but sip_suppress_notify_if_match() function should be used for accessing
+ * the @b Suppress-Notify-If-Match header structure.
*/
/**@ingroup sip_suppress_notify_if_match
* @sa sip_update_default_mclass(), draft-ietf-sip-privacy-04.txt, @RFC3325
*
* @NEW_1_12_7. In order to use @b Remote-Party-ID header,
- * initialize the SIP parser with, e.g.,
+ * initialize the SIP parser before calling nta_agent_create() or
+ * nua_create() with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t structure does not contain @a sip_remote_party_id field, but
+ * sip_remote_party_id() function should be used for accessing the @b
+ * Remote-Party-ID header structure.
*/
/**@ingroup sip_remote_party_id
* @sa @RFC3325, @PPreferredIdentity
*
* @NEW_1_12_7. In order to use @b P-Asserted-Identity header,
- * initialize the SIP parser with, e.g.,
+ * initialize the SIP parser before calling nta_agent_create() or
+ * nua_create() with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t structure does not contain @a sip_p_asserted_identity field,
+ * but sip_p_asserted_identity() function should be used for accessing the
+ * @b P-Asserted-Identity header structure.
*/
/**@ingroup sip_p_asserted_identity
* @sa @RFC3325, @PAssertedIdentity
*
* @NEW_1_12_7. In order to use @b P-Preferred-Identity header,
- * initialize the SIP parser with, e.g.,
+ * initialize the SIP parser before calling nta_agent_create() or
+ * nua_create() with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
+ *
+ * @note
+ * The #sip_t structure does not contain @a sip_p_preferred_identity field,
+ * but sip_p_preferred_identity() function should be used for accessing the
+ * @b P-Preferred-Identity header structure.
*/
/**@ingroup sip_p_preferred_identity
* @retval 0 when successful
* @retval -1 upon an error
*
+ * @sa sip_extend_mclass()
+ *
* @NEW_1_12_7.
*/
int sip_update_default_mclass(msg_mclass_t const *mclass)
/**Extend SIP parser class with extension headers.
*
* Extend given SIP parser class with extension headers. If the given parser
- * class is the default one or NULL, make a clone of it before extending it.
+ * (message class) is the default one or NULL, make a clone of default
+ * parser before extending it.
*
* @param input pointer to a SIP message class (may be NULL)
*
* @return Pointer to extended mclass, or NULL upon an error.
*
+ * @sa
+ * @AlertInfo,
+ * @ReplyTo,
+ * @RemotePartyId,
+ * @PAssertedIdentity,
+ * @PPreferredIdentity,
+ * @SuppressBodyIfMatch,
+ * @SuppressNotifyIfMatch
+ *
* @NEW_1_12_7.
*/
msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
* decide whether to gracefully terminate or not, the
* @a *return_graceful_terminate_usage is left unmodified.
*
- * @sa
- * http://www.ietf.org/internet-drafts/draft-ietf-sipping-dialogusage-02.txt
+ * @RFC 5057
*/
int sip_response_terminates_dialog(int response_code,
sip_method_t method,
usage in an existing dialog, no new usage is created and existing
usages are unaffected.
*/
- *return_graceful_terminate_usage = 0;
- return 0;
case 423: /** @par 423 Interval Too Brief
subscribe usage is not destroyed (or otherwise affected). No
other usages of the dialog are affected.
*/
- *return_graceful_terminate_usage = 0;
- return sip_method_subscribe == method ? terminate_usage : no_effect;
case 428: /** @par 428 Use Identity Header
the usage. The usage is not affected. The dialog is only
affected by a change in its local @CSeq. No other usages of the
dialog are affected. */
- *return_graceful_terminate_usage = 0;
- return 0;
case 429: /** @par 429 Provide Referrer Identity
static int test_identity(void)
{
su_home_t *home;
+ sip_alert_info_t *ai;
+ sip_reply_to_t *rplyto;
+ sip_remote_party_id_t *rpid;
sip_p_asserted_identity_t *paid;
sip_p_preferred_identity_t *ppid;
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
+ "Alert-Info: <http://test.com/tune>;walz, <http://test.com/buzz>\r\n"
+ "Reply-To: Arska <sip:arska@gov.ca.us>;humppa\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
+ "Remote-Party-ID: <sip:test2@test.domain.com>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
+ TEST_1(!sip_alert_info(sip));
+ TEST_1(!sip_reply_to(sip));
TEST_1(!sip_p_asserted_identity(sip));
TEST_1(!sip_p_preferred_identity(sip));
+ TEST_1(!sip_remote_party_id(sip));
msg_destroy(msg);
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
+ "Alert-Info: <http://test.com/tune>;walz, <http://test.com/buzz>\r\n"
+ "Reply-To: Arska <sip:arska@gov.ca.us>;humppa\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
+ "Remote-Party-ID: <sip:test2@test.domain.com>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
+ TEST_1(!sip_alert_info(sip));
+ TEST_1(!sip_reply_to(sip));
+ TEST_1(sip_p_asserted_identity(sip));
+ TEST_1(sip_p_preferred_identity(sip));
+ TEST_1(!sip_remote_party_id(sip));
+
TEST_1(home = msg_home(msg));
TEST_1((paid = sip_p_asserted_identity_make(home, "sip:joe@example.com")));
/* Now with extensions */
TEST_1(test_mclass = msg_mclass_clone(def1, 0, 0));
+ msg = read_message(MSG_DO_EXTRACT_COPY,
+ "BYE sip:foo@bar SIP/2.0\r\n"
+ "To: <sip:foo@bar>;tag=deadbeef\r\n"
+ "From: <sip:bar@foo>;\r\n"
+ "Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
+ "CSeq: 8 SUBSCRIBE\r\n"
+ "Via: SIP/2.0/UDP 135.180.130.133\r\n"
+ "Alert-Info: <http://test.com/tune>;walz, <http://test.com/buzz>\r\n"
+ "Reply-To: Arska <sip:arska@gov.ca.us>;humppa\r\n"
+ "P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
+ "P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
+ "Remote-Party-ID: <sip:test2@test.domain.com>\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n");
+
+ sip = sip_object(msg);
+
+ TEST_1(ai = sip_alert_info(sip));
+ TEST_S(ai->ai_url->url_host, "test.com");
+ TEST_1(rplyto = sip_reply_to(sip));
+ TEST_S(rplyto->rplyto_url->url_host, "gov.ca.us");
+ TEST_1(paid = sip_p_asserted_identity(sip));
+ TEST_1(ppid = sip_p_preferred_identity(sip));
+ TEST_1(rpid = sip_remote_party_id(sip));
+ TEST_S(rpid->rpid_url->url_host, "test.domain.com");
+
+ msg_destroy(msg);
+
{
su_home_t *home = su_home_clone(NULL, sizeof *home);
/* ======================================================================== */
/* Internal prototypes */
-void soa_set_activity(soa_session_t *ss,
- sdp_media_t const *,
- int remote);
-
su_inline int soa_media_is_ready(soa_session_t const *ss);
enum soa_sdp_kind {
if (!new_version)
return 0;
- soa_set_activity(ss, sdp->sdp_media, 1);
+ soa_set_activity(ss, sdp->sdp_media, soa_activity_remote);
ss->ss_remote_version++;
if (!sdp)
return -1;
- soa_set_activity(ss, sdp->sdp_media, 0);
+ soa_set_activity(ss, sdp->sdp_media, soa_activity_local); /* Wanted activity */
ss->ss_offer_sent = 1;
ss->ss_answer_recv = 0;
su_free(ss->ss_home, ss->ss_rsession);
ss->ss_rsession = rsession;
- soa_set_activity(ss, l_sdp->sdp_media, 0);
- soa_set_activity(ss, r_sdp->sdp_media, 1);
+ soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session);
ss->ss_offer_recv = 1;
ss->ss_answer_sent = 1;
su_free(ss->ss_home, ss->ss_rsession);
ss->ss_rsession = rsession;
- soa_set_activity(ss, l_sdp->sdp_media, 0);
- soa_set_activity(ss, r_sdp->sdp_media, 1);
+ soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session);
ss->ss_answer_recv = 1;
ss->ss_complete = 1;
if (!l_sdp)
return -1;
- soa_set_activity(ss, l_sdp->sdp_media, 0);
+ soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session);
ss->ss_offer_sent = 0;
ss->ss_oa_rounds = 0;
soa_description_free(ss, ss->ss_remote);
- soa_set_activity(ss, NULL, 0);
- soa_set_activity(ss, NULL, 1);
+ soa_set_activity(ss, NULL, soa_activity_session);
}
/** Return true if the SDP Offer/Answer negotation is complete.
void soa_set_activity(soa_session_t *ss,
sdp_media_t const *m,
- int remote)
+ enum soa_activity activity)
{
struct soa_media_activity *ma;
sdp_connection_t const *c;
- int mode;
- int ma_audio = SOA_ACTIVE_DISABLED;
- int ma_video = SOA_ACTIVE_DISABLED;
- int ma_chat = SOA_ACTIVE_DISABLED;
- int ma_image = SOA_ACTIVE_DISABLED;
- int *p;
-
- remote = !!remote;
+ int mode, swap;
+ int l_audio = SOA_ACTIVE_DISABLED, r_audio = SOA_ACTIVE_DISABLED;
+ int l_video = SOA_ACTIVE_DISABLED, r_video = SOA_ACTIVE_DISABLED;
+ int l_chat = SOA_ACTIVE_DISABLED, r_chat = SOA_ACTIVE_DISABLED;
+ int l_image = SOA_ACTIVE_DISABLED, r_image = SOA_ACTIVE_DISABLED;
- ma = remote ? ss->ss_remote_activity : ss->ss_local_activity;
+ int *l, *r;
for (; m; m = m->m_next) {
if (m->m_type == sdp_media_audio)
- p = &ma_audio;
+ l = &l_audio, r = &r_audio;
else if (m->m_type == sdp_media_video)
- p = &ma_video;
+ l = &l_video, r = &r_video;
else if (m->m_type == sdp_media_image)
- p = &ma_image;
+ l = &l_image, r = &r_image;
else if (strcasecmp(m->m_type_name, "message") == 0)
- p = &ma_chat;
+ l = &l_chat, r = &r_chat;
else
continue;
if (m->m_rejected) {
- if (*p < 0)
- *p = SOA_ACTIVE_REJECTED;
+ if (*l < 0) *l = SOA_ACTIVE_REJECTED;
+ if (*r < 0) *r = SOA_ACTIVE_REJECTED;
continue;
}
- mode = m->m_mode;
+ mode = m->m_mode, swap = ((mode << 1) & 2) | ((mode >> 1) & 1);
c = sdp_media_connections((sdp_media_t *)m);
- if (remote != (c && c->c_mcast))
- mode = ((mode << 1) & 2) | ((mode >> 1) & 1);
+ switch (activity) {
+ case soa_activity_local:
+ *l &= SOA_ACTIVE_SENDRECV;
+ *l |= c && c->c_mcast ? swap : mode;
+ break;
+ case soa_activity_remote:
+ *r &= SOA_ACTIVE_SENDRECV;
+ *r = c && c->c_mcast ? mode : swap;
+ break;
+ case soa_activity_session:
+ *l &= SOA_ACTIVE_SENDRECV;
+ *l |= c && c->c_mcast ? swap : mode;
+ *r &= SOA_ACTIVE_SENDRECV;
+ *r = c && c->c_mcast ? swap : mode;
+ break;
+ }
+ }
- if (*p < 0)
- *p = mode;
- else
- *p |= mode;
+ if (activity == soa_activity_local ||
+ activity == soa_activity_session) {
+ ma = ss->ss_local_activity;
+ ma->ma_audio = l_audio;
+ ma->ma_video = l_video;
+ ma->ma_image = l_image;
+ ma->ma_chat = l_chat;
}
- ma->ma_audio = ma_audio;
- ma->ma_video = ma_video;
- ma->ma_image = ma_image;
- ma->ma_chat = ma_chat;
+ if (activity == soa_activity_remote ||
+ activity == soa_activity_session) {
+ ma = ss->ss_remote_activity;
+ ma->ma_audio = r_audio;
+ ma->ma_video = r_video;
+ ma->ma_image = r_image;
+ ma->ma_chat = r_chat;
+ }
}
/* ----------------------------------------------------------------------*/
return 0;
}
-/** Check if @a session mode should be changed. */
-static
-int soa_sdp_mode_set_is_needed(sdp_session_t const *session,
- sdp_session_t const *remote,
- char const *hold)
-{
- sdp_media_t const *sm, *rm, *rm_next;
- int hold_all;
- sdp_mode_t recv_mode;
-
- SU_DEBUG_7(("soa_sdp_mode_set_is_needed(%p, %p, \"%s\"): called\n",
- (void *)session, (void *)remote, hold ? hold : ""));
-
- if (!session )
- return 0;
-
- hold_all = str0cmp(hold, "*") == 0;
-
- rm = remote ? remote->sdp_media : NULL, rm_next = NULL;
-
- for (sm = session->sdp_media; sm; sm = sm->m_next, rm = rm_next) {
- rm_next = rm ? rm->m_next : NULL;
-
- if (sm->m_rejected)
- continue;
-
- if (rm) {
- /* Mode bits do not match */
- if (((rm->m_mode & sdp_recvonly) == sdp_recvonly)
- != ((sm->m_mode & sdp_sendonly) == sdp_sendonly))
- return 1;
- }
-
- recv_mode = sm->m_mode & sdp_recvonly;
- if (recv_mode && hold &&
- (hold_all || strcasestr(hold, sm->m_type_name)))
- return 1;
- }
-
- return 0;
-}
-
-/** Update mode within session */
+/** Update mode within session.
+ *
+ * @sa soatag_hold
+ *
+ * @retval 1 if session was changed (or to be changed, if @a dryrun is nonzero)
+ */
static
-int soa_sdp_mode_set(sdp_session_t *session,
+int soa_sdp_mode_set(sdp_session_t const *user,
+ int const *s2u,
+ sdp_session_t *session,
sdp_session_t const *remote,
- char const *hold)
+ char const *hold,
+ int dryrun)
{
sdp_media_t *sm;
- sdp_media_t const *rm, *rm_next;
+ sdp_media_t const *rm, *rm_next, *um;
+ int retval = 0, i, j;
int hold_all;
+ int inactive_all;
+ int inactive = 0;
+ char const *hold_media = NULL;
sdp_mode_t send_mode, recv_mode;
SU_DEBUG_7(("soa_sdp_mode_set(%p, %p, \"%s\"): called\n",
rm = remote ? remote->sdp_media : NULL, rm_next = NULL;
hold_all = str0cmp(hold, "*") == 0;
+ inactive_all = str0cmp(hold, "#") == 0;
+
+ i = 0;
- for (sm = session->sdp_media; sm; sm = sm->m_next, rm = rm_next) {
+ for (sm = session->sdp_media; sm; sm = sm->m_next, rm = rm_next, i++) {
rm_next = rm ? rm->m_next : NULL;
+ inactive = 0;
if (sm->m_rejected)
continue;
- send_mode = sdp_sendonly;
+ assert(s2u);
+
+ for (j = 0, um = user->sdp_media; j != s2u[i]; um = um->m_next, j++)
+ assert(um);
+ assert(um);
+
+ send_mode = um->m_mode & sdp_sendonly;
if (rm)
send_mode = (rm->m_mode & sdp_recvonly) ? sdp_sendonly : 0;
- recv_mode = sm->m_mode & sdp_recvonly;
- if (recv_mode && hold && (hold_all || strcasestr(hold, sm->m_type_name)))
+ recv_mode = um->m_mode & sdp_recvonly;
+
+ if (rm && rm->m_mode == sdp_inactive) {
+ send_mode = recv_mode = 0;
+ }
+ else if (inactive_all) {
+ send_mode = recv_mode = 0;
+ }
+ else if (hold_all) {
+ recv_mode = 0;
+ }
+ else if (hold && (hold_media = strcasestr(hold, sm->m_type_name))) {
recv_mode = 0;
+ hold_media += strlen(sm->m_type_name);
+ hold_media += strspn(hold_media, " \t");
+ if (hold_media[0] == '=') {
+ hold_media += strspn(hold, " \t");
+ if (strncasecmp(hold_media, "inactive", strlen("inactive")) == 0)
+ recv_mode = send_mode = 0;
+ }
+ }
+
+ if (sm->m_mode != (unsigned)(recv_mode | send_mode))
+ retval = 1;
- sm->m_mode = recv_mode | send_mode;
+ if (!dryrun) {
+ sm->m_mode = recv_mode | send_mode;
+ }
}
- return 0;
+ return retval;
}
enum offer_answer_action {
/* Step D: Set media mode bits */
switch (action) {
+ int const *s2u_;
+
case generate_offer:
case generate_answer:
case process_answer:
- if (soa_sdp_mode_set_is_needed(local, remote, ss->ss_hold)) {
+ s2u_ = s2u;
+
+ if (!s2u_) s2u_ = sss->sss_s2u;
+
+ if (soa_sdp_mode_set(user, s2u_, local, remote, ss->ss_hold, 1)) {
if (local != local0) {
*local0 = *local, local = local0;
DUP_LOCAL(local);
}
- soa_sdp_mode_set(local, remote, ss->ss_hold);
+ soa_sdp_mode_set(user, s2u_, local, remote, ss->ss_hold, 0);
}
break;
default:
/**@def SOATAG_HOLD(x)
*
- * Hold media stream or streams. When putting a SIP session on hold, the
- * application can include, e.g., SOATAG_HOLD("audio") or
- * SOATAG_HOLD("video") or SOATAG_HOLD("audio, video") or SOATAG_HOLD("*")
- * as @soa parameters. When resuming the session, it can include
- * SOATAG_HOLD(NULL). Note that last SOATAG_HOLD() in the tag list will
- * override the SOATAG_HOLD() tags before it.
+ * Hold media stream or streams.
+ *
+ * The hold media stream will have the attribute a=sendonly (meaning that
+ * some hold announcements or pause music is sent to the held party but that
+ * the held party should not generate any media) or a=inactive (meaning that
+ * no media is sent).
+ *
+ * When putting a SIP session on hold with sendonly, the application can
+ * include, e.g., SOATAG_HOLD("audio") or SOATAG_HOLD("video") or
+ * SOATAG_HOLD("audio, video") or SOATAG_HOLD("*") as @soa parameters. When
+ * using inactive instead, the application should use "#" or
+ * "audio=inactive" instead. When resuming the session, application should
+ * include the tag SOATAG_HOLD(NULL).
+ *
+ * Note that last SOATAG_HOLD() in the tag list will override the
+ * SOATAG_HOLD() tags before it.
*
* @par Used with
* soa_set_params(), soa_get_params(), soa_get_paramlist() \n
SOFIAPUBFUN int soa_set_status(soa_session_t *ss,
int status, char const *phrase);
+enum soa_activity { soa_activity_local, soa_activity_remote, soa_activity_session };
+
SOFIAPUBFUN void soa_set_activity(soa_session_t *ss,
- sdp_media_t const *m, int remote);
+ sdp_media_t const *m,
+ enum soa_activity activity);
SOFIAPUBFUN int soa_description_set(soa_session_t *ss,
struct soa_description *ssd,
TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDONLY);
TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDONLY);
+ /* 'A' will put call inactive */
+ offer = NONE;
+ TEST(soa_set_params(a, SOATAG_HOLD("#"), TAG_END()), 1);
+
+ TEST(soa_generate_offer(a, 1, test_completed), 0);
+ TEST(soa_get_local_sdp(a, NULL, &offer, &offerlen), 1);
+ TEST_1(offer != NULL && offer != NONE);
+ TEST_1(strstr(offer, "a=inactive"));
+ TEST(soa_set_remote_sdp(b, 0, offer, offerlen), 1);
+ TEST(soa_generate_answer(b, test_completed), 0);
+ TEST_1(soa_is_complete(b));
+ TEST(soa_activate(b, NULL), 0);
+ TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1);
+ TEST_1(answer != NULL && answer != NONE);
+ TEST_1(strstr(answer, "a=inactive"));
+ TEST(soa_set_remote_sdp(a, 0, answer, -1), 1);
+ TEST(soa_process_answer(a, test_completed), 0);
+ TEST(soa_activate(a, NULL), 0);
+
+ TEST(soa_is_audio_active(a), SOA_ACTIVE_INACTIVE);
+ TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_INACTIVE);
+
+ /* B will send an offer to A, but there is no change in O/A status */
+ TEST(soa_generate_offer(b, 1, test_completed), 0);
+ TEST(soa_get_local_sdp(b, NULL, &offer, &offerlen), 1);
+ TEST_1(offer != NULL && offer != NONE);
+ TEST_1(!strstr(offer, "a=inactive"));
+ printf("offer:\n%s", offer);
+ TEST(soa_set_remote_sdp(a, 0, offer, offerlen), 1);
+ TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV);
+ TEST(soa_generate_answer(a, test_completed), 0);
+ TEST(soa_is_audio_active(a), SOA_ACTIVE_INACTIVE);
+ TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_INACTIVE);
+ TEST_1(soa_is_complete(a));
+ TEST(soa_activate(a, NULL), 0);
+ TEST(soa_get_local_sdp(a, NULL, &answer, &answerlen), 1);
+ TEST_1(answer != NULL && answer != NONE);
+ TEST_1(strstr(answer, "a=inactive"));
+ printf("answer:\n%s", answer);
+ TEST(soa_set_remote_sdp(b, 0, answer, -1), 1);
+ TEST(soa_process_answer(b, test_completed), 0);
+ TEST(soa_activate(b, NULL), 0);
+
+
+ TEST(soa_is_audio_active(b), SOA_ACTIVE_INACTIVE);
+ TEST(soa_is_remote_audio_active(b), SOA_ACTIVE_INACTIVE);
+
/* 'A' will release hold. */
TEST(soa_set_params(a, SOATAG_HOLD(NULL), TAG_END()), 1);
TEST(soa_generate_offer(a, 1, test_completed), 0);
TEST(soa_get_local_sdp(a, NULL, &offer, &offerlen), 1);
TEST_1(offer != NULL && offer != NONE);
- TEST_1(!strstr(offer, "a=sendonly"));
+ TEST_1(!strstr(offer, "a=sendonly") && !strstr(offer, "a=inactive"));
TEST(soa_set_remote_sdp(b, 0, offer, offerlen), 1);
TEST(soa_generate_answer(b, test_completed), 0);
TEST_1(soa_is_complete(b));
TEST(soa_activate(b, NULL), 0);
TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1);
TEST_1(answer != NULL && answer != NONE);
- TEST_1(!strstr(answer, "a=recvonly"));
+ TEST_1(!strstr(answer, "a=recvonly") && !strstr(answer, "a=inactive"));
TEST(soa_set_remote_sdp(a, 0, answer, -1), 1);
TEST(soa_process_answer(a, test_completed), 0);
TEST(soa_activate(a, NULL), 0);
{
BEGIN();
-#if 0
+#if 0 /* This has never been implemented */
int n;
char const *caps = NONE, *offer = NONE, *answer = NONE;
uint16_t type,
struct sockaddr const *addr);
+/**Modify the priority of the specified SRV records. */
+SRESPUBFUN
+int sres_set_cached_srv_priority(sres_resolver_t *res,
+ char const *domain,
+ char const *target,
+ uint16_t port,
+ uint32_t newttl,
+ uint16_t newprio);
+
+
/** Send a query, wait for answer, return results. */
SRESPUBFUN
int sres_blocking_query(sres_resolver_t *res,
/** Store a record to cache */
SRESPUBFUN void sres_cache_store(sres_cache_t *, sres_record_t *, time_t now);
+/** Modify the priority in the specified SRV record */
+SRESPUBFUN int sres_cache_set_srv_priority(sres_cache_t *,
+ char const *domain,
+ char const *target,
+ uint16_t port,
+ uint32_t newttl,
+ uint16_t newprio);
+
#ifdef __cplusplus
}
#endif
return result;
}
+/** Set the priority of the matching cached SRV record.
+ *
+ * The SRV records with the domain name, target and port are matched and
+ * their priority value is adjusted. This function is used to implement
+ * greylisting of SIP servers.
+ *
+ * @param res pointer to resolver
+ * @param domain domain name of the SRV record(s) to modify
+ * @param target SRV target of the SRV record(s) to modify
+ * @param port port number of SRV record(s) to modify
+ * (in host byte order)
+ * @param ttl new ttl for SRV records of the domain
+ * @param priority new priority value (0=highest, 65535=lowest)
+ *
+ * @sa sres_cache_set_srv_priority()
+ *
+ * @NEW_1_12_8
+ */
+int sres_set_cached_srv_priority(sres_resolver_t *res,
+ char const *domain,
+ char const *target,
+ uint16_t port,
+ uint32_t ttl,
+ uint16_t priority)
+{
+ char rooted_domain[SRES_MAXDNAME];
+
+ if (res == NULL || res->res_cache == NULL)
+ return su_seterrno(EFAULT);
+
+ domain = sres_toplevel(rooted_domain, sizeof rooted_domain, domain);
+
+ if (!domain)
+ return -1;
+
+ return sres_cache_set_srv_priority(res->res_cache,
+ domain, target, port,
+ ttl, priority);
+}
+
+
/** Sort answers. */
int
sres_sort_answers(sres_resolver_t *res, sres_record_t **answers)
}
}
+/** Set the priority of the matching cached SRV record.
+ *
+ * The SRV records with the domain name, target and port are matched and
+ * their priority value is adjusted. This function is used to implement
+ * greylisting of SIP servers.
+ *
+ * @param cache pointer to DNS cache object
+ * @param domain domain name of the SRV record(s) to modify
+ * (including final dot)
+ * @param target SRV target of the SRV record(s) to modify
+ * @param port port number of SRV record(s) to modify
+ * (in host byte order)
+ * @param ttl new ttl
+ * @param priority new priority value (0=highest, 65535=lowest)
+ *
+ * @sa sres_set_cached_srv_priority()
+ *
+ * @NEW_1_12_8
+ */
+int sres_cache_set_srv_priority(sres_cache_t *cache,
+ char const *domain,
+ char const *target,
+ uint16_t port,
+ uint32_t ttl,
+ uint16_t priority)
+{
+ int ret = 0;
+ unsigned hash;
+ sres_rr_hash_entry_t **iter;
+ time_t expires;
+
+ if (cache == NULL || domain == NULL || target == NULL)
+ return -1;
+
+ hash = sres_hash_key(domain);
+
+ if (!LOCK(cache))
+ return -1;
+
+ time(&expires);
+ expires += ttl;
+
+ for (iter = sres_htable_hash(cache->cache_hash, hash);
+ iter && *iter;
+ iter = sres_htable_next(cache->cache_hash, iter)) {
+ sres_record_t *rr = (*iter)->rr;
+
+ if (rr && rr->sr_name &&
+ sres_type_srv == rr->sr_type &&
+ strcasecmp(rr->sr_name, domain) == 0) {
+
+ (*iter)->rr_expires = expires;
+
+ if ((port == 0 || rr->sr_srv->srv_port == port) &&
+ rr->sr_srv->srv_target &&
+ strcasecmp(rr->sr_srv->srv_target, target) == 0) {
+ /* record found --> change priority of server */
+ rr->sr_srv->srv_priority = priority;
+ ret++;
+ }
+ }
+ }
+
+ UNLOCK(cache);
+
+ /** @return number of modified entries or -1 upon an error. */
+ return ret;
+}
+
HTABLE_BODIES_WITH(sres_htable, ht, sres_rr_hash_entry_t, SRES_HENTRY_HASH,
unsigned, size_t);
* always storing a pointer to element). It can be used without
* <sofia-sip/su_alloc.h>.
*
- * This file contain a hash table template for C. The hash tables are
- * resizeable, and they usually contain pointers to entries. The
- * declaration for template datatypes is instantiated with macro
- * HTABLE2_DECLARE(). The prototypes for hashing functions are instantiated
- * with macro HTABLE2_PROTOS(). The implementation is instantiated with
- * macro HTABLE2_BODIES().
+ * This file contain a hash table template for C. The hash tables are
+ * resizeable, and they usually contain pointers to entries. The declaration
+ * for template datatypes is instantiated with macro HTABLE2_DECLARE2(). The
+ * prototypes for hashing functions are instantiated with macro
+ * HTABLE2_PROTOS2(). The implementation is instantiated with macro
+ * HTABLE2_BODIES2().
*
* The hash table template is most efficient when the hash value is
* precalculated and stored in each entry. The hash "function" given to the
- * HTABLE2_BODIES() would then be something like macro
+ * HTABLE2_BODIES2() would then be something like macro
* @code
- * #define HTABLE2_ENTRY_HASH(e) ((e).e_hash_value)
+ * #define ENTRY_HASH(e) ((e).e_hash_value)
* @endcode
*
- * When a entry with new identical hash key is added to the table, it can be
- * either @e inserted (before any other entry with same key value) or
- * @e appended.
+ * When a entry with new identical key is added to the table, it can be
+ * either @e inserted (before any other entry with same key value) or @e
+ * appended.
*
* Example code can be found from <htable_test.c>.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>.
*
* @date Created: Tue Sep 25 17:42:40 2001 ppessi
- *
*/
typedef unsigned long hash_value_t;
* @param sname name of struct
* @param pr hash table field prefix
* @param entrytype entry type
+ *
+ * @NEW_1_12_8
*/
#define HTABLE2_DECLARE2(type, sname, pr, entrytype, size_t) \
typedef struct sname { \
* @param prefix function prefix
* @param pr hash table field prefix (not used)
* @param entrytype entry type
+ *
+ * @NEW_1_12_8
*/
#define HTABLE2_PROTOS2(type, prefix, pr, entrytype, size_t) \
HTABLE2_SCOPE int prefix##_resize(void *a, type *, size_t); \
* @param reclaim function or macro zeroing entry
* @param is_equal equality test
* @param halloc function allocating or freeing memory
+ *
+ * @NEW_1_12_8
*/
#define HTABLE2_BODIES2(type, prefix, pr, entrytype, size_t, \
hfun, is_used, reclaim, is_equal, halloc) \
#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
#endif
-/** RFC 1576 address info structure. */
+/** @RFC1576 address info structure. */
typedef struct addrinfo su_addrinfo_t;
/** Translate address and service. */
su_msg_r msg,
su_msg_arg_t *arg);
-/** Message deinitialize. */
-typedef void su_msg_deinit_func(su_msg_arg_t *arg);
+/** Message deinitializer function type. @NEW_1_12_8 */
+typedef void su_msg_deinit_function(su_msg_arg_t *arg);
/** Message delivery function pointer type. */
typedef su_msg_function *su_msg_f;
su_task_r const to, su_task_r const from,
su_msg_f wakeup, isize_t size);
SOFIAPUBFUN int su_msg_report(su_msg_r msg, su_msg_f report);
-SOFIAPUBFUN int su_msg_deinitializer(su_msg_r msg, su_msg_deinit_func *);
+SOFIAPUBFUN int su_msg_deinitializer(su_msg_r msg, su_msg_deinit_function *);
SOFIAPUBFUN int su_msg_reply(su_msg_r reply, su_msg_cr msg,
su_msg_f wakeup, isize_t size);
SOFIAPUBFUN void su_msg_destroy(su_msg_r msg);
{
int retval;
su_addrinfo_t *ai;
+ char const *realservice = service;
if (!service || service[0] == '\0')
service = "0";
retval = getaddrinfo(node, service, hints, res);
+ if (service != realservice && retval == EAI_SERVICE)
+ retval = getaddrinfo(node, realservice, hints, res);
+
if (retval == 0) {
for (ai = *res; ai; ai = ai->ai_next) {
if (ai->ai_protocol)
return 0;
}
-/** Release exclusive lock on home and decrease refcount (if home is threadsafe) */
+/** Release exclusive lock on home and decrease refcount (if home is threadsafe).
+ *
+ * @sa su_home_unlock().
+ */
int su_home_mutex_unlock(su_home_t *home)
{
if (home == NULL)
/** Obtain exclusive lock on home without increasing refcount.
+ *
+ * Unless su_home_threadsafe() has been used to intialize locking on home
+ * object the function just returns -1.
*
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
*
+ * @sa su_home_mutex_lock(), su_home_unlock(), su_home_trylock().
+ *
+ * @NEW_1_12_8
*/
int su_home_lock(su_home_t *home)
{
* @return 0 if successful, -1 if not threadsafe,
* EBUSY if already locked, error code otherwise.
*
+ * @sa su_home_lock(), su_home_unlock().
+ *
+ * @NEW_1_12_8
*/
int su_home_trylock(su_home_t *home)
{
}
-/** Release exclusive lock on home.
+/** Release exclusive lock on home.
+ *
+ * Release lock without decreasing refcount.
*
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
+ *
+ * @sa su_home_lock(), su_home_trylock(), su_home_mutex_unlock().
+ *
+ * @NEW_1_12_8
*/
int su_home_unlock(su_home_t *home)
{
#include <sofia-sip/su_log.h>
#include <sofia-sip/su_debug.h>
+#ifdef DOXYGEN_ONLY
/**@var SU_DEBUG
*
* Environment variable determining the debug log level for @b su module.
su_task_r sum_from;
su_msg_f sum_func;
su_msg_f sum_report;
- su_msg_deinit_func *sum_deinit;
+ su_msg_deinit_function *sum_deinit;
su_msg_arg_t sum_data[1]; /* minimum size, may be extended */
};
*
* @retval 0 if successful,
* @retval -1 if message allocation fails.
+ *
+ * @NEW_1_12_8
*/
int su_msg_new(su_msg_r rmsg, size_t size)
{
*
* @param rmsg message reference
* @param deinit pointer to deinitializer function
+ *
+ * @NEW_1_12_8
*/
int su_msg_deinitializer(su_msg_r rmsg,
- su_msg_deinit_func *deinit)
+ su_msg_deinit_function *deinit)
{
if (rmsg && rmsg[0]) {
rmsg[0]->sum_deinit = deinit;
return 0;
}
-/** Send message to the @a to_task and mark @a from_task as sender */
+/** Send message to the @a to_task and mark @a from_task as sender.
+ *
+ * @NEW_1_12_8
+ */
SOFIAPUBFUN int su_msg_send_to(su_msg_r rmsg,
su_task_r const to_task,
su_msg_f wakeup)
typedef struct hentry_s entry_t;
-HTABLE2_DECLARE2(htable2_t, htable2_s, ht2_, entry_t, size_t);
-HTABLE2_PROTOS2(htable2_t, htable2, ht2_, entry_t, size_t);
-
struct hentry_s
{
- unsigned long e_hash;
+ hash_value_t e_hash;
unsigned long e_n;
};
+HTABLE2_DECLARE2(htable2_t, htable2_s, ht2_, entry_t, size_t);
+HTABLE2_PROTOS2(htable2_t, htable2, ht2_, entry_t, size_t);
+
#define HENTRY_HASH(e) ((e).e_hash)
#define HENTRY_IS_USED(e) ((e).e_n != 0)
#define HENTRY_REMOVE(e) ((e)->e_n = 0, (e)->e_hash = 0)
int test_sendrecv(void)
{
su_socket_t s, l, a;
- int n;
+ ssize_t n;
su_sockaddr_t su, csu;
socklen_t sulen = sizeof su.su_sin, csulen = sizeof csu.su_sin;
char b1[8], b2[8], b3[8];
BEGIN();
s = su_socket(AF_INET, SOCK_DGRAM, 0); TEST_1(s != -1);
+ su_setblocking(s, 1);
memset(&su, 0, sulen);
su.su_len = sulen;
TEST(connect(s, &su.su_sa, sulen), 0);
a = accept(l, &csu.su_sa, &csulen); TEST_1(a != -1);
+ TEST(su_setblocking(a, 1), 0);
+
n = su_vsend(s, sv, 3, 0, NULL, 0); TEST(n, 8 + 8 + 6);
n = su_vrecv(a, rv, 3, 0, NULL, NULL); TEST(n, 8 + 8 + 6);
s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
TEST_1(s != SOCKET_ERROR);
-
+
+ su_setblocking(s, 1);
connected = connect(s, ai->ai_addr, (socklen_t)ai->ai_addrlen);
su_root_step(tt->tt_root, 50);
- TEST(send(s, "F", 1, 0), 1);
+ TEST(su_send(s, "F", 1, 0), 1);
su_root_step(tt->tt_root, 50);
- TEST(send(s, "O", 1, 0), 1);
+ TEST(su_send(s, "O", 1, 0), 1);
su_root_step(tt->tt_root, 50);
- TEST(send(s, "O", 1, 0), 1);
+ TEST(su_send(s, "O", 1, 0), 1);
su_root_step(tt->tt_root, 50);
- TEST(send(s, " ", 1, 0), 1);
+ TEST(su_send(s, " ", 1, 0), 1);
su_root_step(tt->tt_root, 50);
tt->tt_received = 0;
int tport_register_type(tport_vtable_t const *vtp);
-/** @internal Test if transport is needs connect() before sending. */
+/** @internal Test if transport needs connect() before sending. */
su_inline int tport_is_connection_oriented(tport_t const *self)
{
return self->tp_conn_orient;
# Tests using check
#
-EXTRA_DIST = check_nua.c
+EXTRA_DIST = check_sofia.h check_sofia.c suite_for_nua.c
TESTS =
check_PROGRAMS =
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/libsofia_sip_ua_static.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\libsofia_sip_ua_static.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/libsofia_sip_ua_static.bsc"\r
+ OutputFile=".\Debug\libsofia_sip_ua_static.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/libsofia_sip_ua_static.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\libsofia_sip_ua_static.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/libsofia_sip_ua_static.bsc"\r
+ OutputFile=".\Release\libsofia_sip_ua_static.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/libsofia_sip_ua.tlb"\r
+ TypeLibraryName=".\Debug\libsofia_sip_ua.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/libsofia_sip_ua.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\libsofia_sip_ua.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib advapi32.lib iphlpapi.lib"\r
- OutputFile=".\Debug/libsofia_sip_ua.dll"\r
+ OutputFile=".\Debug\libsofia_sip_ua.dll"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/libsofia_sip_ua.pdb"\r
- ImportLibrary=".\Debug/libsofia_sip_ua.lib"\r
+ ProgramDatabaseFile=".\Debug\libsofia_sip_ua.pdb"\r
+ ImportLibrary=".\Debug\libsofia_sip_ua.lib"\r
TargetMachine="1"\r
/>\r
<Tool\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/libsofia_sip_ua.bsc"\r
+ OutputFile=".\Debug\libsofia_sip_ua.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/libsofia_sip_ua.tlb"\r
+ TypeLibraryName=".\Release\libsofia_sip_ua.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/libsofia_sip_ua.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\libsofia_sip_ua.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib advapi32.lib iphlpapi.lib"\r
- OutputFile=".\Release/libsofia_sip_ua.dll"\r
+ OutputFile=".\Release\libsofia_sip_ua.dll"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/libsofia_sip_ua.pdb"\r
- ImportLibrary=".\Release/libsofia_sip_ua.lib"\r
+ ProgramDatabaseFile=".\Release\libsofia_sip_ua.pdb"\r
+ ImportLibrary=".\Release\libsofia_sip_ua.lib"\r
TargetMachine="1"\r
/>\r
<Tool\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/libsofia_sip_ua.bsc"\r
+ OutputFile=".\Release\libsofia_sip_ua.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_htable.tlb"\r
+ TypeLibraryName=".\Debug\test_htable.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_htable.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_htable.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/test_htable.exe"\r
+ OutputFile=".\Debug\test_htable.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_htable.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_htable.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_htable.bsc"\r
+ OutputFile=".\Debug\test_htable.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_htable.tlb"\r
+ TypeLibraryName=".\Release\test_htable.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_htable.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_htable.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/test_htable.exe"\r
+ OutputFile=".\Release\test_htable.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_htable.pdb"\r
+ ProgramDatabaseFile=".\Release\test_htable.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_htable.bsc"\r
+ OutputFile=".\Release\test_htable.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_memmem.tlb"\r
+ TypeLibraryName=".\Debug\test_memmem.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_memmem.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_memmem.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile=".\Debug/test_memmem.exe"\r
+ OutputFile=".\Debug\test_memmem.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_memmem.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_memmem.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_memmem.bsc"\r
+ OutputFile=".\Debug\test_memmem.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_memmem.tlb"\r
+ TypeLibraryName=".\Release\test_memmem.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_memmem.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_memmem.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile=".\Release/test_memmem.exe"\r
+ OutputFile=".\Release\test_memmem.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_memmem.pdb"\r
+ ProgramDatabaseFile=".\Release\test_memmem.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_memmem.bsc"\r
+ OutputFile=".\Release\test_memmem.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_nta.tlb"\r
+ TypeLibraryName=".\Release\test_nta.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_nta.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_nta.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/test_nta.exe"\r
+ OutputFile=".\Release\test_nta.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_nta.pdb"\r
+ ProgramDatabaseFile=".\Release\test_nta.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_nta.bsc"\r
+ OutputFile=".\Release\test_nta.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_nta.tlb"\r
+ TypeLibraryName=".\Debug\test_nta.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_nta.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_nta.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/test_nta.exe"\r
+ OutputFile=".\Debug\test_nta.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_nta.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_nta.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_nta.bsc"\r
+ OutputFile=".\Debug\test_nta.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_nua.tlb"\r
+ TypeLibraryName=".\Debug\test_nua.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_nua.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_nua.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/test_nua.exe"\r
+ OutputFile=".\Debug\test_nua.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_nua.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_nua.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_nua.bsc"\r
+ OutputFile=".\Debug\test_nua.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_nua.tlb"\r
+ TypeLibraryName=".\Release\test_nua.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_nua.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_nua.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/test_nua.exe"\r
+ OutputFile=".\Release\test_nua.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_nua.pdb"\r
+ ProgramDatabaseFile=".\Release\test_nua.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_nua.bsc"\r
+ OutputFile=".\Release\test_nua.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_su.tlb"\r
+ TypeLibraryName=".\Debug\test_su.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_su.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_su.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/test_su.exe"\r
+ OutputFile=".\Debug\test_su.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_su.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_su.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_su.bsc"\r
+ OutputFile=".\Debug\test_su.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_su.tlb"\r
+ TypeLibraryName=".\Release\test_su.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_su.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_su.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/test_su.exe"\r
+ OutputFile=".\Release\test_su.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_su.pdb"\r
+ ProgramDatabaseFile=".\Release\test_su.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_su.bsc"\r
+ OutputFile=".\Release\test_su.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/test_tport.tlb"\r
+ TypeLibraryName=".\Debug\test_tport.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/test_tport.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\test_tport.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/test_tport.exe"\r
+ OutputFile=".\Debug\test_tport.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/test_tport.pdb"\r
+ ProgramDatabaseFile=".\Debug\test_tport.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/test_tport.bsc"\r
+ OutputFile=".\Debug\test_tport.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/test_tport.tlb"\r
+ TypeLibraryName=".\Release\test_tport.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/test_tport.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\test_tport.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/test_tport.exe"\r
+ OutputFile=".\Release\test_tport.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/test_tport.pdb"\r
+ ProgramDatabaseFile=".\Release\test_tport.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/test_tport.bsc"\r
+ OutputFile=".\Release\test_tport.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_rbtree.tlb"\r
+ TypeLibraryName=".\Release\torture_rbtree.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_rbtree.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_rbtree.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_rbtree.exe"\r
+ OutputFile=".\Release\torture_rbtree.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_rbtree.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_rbtree.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_rbtree.bsc"\r
+ OutputFile=".\Release\torture_rbtree.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_rbtree.tlb"\r
+ TypeLibraryName=".\Debug\torture_rbtree.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_rbtree.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_rbtree.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_rbtree.exe"\r
+ OutputFile=".\Debug\torture_rbtree.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_rbtree.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_rbtree.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_rbtree.bsc"\r
+ OutputFile=".\Debug\torture_rbtree.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su.tlb"\r
+ TypeLibraryName=".\Release\torture_su.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su.exe"\r
+ OutputFile=".\Release\torture_su.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su.bsc"\r
+ OutputFile=".\Release\torture_su.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su.tlb"\r
+ TypeLibraryName=".\Debug\torture_su.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su.exe"\r
+ OutputFile=".\Debug\torture_su.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su.bsc"\r
+ OutputFile=".\Debug\torture_su.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_alloc.tlb"\r
+ TypeLibraryName=".\Release\torture_su_alloc.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_alloc.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_alloc.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_alloc.exe"\r
+ OutputFile=".\Release\torture_su_alloc.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_alloc.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_alloc.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_alloc.bsc"\r
+ OutputFile=".\Release\torture_su_alloc.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_alloc.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_alloc.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_alloc.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_alloc.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_alloc.exe"\r
+ OutputFile=".\Debug\torture_su_alloc.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_alloc.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_alloc.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_alloc.bsc"\r
+ OutputFile=".\Debug\torture_su_alloc.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_bm.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_bm.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_bm.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_bm.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_bm.exe"\r
+ OutputFile=".\Debug\torture_su_bm.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_bm.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_bm.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_bm.bsc"\r
+ OutputFile=".\Debug\torture_su_bm.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_bm.tlb"\r
+ TypeLibraryName=".\Release\torture_su_bm.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_bm.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_bm.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_bm.exe"\r
+ OutputFile=".\Release\torture_su_bm.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_bm.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_bm.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_bm.bsc"\r
+ OutputFile=".\Release\torture_su_bm.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_port.tlb"\r
+ TypeLibraryName=".\Release\torture_su_port.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_port.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_port.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="3"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_port.exe"\r
+ OutputFile=".\Release\torture_su_port.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_port.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_port.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_port.bsc"\r
+ OutputFile=".\Release\torture_su_port.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_port.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_port.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_port.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_port.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="3"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_port.exe"\r
+ OutputFile=".\Debug\torture_su_port.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_port.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_port.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_port.bsc"\r
+ OutputFile=".\Debug\torture_su_port.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_root.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_root.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_root.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_root.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_root.exe"\r
+ OutputFile=".\Debug\torture_su_root.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_root.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_root.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_root.bsc"\r
+ OutputFile=".\Debug\torture_su_root.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_root.tlb"\r
+ TypeLibraryName=".\Release\torture_su_root.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_root.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_root.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_root.exe"\r
+ OutputFile=".\Release\torture_su_root.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_root.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_root.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_root.bsc"\r
+ OutputFile=".\Release\torture_su_root.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_tag.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_tag.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_tag.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_tag.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_tag.exe"\r
+ OutputFile=".\Debug\torture_su_tag.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_tag.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_tag.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_tag.bsc"\r
+ OutputFile=".\Debug\torture_su_tag.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_tag.tlb"\r
+ TypeLibraryName=".\Release\torture_su_tag.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_tag.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_tag.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_tag.exe"\r
+ OutputFile=".\Release\torture_su_tag.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_tag.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_tag.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_tag.bsc"\r
+ OutputFile=".\Release\torture_su_tag.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_time.tlb"\r
+ TypeLibraryName=".\Release\torture_su_time.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_time.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_time.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_time.exe"\r
+ OutputFile=".\Release\torture_su_time.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_time.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_time.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_time.bsc"\r
+ OutputFile=".\Release\torture_su_time.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_time.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_time.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_time.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_time.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_time.exe"\r
+ OutputFile=".\Debug\torture_su_time.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_time.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_time.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_time.bsc"\r
+ OutputFile=".\Debug\torture_su_time.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Debug/torture_su_timer.tlb"\r
+ TypeLibraryName=".\Debug\torture_su_timer.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/torture_su_timer.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\torture_su_timer.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/torture_su_timer.exe"\r
+ OutputFile=".\Debug\torture_su_timer.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/torture_su_timer.pdb"\r
+ ProgramDatabaseFile=".\Debug\torture_su_timer.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/torture_su_timer.bsc"\r
+ OutputFile=".\Debug\torture_su_timer.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\Release/torture_su_timer.tlb"\r
+ TypeLibraryName=".\Release\torture_su_timer.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/torture_su_timer.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\torture_su_timer.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
BrowseInformation="1"\r
WarningLevel="4"\r
WarnAsError="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/torture_su_timer.exe"\r
+ OutputFile=".\Release\torture_su_timer.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/torture_su_timer.pdb"\r
+ ProgramDatabaseFile=".\Release\torture_su_timer.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/torture_su_timer.bsc"\r
+ OutputFile=".\Release\torture_su_timer.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/localinfo.tlb"\r
+ TypeLibraryName=".\Debug\localinfo.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- PrecompiledHeaderFile=".\Debug/localinfo.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\localinfo.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/localinfo.exe"\r
+ OutputFile=".\Debug\localinfo.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/localinfo.pdb"\r
+ ProgramDatabaseFile=".\Debug\localinfo.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/localinfo.bsc"\r
+ OutputFile=".\Debug\localinfo.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/localinfo.tlb"\r
+ TypeLibraryName=".\Release\localinfo.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="0"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/localinfo.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\localinfo.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/localinfo.exe"\r
+ OutputFile=".\Release\localinfo.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/localinfo.pdb"\r
+ ProgramDatabaseFile=".\Release\localinfo.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/localinfo.bsc"\r
+ OutputFile=".\Release\localinfo.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/sip_dig.tlb"\r
+ TypeLibraryName=".\Release\sip_dig.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/sip_dig.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\sip_dig.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/sip_dig.exe"\r
+ OutputFile=".\Release\sip_dig.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/sip_dig.pdb"\r
+ ProgramDatabaseFile=".\Release\sip_dig.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/sip_dig.bsc"\r
+ OutputFile=".\Release\sip_dig.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/sip_dig.tlb"\r
+ TypeLibraryName=".\Debug\sip_dig.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/sip_dig.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\sip_dig.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/sip_dig.exe"\r
+ OutputFile=".\Debug\sip_dig.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/sip_dig.pdb"\r
+ ProgramDatabaseFile=".\Debug\sip_dig.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/sip_dig.bsc"\r
+ OutputFile=".\Debug\sip_dig.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/sip_options.tlb"\r
+ TypeLibraryName=".\Release\sip_options.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/sip_options.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\sip_options.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/sip_options.exe"\r
+ OutputFile=".\Release\sip_options.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/sip_options.pdb"\r
+ ProgramDatabaseFile=".\Release\sip_options.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/sip_options.bsc"\r
+ OutputFile=".\Release\sip_options.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/sip_options.tlb"\r
+ TypeLibraryName=".\Debug\sip_options.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/sip_options.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\sip_options.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/sip_options.exe"\r
+ OutputFile=".\Debug\sip_options.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/sip_options.pdb"\r
+ ProgramDatabaseFile=".\Debug\sip_options.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/sip_options.bsc"\r
+ OutputFile=".\Debug\sip_options.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/sip_options_static.tlb"\r
+ TypeLibraryName=".\Release\sip_options_static.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/sip_options_static.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\sip_options_static.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib advapi32.lib iphlpapi.lib"\r
- OutputFile=".\Release/sip_options_static.exe"\r
+ OutputFile=".\Release\sip_options_static.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/sip_options_static.pdb"\r
+ ProgramDatabaseFile=".\Release\sip_options_static.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/sip_options_static.bsc"\r
+ OutputFile=".\Release\sip_options_static.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/sip_options_static.tlb"\r
+ TypeLibraryName=".\Debug\sip_options_static.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/sip_options_static.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\sip_options_static.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib advapi32.lib iphlpapi.lib"\r
- OutputFile=".\Debug/sip_options_static.exe"\r
+ OutputFile=".\Debug\sip_options_static.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/sip_options_static.pdb"\r
+ ProgramDatabaseFile=".\Debug\sip_options_static.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/sip_options_static.bsc"\r
+ OutputFile=".\Debug\sip_options_static.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Debug/stunc.tlb"\r
+ TypeLibraryName=".\Debug\stunc.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="3"\r
- PrecompiledHeaderFile=".\Debug/stunc.pch"\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ PrecompiledHeaderFile=".\Debug\stunc.pch"\r
+ AssemblerListingLocation=".\Debug\"\r
+ ObjectFile=".\Debug\"\r
+ ProgramDataBaseFileName=".\Debug\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Debug/stunc.exe"\r
+ OutputFile=".\Debug\stunc.exe"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\Debug/stunc.pdb"\r
+ ProgramDatabaseFile=".\Debug\stunc.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Debug/stunc.bsc"\r
+ OutputFile=".\Debug\stunc.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
TargetEnvironment="1"\r
- TypeLibraryName=".\Release/stunc.tlb"\r
+ TypeLibraryName=".\Release\stunc.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
StringPooling="true"\r
RuntimeLibrary="2"\r
EnableFunctionLevelLinking="true"\r
- PrecompiledHeaderFile=".\Release/stunc.pch"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ PrecompiledHeaderFile=".\Release\stunc.pch"\r
+ AssemblerListingLocation=".\Release\"\r
+ ObjectFile=".\Release\"\r
+ ProgramDataBaseFileName=".\Release\"\r
WarningLevel="4"\r
WarnAsError="true"\r
SuppressStartupBanner="true"\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib"\r
- OutputFile=".\Release/stunc.exe"\r
+ OutputFile=".\Release\stunc.exe"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- ProgramDatabaseFile=".\Release/stunc.pdb"\r
+ ProgramDatabaseFile=".\Release\stunc.pdb"\r
SubSystem="1"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCBscMakeTool"\r
SuppressStartupBanner="true"\r
- OutputFile=".\Release/stunc.bsc"\r
+ OutputFile=".\Release\stunc.bsc"\r
/>\r
<Tool\r
Name="VCFxCopTool"\r