merge with sofia darcs trunk:

Fri Oct 12 08:42:17 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * Makefile.am: fixed ordering of SUBDIRS

Fri Oct 12 13:32:02 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * win32/utils/stunc.dsp: fixed include paths

Fri Oct 12 13:32:19 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * win32/tests/torture_su_root: fixed include paths

Fri Oct 12 13:32:52 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * win32: added missing files from Makefile.am, .dsp, vproj

Fri Oct 12 13:33:42 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * win32/build_sources.cmd: added extra headers to sip_tag.c and sip_parser_table.c

Fri Oct 12 13:37:00 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * win32/check.cmd: added option -a to relevant tests. 
    Optionally check Release build.

Fri Oct 12 13:37:25 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * url.h: silenced warning on URL_INIT_AS()

Fri Oct 12 13:37:43 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * tstdef.h: silenced warnings on TEST_M()

Fri Oct 12 13:38:15 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * nta_internal.h, nua_params.c: fixed NTATAG_UDP_MTU() type

Fri Oct 12 13:39:06 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_class.h: fixed test_auth_class, test_numeric_class declaration

Fri Oct 12 13:39:51 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * Fixed various tests on win32.

Fri Oct 12 13:39:58 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * sip_basic.c: removed dead code

Fri Oct 12 14:38:02 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * nea_server.c: avoid raporting un-SUBSCRIBE twice

Fri Oct 12 14:38:31 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_sip_events.c: checking some nua_i_notifier/nua_i_subscriber events

Fri Oct 12 14:38:42 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  tagged Release candidate 2 for 1.12.7

Mon Oct 15 04:03:22 EDT 2007  Pekka.Pessi@nokia.com
  * configure.ac, RELEASE: version 1.12.7

Mon Oct 15 08:27:13 EDT 2007  Pekka.Pessi@nokia.com
  * open_c: included in the dist

Tue Oct 16 08:07:46 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * nua: Open C fixes

Wed Oct 17 06:50:11 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * nua.docs: replace reference to nua_cli.c with sofsip_cli

Wed Oct 17 08:43:11 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  tagged rel-sofia-sip-1_12_7

Wed Oct 17 08:43:15 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  tagged 1.12.7

Wed Oct 17 11:01:12 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * libsofia-sip-ua/su/Makefile.am: fixed problem with automake 1.9

Wed Oct 17 11:13:15 EDT 2007  Pekka.Pessi@nokia.com
  * configure.ac, RELEASE: opened tree for development

Tue Oct 23 10:45:17 EDT 2007  Pekka.Pessi@nokia.com
  * su_alloc.c: fixed su_home_init() (not initializing pointer to mutexes)

Thu Oct 25 13:15:45 EDT 2007  Pekka.Pessi@nokia.com
  * nua_notifier.c: updated nua_i_subscribe, nua_notify() and nua_r_notify documentation

Wed Nov  7 07:58:08 EST 2007  Pekka.Pessi@nokia.com
  * sofia-sip/htable2.h: fixed HTABLE_PROTOS2()



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6219 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris committed 2007-11-12 16:04:47 +00:00
1 parent 3f4fd53c97
commit 8ff118dc2c
37 files changed
+689 -300

No files matched your search

