diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.am b/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.am index 18c7cedba7..d682737394 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.am +++ b/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.am @@ -17,7 +17,7 @@ INCLUDES = -I$(srcdir)/../bnf -I../bnf \ noinst_LTLIBRARIES = libsip.la check_PROGRAMS = torture_sip \ - sip_test_msg validator date_test + test_sip_msg validator date_test # ---------------------------------------------------------------------- # Rules for building the targets @@ -58,7 +58,7 @@ LDADD = libsip.la \ ../su/libsu.la torture_sip_LDFLAGS = -static -sip_test_msg_LDFLAGS = -static +test_sip_msg_LDFLAGS = -static date_test_LDFLAGS = -static # ---------------------------------------------------------------------- @@ -93,9 +93,9 @@ EXTRA_DIST = Doxyfile sip.docs sip_parser.docs sip.doxyaliases \ # ---------------------------------------------------------------------- # Tests -#TESTS = torture_sip run_sip_test_msg run_date_test +TESTS = torture_sip run_test_sip_msg run_date_test -#dist_noinst_SCRIPTS = run_sip_test_msg run_date_test +dist_noinst_SCRIPTS = run_test_sip_msg run_date_test # ---------------------------------------------------------------------- # Sofia specific rules diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.in b/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.in index ff6033d866..35f915fcea 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.in +++ b/libs/sofia-sip/libsofia-sip-ua/sip/Makefile.in @@ -25,7 +25,8 @@ # --------------------------------------------------- -SOURCES = $(libsip_la_SOURCES) date_test.c sip_test_msg.c torture_sip.c validator.c + +SOURCES = $(libsip_la_SOURCES) date_test.c test_sip_msg.c torture_sip.c validator.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -50,10 +51,11 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -check_PROGRAMS = torture_sip$(EXEEXT) sip_test_msg$(EXEEXT) \ +check_PROGRAMS = torture_sip$(EXEEXT) test_sip_msg$(EXEEXT) \ validator$(EXEEXT) date_test$(EXEEXT) -DIST_COMMON = $(nobase_include_sofia_HEADERS) $(srcdir)/../sofia.am \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog +DIST_COMMON = $(dist_noinst_SCRIPTS) $(nobase_include_sofia_HEADERS) \ + $(srcdir)/../sofia.am $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ChangeLog subdir = libsofia-sip-ua/sip ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/sac-general.m4 \ @@ -80,10 +82,10 @@ date_test_OBJECTS = date_test.$(OBJEXT) date_test_LDADD = $(LDADD) date_test_DEPENDENCIES = libsip.la ../msg/libmsg.la ../bnf/libbnf.la \ ../url/liburl.la ../su/libsu.la -sip_test_msg_SOURCES = sip_test_msg.c -sip_test_msg_OBJECTS = sip_test_msg.$(OBJEXT) -sip_test_msg_LDADD = $(LDADD) -sip_test_msg_DEPENDENCIES = libsip.la ../msg/libmsg.la \ +test_sip_msg_SOURCES = test_sip_msg.c +test_sip_msg_OBJECTS = test_sip_msg.$(OBJEXT) +test_sip_msg_LDADD = $(LDADD) +test_sip_msg_DEPENDENCIES = libsip.la ../msg/libmsg.la \ ../bnf/libbnf.la ../url/liburl.la ../su/libsu.la torture_sip_SOURCES = torture_sip.c torture_sip_OBJECTS = torture_sip.$(OBJEXT) @@ -95,6 +97,7 @@ validator_OBJECTS = validator.$(OBJEXT) validator_LDADD = $(LDADD) validator_DEPENDENCIES = libsip.la ../msg/libmsg.la ../bnf/libbnf.la \ ../url/liburl.la ../su/libsu.la +SCRIPTS = $(dist_noinst_SCRIPTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I$(top_builddir)/libsofia-sip-ua/su/sofia-sip depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -106,9 +109,9 @@ LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \ CCLD = $(CC) LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libsip_la_SOURCES) date_test.c sip_test_msg.c \ +SOURCES = $(libsip_la_SOURCES) date_test.c test_sip_msg.c \ torture_sip.c validator.c -DIST_SOURCES = $(libsip_la_SOURCES) date_test.c sip_test_msg.c \ +DIST_SOURCES = $(libsip_la_SOURCES) date_test.c test_sip_msg.c \ torture_sip.c validator.c am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -314,7 +317,7 @@ LDADD = libsip.la \ ../su/libsu.la torture_sip_LDFLAGS = -static -sip_test_msg_LDFLAGS = -static +test_sip_msg_LDFLAGS = -static date_test_LDFLAGS = -static # ---------------------------------------------------------------------- @@ -345,6 +348,11 @@ EXTRA_DIST = Doxyfile sip.docs sip_parser.docs sip.doxyaliases \ tests/test35.txt tests/test36.txt tests/test37.txt tests/test38.txt \ tests/test39.txt tests/test40.txt tests/test41.txt tests/test42.txt + +# ---------------------------------------------------------------------- +# Tests +TESTS = torture_sip run_test_sip_msg run_date_test +dist_noinst_SCRIPTS = run_test_sip_msg run_date_test AM_CFLAGS = $(CWFLAG) $(SOFIA_CFLAGS) DISTCLEANFILES = $(BUILT_SOURCES) @@ -372,13 +380,6 @@ INTERNAL_INCLUDES = \ -I$(srcdir)/../su -I../su -# ---------------------------------------------------------------------- -# Tests - -#TESTS = torture_sip run_sip_test_msg run_date_test - -#dist_noinst_SCRIPTS = run_sip_test_msg run_date_test - # ---------------------------------------------------------------------- # Sofia specific rules MSG_PARSER_AWK = $(srcdir)/../msg/msg_parser.awk @@ -439,9 +440,9 @@ clean-checkPROGRAMS: date_test$(EXEEXT): $(date_test_OBJECTS) $(date_test_DEPENDENCIES) @rm -f date_test$(EXEEXT) $(LINK) $(date_test_LDFLAGS) $(date_test_OBJECTS) $(date_test_LDADD) $(LIBS) -sip_test_msg$(EXEEXT): $(sip_test_msg_OBJECTS) $(sip_test_msg_DEPENDENCIES) - @rm -f sip_test_msg$(EXEEXT) - $(LINK) $(sip_test_msg_LDFLAGS) $(sip_test_msg_OBJECTS) $(sip_test_msg_LDADD) $(LIBS) +test_sip_msg$(EXEEXT): $(test_sip_msg_OBJECTS) $(test_sip_msg_DEPENDENCIES) + @rm -f test_sip_msg$(EXEEXT) + $(LINK) $(test_sip_msg_LDFLAGS) $(test_sip_msg_OBJECTS) $(test_sip_msg_LDADD) $(LIBS) torture_sip$(EXEEXT): $(torture_sip_OBJECTS) $(torture_sip_DEPENDENCIES) @rm -f torture_sip$(EXEEXT) $(LINK) $(torture_sip_LDFLAGS) $(torture_sip_OBJECTS) $(torture_sip_LDADD) $(LIBS) @@ -475,9 +476,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_tag.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_tag_class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_tag_ref.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_test_msg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sip_msg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/torture_sip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validator.Po@am__quote@ @@ -579,6 +580,79 @@ GTAGS: distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) $(mkdir_p) $(distdir)/.. $(distdir)/images $(distdir)/sofia-sip $(distdir)/tests @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ @@ -609,9 +683,10 @@ distdir: $(DISTFILES) done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(include_sofiadir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ @@ -695,7 +770,7 @@ ps-am: uninstall-am: uninstall-info-am uninstall-nobase_include_sofiaHEADERS -.PHONY: CTAGS GTAGS all all-am check check-am clean \ +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/test_sip_msg.c b/libs/sofia-sip/libsofia-sip-ua/sip/test_sip_msg.c new file mode 100644 index 0000000000..8139330e98 --- /dev/null +++ b/libs/sofia-sip/libsofia-sip-ua/sip/test_sip_msg.c @@ -0,0 +1,293 @@ +/* + * This file is part of the Sofia-SIP package + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Pekka Pessi + * + * 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 + * + */ + +/**@SIP_PARSER + * + * @file test_sip_msg.c Simple SIP message parser/printer tester. + * + * @author Pekka Pessi . + * + * @date Created: Fri Feb 18 10:25:08 2000 ppessi + */ + +#include "config.h" + +/* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */ +#define MSG_PUB_T struct sip_s +#define MSG_HDR_T union sip_header_u + +#include "sofia-sip/sip_parser.h" +#include "sofia-sip/msg_mclass.h" +#include "sofia-sip/msg_mclass_hash.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +int diff(const char *olds, const char *news, int *linep, int *pos) +{ + const char *o, *n; + + *linep = 0; + + for (o = olds, n = news; *o && *n && *o == *n ; o++, n++) { + if (*o == '\n') ++*linep; + } + + *pos = o - olds; + + return *o != *n; +} + +int test_msg_class(msg_mclass_t *mc) +{ + int i, j, N; + + N = mc->mc_hash_size; + + /* Check parser table sanity */ + for (i = 0; i < N; i++) { + /* Verify each header entry */ + msg_hclass_t *hc = mc->mc_hash[i].hr_class; + + if (hc == NULL) + continue; + + /* Short form */ + if (hc->hc_short[0]) + assert(mc->mc_short[hc->hc_short[0] - 'a'].hr_class == hc); + + /* Long form */ + for (j = MC_HASH(hc->hc_name, N); j != i; j = (j + 1) % N) + assert(mc->mc_hash[j].hr_class); + } + + return 0; +} + +char * url_print(url_t *url, char buf[1024]) +{ + url_e(buf, 1024, url); + + return buf; +} + +void print_contact(FILE *f, sip_contact_t *m) +{ + char const * const *p; + char buf[1024]; + const char *sep = "\tContact: "; + + for (;m; m = m->m_next) { + int quoted_url = 0; + fputs(sep, f); sep = ", "; + + if (m->m_display) { + quoted_url = 1; + fprintf(f, "\"%s\" <", m->m_display); + } + url_print(m->m_url, buf); + if (!quoted_url && strpbrk(buf, ",;?")) { + fputs("<", f); + } + fputs(buf, f); + if (quoted_url) fputs(">", f); + + if (m->m_params) + for (p = m->m_params; *p; p++) + fprintf(f, " ;%s", *p); + + if (m->m_comment) + fprintf(f, " (%s)", m->m_comment); + } + + fputs("\n", f); +} + +void print_via(FILE *f, sip_via_t *v) +{ + char const * const *p; + char const * sep = "\tVia: "; + + for (;v; v = v->v_next) { + fputs(sep, f); sep = ", "; + + fprintf(f, "%s %s", v->v_protocol, v->v_host); + if (v->v_port) + fprintf(f, ":%s", v->v_port); + + if (v->v_params) + for (p = v->v_params; *p; p++) + fprintf(f, " ;%s", *p); + if (v->v_comment) + fprintf(f, " (%s)", v->v_comment); + } + + fputs("\n", f); +} + +int main(int argc, char *argv[]) +{ + char urlbuf[1024]; + size_t n; + int m, tcp; + sip_t *sip; + int exitcode = 0; + msg_mclass_t *sip_mclass = sip_default_mclass(); + msg_t *msg = msg_create(sip_mclass, MSG_FLG_EXTRACT_COPY); + msg_iovec_t iovec[1]; + + tcp = argv[1] && strcmp(argv[1], "-t") == 0; + + test_msg_class(sip_mclass); + + for (n = 0, m = 0;;) { + if (msg_recv_iovec(msg, iovec, 1, 1, 0) < 0) { + perror("msg_recv_iovec"); + exit(1); + } + assert(iovec->mv_len >= 1); + + n = read(0, iovec->mv_base, 1); + + if (n < 0) { + perror("test_sip_msg read"); + exit(1); + } + + msg_recv_commit(msg, n, n == 0); + + if (tcp) + m = msg_extract(msg); + + if (n == 0 || m < 0) + break; + } + + if (!tcp) + m = msg_extract(msg); + + sip = msg_object(msg); + if (sip) + fprintf(stdout, "sip flags = %x\n", sip->sip_flags); + + if (m < 0) { + fprintf(stderr, "test_sip_msg: parsing error ("MOD_ZD")\n", n); + exit(1); + } + + if (sip->sip_flags & MSG_FLG_TRUNC) { + fprintf(stderr, "test_sip_msg: message truncated\n"); + exit(1); + } + + if (msg_next(msg)) { + fprintf(stderr, "test_sip_msg: stuff after message\n"); + exit(1); + } + +#if 0 + fprintf(stderr, "test_sip_msg: %d headers (%d short ones), %d unknown\n", + msg->mh_n_headers, msg->mh_n_short, msg->mh_n_unknown); + + if (msg->mh_payload) { + fprintf(stderr, "\twith payload of %d bytes\n", + msg->mh_payload->pl_len); + } +#endif + + if (MSG_HAS_ERROR(sip->sip_flags) || sip->sip_error) { + fprintf(stderr, "test_sip_msg: parsing error\n"); + exit(1); + } + else if (sip_sanity_check(sip) < 0) { + fprintf(stderr, "test_sip_msg: message failed sanity check\n"); + exit(1); + } + + if (sip->sip_request) { + fprintf(stdout, "\trequest %s (%d) %s %s\n", + sip->sip_request->rq_method_name, + sip->sip_request->rq_method, + url_print(sip->sip_request->rq_url, urlbuf), + sip->sip_request->rq_version); + if (sip->sip_request->rq_url->url_type == url_unknown) { + exitcode = 1; + fprintf(stderr, "test_sip_msg: invalid request URI\n"); + } + } + + if (sip->sip_status) + fprintf(stdout, "\tstatus %s %03d %s\n", + sip->sip_status->st_version, + sip->sip_status->st_status, + sip->sip_status->st_phrase); + + if (sip->sip_cseq) + fprintf(stdout, "\tCSeq: %u %s (%d)\n", + sip->sip_cseq->cs_seq, + sip->sip_cseq->cs_method_name, + sip->sip_cseq->cs_method); + + if (sip->sip_call_id) + fprintf(stdout, "\tCall-ID: %s (%x)\n", + sip->sip_call_id->i_id, + sip->sip_call_id->i_hash); + + if (sip->sip_from) + fprintf(stdout, "\tFrom: %s@%s%s%s\n", + sip->sip_from->a_user ? sip->sip_from->a_user : "[nobody]", + sip->sip_from->a_host ? sip->sip_from->a_host : "[nowhere]", + sip->sip_from->a_tag ? " ;tag=" : "", + sip->sip_from->a_tag ? sip->sip_from->a_tag : ""); + + if (sip->sip_to) + fprintf(stdout, "\tTo: %s@%s%s%s\n", + sip->sip_to->a_user ? sip->sip_to->a_user : "[nobody]", + sip->sip_to->a_host ? sip->sip_to->a_host : "[nowhere]", + sip->sip_to->a_tag ? " ;tag=" : "", + sip->sip_to->a_tag ? sip->sip_to->a_tag : ""); + + if (sip->sip_contact) + print_contact(stdout, sip->sip_contact); + if (sip->sip_via) + print_via(stdout, sip->sip_via); + + if (sip->sip_content_length) { + fprintf(stdout, "\tcontent length %u\n", + sip->sip_content_length->l_length); + } + + if (msg_next(msg)) { + fprintf(stderr, "test_sip_msg: extra stuff after valid message\n"); + exit(1); + } + + return exitcode; +} diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c b/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c index 27d566237e..67a24b6752 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c @@ -578,6 +578,8 @@ su_duration_t su_timer_next_expires(su_timer_t const * t, su_time_t now) { su_duration_t tout; + t = timers_first(t); + if (!t) return SU_DURATION_MAX;