test_tport.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2006 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@CFILE tport_test.c
  25. *
  26. * Test functions for transports
  27. *
  28. * @internal
  29. *
  30. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  31. *
  32. * @date Created: Wed Apr 3 11:25:13 2002 ppessi
  33. */
  34. /* always assert()s */
  35. #undef NDEBUG
  36. #include "config.h"
  37. #include <stddef.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <limits.h>
  41. #include <stdio.h>
  42. #include <assert.h>
  43. typedef struct tp_test_s tp_test_t;
  44. #define TP_STACK_T tp_test_t
  45. #define TP_CLIENT_T struct called
  46. #include <sofia-sip/su_wait.h>
  47. #include <sofia-sip/su_md5.h>
  48. #include "tport_internal.h" /* Get SU_DEBUG_*() */
  49. #include "test_class.h"
  50. #include "test_protos.h"
  51. #include "sofia-sip/msg.h"
  52. #include "sofia-sip/msg_mclass.h"
  53. #include "sofia-sip/msg_addr.h"
  54. #if HAVE_SIGCOMP
  55. #include <sigcomp.h>
  56. #endif
  57. #include <sofia-sip/base64.h>
  58. #include <sofia-sip/su_log.h>
  59. #include "sofia-sip/tport.h"
  60. struct tp_test_s {
  61. su_home_t tt_home[1];
  62. int tt_flags;
  63. su_root_t *tt_root;
  64. msg_mclass_t *tt_mclass;
  65. tport_t *tt_srv_tports;
  66. tport_t *tt_tports;
  67. tport_t *tt_rtport;
  68. tp_name_t tt_udp_name[1];
  69. tp_name_t tt_udp_comp[1];
  70. tp_name_t tt_tcp_name[1];
  71. tp_name_t tt_tcp_comp[1];
  72. tp_name_t tt_sctp_name[1];
  73. tp_name_t tt_sctp_comp[1];
  74. tp_name_t tt_tls_name[1];
  75. tp_name_t tt_tls_comp[1];
  76. #if HAVE_SIGCOMP
  77. struct sigcomp_state_handler *state_handler;
  78. struct sigcomp_algorithm const *algorithm;
  79. struct sigcomp_compartment *master_cc;
  80. #define IF_SIGCOMP_TPTAG_COMPARTMENT(cc) TAG_IF(cc, TPTAG_COMPARTMENT(cc)),
  81. #else
  82. #define IF_SIGCOMP_TPTAG_COMPARTMENT(cc)
  83. #endif
  84. int tt_status;
  85. int tt_received;
  86. msg_t *tt_rmsg;
  87. uint8_t tt_digest[SU_MD5_DIGEST_SIZE];
  88. su_addrinfo_t const *tt_tcp_addr;
  89. tport_t *tt_tcp;
  90. };
  91. int tstflags;
  92. #define TSTFLAGS tstflags
  93. #include <sofia-sip/tstdef.h>
  94. char const name[] = "tport_test";
  95. SOFIAPUBVAR su_log_t tport_log[];
  96. static int name_test(tp_test_t *tt)
  97. {
  98. tp_name_t tpn[1];
  99. su_home_t home[1] = { SU_HOME_INIT(home) };
  100. su_sockaddr_t su[1];
  101. BEGIN();
  102. memset(su, 0, sizeof su);
  103. su->su_port = htons(5060);
  104. su->su_family = AF_INET;
  105. TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0);
  106. su->su_family = AF_INET;
  107. TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0);
  108. #if SU_HAVE_IN6
  109. su->su_family = AF_INET6;
  110. TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0);
  111. #endif
  112. END();
  113. }
  114. /* Count number of transports in chain */
  115. static
  116. int count_tports(tport_t *tp)
  117. {
  118. int n = 0;
  119. for (tp = tport_primaries(tp); tp; tp = tport_next(tp))
  120. n++;
  121. return n;
  122. }
  123. static int check_msg(tp_test_t *tt, msg_t *msg, char const *ident)
  124. {
  125. msg_test_t *tst;
  126. msg_payload_t *pl;
  127. usize_t i, len;
  128. BEGIN();
  129. TEST_1(tst = msg_test_public(msg));
  130. TEST_1(pl = tst->msg_payload);
  131. if (ident) {
  132. if (!tst->msg_content_location ||
  133. strcmp(ident, tst->msg_content_location->g_string))
  134. return 1;
  135. }
  136. len = pl->pl_len;
  137. for (i = 0; i < len; i++) {
  138. if (pl->pl_data[i] != (char) (i % 240))
  139. break;
  140. }
  141. if (pl)
  142. return i != len;
  143. END();
  144. }
  145. static int test_create_md5(tp_test_t *tt, msg_t *msg)
  146. {
  147. msg_test_t *tst;
  148. msg_payload_t *pl;
  149. su_md5_t md5[1];
  150. BEGIN();
  151. TEST_1(tst = msg_test_public(msg));
  152. TEST_1(pl = tst->msg_payload);
  153. su_md5_init(md5);
  154. su_md5_update(md5, pl->pl_data, pl->pl_len);
  155. su_md5_digest(md5, tt->tt_digest);
  156. END();
  157. }
  158. static int test_check_md5(tp_test_t *tt, msg_t *msg)
  159. {
  160. msg_test_t *tst;
  161. msg_payload_t *pl;
  162. su_md5_t md5[1];
  163. uint8_t digest[SU_MD5_DIGEST_SIZE];
  164. BEGIN();
  165. TEST_1(tst = msg_test_public(msg));
  166. TEST_1(pl = tst->msg_payload);
  167. su_md5_init(md5);
  168. su_md5_update(md5, pl->pl_data, pl->pl_len);
  169. su_md5_digest(md5, digest);
  170. TEST(memcmp(digest, tt->tt_digest, sizeof digest), 0);
  171. END();
  172. }
  173. static int test_msg_md5(tp_test_t *tt, msg_t *msg)
  174. {
  175. msg_test_t *tst;
  176. BEGIN();
  177. TEST_1(tst = msg_test_public(msg));
  178. if (tst->msg_content_md5) {
  179. su_md5_t md5sum[1];
  180. uint8_t digest[SU_MD5_DIGEST_SIZE];
  181. char b64[BASE64_SIZE(SU_MD5_DIGEST_SIZE) + 1];
  182. msg_payload_t *pl =tst->msg_payload;
  183. su_md5_init(md5sum);
  184. su_md5_update(md5sum, pl->pl_data, pl->pl_len);
  185. su_md5_digest(md5sum, digest);
  186. base64_e(b64, sizeof(b64), digest, sizeof(digest));
  187. if (strcmp(b64, tst->msg_content_md5->g_string)) {
  188. ;
  189. }
  190. TEST_S(b64, tst->msg_content_md5->g_string);
  191. } else {
  192. TEST_1(tst->msg_content_md5);
  193. }
  194. END();
  195. }
  196. #define TPORT_TEST_VERSION MSG_TEST_VERSION_CURRENT
  197. static int new_test_msg(tp_test_t *tt, msg_t **retval,
  198. char const *ident,
  199. int N, int len)
  200. {
  201. msg_t *msg;
  202. msg_test_t *tst;
  203. su_home_t *home;
  204. msg_request_t *rq;
  205. msg_unknown_t *u;
  206. msg_content_location_t *cl;
  207. msg_content_md5_t *md5;
  208. msg_content_length_t *l;
  209. msg_separator_t *sep;
  210. msg_payload_t payload[1];
  211. msg_header_t *h;
  212. int i;
  213. su_md5_t md5sum[1];
  214. uint8_t digest[SU_MD5_DIGEST_SIZE];
  215. char b64[BASE64_SIZE(SU_MD5_DIGEST_SIZE) + 1];
  216. BEGIN();
  217. TEST_1(msg = msg_create(tt->tt_mclass, 0));
  218. TEST_1(tst = msg_test_public(msg));
  219. TEST_1(home = msg_home(msg));
  220. TEST_SIZE(msg_maxsize(msg, 1024 + N * len), 0);
  221. TEST_1(rq = msg_request_make(home, "DO im:foo@faa " TPORT_TEST_VERSION));
  222. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)rq), 0);
  223. TEST_1(u = msg_unknown_make(home, "Foo: faa"));
  224. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)u), 0);
  225. TEST_1(u = msg_unknown_make(home, "Foo: faa"));
  226. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)u), 0);
  227. if (ident) {
  228. TEST_1(cl = msg_content_location_make(home, ident));
  229. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)cl), 0);
  230. }
  231. msg_payload_init(payload);
  232. payload->pl_len = len;
  233. TEST_1(payload->pl_data = su_zalloc(home, payload->pl_len));
  234. for (i = 0; i < len; i++) {
  235. payload->pl_data[i] = (char) (i % 240);
  236. }
  237. su_md5_init(md5sum);
  238. for (i = 0; i < N; i++) {
  239. h = msg_header_dup(home, (msg_header_t*)payload);
  240. TEST_1(h);
  241. TEST(msg_header_insert(msg, (void *)tst, h), 0);
  242. su_md5_update(md5sum, payload->pl_data, payload->pl_len);
  243. }
  244. TEST_1(l = msg_content_length_format(home, MOD_ZU, (size_t)(N * payload->pl_len)));
  245. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)l), 0);
  246. su_md5_digest(md5sum, digest);
  247. base64_e(b64, sizeof(b64), digest, sizeof(digest));
  248. TEST_1(md5 = msg_content_md5_make(home, b64));
  249. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)md5), 0);
  250. TEST_1(sep = msg_separator_create(home));
  251. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)sep), 0);
  252. TEST(msg_serialize(msg, (void *)tst), 0);
  253. *retval = msg;
  254. END();
  255. }
  256. static
  257. struct sigcomp_compartment *
  258. test_sigcomp_compartment(tp_test_t *tt, tport_t *tp, tp_name_t const *tpn);
  259. static void tp_test_recv(tp_test_t *tt,
  260. tport_t *tp,
  261. msg_t *msg,
  262. tp_magic_t *magic,
  263. su_time_t now)
  264. {
  265. tp_name_t frm[1];
  266. if (tport_delivered_from(tp, msg, frm) != -1 && frm->tpn_comp) {
  267. struct sigcomp_compartment *cc = test_sigcomp_compartment(tt, tp, frm);
  268. tport_sigcomp_accept(tp, cc, msg);
  269. }
  270. tt->tt_status = 1;
  271. tt->tt_received++;
  272. if (msg_has_error(msg)) {
  273. tt->tt_status = -1;
  274. tt->tt_rtport = tp;
  275. }
  276. else if (test_msg_md5(tt, msg))
  277. msg_destroy(msg);
  278. else if (tt->tt_rmsg)
  279. msg_destroy(msg);
  280. else {
  281. tt->tt_rmsg = msg;
  282. tt->tt_rtport = tp;
  283. }
  284. }
  285. static void tp_test_error(tp_test_t *tt,
  286. tport_t *tp,
  287. int errcode,
  288. char const *remote)
  289. {
  290. tt->tt_status = -1;
  291. fprintf(stderr, "tp_test_error(%p): error %d (%s) from %s\n",
  292. (void *)tp, errcode, su_strerror(errcode),
  293. remote ? remote : "<unknown destination>");
  294. }
  295. msg_t *tp_test_msg(tp_test_t *tt, int flags,
  296. char const data[], usize_t size,
  297. tport_t const *tp,
  298. tp_client_t *tpc)
  299. {
  300. msg_t *msg = msg_create(tt->tt_mclass, flags);
  301. msg_maxsize(msg, 2 * 1024 * 1024);
  302. return msg;
  303. }
  304. static
  305. struct sigcomp_compartment *
  306. test_sigcomp_compartment(tp_test_t *tt,
  307. tport_t *tp,
  308. tp_name_t const *tpn)
  309. {
  310. struct sigcomp_compartment *cc = NULL;
  311. #if HAVE_SIGCOMP
  312. char name[256];
  313. int namesize;
  314. namesize = snprintf(name, sizeof name, "TEST_%s/%s:%s",
  315. tpn->tpn_proto,
  316. tpn->tpn_host,
  317. tpn->tpn_port);
  318. if (namesize <= 0 || namesize >= sizeof name)
  319. return NULL;
  320. cc = sigcomp_compartment_access(tt->state_handler,
  321. 0, name, namesize, NULL, 0);
  322. if (cc == NULL) {
  323. cc = sigcomp_compartment_create(tt->algorithm, tt->state_handler,
  324. 0, name, namesize, NULL, 0);
  325. sigcomp_compartment_option(cc, "dms=32768");
  326. }
  327. #endif
  328. return cc;
  329. }
  330. /* Accept/reject early SigComp message */
  331. int test_sigcomp_accept(tp_stack_t *tt, tport_t *tp, msg_t *msg)
  332. {
  333. struct sigcomp_compartment *cc = NULL;
  334. cc = test_sigcomp_compartment(tt, tp, tport_name(tp));
  335. if (cc)
  336. tport_sigcomp_assign(tp, cc);
  337. return tport_sigcomp_accept(tp, cc, msg);
  338. }
  339. tp_stack_class_t const tp_test_class[1] =
  340. {{
  341. /* tpac_size */ sizeof(tp_test_class),
  342. /* tpac_recv */ tp_test_recv,
  343. /* tpac_error */ tp_test_error,
  344. /* tpac_alloc */ tp_test_msg,
  345. }};
  346. static int init_test(tp_test_t *tt)
  347. {
  348. tp_name_t myname[1] = {{ "*", "*", "*", "*", "sigcomp" }};
  349. #if HAVE_SCTP
  350. char const * transports[] = { "udp", "tcp", "sctp", NULL };
  351. #else
  352. char const * transports[] = { "udp", "tcp", NULL };
  353. #endif
  354. tp_name_t const *tpn;
  355. tport_t *tp;
  356. unsigned idle;
  357. int logging = -1;
  358. BEGIN();
  359. int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST;
  360. #ifdef AI_ALL
  361. mask |= AI_ALL;
  362. #endif
  363. #ifdef AI_V4MAPPED_CFG
  364. mask |= AI_V4MAPPED_CFG;
  365. #endif
  366. #ifdef AI_ADDRCONFIG
  367. mask |= AI_ADDRCONFIG;
  368. #endif
  369. #ifdef AI_V4MAPPED
  370. mask |= AI_V4MAPPED;
  371. #endif
  372. /* Test that we have no common flags with underlying getaddrinfo() */
  373. TEST(mask & TP_AI_MASK, 0);
  374. TEST_1(tt->tt_root = su_root_create(NULL));
  375. myname->tpn_host = "127.0.0.1";
  376. myname->tpn_ident = "client";
  377. /* Create message class */
  378. TEST_1(tt->tt_mclass = msg_mclass_clone(msg_test_mclass, 0, 0));
  379. /* Try to insert Content-Length header (expecting failure) */
  380. TEST(msg_mclass_insert(tt->tt_mclass, msg_content_length_href), -1);
  381. #if HAVE_SIGCOMP
  382. TEST_1(tt->state_handler = sigcomp_state_handler_create());
  383. TEST_1(tt->algorithm =
  384. sigcomp_algorithm_by_name(getenv("SIGCOMP_ALGORITHM")));
  385. TEST_1(tt->master_cc =
  386. sigcomp_compartment_create(tt->algorithm, tt->state_handler,
  387. 0, "", 0, NULL, 0));
  388. TEST(sigcomp_compartment_option(tt->master_cc, "stateless"), 1);
  389. #endif
  390. /* Create client transport */
  391. TEST_1(tt->tt_tports =
  392. tport_tcreate(tt, tp_test_class, tt->tt_root,
  393. IF_SIGCOMP_TPTAG_COMPARTMENT(tt->master_cc)
  394. TAG_END()));
  395. /* Bind client transports */
  396. TEST(tport_tbind(tt->tt_tports, myname, transports,
  397. TPTAG_SERVER(0), TAG_END()),
  398. 0);
  399. if (getenv("TPORT_TEST_HOST"))
  400. myname->tpn_host = getenv("TPORT_TEST_HOST");
  401. else
  402. myname->tpn_host = "*";
  403. if (getenv("TPORT_TEST_PORT"))
  404. myname->tpn_port = getenv("TPORT_TEST_PORT");
  405. myname->tpn_ident = "server";
  406. /* Create server transport */
  407. TEST_1(tt->tt_srv_tports =
  408. tport_tcreate(tt, tp_test_class, tt->tt_root,
  409. IF_SIGCOMP_TPTAG_COMPARTMENT(tt->master_cc)
  410. TAG_END()));
  411. /* Bind server transports */
  412. TEST(tport_tbind(tt->tt_srv_tports, myname, transports,
  413. TPTAG_SERVER(1),
  414. TAG_END()),
  415. 0);
  416. /* Check that the master transport has idle parameter */
  417. TEST(tport_get_params(tt->tt_srv_tports,
  418. TPTAG_IDLE_REF(idle),
  419. TAG_END()), 1);
  420. /* Check that logging tag works */
  421. TEST(tport_get_params(tt->tt_srv_tports,
  422. TPTAG_LOG_REF(logging),
  423. TAG_END()), 1);
  424. TEST(tport_set_params(tt->tt_srv_tports,
  425. TPTAG_LOG(logging),
  426. TAG_END()), 1);
  427. for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp))
  428. TEST_S(tport_name(tp)->tpn_ident, "server");
  429. {
  430. su_sockaddr_t su[1];
  431. socklen_t sulen;
  432. int s;
  433. int i, before, after;
  434. char port[8];
  435. tp_name_t rname[1];
  436. *rname = *myname;
  437. /* Check that we cannot bind to an already used socket */
  438. memset(su, 0, sulen = sizeof(su->su_sin));
  439. s = su_socket(su->su_family = AF_INET, SOCK_STREAM, 0); TEST_1(s != -1);
  440. TEST_1(bind(s, &su->su_sa, sulen) != -1);
  441. TEST_1(listen(s, 5) != -1);
  442. TEST_1(getsockname(s, &su->su_sa, &sulen) != -1);
  443. sprintf(port, "%u", ntohs(su->su_port));
  444. rname->tpn_port = port;
  445. rname->tpn_ident = "failure";
  446. before = count_tports(tt->tt_srv_tports);
  447. /* Bind server transports to an reserved port - this should fail */
  448. TEST(tport_tbind(tt->tt_srv_tports, rname, transports,
  449. TPTAG_SERVER(1),
  450. TAG_END()),
  451. -1);
  452. after = count_tports(tt->tt_srv_tports);
  453. /* Check that no new primary transports has been added by failed call */
  454. TEST(before, after);
  455. /* Add new transports to an ephemeral port with new identity */
  456. for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp))
  457. TEST_S(tport_name(tp)->tpn_ident, "server");
  458. rname->tpn_port = "*";
  459. rname->tpn_ident = "server2";
  460. /* Bind server transports to another port */
  461. TEST(tport_tbind(tt->tt_srv_tports, rname, transports,
  462. TPTAG_SERVER(1),
  463. TAG_END()),
  464. 0);
  465. /* Check that new transports are after old ones. */
  466. for (i = 0, tp = tport_primaries(tt->tt_srv_tports);
  467. i < before;
  468. i++, tp = tport_next(tp))
  469. TEST_S(tport_name(tp)->tpn_ident, "server");
  470. for (; tp; tp = tport_next(tp))
  471. TEST_S(tport_name(tp)->tpn_ident, "server2");
  472. }
  473. #if HAVE_TLS
  474. {
  475. tp_name_t tlsname[1] = {{ "tls", "*", "*", "*", NULL }};
  476. char const * transports[] = { "tls", NULL };
  477. char const *srcdir = getenv("srcdir");
  478. if (srcdir == NULL)
  479. srcdir = ".";
  480. tlsname->tpn_host = myname->tpn_host;
  481. tlsname->tpn_ident = "server";
  482. /* Bind client transports */
  483. TEST(tport_tbind(tt->tt_tports, tlsname, transports,
  484. TPTAG_SERVER(0),
  485. TPTAG_CERTIFICATE(srcdir),
  486. TAG_END()),
  487. 0);
  488. /* Bind tls server transport */
  489. TEST(tport_tbind(tt->tt_srv_tports, tlsname, transports,
  490. TPTAG_SERVER(1),
  491. TPTAG_CERTIFICATE(srcdir),
  492. TAG_END()),
  493. 0);
  494. }
  495. #endif
  496. for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp)) {
  497. TEST_1(tpn = tport_name(tp));
  498. if (tt->tt_flags & tst_verbatim) {
  499. char const *host = tpn->tpn_host != tpn->tpn_canon ? tpn->tpn_host : "";
  500. printf("bound transport to %s/%s:%s%s%s%s%s\n",
  501. tpn->tpn_proto, tpn->tpn_canon, tpn->tpn_port,
  502. host[0] ? ";maddr=" : "", host,
  503. tpn->tpn_comp ? ";comp=" : "",
  504. tpn->tpn_comp ? tpn->tpn_comp : "");
  505. }
  506. /* Ignore server2 tports for now */
  507. if (strcmp(tpn->tpn_ident, "server"))
  508. continue;
  509. if (strcmp(tpn->tpn_proto, "udp") == 0) {
  510. *tt->tt_udp_name = *tpn;
  511. tt->tt_udp_name->tpn_comp = NULL;
  512. tt->tt_udp_name->tpn_ident = NULL;
  513. *tt->tt_udp_comp = *tpn;
  514. tt->tt_udp_comp->tpn_ident = NULL;
  515. }
  516. else if (strcmp(tpn->tpn_proto, "tcp") == 0) {
  517. *tt->tt_tcp_name = *tpn;
  518. tt->tt_tcp_name->tpn_comp = NULL;
  519. tt->tt_tcp_name->tpn_ident = NULL;
  520. *tt->tt_tcp_comp = *tpn;
  521. tt->tt_tcp_comp->tpn_ident = NULL;
  522. if (tt->tt_tcp_addr == NULL) {
  523. tt->tt_tcp_addr = tport_get_address(tp);
  524. tt->tt_tcp = tp;
  525. }
  526. }
  527. else if (strcmp(tpn->tpn_proto, "sctp") == 0) {
  528. *tt->tt_sctp_name = *tpn;
  529. tt->tt_sctp_name->tpn_ident = NULL;
  530. }
  531. else if (strcmp(tpn->tpn_proto, "tls") == 0) {
  532. *tt->tt_tls_name = *tpn;
  533. tt->tt_tls_name->tpn_ident = NULL;
  534. }
  535. }
  536. END();
  537. }
  538. char const payload[] =
  539. "Some data\n"
  540. "More data\n";
  541. #include <time.h>
  542. int
  543. tport_test_run(tp_test_t *tt, unsigned timeout)
  544. {
  545. time_t now = time(NULL);
  546. tt->tt_status = 0;
  547. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  548. tt->tt_rtport = NULL;
  549. while (!tt->tt_status) {
  550. if (tt->tt_flags & tst_verbatim) {
  551. fputs(".", stdout); fflush(stdout);
  552. }
  553. su_root_step(tt->tt_root, 500L);
  554. if (!getenv("TPORT_TEST_DEBUG") &&
  555. time(NULL) > (time_t)(now + timeout))
  556. return 0;
  557. }
  558. return tt->tt_status;
  559. }
  560. static int udp_test(tp_test_t *tt)
  561. {
  562. tport_t *tp;
  563. msg_t *msg;
  564. msg_test_t *tst;
  565. su_home_t *home;
  566. msg_request_t *rq;
  567. msg_unknown_t *u;
  568. msg_content_length_t *l;
  569. msg_content_md5_t *md5;
  570. msg_separator_t *sep;
  571. msg_payload_t *pl;
  572. BEGIN();
  573. TEST_1(msg = msg_create(tt->tt_mclass, 0));
  574. TEST_1(tst = msg_test_public(msg));
  575. TEST_1(home = msg_home(msg));
  576. TEST_1(rq = msg_request_make(home, "DO im:foo@faa " TPORT_TEST_VERSION));
  577. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)rq), 0);
  578. TEST_1(u = msg_unknown_make(home, "Foo: faa"));
  579. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)u), 0);
  580. TEST_1(pl = msg_payload_make(home, payload));
  581. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)pl), 0);
  582. TEST_1(l = msg_content_length_format(home, MOD_ZU, (size_t)pl->pl_len));
  583. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)l), 0);
  584. TEST_1(md5 = msg_content_md5_make(home, "R6nitdrtJFpxYzrPaSXfrA=="));
  585. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)md5), 0);
  586. TEST_1(sep = msg_separator_create(home));
  587. TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)sep), 0);
  588. TEST(msg_serialize(msg, (void *)tst), 0);
  589. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_udp_name, TAG_END()));
  590. TEST_S(tport_name(tp)->tpn_ident, "client");
  591. TEST(tport_test_run(tt, 5), 1);
  592. msg_destroy(msg);
  593. #if 0
  594. tp_name_t tpn[1] = {{ NULL }};
  595. TEST_1(msg = tt->tt_rmsg); tt->tt_rmsg = NULL;
  596. TEST_1(home = msg_home(msg));
  597. TEST_1(tport_convert_addr(home, tpn, "udp", NULL, msg_addr(msg)) == 0);
  598. tpn->tpn_comp = tport_name(tt->tt_rtport)->tpn_comp;
  599. /* reply */
  600. TEST_1(tport_tsend(tt->tt_rtport, msg, tpn, TAG_END()) != NULL);
  601. msg_destroy(msg);
  602. TEST(tport_test_run(tt, 5), 1);
  603. msg_destroy(msg);
  604. #endif
  605. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  606. END();
  607. }
  608. int pending_server_close, pending_client_close;
  609. void server_closed_callback(tp_stack_t *tt, tp_client_t *client,
  610. tport_t *tp, msg_t *msg, int error)
  611. {
  612. assert(msg == NULL);
  613. assert(client == NULL);
  614. if (msg == NULL) {
  615. tport_release(tp, pending_server_close, NULL, NULL, client, 0);
  616. pending_server_close = 0;
  617. }
  618. }
  619. void client_closed_callback(tp_stack_t *tt, tp_client_t *client,
  620. tport_t *tp, msg_t *msg, int error)
  621. {
  622. assert(msg == NULL);
  623. assert(client == NULL);
  624. if (msg == NULL) {
  625. tport_release(tp, pending_client_close, NULL, NULL, client, 0);
  626. pending_client_close = 0;
  627. }
  628. }
  629. static int tcp_test(tp_test_t *tt)
  630. {
  631. BEGIN();
  632. msg_t *msg = NULL;
  633. int i, N;
  634. tport_t *tp, *tp0;
  635. char ident[16];
  636. su_time_t started;
  637. /* Send a single message */
  638. TEST_1(!new_test_msg(tt, &msg, "tcp-first", 1, 1024));
  639. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  640. TEST_S(tport_name(tp)->tpn_ident, "client");
  641. tp0 = tport_incref(tp);
  642. msg_destroy(msg);
  643. tport_set_params(tp,
  644. TPTAG_KEEPALIVE(100),
  645. TPTAG_PINGPONG(500),
  646. TPTAG_IDLE(500),
  647. TAG_END());
  648. TEST(tport_test_run(tt, 5), 1);
  649. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-first"));
  650. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  651. /* Ask for notification upon close */
  652. pending_client_close = tport_pend(tp0, NULL, client_closed_callback, NULL);
  653. TEST_1(pending_client_close > 0);
  654. tp = tt->tt_rtport;
  655. pending_server_close = tport_pend(tp, NULL, server_closed_callback, NULL);
  656. TEST_1(pending_server_close > 0);
  657. N = 0; tt->tt_received = 0;
  658. #ifndef WIN32 /* Windows seems to be buffering too much */
  659. /* Create a large message, just to force queueing in sending end */
  660. TEST(new_test_msg(tt, &msg, "tcp-0", 1, 16 * 64 * 1024), 0);
  661. test_create_md5(tt, msg);
  662. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  663. N++;
  664. TEST_S(tport_name(tp)->tpn_ident, "client");
  665. TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
  666. msg_destroy(msg);
  667. /* Fill up the queue */
  668. for (i = 1; i < TPORT_QUEUESIZE; i++) {
  669. snprintf(ident, sizeof ident, "tcp-%u", i);
  670. TEST(new_test_msg(tt, &msg, ident, 1, 64 * 1024), 0);
  671. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  672. N++;
  673. TEST_S(tport_name(tp)->tpn_ident, "client");
  674. TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
  675. msg_destroy(msg);
  676. }
  677. /* This overflows the queue */
  678. TEST(new_test_msg(tt, &msg, "tcp-overflow", 1, 1024), 0);
  679. //TEST_1(!tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  680. msg_destroy(msg);
  681. TEST(tport_test_run(tt, 60), 1);
  682. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-0"));
  683. test_check_md5(tt, tt->tt_rmsg);
  684. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  685. if (tt->tt_received < TPORT_QUEUESIZE) { /* We have not received it all */
  686. snprintf(ident, sizeof ident, "tcp-%u", tt->tt_received);
  687. TEST(tport_test_run(tt, 5), 1);
  688. TEST_1(!check_msg(tt, tt->tt_rmsg, ident));
  689. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  690. }
  691. #else
  692. (void)i; (void)ident;
  693. #endif
  694. /* This uses a new connection */
  695. TEST_1(!new_test_msg(tt, &msg, "tcp-no-reuse", 1, 1024));
  696. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
  697. TPTAG_REUSE(0), TAG_END()));
  698. N++;
  699. TEST_S(tport_name(tp)->tpn_ident, "client");
  700. TEST_1(tport_incref(tp) != tp0); tport_decref(&tp);
  701. msg_destroy(msg);
  702. /* This uses the old connection */
  703. TEST_1(!new_test_msg(tt, &msg, "tcp-reuse", 1, 1024));
  704. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
  705. TPTAG_REUSE(1), TAG_END()));
  706. N++;
  707. TEST_S(tport_name(tp)->tpn_ident, "client");
  708. TEST_1(tport_incref(tp) == tp0); tport_decref(&tp);
  709. msg_destroy(msg);
  710. /* Receive every message from queue */
  711. while (tt->tt_received < N) {
  712. TEST(tport_test_run(tt, 5), 1);
  713. /* Validate message */
  714. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  715. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  716. }
  717. /* Try to send a single message */
  718. TEST_1(!new_test_msg(tt, &msg, "tcp-last", 1, 1024));
  719. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  720. TEST_S(tport_name(tp)->tpn_ident, "client");
  721. TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
  722. msg_destroy(msg);
  723. TEST(tport_test_run(tt, 5), 1);
  724. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-last"));
  725. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  726. TEST_1(pending_server_close && pending_client_close);
  727. SU_DEBUG_3(("tport_test(%p): waiting for PONG timeout\n", (void *)tp0));
  728. /* Wait until notifications -
  729. client closes when no pong is received and notifys pending,
  730. then server closes and notifys pending */
  731. while (pending_server_close || pending_client_close)
  732. su_root_step(tt->tt_root, 50);
  733. tport_decref(&tp0);
  734. /* Again a single message */
  735. TEST_1(!new_test_msg(tt, &msg, "tcp-pingpong", 1, 512));
  736. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  737. TEST_S(tport_name(tp)->tpn_ident, "client");
  738. tp0 = tport_incref(tp);
  739. msg_destroy(msg);
  740. tport_set_params(tp0,
  741. TPTAG_KEEPALIVE(250),
  742. TPTAG_PINGPONG(200),
  743. TAG_END());
  744. TEST(tport_test_run(tt, 5), 1);
  745. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-pingpong"));
  746. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  747. /* Ask for notifications upon close */
  748. pending_client_close = tport_pend(tp0, NULL, client_closed_callback, NULL);
  749. TEST_1(pending_client_close > 0);
  750. tp = tt->tt_rtport;
  751. pending_server_close = tport_pend(tp, NULL, server_closed_callback, NULL);
  752. TEST_1(pending_server_close > 0);
  753. /* Now server responds with pong ... */
  754. TEST(tport_set_params(tp, TPTAG_PONG2PING(1), TAG_END()), 1);
  755. started = su_now();
  756. while (pending_server_close && pending_client_close) {
  757. su_root_step(tt->tt_root, 50);
  758. if (su_duration(su_now(), started) > 1000)
  759. break;
  760. }
  761. /* ... and we are still pending after a second */
  762. TEST_1(pending_client_close && pending_server_close);
  763. TEST_1(su_duration(su_now(), started) > 1000);
  764. tport_shutdown(tp0, 2);
  765. tport_unref(tp0);
  766. while (pending_server_close || pending_client_close)
  767. su_root_step(tt->tt_root, 50);
  768. END();
  769. }
  770. static int test_incomplete(tp_test_t *tt)
  771. {
  772. BEGIN();
  773. su_addrinfo_t const *ai = tt->tt_tcp_addr;
  774. su_socket_t s;
  775. int connected;
  776. TEST_1(ai != NULL);
  777. TEST(tport_set_params(tt->tt_tcp, TPTAG_TIMEOUT(500), TAG_END()), 1);
  778. s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  779. TEST_1(s != SOCKET_ERROR);
  780. su_setblocking(s, 1);
  781. connected = connect(s, ai->ai_addr, (socklen_t)ai->ai_addrlen);
  782. su_root_step(tt->tt_root, 50);
  783. TEST(su_send(s, "F", 1, 0), 1);
  784. su_root_step(tt->tt_root, 50);
  785. TEST(su_send(s, "O", 1, 0), 1);
  786. su_root_step(tt->tt_root, 50);
  787. TEST(su_send(s, "O", 1, 0), 1);
  788. su_root_step(tt->tt_root, 50);
  789. TEST(su_send(s, " ", 1, 0), 1);
  790. su_root_step(tt->tt_root, 50);
  791. tt->tt_received = 0;
  792. TEST(tport_test_run(tt, 5), -1);
  793. TEST(tt->tt_received, 1);
  794. TEST_P(tt->tt_rmsg, NULL);
  795. su_close(s);
  796. END();
  797. }
  798. static int reuse_test(tp_test_t *tt)
  799. {
  800. msg_t *msg = NULL;
  801. int i, reuse = -1;
  802. tport_t *tp, *tp0, *tp1;
  803. tp_name_t tpn[1];
  804. BEGIN();
  805. /* Flush existing connections */
  806. *tpn = *tt->tt_tcp_name;
  807. tpn->tpn_port = "*";
  808. TEST_1(tp = tport_by_name(tt->tt_tports, tpn));
  809. TEST_1(tport_is_primary(tp));
  810. TEST(tport_flush(tp), 0);
  811. for (i = 0; i < 10; i++)
  812. su_root_step(tt->tt_root, 10L);
  813. TEST(tport_set_params(tp, TPTAG_REUSE(0), TAG_END()), 1);
  814. /* Send two messages */
  815. TEST(new_test_msg(tt, &msg, "reuse-1", 1, 1024), 0);
  816. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  817. TEST_S(tport_name(tp)->tpn_ident, "client");
  818. TEST_1(tp0 = tport_incref(tp));
  819. TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
  820. TEST(reuse, 0);
  821. msg_destroy(msg), msg = NULL;
  822. TEST(new_test_msg(tt, &msg, "reuse-2", 1, 1024), 0);
  823. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
  824. TEST_S(tport_name(tp)->tpn_ident, "client");
  825. TEST_1(tp1 = tport_incref(tp)); TEST_1(tp0 != tp1);
  826. TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
  827. TEST(reuse, 0);
  828. msg_destroy(msg), msg = NULL;
  829. /* Receive every message from queue */
  830. for (tt->tt_received = 0;
  831. tt->tt_received < 2;) {
  832. TEST(tport_test_run(tt, 5), 1);
  833. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  834. }
  835. /* Enable reuse on single connection */
  836. TEST(tport_set_params(tp1, TPTAG_REUSE(1), TAG_END()), 1);
  837. TEST(new_test_msg(tt, &msg, "reuse-3", 1, 1024), 0);
  838. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
  839. TPTAG_REUSE(1),
  840. TAG_END()));
  841. TEST_S(tport_name(tp)->tpn_ident, "client");
  842. TEST_1(tp1 == tp);
  843. TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
  844. TEST(reuse, 1);
  845. msg_destroy(msg), msg = NULL;
  846. TEST(tport_test_run(tt, 5), 1);
  847. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  848. TEST_1(tp = tport_by_name(tt->tt_tports, tpn));
  849. TEST_1(tport_is_primary(tp));
  850. TEST(tport_set_params(tp, TPTAG_REUSE(1), TAG_END()), 1);
  851. /* Send a single message with different connection */
  852. TEST_1(!new_test_msg(tt, &msg, "fresh-1", 1, 1024));
  853. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
  854. TPTAG_FRESH(1),
  855. TPTAG_REUSE(1),
  856. TAG_END()));
  857. TEST_S(tport_name(tp)->tpn_ident, "client");
  858. TEST_1(tport_incref(tp) != tp1); tport_decref(&tp);
  859. msg_destroy(msg);
  860. TEST(tport_test_run(tt, 5), 1);
  861. TEST_1(!check_msg(tt, tt->tt_rmsg, "fresh-1"));
  862. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  863. TEST_1(tport_shutdown(tp0, 2) >= 0);
  864. TEST_1(tport_shutdown(tp1, 2) >= 0);
  865. TEST_1(tport_shutdown(tp0, 1) >= 0);
  866. TEST(tport_shutdown(NULL, 0), -1);
  867. tport_decref(&tp0);
  868. tport_decref(&tp1);
  869. END();
  870. }
  871. static int sctp_test(tp_test_t *tt)
  872. {
  873. BEGIN();
  874. msg_t *msg = NULL;
  875. int i, n;
  876. tport_t *tp, *tp0;
  877. char buffer[32];
  878. if (!tt->tt_sctp_name->tpn_proto)
  879. return 0;
  880. /* Just a small and nice message first */
  881. TEST_1(!new_test_msg(tt, &msg, "cid:sctp-first", 1, 1024));
  882. test_create_md5(tt, msg);
  883. TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
  884. TEST_S(tport_name(tp)->tpn_ident, "client");
  885. msg_destroy(msg);
  886. tport_set_params(tp, TPTAG_KEEPALIVE(100), TPTAG_IDLE(500), TAG_END());
  887. TEST(tport_test_run(tt, 5), 1);
  888. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  889. test_check_md5(tt, tt->tt_rmsg);
  890. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  891. tp0 = tport_ref(tp);
  892. pending_server_close = pending_client_close = 0;
  893. /* Ask for notification upon close */
  894. pending_client_close = tport_pend(tp, NULL, client_closed_callback, NULL);
  895. TEST_1(pending_client_close > 0);
  896. tp = tt->tt_rtport;
  897. pending_server_close = tport_pend(tp, NULL, server_closed_callback, NULL);
  898. TEST_1(pending_server_close > 0);
  899. if (0) { /* SCTP does not work reliably. Really. */
  900. tt->tt_received = 0;
  901. /* Create large messages, just to force queueing in sending end */
  902. for (n = 0; !tport_queuelen(tp); n++) {
  903. snprintf(buffer, sizeof buffer, "cid:sctp-%u", n);
  904. TEST_1(!new_test_msg(tt, &msg, buffer, 1, 32000));
  905. test_create_md5(tt, msg);
  906. TEST_1(tp = tport_tsend(tp0, msg, tt->tt_sctp_name, TAG_END()));
  907. TEST_S(tport_name(tp)->tpn_ident, "client");
  908. msg_destroy(msg);
  909. }
  910. /* Fill up the queue */
  911. for (i = 1; i < TPORT_QUEUESIZE; i++) {
  912. snprintf(buffer, sizeof buffer, "cid:sctp-%u", n + i);
  913. TEST_1(!new_test_msg(tt, &msg, buffer, 1, 1024));
  914. TEST_1(tp = tport_tsend(tp0, msg, tt->tt_sctp_name, TAG_END()));
  915. msg_destroy(msg);
  916. }
  917. /* Try to overflow the queue */
  918. snprintf(buffer, sizeof buffer, "cid:sctp-%u", n + i);
  919. TEST_1(!new_test_msg(tt, &msg, buffer, 1, 1024));
  920. TEST_1(!tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
  921. msg_destroy(msg);
  922. TEST(tport_test_run(tt, 5), 1);
  923. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  924. test_check_md5(tt, tt->tt_rmsg);
  925. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  926. /* This uses a new connection */
  927. TEST_1(!new_test_msg(tt, &msg, "cid:sctp-new", 1, 1024));
  928. TEST_1(tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name,
  929. TPTAG_REUSE(0), TAG_END()));
  930. msg_destroy(msg);
  931. /* Receive every message from queue */
  932. for (; tt->tt_received < n + TPORT_QUEUESIZE - 1;) {
  933. TEST(tport_test_run(tt, 10), 1);
  934. /* Validate message */
  935. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  936. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  937. }
  938. /* Try to send a single message */
  939. TEST_1(!new_test_msg(tt, &msg, "cid:sctp-final", 1, 512));
  940. TEST_1(tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
  941. msg_destroy(msg);
  942. TEST(tport_test_run(tt, 10), 1);
  943. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  944. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  945. }
  946. tport_unref(tp0);
  947. /* Wait until notifications -
  948. client closes when idle and notifys pending,
  949. then server closes and notifys pending */
  950. while (pending_server_close || pending_client_close)
  951. su_root_step(tt->tt_root, 50);
  952. END();
  953. }
  954. struct called {
  955. int n, error, pending, released;
  956. };
  957. static
  958. void tls_error_callback(tp_stack_t *tt, tp_client_t *client,
  959. tport_t *tp, msg_t *msg, int error)
  960. {
  961. struct called *called = (struct called *)client;
  962. tt->tt_status = -1;
  963. called->n++, called->error = error;
  964. if (called->pending) {
  965. called->released = tport_release(tp, called->pending, msg, NULL, client, 0);
  966. called->pending = 0;
  967. }
  968. }
  969. static int tls_test(tp_test_t *tt)
  970. {
  971. BEGIN();
  972. #if HAVE_TLS
  973. tp_name_t const *dst = tt->tt_tls_name;
  974. msg_t *msg = NULL;
  975. int i;
  976. char ident[16];
  977. tport_t *tp, *tp0;
  978. struct called called[1] = {{ 0, 0, 0, 0 }};
  979. TEST_S(dst->tpn_proto, "tls");
  980. /* Send a single message */
  981. TEST_1(!new_test_msg(tt, &msg, "tls-first", 1, 1024));
  982. TEST_1(tp = tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
  983. TEST_1(tp0 = tport_ref(tp));
  984. TEST_1(called->pending = tport_pend(tp, msg, tls_error_callback, (tp_client_t *)called));
  985. i = tport_test_run(tt, 5);
  986. msg_destroy(msg);
  987. if (i < 0) {
  988. if (called->n) {
  989. TEST(called->released, 0);
  990. puts("test_tport: skipping TLS tests");
  991. tport_unref(tp0);
  992. return 0;
  993. }
  994. }
  995. TEST(i, 1);
  996. TEST_1(!check_msg(tt, tt->tt_rmsg, "tls-first"));
  997. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  998. tport_set_params(tp, TPTAG_KEEPALIVE(100), TPTAG_IDLE(500), TAG_END());
  999. /* Ask for notification upon close */
  1000. pending_client_close = tport_pend(tp0, NULL, client_closed_callback, NULL);
  1001. TEST_1(pending_client_close > 0);
  1002. tp = tt->tt_rtport;
  1003. pending_server_close = tport_pend(tp, NULL, server_closed_callback, NULL);
  1004. TEST_1(pending_server_close > 0);
  1005. /* Send a largish message */
  1006. TEST_1(!new_test_msg(tt, &msg, "tls-0", 16, 16 * 1024));
  1007. test_create_md5(tt, msg);
  1008. TEST_1(tp = tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
  1009. TEST_1(tp == tp0);
  1010. msg_destroy(msg);
  1011. /* Fill up the queue */
  1012. for (i = 1; i < TPORT_QUEUESIZE; i++) {
  1013. snprintf(ident, sizeof ident, "tls-%u", i);
  1014. TEST_1(!new_test_msg(tt, &msg, ident, 2, 512));
  1015. TEST_1(tp = tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
  1016. TEST_1(tp == tp0);
  1017. msg_destroy(msg);
  1018. }
  1019. /* This uses a new connection */
  1020. TEST_1(!new_test_msg(tt, &msg, "tls-no-reuse", 1, 1024));
  1021. TEST_1(tp = tport_tsend(tt->tt_tports, msg, dst,
  1022. TPTAG_REUSE(0), TAG_END()));
  1023. TEST_1(tp != tp0);
  1024. msg_destroy(msg);
  1025. tt->tt_received = 0;
  1026. /* Receive every message from queue */
  1027. while (tt->tt_received < TPORT_QUEUESIZE + 1) {
  1028. TEST(tport_test_run(tt, 5), 1);
  1029. /* Validate message */
  1030. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1031. }
  1032. /* Try to send a single message */
  1033. TEST_1(!new_test_msg(tt, &msg, "tls-last", 1, 1024));
  1034. TEST_1(tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
  1035. msg_destroy(msg);
  1036. TEST(tport_test_run(tt, 5), 1);
  1037. TEST_1(!check_msg(tt, tt->tt_rmsg, "tls-last"));
  1038. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1039. tport_decref(&tp0);
  1040. /* Wait until notifications -
  1041. client closes when idle and notifys pending,
  1042. then server closes and notifys pending */
  1043. while (pending_server_close || pending_client_close)
  1044. su_root_step(tt->tt_root, 50);
  1045. #endif
  1046. END();
  1047. }
  1048. static int sigcomp_test(tp_test_t *tt)
  1049. {
  1050. BEGIN();
  1051. #if HAVE_SIGCOMP
  1052. su_home_t *home;
  1053. tp_name_t tpn[1] = {{ NULL }};
  1054. struct sigcomp_compartment *cc;
  1055. if (tt->tt_udp_comp->tpn_comp) {
  1056. msg_t *msg = NULL;
  1057. TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tt->tt_udp_comp));
  1058. TEST_1(!new_test_msg(tt, &msg, "udp-sigcomp", 1, 1200));
  1059. test_create_md5(tt, msg);
  1060. TEST_1(tport_tsend(tt->tt_tports,
  1061. msg,
  1062. tt->tt_udp_comp,
  1063. TPTAG_COMPARTMENT(cc),
  1064. TAG_END()));
  1065. msg_destroy(msg);
  1066. TEST(tport_test_run(tt, 5), 1);
  1067. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  1068. test_check_md5(tt, tt->tt_rmsg);
  1069. TEST_1(msg = tt->tt_rmsg); tt->tt_rmsg = NULL;
  1070. TEST_1(home = msg_home(msg));
  1071. TEST_1(tport_convert_addr(home, tpn, "udp", NULL, msg_addr(msg)) == 0);
  1072. tpn->tpn_comp = tport_name(tt->tt_rtport)->tpn_comp;
  1073. /* reply */
  1074. TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
  1075. TEST_1(tport_tsend(tt->tt_rtport, msg, tpn,
  1076. TPTAG_COMPARTMENT(cc),
  1077. TAG_END()) != NULL);
  1078. msg_destroy(msg);
  1079. TEST(tport_test_run(tt, 5), 1);
  1080. TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
  1081. test_check_md5(tt, tt->tt_rmsg);
  1082. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1083. }
  1084. if (tt->tt_tcp_comp->tpn_comp) {
  1085. tport_t *tp;
  1086. msg_t *msg = NULL;
  1087. *tpn = *tt->tt_tcp_comp;
  1088. TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp", 1, 1500));
  1089. test_create_md5(tt, msg);
  1090. tport_log->log_level = 9;
  1091. TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
  1092. TEST_1(tp = tport_tsend(tt->tt_tports,
  1093. msg,
  1094. tpn,
  1095. TPTAG_COMPARTMENT(cc),
  1096. TAG_END()));
  1097. TEST_1(tport_incref(tp)); tport_decref(&tp);
  1098. msg_destroy(msg);
  1099. TEST(tport_test_run(tt, 5), 1);
  1100. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp"));
  1101. test_check_md5(tt, tt->tt_rmsg);
  1102. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1103. TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-2", 1, 3000));
  1104. test_create_md5(tt, msg);
  1105. TEST_1(tp = tport_tsend(tt->tt_tports,
  1106. msg,
  1107. tt->tt_tcp_comp,
  1108. TPTAG_COMPARTMENT(cc),
  1109. TAG_END()));
  1110. TEST_1(tport_incref(tp)); tport_decref(&tp);
  1111. msg_destroy(msg);
  1112. TEST(tport_test_run(tt, 5), 1);
  1113. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-2"));
  1114. test_check_md5(tt, tt->tt_rmsg);
  1115. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1116. TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-3", 1, 45500));
  1117. test_create_md5(tt, msg);
  1118. TEST_1(tp = tport_tsend(tt->tt_tports,
  1119. msg,
  1120. tt->tt_tcp_comp,
  1121. TPTAG_COMPARTMENT(cc),
  1122. TAG_END()));
  1123. TEST_1(tport_incref(tp));
  1124. msg_destroy(msg);
  1125. TEST(tport_test_run(tt, 5), 1);
  1126. tport_decref(&tp);
  1127. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-3"));
  1128. test_check_md5(tt, tt->tt_rmsg);
  1129. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1130. {
  1131. tp_name_t tpn[1];
  1132. tport_t *ctp, *rtp;
  1133. *tpn = *tt->tt_tcp_comp; tpn->tpn_comp = NULL;
  1134. TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-4", 1, 1000));
  1135. test_create_md5(tt, msg);
  1136. TEST_1(tp = tport_tsend(tt->tt_tports,
  1137. msg,
  1138. tpn,
  1139. TPTAG_COMPARTMENT(cc),
  1140. TPTAG_FRESH(1),
  1141. TAG_END()));
  1142. TEST_1(ctp = tport_incref(tp));
  1143. msg_destroy(msg);
  1144. TEST(tport_test_run(tt, 5), 1);
  1145. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-4"));
  1146. test_check_md5(tt, tt->tt_rmsg);
  1147. TEST_1((msg_addrinfo(tt->tt_rmsg)->ai_flags & TP_AI_COMPRESSED) == 0);
  1148. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1149. TEST_1(rtp = tport_incref(tt->tt_rtport));
  1150. TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-5", 1, 1000));
  1151. test_create_md5(tt, msg);
  1152. {
  1153. /* Mess with internal data structures in order to
  1154. force tport to use SigComp on this connection */
  1155. tp_name_t *tpn = (tp_name_t *)tport_name(rtp);
  1156. tpn->tpn_comp = "sigcomp";
  1157. }
  1158. TEST_1(tp = tport_tsend(rtp,
  1159. msg,
  1160. tt->tt_tcp_comp,
  1161. TPTAG_COMPARTMENT(cc),
  1162. TAG_END()));
  1163. TEST_1(tport_incref(tp));
  1164. msg_destroy(msg);
  1165. TEST(tp, rtp);
  1166. TEST(tport_test_run(tt, 5), 1);
  1167. tport_decref(&tp);
  1168. TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-5"));
  1169. test_check_md5(tt, tt->tt_rmsg);
  1170. TEST_1((msg_addrinfo(tt->tt_rmsg)->ai_flags & TP_AI_COMPRESSED) != 0);
  1171. msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
  1172. TEST(ctp, tt->tt_rtport);
  1173. tport_decref(&ctp);
  1174. }
  1175. }
  1176. #endif
  1177. END();
  1178. }
  1179. #if HAVE_SOFIA_STUN
  1180. #include <sofia-sip/stun_tag.h>
  1181. static int stun_test(tp_test_t *tt)
  1182. {
  1183. BEGIN();
  1184. tport_t *mr;
  1185. tp_name_t tpn[1] = {{ "*", "*", "*", "*", NULL }};
  1186. #if HAVE_NETINET_SCTP_H
  1187. char const * transports[] = { "udp", "tcp", "sctp", NULL };
  1188. #else
  1189. char const * transports[] = { "udp", "tcp", NULL };
  1190. #endif
  1191. TEST_1(mr = tport_tcreate(tt, tp_test_class, tt->tt_root, TAG_END()));
  1192. TEST(tport_tbind(tt->tt_tports, tpn, transports, TPTAG_SERVER(1),
  1193. STUNTAG_SERVER("999.999.999.999"),
  1194. TAG_END()), -1);
  1195. tport_destroy(mr);
  1196. END();
  1197. }
  1198. #else
  1199. static int stun_test(tp_test_t *tt)
  1200. {
  1201. return 0;
  1202. }
  1203. #endif
  1204. static int deinit_test(tp_test_t *tt)
  1205. {
  1206. BEGIN();
  1207. /* Destroy client transports */
  1208. tport_destroy(tt->tt_tports), tt->tt_tports = NULL;
  1209. /* Destroy server transports */
  1210. tport_destroy(tt->tt_srv_tports), tt->tt_srv_tports = NULL;
  1211. #if HAVE_SIGCOMP
  1212. sigcomp_state_handler_free(tt->state_handler); tt->state_handler = NULL;
  1213. #endif
  1214. END();
  1215. }
  1216. /* Test tport_tags filter */
  1217. static int filter_test(tp_test_t *tt)
  1218. {
  1219. tagi_t *lst, *result;
  1220. su_home_t home[1] = { SU_HOME_INIT(home) };
  1221. BEGIN();
  1222. lst = tl_list(TSTTAG_HEADER_STR("X: Y"),
  1223. TAG_SKIP(2),
  1224. TPTAG_IDENT("foo"),
  1225. TSTTAG_HEADER_STR("X: Y"),
  1226. TPTAG_IDENT("bar"),
  1227. TAG_NULL());
  1228. TEST_1(lst);
  1229. result = tl_afilter(home, tport_tags, lst);
  1230. TEST_1(result);
  1231. TEST_P(result[0].t_tag, tptag_ident);
  1232. TEST_P(result[1].t_tag, tptag_ident);
  1233. free(lst);
  1234. su_home_deinit(home);
  1235. END();
  1236. }
  1237. #if HAVE_ALARM
  1238. #include <signal.h>
  1239. static RETSIGTYPE sig_alarm(int s)
  1240. {
  1241. fprintf(stderr, "%s: FAIL! test timeout!\n", name);
  1242. exit(1);
  1243. }
  1244. char const alarm_option[] = " [--no-alarm]";
  1245. #else
  1246. char const alarm_option[] = "";
  1247. #endif
  1248. void usage(int exitcode)
  1249. {
  1250. fprintf(stderr, "usage: %s [-v] [-a]%s\n", name, alarm_option);
  1251. exit(exitcode);
  1252. }
  1253. int main(int argc, char *argv[])
  1254. {
  1255. int flags = 0; /* XXX */
  1256. int retval = 0;
  1257. int no_alarm = 0;
  1258. int i;
  1259. tp_test_t tt[1] = {{{ SU_HOME_INIT(tt) }}};
  1260. for (i = 1; argv[i]; i++) {
  1261. if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbatim") == 0)
  1262. tstflags |= tst_verbatim;
  1263. else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--abort") == 0)
  1264. tstflags |= tst_abort;
  1265. else if (strcmp(argv[i], "--no-alarm") == 0)
  1266. no_alarm = 1;
  1267. else
  1268. usage(1);
  1269. }
  1270. #if HAVE_OPEN_C
  1271. tstflags |= tst_verbatim;
  1272. #endif
  1273. #if HAVE_ALARM
  1274. if (!no_alarm) {
  1275. signal(SIGALRM, sig_alarm);
  1276. alarm(120);
  1277. }
  1278. #endif
  1279. /* Use log */
  1280. if (flags & tst_verbatim)
  1281. tport_log->log_default = 9;
  1282. else
  1283. tport_log->log_default = 1;
  1284. su_init();
  1285. retval |= name_test(tt); fflush(stdout);
  1286. retval |= filter_test(tt); fflush(stdout);
  1287. retval |= init_test(tt); fflush(stdout);
  1288. if (retval == 0) {
  1289. retval |= sigcomp_test(tt); fflush(stdout);
  1290. retval |= sctp_test(tt); fflush(stdout);
  1291. retval |= udp_test(tt); fflush(stdout);
  1292. retval |= tcp_test(tt); fflush(stdout);
  1293. retval |= test_incomplete(tt); fflush(stdout);
  1294. retval |= reuse_test(tt); fflush(stdout);
  1295. retval |= tls_test(tt); fflush(stdout);
  1296. if (0) /* Not yet working... */
  1297. retval |= stun_test(tt); fflush(stdout);
  1298. retval |= deinit_test(tt); fflush(stdout);
  1299. }
  1300. su_deinit();
  1301. #if HAVE_OPEN_C
  1302. sleep(10);
  1303. #endif
  1304. return retval;
  1305. }