+10 -6
View File
@@ -13,21 +13,25 @@ AUTOMAKE_OPTIONS = foreign
# in the build
OPT_LIBADD =
OPT_SUBDIRS_STUN =
OPT_SUBDIRS_HTTP =
OPT_SUBDIRS_NTH =
if HAVE_STUN
OPT_LIBADD += stun/libstun.la
OPT_SUBDIRS_STUN += stun
endif
if HAVE_NTH
OPT_LIBADD += nth/libnth.la http/libhttp.la
OPT_SUBDIRS_NTH += nth http
OPT_LIBADD += http/libhttp.la nth/libnth.la
OPT_SUBDIRS_HTTP += http
OPT_SUBDIRS_NTH += nth
endif
# note: order does matter in the subdir list
SUBDIRS = su features bnf sresolv sdp url msg sip $(OPT_SUBDIRS_STUN) ipt soa \
tport nta nea iptsec $(OPT_SUBDIRS_NTH) nua
DIST_SUBDIRS = su features bnf sresolv sdp url msg sip stun ipt soa \
tport nta nea iptsec nth http nua docs
SUBDIRS = su features bnf sresolv ipt sdp url msg sip $(OPT_SUBDIRS_HTTP) \
$(OPT_SUBDIRS_STUN) soa tport nta $(OPT_SUBDIRS_NTH) \
nea iptsec nua
DIST_SUBDIRS = su features bnf sresolv ipt sdp url msg sip http \
stun soa tport nta nth \
nea iptsec nua docs
DOXYGEN = doxygen
@@ -172,7 +172,7 @@ enum {
msg_numeric_hash = 24435
};
SOFIAPUBVAR msg_hclass_t test_auth_class[1], test_numeric_class[1];
extern msg_hclass_t test_auth_class[1], test_numeric_class[1];
SOFIA_END_DECLS
+20 -13
View File
@@ -201,6 +201,8 @@ struct nea_sub_s {
sip_content_type_t *s_content_type; /** Content-Type of SUBSCRIBE body. */
sip_payload_t *s_payload; /**< Body of SUBSCRIBE. */
unsigned s_reported :1 ; /**< Made watcher report upon un-SUBSCRIBE */
unsigned s_processing : 1;
unsigned s_rejected : 1;
unsigned s_pending_flush : 1;
@@ -1384,14 +1386,18 @@ static
int nes_watcher_callback(nea_server_t *nes,
nea_event_t *ev,
nea_sub_t *s,
sip_t const *sip)
sip_t const *sip,
sip_time_t now)
{
if (!nes->nes_in_callback) {
nes->nes_in_callback = 1;
if (ev->ev_callback) {
if (ev->ev_callback && !s->s_reported) {
nea_subnode_t sn[1];
nea_subnode_init(sn, s, sip_now());
nea_subnode_init(sn, s, now);
if (sn->sn_expires == 0 || sn->sn_state == nea_terminated)
s->s_reported = 1;
ev->ev_callback(nes, ev->ev_magic, ev, sn, sip);
}
@@ -1908,13 +1914,15 @@ int nea_sub_process_subscribe(nea_sub_t *s,
}
/* Callback for checking subscriber authorization */
if (nes_watcher_callback(nes, ev, s, sip) < 0) {
if (nes_watcher_callback(nes, ev, s, sip, now) < 0) {
if (irq) {
nta_incoming_treply(irq, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
nta_incoming_destroy(irq);
}
return -1;
}
evv = s->s_view; /* Callback can change event view */
@@ -1975,7 +1983,7 @@ int nea_sub_notify(nea_server_t *nes, nea_sub_t *s,
{
int notified = 0;
ta_list ta;
int subscription_state_change = now == 0;
int suppress = now != 0;
nea_event_t *ev = s->s_event;
nea_state_t substate = s->s_state;
@@ -1990,7 +1998,7 @@ int nea_sub_notify(nea_server_t *nes, nea_sub_t *s,
assert(s->s_view); assert(ev);
if (!subscription_state_change && s->s_view->evv_updated == s->s_updated)
if (suppress && s->s_view->evv_updated == s->s_updated)
return 0;
if (now == 0)
@@ -2069,7 +2077,7 @@ int nea_sub_notify(nea_server_t *nes, nea_sub_t *s,
break;
}
subscription_state_change = (s->s_view->evv_updated == s->s_updated);
suppress = (s->s_view->evv_updated == s->s_updated);
n_evq = evq->evq_payload ? evq : evv->evv_primary->evv_head;
@@ -2083,9 +2091,9 @@ int nea_sub_notify(nea_server_t *nes, nea_sub_t *s,
SIPTAG_USER_AGENT_STR(nes->nes_server),
SIPTAG_CONTACT(s->s_local),
SIPTAG_EVENT(s->s_id),
TAG_IF(!subscription_state_change,
TAG_IF(!suppress,
SIPTAG_CONTENT_TYPE(n_evq->evq_content_type)),
TAG_IF(!subscription_state_change,
TAG_IF(!suppress,
SIPTAG_PAYLOAD(n_evq->evq_payload)),
ta_tags(ta));
@@ -2104,7 +2112,7 @@ int nea_sub_notify(nea_server_t *nes, nea_sub_t *s,
if (callback == NULL) {
nta_outgoing_destroy(s->s_oreq), s->s_oreq = NULL;
/* Inform the application of a subscriber leaving the subscription. */
nes_watcher_callback(nes, ev, s, NULL);
nes_watcher_callback(nes, ev, s, NULL, now);
}
}
ta_end(ta);
@@ -2127,6 +2135,7 @@ int response_to_notify(nea_sub_t *s,
{
nea_server_t *nes = s->s_nes;
int status = sip->sip_status->st_status;
sip_time_t now = sip_now();
if (status < 200)
return 0;
@@ -2135,8 +2144,6 @@ int response_to_notify(nea_sub_t *s,
if (status < 300) {
if (s->s_view->evv_updated != s->s_updated) {
sip_time_t now = sip_now();
if (s->s_notified + s->s_throttle <= now)
nea_sub_notify(nes, s, now, TAG_END());
else
@@ -2148,7 +2155,7 @@ int response_to_notify(nea_sub_t *s,
SU_DEBUG_5(("nea_server: removing subscriber " URL_PRINT_FORMAT "\n",
URL_PRINT_ARGS(s->s_from->a_url)));
/* Inform the application of a subscriber leaving the subscription. */
nes_watcher_callback(nes, s->s_event, s, NULL);
nes_watcher_callback(nes, s->s_event, s, NULL, now);
}
return 0;
+3 -3
View File
@@ -332,15 +332,15 @@ message sequence charts.
@image html SIP_outgoing_operation_with_auth.gif
@section nua_simpleapplication Simple Application
The following sections will present code examples from a simple application
that uses services of NUA. The example is not complete but should present
all relevant details of the basic use of NUA.
The source distribution of Sofia stack contains in directory nua an example
application nua_cli.c that can be studied for more complete example.
On sourceforge.net there is available an example application
<a href="http://sourceforge.net/project/showfiles.php?group_id=143636&package_id=179933">
sofisip_cli.c</a> that can be studied for more complete example.
@subsection nua_datastructures Data Structures & Defines
@@ -129,28 +129,6 @@ void nua_notify_usage_remove(nua_handle_t *nh,
* @b SUBSCRIBE request is used to query SIP event state or establish a SIP
* event subscription.
*
* Initial SUBSCRIBE requests are dropped with <i>489 Bad Event</i>
* response, unless the application has explicitly included the @Event in
* the list of allowed events with nua_set_params() tag NUTAG_ALLOW_EVENTS()
* (or SIPTAG_ALLOW_EVENTS() or SIPTAG_ALLOW_EVENTS_STR()). The application
* can decide whether to accept the SUBSCRIBE request or reject it. The
* nua_response() call responding to a SUBSCRIBE request must have
* NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag.
*
* If the application accepts the SUBSCRIBE request, it must immediately
* send an initial NOTIFY establishing the dialog. This is because the
* response to the SUBSCRIBE request may be lost because the SUBSCRIBE
* request was forked by an intermediate proxy.
*
* SUBSCRIBE requests modifying (usually refreshing or terminating) an
* existing event subscription are accepted by default and a <i>200 OK</i>
* response along with a copy of previously sent NOTIFY is sent
* automatically.
*
* By default, only event subscriptions accepted are those created
* implicitly by REFER request. See #nua_i_refer how the application must
* handle the REFER requests.
*
* @param status status code of response sent automatically by stack
* @param phrase response phrase sent automatically by stack
* @param nh operation handle associated with the incoming request
@@ -159,6 +137,46 @@ void nua_notify_usage_remove(nua_handle_t *nh,
* @param sip SUBSCRIBE request headers
* @param tags NUTAG_SUBSTATE()
*
* Initial SUBSCRIBE requests are dropped with <i>489 Bad Event</i>
* response, unless the application has explicitly included the @Event in
* the list of allowed events with nua_set_params() tag NUTAG_ALLOW_EVENTS()
* (or SIPTAG_ALLOW_EVENTS() or SIPTAG_ALLOW_EVENTS_STR()).
*
* If the event has been allowed the application
* can decide whether to accept the SUBSCRIBE request or reject it. The
* nua_response() call responding to a SUBSCRIBE request must have
* NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag.
*
* If the application accepts the SUBSCRIBE request, it must immediately
* send an initial NOTIFY establishing the dialog. This is because the
* response to the SUBSCRIBE request may be lost by an intermediate proxy
* because it had forked the SUBSCRIBE request.
*
* SUBSCRIBE requests modifying (usually refreshing or terminating) an
* existing event subscription are accepted by default and a <i>200 OK</i>
* response along with a copy of previously sent NOTIFY is sent
* automatically to the subscriber.
*
* By default, only event subscriptions accepted are those created
* implicitly by REFER request. See #nua_i_refer how the application must
* handle the REFER requests.
*
* @par Subscription Lifetime and Terminating Subscriptions
*
* Accepting the SUBSCRIBE request creates a dialog with a <i>notifier
* dialog usage</i> on the handle. The dialog usage is active, until the
* subscriber terminates the subscription, it times out or the application
* terminates the usage with nua_notify() call containing the tag
* NUTAG_SUBSTATE(nua_substate_terminated) or @SubscriptionState header with
* state "terminated" and/or expiration time 0.
*
* When the subscriber terminates the subscription, the application is
* notified of an termination by a #nua_i_subscribe event with
* NUTAG_SUBSTATE(nua_substate_terminated) tag. When the subscription times
* out, nua automatically initiates a NOTIFY transaction. When it is
* terminated, the application is sent a #nua_r_notify event with
* NUTAG_SUBSTATE(nua_substate_terminated) tag.
*
* @sa @RFC3265, nua_notify(), NUTAG_SUBSTATE(), @SubscriptionState,
* @Event, nua_subscribe(), #nua_r_subscribe, #nua_i_refer, nua_refer()
*
@@ -351,11 +369,22 @@ int nua_subscribe_server_report(nua_server_request_t *sr, tagi_t const *tags)
*
* This function is used when the application implements itself the
* notifier. The application must provide valid @SubscriptionState and
* @Event headers using SIP tags. If there is no @SubscriptionState header,
* the subscription state can be modified with NUTAG_SUBSTATE().
* @Event headers using SIP tags. The subscription state can be modified
* with NUTAG_SUBSTATE(), however, its effect is overriden by
* @SubscriptionState header included in the nua_notify() tags.
*
* @bug If the @Event is not given by application, stack uses the @Event
* header from the first subscription usage on handle.
*
* If there is no active <i>notifier dialog usage</i> or no notifier dialog
* usage matches the @Event header given by the application the nua_notify()
* request is rejected locally by the stack with status code 481. The local
* rejection can be bypassed if NUTAG_NEWSUB(1) is included in tags.
*
* Please note that including NUTAG_NEWSUB(1) in nua_notify() tags if there
* is a valid subscription may lead to an extra NOTIFY sent to subscriber if
* the subscription had been terminated by the subscriber or by a timeout
* before the nua_notify() is processed.
*
* @param nh Pointer to operation handle
* @param tag, value, ... List of tagged parameters
@@ -365,6 +394,7 @@ int nua_subscribe_server_report(nua_server_request_t *sr, tagi_t const *tags)
*
* @par Related Tags:
* NUTAG_SUBSTATE() \n
* NUTAG_NEWSUB() \n
* Tags of nua_set_hparams() \n
* Header tags defined in <sofia-sip/sip_tag.h>
*
@@ -461,8 +491,11 @@ static int nua_notify_client_init(nua_client_request_t *cr,
if (now + expires < now)
expires = SIP_TIME_MAX - now - 1;
/* Notifier can only shorten the subscription time */
if (nu->nu_requested == 0 || nu->nu_requested >= now + expires)
/* We can change the lifetime of unsolicited subscription at will */
if (nu->nu_requested == 0)
nu->nu_expires = nu->nu_requested = now + expires;
/* Notifier can only shorten the subscribed time */
else if (nu->nu_requested >= now + expires)
nu->nu_expires = nu->nu_requested = now + expires;
}
}
@@ -648,7 +681,12 @@ int nua_notify_client_request(nua_client_request_t *cr,
* The @b NOTIFY may be sent explicitly by nua_notify() or implicitly by NUA
* state machine. Implicit @b NOTIFY is sent when an established dialog is
* refreshed by client or it is terminated (either by client or because of a
* timeout)
* timeout).
*
* The current subscription state is included in NUTAG_SUBSTATE() tag. The
* nua_substate_terminated indicates that the subscription is terminated,
* the notifier usage has been removed and when there was no other usages of
* the dialog the dialog state is also removed.
*
* @param status response status code
* (if the request is retried, @a status is 100, the @a
@@ -663,7 +701,7 @@ int nua_notify_client_request(nua_client_request_t *cr,
* @param tags NUTAG_SUBSTATE() indicating subscription state
* SIPTAG_EVENT() indicating subscription event
*
* @sa nua_notify(), @RFC3265, #nua_i_subscribe, #nua_i_refer
* @sa nua_notify(), @RFC3265, #nua_i_subscribe, #nua_i_refer, NUTAG_SUBSTATE()
*
* @END_NUA_EVENT
*/
@@ -1525,7 +1525,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
sip_contact_t const *m;
/* nta */
usize_t udp_mtu = 0;
unsigned udp_mtu = 0;
usize_t max_proceeding = 0;
unsigned sip_t1 = 0, sip_t2 = 0, sip_t4 = 0, sip_t1x64 = 0;
unsigned debug_drop_prob = 0;
@@ -1003,6 +1003,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
msg_t *msg,
int error)
{
nua_dialog_usage_t *du = nua_dialog_usage_public(nr);
tp_name_t const *tpn;
int pending = nr->nr_error_report_id;
@@ -1018,7 +1019,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
tpn = tport_name(nr->nr_tport);
SU_DEBUG_5(("nua_register(%p): tport to %s/%s:%s%s%s closed %s\n",
nua_dialog_usage_public(nr)->du_dialog->ds_owner,
du->du_dialog->ds_owner,
tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port,
tpn->tpn_comp ? ";comp=" : "",
tpn->tpn_comp ? tpn->tpn_comp : "",
@@ -1027,7 +1028,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
tport_unref(nr->nr_tport), nr->nr_tport = NULL;
/* Schedule re-REGISTER immediately */
nua_dialog_usage_set_refresh_range(nua_dialog_usage_public(nr), 0, 0);
nua_dialog_usage_set_refresh_range(du, 0, 0);
}
@@ -330,8 +330,6 @@ int main(int argc, char *argv[])
ctx->a.printer = o_events_init ? print_event : NULL;
sleep(2);
retval |= test_nua_api_errors(ctx); SINGLE_FAILURE_CHECK();
retval |= test_tag_filter(); SINGLE_FAILURE_CHECK();
@@ -86,7 +86,7 @@ STORAGE void PREFIX ##_remove(T *node) \
} \
extern int LIST_DUMMY_VARIABLE
#include <test_proxy.h>
#include "test_proxy.h"
#include <sofia-sip/auth_module.h>
struct proxy {
@@ -99,6 +99,7 @@ int test_events(struct context *ctx)
sip_t const *sip;
tagi_t const *t, *n_tags, *r_tags;
url_t b_url[1];
enum nua_substate substate;
nea_sub_t *sub = NULL;
char const open[] =
@@ -207,7 +208,7 @@ int test_events(struct context *ctx)
TAG_END());
run_ab_until(ctx, -1, save_until_notified_and_responded,
-1, NULL /* XXX save_until_received */);
-1, save_until_received);
/* Client events:
nua_subscribe(), nua_i_notify/nua_r_subscribe
@@ -242,6 +243,9 @@ int test_events(struct context *ctx)
TEST_1(!en->next || !es->next);
free_events_in_list(ctx, a->events);
/* XXX --- Do not check server side events */
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-12.2: PASSED\n");
@@ -266,8 +270,7 @@ int test_events(struct context *ctx)
SIPTAG_PAYLOAD_STR(open),
TAG_END());
run_ab_until(ctx, -1, save_until_notified,
-1, NULL /* XXX save_until_received */);
run_ab_until(ctx, -1, save_until_notified, -1, save_until_received);
/* subscriber events:
nua_i_notify
@@ -287,6 +290,9 @@ int test_events(struct context *ctx)
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
/* XXX --- Do not check server side events */
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-12.3: PASSED\n");
@@ -308,7 +314,7 @@ int test_events(struct context *ctx)
UNSUBSCRIBE(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, save_until_final_response,
-1, NULL /* XXX save_until_received */);
-1, save_until_subscription);
/* Client events:
nua_unsubscribe(), nua_i_notify/nua_r_unsubscribe
@@ -335,6 +341,19 @@ int test_events(struct context *ctx)
/* TEST_1(!e->next); */
free_events_in_list(ctx, a->events);
/* Server events: nua_i_subscription with terminated status */
TEST_1(e = b->events->head);
TEST_E(e->data->e_event, nua_i_subscription);
TEST(tl_gets(e->data->e_tags,
NEATAG_SUB_REF(sub),
NUTAG_SUBSTATE_REF(substate),
TAG_END()), 2);
TEST_1(sub);
TEST(substate, nua_substate_terminated);
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-12.5: PASSED\n");
@@ -18,7 +18,7 @@ bin_PROGRAMS = addrinfo localinfo
check_PROGRAMS = torture_su torture_su_port \
torture_su_alloc torture_su_time torture_su_tag \
test_htable torture_rbtree torture_heap \
test_htable test_htable2 torture_rbtree torture_heap \
test_memmem torture_su_bm \
torture_su_root torture_su_timer \
test_su su_proxy test_poll $(OSXPROGS)
@@ -28,7 +28,7 @@ check_PROGRAMS = torture_su torture_su_port \
TESTS = torture_su torture_su_port \
torture_su_alloc torture_su_time torture_su_tag \
test_htable torture_rbtree torture_heap \
test_htable test_htable2 torture_rbtree torture_heap \
test_memmem torture_su_bm \
torture_su_root torture_su_timer \
run_addrinfo run_localinfo run_test_su \
@@ -80,7 +80,11 @@ EXTRA_libsu_la_SOURCES = \
memmem.c strtoull.c strcasestr.c \
memspn.c memcspn.c memccpy.c \
inet_ntop.c inet_pton.c poll.c getopt.c \
su_tag_ref.c su_win32_port.c
su_tag_ref.c
# Automake 1.9 complains about missing CXX
EXTRA_DIST = su_win32_port.c \
su_open_c_localinfo.cpp
libsu_la_LIBADD = $(REPLACE_LIBADD)
libsu_la_DEPENDENCIES = $(REPLACE_LIBADD)
@@ -92,7 +96,7 @@ LDADD = libsu.la
# ----------------------------------------------------------------------
# Install and distribution rules
EXTRA_DIST = su.docs \
EXTRA_DIST += su.docs \
run_addrinfo run_localinfo run_test_su
dist_pkgdata_SCRIPTS = tag_dll.awk
@@ -141,6 +141,8 @@ int prefix##_resize(su_home_t *home, \
new_size = 2 * pr->pr##_size + 1; \
if (new_size < HTABLE_MIN_SIZE) \
new_size = HTABLE_MIN_SIZE; \
if (new_size < 5 * pr->pr##_used / 4) \
new_size = 5 * pr->pr##_used / 4; \
\
if (!(new_hash = su_zalloc(home, sizeof(*new_hash) * new_size))) \
return -1; \
@@ -169,6 +171,8 @@ int prefix##_resize(su_home_t *home, \
pr->pr##_table = new_hash, pr->pr##_size = new_size; \
\
assert(pr->pr##_used == used); \
\
su_free(home, old_hash); \
\
return 0; \
} \
@@ -30,8 +30,9 @@
*
* Hash tables templates, take 2.
*
* Note: this version can handle structures as entries, and it can be used
* without <sofia-sip/su_alloc.h>.
* Note: this version stores the given element types as entries (instead of
* 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
@@ -66,21 +67,24 @@ typedef unsigned long hash_value_t;
/** Declare hash table structure type.
*
* The macro HTABLE2_DECLARE() expands to a declaration for hash table
* structure. The its typedef will be <em>prefix</em><code>_t</code>, the
* field names start with @a pr. The entry type is @a entrytype.
* The macro HTABLE2_DECLARE2() expands to a declaration for hash table
* structure. The its typedef will be @a type, the field names start with @a
* pr. The entry type is @a entrytype.
*
* @param type hash table typedef
* @param sname name of struct
* @param prefix hash table type and function prefix
* @param pr hash table field prefix
* @param entrytype entry type
*/
#define HTABLE2_DECLARE2(type, sname, pr, entrytype, size_t) \
typedef struct sname { \
size_t pr##size; \
size_t pr##used; \
entrytype *pr##table; \
} type
#define HTABLE2_DECLARE(sname, prefix, pr, entrytype) \
struct sname { \
unsigned pr##size; \
unsigned pr##used; \
entrytype *pr##table; /**< Hash table itself */ \
}
HTABLE2_DECLARE2(prefix##t, sname, pr, entrytype, unsigned)
#ifndef HTABLE2_SCOPE
/** Default scope for hash table functions. */
@@ -89,27 +93,30 @@ struct sname { \
/** Prototypes for hash table
*
* The macro HTABLE2_PROTOS() expands to the prototypes of hash table
* The macro HTABLE2_PROTOS2() expands to the prototypes of hash table
* functions. The function and type names start with @a prefix, the field
* names start with @a pr. The entry type is @a entrytype.
*
* @param type hash table typedef
* @param prefix function prefix
* @param pr hash table field prefix
* @param pr hash table field prefix (not used)
* @param entrytype entry type
*/
#define HTABLE2_PROTOS(type, prefix, pr, entrytype) \
HTABLE2_SCOPE int prefix##_resize(void *a, type pr[1], unsigned); \
#define HTABLE2_PROTOS2(type, prefix, pr, entrytype, size_t) \
HTABLE2_SCOPE int prefix##_resize(void *a, type *, size_t); \
HTABLE2_SCOPE int prefix##_is_full(type const *); \
HTABLE2_SCOPE entrytype *prefix##_hash(type const *, hash_value_t hv); \
HTABLE2_SCOPE entrytype *prefix##_next(type const *, entrytype *ee); \
HTABLE2_SCOPE void prefix##_append(type *pr, entrytype e); \
HTABLE2_SCOPE void prefix##_insert(type *pr, entrytype e); \
HTABLE2_SCOPE int prefix##_remove(type *, entrytype const e)
HTABLE2_SCOPE entrytype *prefix##_hash(type const *, hash_value_t); \
HTABLE2_SCOPE entrytype *prefix##_next(type const *, entrytype *); \
HTABLE2_SCOPE entrytype *prefix##_append(type *, entrytype); \
HTABLE2_SCOPE entrytype *prefix##_insert(type *, entrytype); \
HTABLE2_SCOPE int prefix##_remove(type *, entrytype const)
#define HTABLE2_PROTOS(type, prefix, pr, entrytype) \
HTABLE2_PROTOS2(type, prefix, pr, entrytype, unsigned)
/** Hash table implementation.
*
* The macro HTABLE2_BODIES() expands the hash table functions. The function
* The macro HTABLE2_BODIES2() expands the hash table functions. The function
* and type names start with @a prefix, the field names start with @a pr.
* The entry type is @a entrytype. The function (or macro) name returning
* hash value of each entry is given as @a hfun.
@@ -118,25 +125,26 @@ HTABLE2_SCOPE int prefix##_remove(type *, entrytype const e)
* @param prefix function prefix for hash table
* @param pr field prefix for hash table
* @param entrytype type of entry element
* @param size_t size_t type
* @param hfun function or macro returning hash value of entry
* @param is_used function or macro returning true if entry is occupied
* @param reclaim function or macro zeroing entry
* @param is_equal equality test
* @param halloc function allocating or freeing memory
*/
#define HTABLE2_BODIES(type, prefix, pr, entrytype, \
hfun, is_used, reclaim, is_equal, halloc) \
#define HTABLE2_BODIES2(type, prefix, pr, entrytype, size_t, \
hfun, is_used, reclaim, is_equal, halloc) \
/** Reallocate new hash table */ \
HTABLE2_SCOPE \
int prefix##_resize(void *realloc_arg, \
type pr[1], \
unsigned new_size) \
usize_t new_size) \
{ \
entrytype *new_hash; \
entrytype *old_hash = pr->pr##table; \
unsigned old_size; \
unsigned i, j, i0; \
unsigned again = 0, used = 0, collisions = 0; \
usize_t old_size; \
usize_t i, j, i0; \
usize_t again = 0, used = 0, collisions = 0; \
\
(void)realloc_arg; \
\
@@ -144,11 +152,15 @@ int prefix##_resize(void *realloc_arg, \
new_size = 2 * pr->pr##size + 1; \
if (new_size < HTABLE2_MIN_SIZE) \
new_size = HTABLE2_MIN_SIZE; \
if (new_size < 5 * pr->pr##used / 4) \
new_size = 5 * pr->pr##used / 4; \
\
if (!(new_hash = halloc(realloc_arg, NULL, sizeof(*new_hash) * new_size))) \
return -1; \
\
memset(new_hash, 0, sizeof(*new_hash) * new_size); \
for (i = 0; i < new_size; i++) { \
(reclaim(&new_hash[i])); \
} \
old_size = pr->pr##size; \
\
do for (j = 0; j < old_size; j++) { \
@@ -202,9 +214,13 @@ entrytype *prefix##_next(type const *pr, entrytype *ee) \
} \
\
HTABLE2_SCOPE \
void prefix##_append(type *pr, entrytype e) \
entrytype *prefix##_append(type *pr, entrytype e) \
{ \
entrytype *ee; \
\
assert(pr->pr##used < pr->pr##size); \
if (pr->pr##used == pr->pr##size) \
return (entrytype *)0; \
\
pr->pr##used++; \
for (ee = prefix##_hash(pr, hfun(e)); \
@@ -212,13 +228,19 @@ void prefix##_append(type *pr, entrytype e) \
ee = prefix##_next(pr, ee)) \
; \
*ee = e; \
\
return ee; \
} \
\
HTABLE2_SCOPE \
void prefix##_insert(type *pr, entrytype e) \
entrytype *prefix##_insert(type *pr, entrytype e) \
{ \
entrytype e0; \
entrytype *ee; \
\
assert(pr->pr##used < pr->pr##size); \
if (pr->pr##used == pr->pr##size) \
return (entrytype *)0; \
\
pr->pr##used++; \
/* Insert entry into hash table (before other entries with same hash) */ \
@@ -227,12 +249,14 @@ void prefix##_insert(type *pr, entrytype e) \
ee = prefix##_next(pr, ee)) \
*ee = e, e = e0; \
*ee = e; \
\
return ee; \
} \
\
HTABLE2_SCOPE \
int prefix##_remove(type *pr, entrytype const e) \
{ \
unsigned i, j, k, size = pr->pr##size; \
usize_t i, j, k, size = pr->pr##size; \
entrytype *htable = pr->pr##table; \
\
/* Search for entry */ \
@@ -263,4 +287,10 @@ int prefix##_remove(type *pr, entrytype const e) \
} \
extern int const prefix##_dummy
#define HTABLE2_BODIES(type, prefix, pr, entrytype, \
hfun, is_used, reclaim, is_equal, halloc) \
HTABLE2_BODIES2(type, prefix, pr, entrytype, unsigned, \
hfun, is_used, reclaim, is_equal, halloc)
#endif /** !defined(HTABLE2_H) */
@@ -319,13 +319,13 @@ enum {
/** @HIDE */
#define TEST_M_(flags, suite, expect, len) do { \
void const * _value, * _expect; \
int _len; \
size_t _len; \
if (flags & tst_verbatim) { \
printf("%s: %s%stesting %s is %s\n", TSTNAME, #suite, #expect); \
fflush(stdout); } \
_value = (suite); \
_expect = (expect); \
_len = (len); \
_len = (size_t)(len); \
if (((_value == NULL || _expect == NULL) && _value == _expect) || \
memcmp(_value, _expect, _len) == 0) \
{ if (flags & tst_verbatim) \
@@ -333,7 +333,8 @@ enum {
fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s "\
"or \"%.*s\" != \"%.*s\"\n", \
__FILE__, __LINE__, TSTNAME, \
#suite, #expect, _len, (char *)_value, _len, (char *)_expect); \
#suite, #expect, (int)_len, \
(char *)_value, (int)_len, (char *)_expect); \
fflush(stderr); \
TEST_FAILED(flags); \
} while(0)
@@ -915,6 +915,11 @@ void su_home_destroy(su_home_t *home)
* @retval -1 upon an error.
*
* @sa SU_HOME_INIT(), su_home_deinit(), su_home_new(), su_home_clone()
*
* @bug
* Prior to @VERSION_1_12_8 the su_home_t structure should have been
* initialized with SU_HOME_INIT() or otherwise zeroed before calling
* su_home_init().
*/
int su_home_init(su_home_t *home)
{
@@ -924,6 +929,8 @@ int su_home_init(su_home_t *home)
return -1;
home->suh_blocks = sub = su_hash_alloc(SUB_N);
home->suh_lock = NULL;
if (!sub)
return -1;
@@ -157,18 +157,23 @@ void zap(context_t *c, entry_t *e)
su_free(c->c_home, e);
}
/*
* Check that all n entries with hash h are in hash table
* and they are stored in same order
* in which they were added to the hash
*/
static unsigned long count(context_t *c, hash_value_t h)
{
entry_t *e, **ee;
unsigned long n;
unsigned long n, expect = 1;
for (ee = htable_hash(c->c_hash, h), n = 0;
(e = *ee);
ee = htable_next(c->c_hash, ee)) {
if (e->e_value != h)
continue;
if (e->e_n == n)
n++;
if (e->e_n == expect)
n++, expect++;
}
return n;
@@ -218,9 +223,9 @@ int table_test(int flags)
for correct ordering */
hash_value_t size = c->c_hash->ht_size, h = size - 1;
TEST_1(add(c, h, 0)); TEST_1(add(c, h, 1)); TEST_1(add(c, h, 2));
TEST_1(add(c, h, 3)); TEST_1(add(c, h, 4)); TEST_1(add(c, h, 5));
TEST_1(add(c, h, 6)); TEST_1(add(c, h, 7)); TEST_1(add(c, h, 8));
TEST_1(add(c, h, 1)); TEST_1(add(c, h, 2)); TEST_1(add(c, h, 3));
TEST_1(add(c, h, 4)); TEST_1(add(c, h, 5)); TEST_1(add(c, h, 6));
TEST_1(add(c, h, 7)); TEST_1(add(c, h, 8)); TEST_1(add(c, h, 9));
TEST(count(c, h), 9);
@@ -0,0 +1,267 @@
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@ingroup su_htable
*
* @CFILE test_htable.c
*
* Test functions for the @b su library hash table implementation.
*
* @internal
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Tue Aug 21 15:18:26 2001 ppessi
*/
#include "config.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <assert.h>
#include "sofia-sip/su_alloc.h"
#include "sofia-sip/htable2.h"
#define TSTFLAGS flags
#include <sofia-sip/tstdef.h>
char const name[] = "test_htable2";
void usage(int exitcode)
{
fprintf(stderr, "usage: %s [-v|--verbatim] [-a|--abort]\n", name);
exit(exitcode);
}
static int table2_test(int flags);
int main(int argc, char *argv[])
{
int flags = 0;
int retval = 0;
int i;
for (i = 1; argv[i]; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbatim") == 0)
flags |= tst_verbatim;
else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--abort") == 0)
flags |= tst_abort;
else
usage(1);
}
retval |= table2_test(flags); fflush(stdout);
return retval;
}
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;
unsigned long e_n;
};
#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)
#define HENTRY_IS_EQUAL(a, b) ((a).e_n == (b).e_n)
#define HALLOC(home, old, newsize) (su_realloc(home, old, newsize))
HTABLE2_BODIES2(htable2_t, htable2, ht2_, entry_t, size_t,
HENTRY_HASH, HENTRY_IS_USED, HENTRY_REMOVE, HENTRY_IS_EQUAL,
HALLOC);
typedef struct context_s
{
su_home_t c_home[1];
htable2_t c_hash[1];
} context_t;
context_t *context_create(void)
{
context_t *c = su_home_clone(NULL, sizeof(*c));
if (c)
htable2_resize(c->c_home, c->c_hash, 0);
return c;
}
static
entry_t *search(context_t *c, unsigned long value, unsigned long n, int add)
{
htable2_t *ht = c->c_hash;
entry_t *e;
unsigned long hash = value;
/* Search for entry in hash table */
for (e = htable2_hash(ht, hash);
e->e_n != 0;
e = htable2_next(ht, e)) {
if (e->e_hash == value && e->e_n == n)
return e;
}
if (add) {
entry_t entry;
/* Resize hash table */
if (htable2_is_full(ht)) {
htable2_resize(c->c_home, ht, 0);
fprintf(stderr, "htable: resized to "MOD_ZU" with "MOD_ZU" entries\n",
ht->ht2_size, ht->ht2_used);
}
/* Add an entry */
e = &entry, e->e_hash = value, e->e_n = n;
return htable2_append(ht, *e);
}
return NULL;
}
static int add(context_t *c, unsigned long value, unsigned long n)
{
return search(c, value, n, 1) != NULL;
}
static
void zap(context_t *c, entry_t e)
{
htable2_remove(c->c_hash, e);
}
/*
* Check that all n entries with hash h are in hash table
* and they are stored in same order
* in which they were added to the hash
*/
static unsigned long count(context_t *c, hash_value_t h)
{
entry_t *e;
unsigned long n;
unsigned long expect = 1;
for (e = htable2_hash(c->c_hash, h), n = 0;
e->e_n != 0;
e = htable2_next(c->c_hash, e)) {
if (e->e_hash != h)
continue;
if (e->e_n == expect)
n++, expect++;
}
return n;
}
int table2_test(int flags)
{
context_t *c;
entry_t *e, e0;
BEGIN();
TEST_1(c = context_create());
TEST_1(add(c, 0, 1)); TEST_1(c->c_hash->ht2_table[0].e_n == 1);
TEST_1(add(c, 1, 2)); TEST_1(c->c_hash->ht2_table[1].e_n == 2);
TEST_1(add(c, 2, 3)); TEST_1(c->c_hash->ht2_table[2].e_n == 3);
TEST_1(add(c, 0, 4)); TEST_1(c->c_hash->ht2_table[3].e_n == 4);
TEST_1(add(c, 2, 5)); TEST_1(c->c_hash->ht2_table[4].e_n == 5);
TEST_1(e = search(c, 1, 2, 0));
e0 = *e;
TEST(htable2_remove(c->c_hash, e0), 0);
TEST(htable2_remove(c->c_hash, e0), -1);
/* after remove , 4 is mode to [1], 5 to [4] */
TEST(c->c_hash->ht2_table[0].e_n, 1);
TEST(c->c_hash->ht2_table[1].e_n, 4);
TEST(c->c_hash->ht2_table[2].e_n, 3);
TEST(c->c_hash->ht2_table[3].e_n, 5);
TEST(c->c_hash->ht2_table[4].e_n, 0);
zap(c, c->c_hash->ht2_table[0]);
/* after remove , 4 is mode to [1], 5 to [4] */
TEST(c->c_hash->ht2_table[0].e_n, 4);
TEST(c->c_hash->ht2_table[1].e_n, 0);
TEST(c->c_hash->ht2_table[2].e_n, 3);
TEST(c->c_hash->ht2_table[3].e_n, 5);
TEST(c->c_hash->ht2_table[4].e_n, 0);
TEST_1(add(c, 0, 6)); TEST(c->c_hash->ht2_table[1].e_n, 6);
TEST_1(add(c, 1, 7)); TEST(c->c_hash->ht2_table[4].e_n, 7);
/* Test that zapping entry 0 does not move 2 and 3 */
zap(c, c->c_hash->ht2_table[0]);
TEST(c->c_hash->ht2_table[4].e_n, 0);
{
/* Insert entries at the end of hash, then resize and check
for correct ordering */
size_t size = c->c_hash->ht2_size;
hash_value_t h = (hash_value_t)size - 1;
TEST_1(add(c, h, 1)); TEST_1(add(c, h, 2)); TEST_1(add(c, h, 3));
TEST_1(add(c, h, 4)); TEST_1(add(c, h, 5)); TEST_1(add(c, h, 6));
TEST_1(add(c, h, 7)); TEST_1(add(c, h, 8)); TEST_1(add(c, h, 9));
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
TEST(htable2_resize(c->c_home, c->c_hash, ++size), 0);
TEST(count(c, h), 9);
}
TEST_VOID(su_home_unref(c->c_home));
END();
}
+2 -2
View File
@@ -52,7 +52,7 @@ struct pinger;
#include <assert.h>
char const name[] = "su_test";
char const name[] = "test_su";
#if HAVE_FUNC
#define enter (void)SU_DEBUG_9(("%s: %s: entering\n", name, __func__))
@@ -64,7 +64,7 @@ char const name[] = "su_test";
#else
#define enter ((void)0)
#define nh_enter ((void)0)
#define __func__ "su_test"
#define __func__ "test_su"
#endif
struct pinger {
@@ -69,6 +69,7 @@ static int test_alloc(void)
{
exhome_t *h0, *h1, *h2, *h3;
su_home_t home[1] = { SU_HOME_INIT(home) };
su_home_t home0[1];
enum { N = 40 };
void *m0[N], *m1[N], *m;
char *c, *c0, *p0, *p1;
@@ -78,6 +79,11 @@ static int test_alloc(void)
BEGIN();
/* su_home_init() was not initializing suh_locks */
memset(home0, 0xff, sizeof home0);
TEST(su_home_init(home0), 0);
TEST_VOID(su_home_deinit(home0));
TEST_1(h0 = su_home_new(sizeof(*h0)));
TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
@@ -165,6 +165,8 @@ void *suspend_resume_test_thread(void *_rt)
{
root_test_t *rt = _rt;
su_init();
pthread_mutex_lock(rt->rt_sr.mutex);
rt->rt_root = su_root_create(rt);
rt->rt_sr.done = 1;
@@ -177,6 +179,9 @@ void *suspend_resume_test_thread(void *_rt)
su_root_destroy(rt->rt_root);
rt->rt_root = NULL;
pthread_mutex_unlock(rt->rt_sr.deinit);
su_deinit();
return NULL;
}
#endif
@@ -192,8 +197,6 @@ int init_test(root_test_t *rt,
BEGIN();
su_init();
su_port_prefer(create, start);
#if SU_HAVE_PTHREADS
@@ -257,8 +260,6 @@ static int deinit_test(root_test_t *rt)
TEST_VOID(su_root_destroy(rt->rt_root)); rt->rt_root = NULL;
#endif
su_deinit();
END();
}
@@ -724,6 +725,8 @@ int main(int argc, char *argv[])
i = 0;
su_init();
do {
rt = rt1, *rt = *rt0;
@@ -739,5 +742,7 @@ int main(int argc, char *argv[])
retval |= deinit_test(rt);
} while (prefer[++i].create);
su_deinit();
return retval;
}
@@ -824,7 +824,7 @@ static int tcp_test(tp_test_t *tt)
BEGIN();
msg_t *msg = NULL;
int i;
int i, N;
tport_t *tp, *tp0;
char ident[16];
su_time_t started;
@@ -853,12 +853,15 @@ static int tcp_test(tp_test_t *tt)
pending_server_close = tport_pend(tp, NULL, server_closed_callback, NULL);
TEST_1(pending_server_close > 0);
N = 0; tt->tt_received = 0;
#ifndef WIN32 /* Windows seems to be buffering too much */
/* Create a large message, just to force queueing in sending end */
TEST(new_test_msg(tt, &msg, "tcp-0", 1, 16 * 64 * 1024), 0);
test_create_md5(tt, msg);
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
N++;
TEST_S(tport_name(tp)->tpn_ident, "client");
TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
msg_destroy(msg);
@@ -869,6 +872,7 @@ static int tcp_test(tp_test_t *tt)
TEST(new_test_msg(tt, &msg, ident, 1, 64 * 1024), 0);
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
N++;
TEST_S(tport_name(tp)->tpn_ident, "client");
TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
msg_destroy(msg);
@@ -879,8 +883,6 @@ static int tcp_test(tp_test_t *tt)
TEST_1(!tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
msg_destroy(msg);
tt->tt_received = 0;
TEST(tport_test_run(tt, 60), 1);
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-0"));
test_check_md5(tt, tt->tt_rmsg);
@@ -892,13 +894,15 @@ static int tcp_test(tp_test_t *tt)
TEST_1(!check_msg(tt, tt->tt_rmsg, ident));
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
}
#else
(void)i; (void)ident;
#endif
/* This uses a new connection */
TEST_1(!new_test_msg(tt, &msg, "tcp-no-reuse", 1, 1024));
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
TPTAG_REUSE(0), TAG_END()));
N++;
TEST_S(tport_name(tp)->tpn_ident, "client");
TEST_1(tport_incref(tp) != tp0); tport_decref(&tp);
msg_destroy(msg);
@@ -907,12 +911,13 @@ static int tcp_test(tp_test_t *tt)
TEST_1(!new_test_msg(tt, &msg, "tcp-reuse", 1, 1024));
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
TPTAG_REUSE(1), TAG_END()));
N++;
TEST_S(tport_name(tp)->tpn_ident, "client");
TEST_1(tport_incref(tp) == tp0); tport_decref(&tp);
msg_destroy(msg);
/* Receive every message from queue */
while (tt->tt_received < TPORT_QUEUESIZE + 2) {
while (tt->tt_received < N) {
TEST(tport_test_run(tt, 5), 1);
/* Validate message */
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
@@ -1005,7 +1010,7 @@ static int test_incomplete(tp_test_t *tt)
s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
TEST_1(s != SOCKET_ERROR);
connected = connect(s, ai->ai_addr, ai->ai_addrlen);
connected = connect(s, ai->ai_addr, (socklen_t)ai->ai_addrlen);
su_root_step(tt->tt_root, 50);