sock.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <pjlib.h>
  20. #include "test.h"
  21. /**
  22. * \page page_pjlib_sock_test Test: Socket
  23. *
  24. * This file provides implementation of \b sock_test(). It tests the
  25. * various aspects of the socket API.
  26. *
  27. * \section sock_test_scope_sec Scope of the Test
  28. *
  29. * The scope of the test:
  30. * - verify the validity of the address structs.
  31. * - verify that address manipulation API works.
  32. * - simple socket creation and destruction.
  33. * - simple socket send/recv and sendto/recvfrom.
  34. * - UDP connect()
  35. * - send/recv big data.
  36. * - all for both UDP and TCP.
  37. *
  38. * The APIs tested in this test:
  39. * - pj_inet_aton()
  40. * - pj_inet_ntoa()
  41. * - pj_inet_pton() (only if IPv6 is enabled)
  42. * - pj_inet_ntop() (only if IPv6 is enabled)
  43. * - pj_gethostname()
  44. * - pj_sock_socket()
  45. * - pj_sock_close()
  46. * - pj_sock_send()
  47. * - pj_sock_sendto()
  48. * - pj_sock_recv()
  49. * - pj_sock_recvfrom()
  50. * - pj_sock_bind()
  51. * - pj_sock_connect()
  52. * - pj_sock_listen()
  53. * - pj_sock_accept()
  54. * - pj_gethostbyname()
  55. *
  56. *
  57. * This file is <b>pjlib-test/sock.c</b>
  58. *
  59. * \include pjlib-test/sock.c
  60. */
  61. #if INCLUDE_SOCK_TEST
  62. #define UDP_PORT 51234
  63. #define TCP_PORT (UDP_PORT+10)
  64. #define BIG_DATA_LEN 8192
  65. #define ADDRESS "127.0.0.1"
  66. static char bigdata[BIG_DATA_LEN];
  67. static char bigbuffer[BIG_DATA_LEN];
  68. /* Macro for checking the value of "sin_len" member of sockaddr
  69. * (it must always be zero).
  70. */
  71. #if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
  72. # define CHECK_SA_ZERO_LEN(addr, ret) \
  73. if (((pj_addr_hdr*)(addr))->sa_zero_len != 0) \
  74. return ret
  75. #else
  76. # define CHECK_SA_ZERO_LEN(addr, ret)
  77. #endif
  78. static int format_test(void)
  79. {
  80. pj_str_t s = pj_str(ADDRESS);
  81. unsigned char *p;
  82. pj_in_addr addr;
  83. char zero[64];
  84. pj_sockaddr_in addr2;
  85. const pj_str_t *hostname;
  86. const unsigned char A[] = {127, 0, 0, 1};
  87. PJ_LOG(3,("test", "...format_test()"));
  88. /* pj_inet_aton() */
  89. if (pj_inet_aton(&s, &addr) != 1)
  90. return -10;
  91. /* Check the result. */
  92. p = (unsigned char*)&addr;
  93. if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
  94. PJ_LOG(3,("test", " error: mismatched address. p0=%d, p1=%d, "
  95. "p2=%d, p3=%d", p[0] & 0xFF, p[1] & 0xFF,
  96. p[2] & 0xFF, p[3] & 0xFF));
  97. return -15;
  98. }
  99. /* pj_inet_ntoa() */
  100. p = (unsigned char*) pj_inet_ntoa(addr);
  101. if (!p)
  102. return -20;
  103. if (pj_strcmp2(&s, (char*)p) != 0)
  104. return -22;
  105. #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0
  106. /* pj_inet_pton() */
  107. /* pj_inet_ntop() */
  108. {
  109. const pj_str_t s_ipv4 = pj_str("127.0.0.1");
  110. const pj_str_t s_ipv6 = pj_str("fe80::2ff:83ff:fe7c:8b42");
  111. char buf_ipv4[PJ_INET_ADDRSTRLEN];
  112. char buf_ipv6[PJ_INET6_ADDRSTRLEN];
  113. pj_in_addr ipv4;
  114. pj_in6_addr ipv6;
  115. if (pj_inet_pton(pj_AF_INET(), &s_ipv4, &ipv4) != PJ_SUCCESS)
  116. return -24;
  117. p = (unsigned char*)&ipv4;
  118. if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
  119. return -25;
  120. }
  121. if (pj_inet_pton(pj_AF_INET6(), &s_ipv6, &ipv6) != PJ_SUCCESS)
  122. return -26;
  123. p = (unsigned char*)&ipv6;
  124. if (p[0] != 0xfe || p[1] != 0x80 || p[2] != 0 || p[3] != 0 ||
  125. p[4] != 0 || p[5] != 0 || p[6] != 0 || p[7] != 0 ||
  126. p[8] != 0x02 || p[9] != 0xff || p[10] != 0x83 || p[11] != 0xff ||
  127. p[12]!=0xfe || p[13]!=0x7c || p[14] != 0x8b || p[15]!=0x42)
  128. {
  129. return -27;
  130. }
  131. if (pj_inet_ntop(pj_AF_INET(), &ipv4, buf_ipv4, sizeof(buf_ipv4)) != PJ_SUCCESS)
  132. return -28;
  133. if (pj_stricmp2(&s_ipv4, buf_ipv4) != 0)
  134. return -29;
  135. if (pj_inet_ntop(pj_AF_INET6(), &ipv6, buf_ipv6, sizeof(buf_ipv6)) != PJ_SUCCESS)
  136. return -30;
  137. if (pj_stricmp2(&s_ipv6, buf_ipv6) != 0)
  138. return -31;
  139. }
  140. #endif /* PJ_HAS_IPV6 */
  141. #ifdef NDEBUG
  142. /* This should not crash */
  143. pj_sockaddr_in_init(NULL, 0, 1000);
  144. #endif
  145. /* Test that pj_sockaddr_in_init() initialize the whole structure,
  146. * including sin_zero_pad.
  147. */
  148. pj_sockaddr_in_init(&addr2, 0, 1000);
  149. pj_bzero(zero, sizeof(zero));
  150. if (pj_memcmp(addr2.sin_zero_pad, zero, sizeof(addr2.sin_zero_pad)) != 0)
  151. return -35;
  152. /* pj_gethostname() */
  153. hostname = pj_gethostname();
  154. if (!hostname || !hostname->ptr || !hostname->slen)
  155. return -40;
  156. PJ_LOG(3,("test", "....hostname is %.*s",
  157. (int)hostname->slen, hostname->ptr));
  158. /* pj_gethostaddr() */
  159. /* Various constants */
  160. #if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
  161. if (PJ_AF_INET==0xFFFF) return -5500;
  162. if (PJ_AF_INET6==0xFFFF) return -5501;
  163. /* 0xFFFF could be a valid SOL_SOCKET (e.g: on some Win or Mac) */
  164. //if (PJ_SOL_SOCKET==0xFFFF) return -5503;
  165. if (PJ_SOL_IP==0xFFFF) return -5502;
  166. if (PJ_SOL_TCP==0xFFFF) return -5510;
  167. if (PJ_SOL_UDP==0xFFFF) return -5520;
  168. if (PJ_SOL_IPV6==0xFFFF) return -5530;
  169. if (PJ_SO_TYPE==0xFFFF) return -5540;
  170. if (PJ_SO_RCVBUF==0xFFFF) return -5550;
  171. if (PJ_SO_SNDBUF==0xFFFF) return -5560;
  172. if (PJ_TCP_NODELAY==0xFFFF) return -5570;
  173. if (PJ_SO_REUSEADDR==0xFFFF) return -5580;
  174. if (PJ_MSG_OOB==0xFFFF) return -5590;
  175. if (PJ_MSG_PEEK==0xFFFF) return -5600;
  176. #endif
  177. return 0;
  178. }
  179. static int parse_test(void)
  180. {
  181. #define IPv4 1
  182. #define IPv6 2
  183. struct test_t {
  184. const char *input;
  185. int result_af;
  186. const char *result_ip;
  187. pj_uint16_t result_port;
  188. };
  189. struct test_t valid_tests[] =
  190. {
  191. /* IPv4 */
  192. { "10.0.0.1:80", IPv4, "10.0.0.1", 80},
  193. { "10.0.0.1", IPv4, "10.0.0.1", 0},
  194. { "10.0.0.1:", IPv4, "10.0.0.1", 0},
  195. { "10.0.0.1:0", IPv4, "10.0.0.1", 0},
  196. { ":80", IPv4, "0.0.0.0", 80},
  197. { ":", IPv4, "0.0.0.0", 0},
  198. #if !PJ_SYMBIAN
  199. { "localhost", IPv4, "127.0.0.1", 0},
  200. { "localhost:", IPv4, "127.0.0.1", 0},
  201. { "localhost:80", IPv4, "127.0.0.1", 80},
  202. #endif
  203. #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
  204. { "fe::01:80", IPv6, "fe::01:80", 0},
  205. { "[fe::01]:80", IPv6, "fe::01", 80},
  206. { "fe::01", IPv6, "fe::01", 0},
  207. { "[fe::01]", IPv6, "fe::01", 0},
  208. { "fe::01:", IPv6, "fe::01", 0},
  209. { "[fe::01]:", IPv6, "fe::01", 0},
  210. { "::", IPv6, "::0", 0},
  211. { "[::]", IPv6, "::", 0},
  212. { ":::", IPv6, "::", 0},
  213. { "[::]:", IPv6, "::", 0},
  214. { ":::80", IPv6, "::", 80},
  215. { "[::]:80", IPv6, "::", 80},
  216. #endif
  217. };
  218. struct test_t invalid_tests[] =
  219. {
  220. /* IPv4 */
  221. { "10.0.0.1:abcd", IPv4}, /* port not numeric */
  222. { "10.0.0.1:-1", IPv4}, /* port contains illegal character */
  223. { "10.0.0.1:123456", IPv4}, /* port too big */
  224. //this actually is fine on my Mac OS 10.9
  225. //it will be resolved with gethostbyname() and something is returned!
  226. //{ "1.2.3.4.5:80", IPv4}, /* invalid IP */
  227. { "10:0:80", IPv4}, /* hostname has colon */
  228. #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
  229. { "[fe::01]:abcd", IPv6}, /* port not numeric */
  230. { "[fe::01]:-1", IPv6}, /* port contains illegal character */
  231. { "[fe::01]:123456", IPv6}, /* port too big */
  232. { "fe::01:02::03:04:80", IPv6}, /* invalid IP */
  233. { "[fe::01:02::03:04]:80", IPv6}, /* invalid IP */
  234. { "[fe:01", IPv6}, /* Unterminated bracket */
  235. #endif
  236. };
  237. unsigned i;
  238. PJ_LOG(3,("test", "...IP address parsing"));
  239. for (i=0; i<PJ_ARRAY_SIZE(valid_tests); ++i) {
  240. pj_status_t status;
  241. pj_str_t input;
  242. pj_sockaddr addr, result;
  243. switch (valid_tests[i].result_af) {
  244. case IPv4:
  245. valid_tests[i].result_af = PJ_AF_INET;
  246. break;
  247. case IPv6:
  248. valid_tests[i].result_af = PJ_AF_INET6;
  249. break;
  250. default:
  251. pj_assert(!"Invalid AF!");
  252. continue;
  253. }
  254. /* Try parsing with PJ_AF_UNSPEC */
  255. status = pj_sockaddr_parse(PJ_AF_UNSPEC, 0,
  256. pj_cstr(&input, valid_tests[i].input),
  257. &addr);
  258. if (status != PJ_SUCCESS) {
  259. PJ_LOG(1,("test", ".... failed when parsing %s (i=%d)",
  260. valid_tests[i].input, i));
  261. return -10;
  262. }
  263. /* Check "sin_len" member of parse result */
  264. CHECK_SA_ZERO_LEN(&addr, -20);
  265. /* Build the correct result */
  266. status = pj_sockaddr_init(valid_tests[i].result_af,
  267. &result,
  268. pj_cstr(&input, valid_tests[i].result_ip),
  269. valid_tests[i].result_port);
  270. if (status != PJ_SUCCESS) {
  271. PJ_LOG(1,("test", ".... error building IP address %s",
  272. valid_tests[i].input));
  273. return -30;
  274. }
  275. /* Compare the result */
  276. if (pj_sockaddr_cmp(&addr, &result) != 0) {
  277. PJ_LOG(1,("test", ".... parsed result mismatched for %s",
  278. valid_tests[i].input));
  279. return -40;
  280. }
  281. /* Parse again with the specified af */
  282. status = pj_sockaddr_parse(valid_tests[i].result_af, 0,
  283. pj_cstr(&input, valid_tests[i].input),
  284. &addr);
  285. if (status != PJ_SUCCESS) {
  286. PJ_LOG(1,("test", ".... failed when parsing %s",
  287. valid_tests[i].input));
  288. return -50;
  289. }
  290. /* Check "sin_len" member of parse result */
  291. CHECK_SA_ZERO_LEN(&addr, -55);
  292. /* Compare the result again */
  293. if (pj_sockaddr_cmp(&addr, &result) != 0) {
  294. PJ_LOG(1,("test", ".... parsed result mismatched for %s",
  295. valid_tests[i].input));
  296. return -60;
  297. }
  298. }
  299. for (i=0; i<PJ_ARRAY_SIZE(invalid_tests); ++i) {
  300. pj_status_t status;
  301. pj_str_t input;
  302. pj_sockaddr addr;
  303. switch (invalid_tests[i].result_af) {
  304. case IPv4:
  305. invalid_tests[i].result_af = PJ_AF_INET;
  306. break;
  307. case IPv6:
  308. invalid_tests[i].result_af = PJ_AF_INET6;
  309. break;
  310. default:
  311. pj_assert(!"Invalid AF!");
  312. continue;
  313. }
  314. /* Try parsing with PJ_AF_UNSPEC */
  315. status = pj_sockaddr_parse(PJ_AF_UNSPEC, 0,
  316. pj_cstr(&input, invalid_tests[i].input),
  317. &addr);
  318. if (status == PJ_SUCCESS) {
  319. PJ_LOG(1,("test", ".... expecting failure when parsing %s",
  320. invalid_tests[i].input));
  321. return -100;
  322. }
  323. }
  324. return 0;
  325. }
  326. static int purity_test(void)
  327. {
  328. PJ_LOG(3,("test", "...purity_test()"));
  329. #if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
  330. /* Check on "sin_len" member of sockaddr */
  331. {
  332. const pj_str_t str_ip = {"1.1.1.1", 7};
  333. pj_sockaddr addr[16];
  334. pj_addrinfo ai[16];
  335. unsigned cnt;
  336. pj_status_t rc;
  337. /* pj_enum_ip_interface() */
  338. cnt = PJ_ARRAY_SIZE(addr);
  339. rc = pj_enum_ip_interface(pj_AF_UNSPEC(), &cnt, addr);
  340. if (rc == PJ_SUCCESS) {
  341. while (cnt--)
  342. CHECK_SA_ZERO_LEN(&addr[cnt], -10);
  343. }
  344. /* pj_gethostip() on IPv4 */
  345. rc = pj_gethostip(pj_AF_INET(), &addr[0]);
  346. if (rc == PJ_SUCCESS)
  347. CHECK_SA_ZERO_LEN(&addr[0], -20);
  348. /* pj_gethostip() on IPv6 */
  349. rc = pj_gethostip(pj_AF_INET6(), &addr[0]);
  350. if (rc == PJ_SUCCESS)
  351. CHECK_SA_ZERO_LEN(&addr[0], -30);
  352. /* pj_getdefaultipinterface() on IPv4 */
  353. rc = pj_getdefaultipinterface(pj_AF_INET(), &addr[0]);
  354. if (rc == PJ_SUCCESS)
  355. CHECK_SA_ZERO_LEN(&addr[0], -40);
  356. /* pj_getdefaultipinterface() on IPv6 */
  357. rc = pj_getdefaultipinterface(pj_AF_INET6(), &addr[0]);
  358. if (rc == PJ_SUCCESS)
  359. CHECK_SA_ZERO_LEN(&addr[0], -50);
  360. /* pj_getaddrinfo() on a host name */
  361. cnt = PJ_ARRAY_SIZE(ai);
  362. rc = pj_getaddrinfo(pj_AF_UNSPEC(), pj_gethostname(), &cnt, ai);
  363. if (rc == PJ_SUCCESS) {
  364. while (cnt--)
  365. CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -60);
  366. }
  367. /* pj_getaddrinfo() on an IP address */
  368. cnt = PJ_ARRAY_SIZE(ai);
  369. rc = pj_getaddrinfo(pj_AF_UNSPEC(), &str_ip, &cnt, ai);
  370. if (rc == PJ_SUCCESS) {
  371. while (cnt--)
  372. CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -70);
  373. }
  374. }
  375. #endif
  376. return 0;
  377. }
  378. static int simple_sock_test(void)
  379. {
  380. int types[2];
  381. pj_sock_t sock;
  382. int i;
  383. pj_status_t rc = PJ_SUCCESS;
  384. types[0] = pj_SOCK_STREAM();
  385. types[1] = pj_SOCK_DGRAM();
  386. PJ_LOG(3,("test", "...simple_sock_test()"));
  387. for (i=0; i<(int)PJ_ARRAY_SIZE(types); ++i) {
  388. rc = pj_sock_socket(pj_AF_INET(), types[i], 0, &sock);
  389. if (rc != PJ_SUCCESS) {
  390. app_perror("...error: unable to create socket", rc);
  391. break;
  392. } else {
  393. rc = pj_sock_close(sock);
  394. if (rc != 0) {
  395. app_perror("...error: close socket", rc);
  396. break;
  397. }
  398. }
  399. }
  400. return rc;
  401. }
  402. static int send_recv_test(int sock_type,
  403. pj_sock_t ss, pj_sock_t cs,
  404. pj_sockaddr_in *dstaddr, pj_sockaddr_in *srcaddr,
  405. int addrlen)
  406. {
  407. enum { DATA_LEN = 16 };
  408. char senddata[DATA_LEN+4], recvdata[DATA_LEN+4];
  409. pj_ssize_t sent, received, total_received;
  410. pj_status_t rc;
  411. TRACE_(("test", "....create_random_string()"));
  412. pj_create_random_string(senddata, DATA_LEN);
  413. senddata[DATA_LEN-1] = '\0';
  414. /*
  415. * Test send/recv small data.
  416. */
  417. TRACE_(("test", "....sendto()"));
  418. if (dstaddr) {
  419. sent = DATA_LEN;
  420. rc = pj_sock_sendto(cs, senddata, &sent, 0, dstaddr, addrlen);
  421. if (rc != PJ_SUCCESS || sent != DATA_LEN) {
  422. app_perror("...sendto error", rc);
  423. rc = -140; goto on_error;
  424. }
  425. } else {
  426. sent = DATA_LEN;
  427. rc = pj_sock_send(cs, senddata, &sent, 0);
  428. if (rc != PJ_SUCCESS || sent != DATA_LEN) {
  429. app_perror("...send error", rc);
  430. rc = -145; goto on_error;
  431. }
  432. }
  433. TRACE_(("test", "....recv()"));
  434. if (srcaddr) {
  435. pj_sockaddr_in addr;
  436. int srclen = sizeof(addr);
  437. pj_bzero(&addr, sizeof(addr));
  438. received = DATA_LEN;
  439. rc = pj_sock_recvfrom(ss, recvdata, &received, 0, &addr, &srclen);
  440. if (rc != PJ_SUCCESS || received != DATA_LEN) {
  441. app_perror("...recvfrom error", rc);
  442. rc = -150; goto on_error;
  443. }
  444. if (srclen != addrlen)
  445. return -151;
  446. if (pj_sockaddr_cmp(&addr, srcaddr) != 0) {
  447. char srcaddr_str[32], addr_str[32];
  448. pj_ansi_strxcpy(srcaddr_str, pj_inet_ntoa(srcaddr->sin_addr),
  449. sizeof(srcaddr_str));
  450. pj_ansi_strxcpy(addr_str, pj_inet_ntoa(addr.sin_addr),
  451. sizeof(addr_str));
  452. PJ_LOG(3,("test", "...error: src address mismatch (original=%s, "
  453. "recvfrom addr=%s)",
  454. srcaddr_str, addr_str));
  455. return -152;
  456. }
  457. } else {
  458. /* Repeat recv() until all data is received.
  459. * This applies only for non-UDP of course, since for UDP
  460. * we would expect all data to be received in one packet.
  461. */
  462. total_received = 0;
  463. do {
  464. received = DATA_LEN-total_received;
  465. rc = pj_sock_recv(ss, recvdata+total_received, &received, 0);
  466. if (rc != PJ_SUCCESS) {
  467. app_perror("...recv error", rc);
  468. rc = -155; goto on_error;
  469. }
  470. if (received <= 0) {
  471. PJ_LOG(3,("", "...error: socket has closed! (received=%lu)",
  472. (unsigned long)received));
  473. rc = -156; goto on_error;
  474. }
  475. if (received != DATA_LEN-total_received) {
  476. if (sock_type != pj_SOCK_STREAM()) {
  477. PJ_LOG(3,("", "...error: expecting %lu bytes, got %lu bytes",
  478. (unsigned long)(DATA_LEN-total_received),
  479. (unsigned long)received));
  480. rc = -157; goto on_error;
  481. }
  482. }
  483. total_received += received;
  484. } while (total_received < DATA_LEN);
  485. }
  486. TRACE_(("test", "....memcmp()"));
  487. if (pj_memcmp(senddata, recvdata, DATA_LEN) != 0) {
  488. PJ_LOG(3,("","...error: received data mismatch "
  489. "(got:'%s' expecting:'%s'",
  490. recvdata, senddata));
  491. rc = -160; goto on_error;
  492. }
  493. /*
  494. * Test send/recv big data.
  495. */
  496. TRACE_(("test", "....sendto()"));
  497. if (dstaddr) {
  498. sent = BIG_DATA_LEN;
  499. rc = pj_sock_sendto(cs, bigdata, &sent, 0, dstaddr, addrlen);
  500. if (rc != PJ_SUCCESS || sent != BIG_DATA_LEN) {
  501. app_perror("...sendto error", rc);
  502. rc = -161; goto on_error;
  503. }
  504. } else {
  505. sent = BIG_DATA_LEN;
  506. rc = pj_sock_send(cs, bigdata, &sent, 0);
  507. if (rc != PJ_SUCCESS || sent != BIG_DATA_LEN) {
  508. app_perror("...send error", rc);
  509. rc = -165; goto on_error;
  510. }
  511. }
  512. TRACE_(("test", "....recv()"));
  513. /* Repeat recv() until all data is received.
  514. * This applies only for non-UDP of course, since for UDP
  515. * we would expect all data to be received in one packet.
  516. */
  517. total_received = 0;
  518. do {
  519. received = BIG_DATA_LEN-total_received;
  520. rc = pj_sock_recv(ss, bigbuffer+total_received, &received, 0);
  521. if (rc != PJ_SUCCESS) {
  522. app_perror("...recv error", rc);
  523. rc = -170; goto on_error;
  524. }
  525. if (received <= 0) {
  526. PJ_LOG(3,("", "...error: socket has closed! (received=%lu)",
  527. (unsigned long)received));
  528. rc = -173; goto on_error;
  529. }
  530. if (received != BIG_DATA_LEN-total_received) {
  531. if (sock_type != pj_SOCK_STREAM()) {
  532. PJ_LOG(3,("", "...error: expecting %lu bytes, got %lu bytes",
  533. (unsigned long)BIG_DATA_LEN-total_received,
  534. (unsigned long)received));
  535. rc = -176; goto on_error;
  536. }
  537. }
  538. total_received += received;
  539. } while (total_received < BIG_DATA_LEN);
  540. TRACE_(("test", "....memcmp()"));
  541. if (pj_memcmp(bigdata, bigbuffer, BIG_DATA_LEN) != 0) {
  542. PJ_LOG(3,("", "...error: received data has been altered!"));
  543. rc = -180; goto on_error;
  544. }
  545. rc = 0;
  546. on_error:
  547. return rc;
  548. }
  549. static int udp_test(void)
  550. {
  551. pj_sock_t cs = PJ_INVALID_SOCKET, ss = PJ_INVALID_SOCKET;
  552. pj_sockaddr_in dstaddr, srcaddr;
  553. pj_str_t s;
  554. pj_status_t rc = 0, retval;
  555. PJ_LOG(3,("test", "...udp_test()"));
  556. rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &ss);
  557. if (rc != 0) {
  558. app_perror("...error: unable to create socket", rc);
  559. return -100;
  560. }
  561. rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &cs);
  562. if (rc != 0) {
  563. rc = -110; goto on_error;
  564. }
  565. /* Bind server socket. */
  566. pj_bzero(&dstaddr, sizeof(dstaddr));
  567. dstaddr.sin_family = pj_AF_INET();
  568. dstaddr.sin_port = pj_htons(UDP_PORT);
  569. dstaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
  570. if ((rc=pj_sock_bind(ss, &dstaddr, sizeof(dstaddr))) != 0) {
  571. app_perror("...bind error udp:"ADDRESS, rc);
  572. rc = -120; goto on_error;
  573. }
  574. /* Bind client socket. */
  575. pj_bzero(&srcaddr, sizeof(srcaddr));
  576. srcaddr.sin_family = pj_AF_INET();
  577. srcaddr.sin_port = pj_htons(UDP_PORT-1);
  578. srcaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
  579. if ((rc=pj_sock_bind(cs, &srcaddr, sizeof(srcaddr))) != 0) {
  580. app_perror("...bind error", rc);
  581. rc = -121; goto on_error;
  582. }
  583. /* Test send/recv, with sendto */
  584. rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, &dstaddr, NULL,
  585. sizeof(dstaddr));
  586. if (rc != 0)
  587. goto on_error;
  588. /* Test send/recv, with sendto and recvfrom */
  589. rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, &dstaddr,
  590. &srcaddr, sizeof(dstaddr));
  591. if (rc != 0)
  592. goto on_error;
  593. /* Disable this test on Symbian since UDP connect()/send() failed
  594. * with S60 3rd edition (including MR2).
  595. * See https://github.com/pjsip/pjproject/issues/264
  596. */
  597. #if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
  598. /* connect() the sockets. */
  599. rc = pj_sock_connect(cs, &dstaddr, sizeof(dstaddr));
  600. if (rc != 0) {
  601. app_perror("...connect() error", rc);
  602. rc = -122; goto on_error;
  603. }
  604. /* Test send/recv with send() */
  605. rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, NULL, NULL, 0);
  606. if (rc != 0)
  607. goto on_error;
  608. /* Test send/recv with send() and recvfrom */
  609. rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, NULL, &srcaddr,
  610. sizeof(srcaddr));
  611. if (rc != 0)
  612. goto on_error;
  613. #endif
  614. on_error:
  615. retval = rc;
  616. if (cs != PJ_INVALID_SOCKET) {
  617. rc = pj_sock_close(cs);
  618. if (rc != PJ_SUCCESS) {
  619. app_perror("...error in closing socket", rc);
  620. return -1000;
  621. }
  622. }
  623. if (ss != PJ_INVALID_SOCKET) {
  624. rc = pj_sock_close(ss);
  625. if (rc != PJ_SUCCESS) {
  626. app_perror("...error in closing socket", rc);
  627. return -1010;
  628. }
  629. }
  630. return retval;
  631. }
  632. static int tcp_test(void)
  633. {
  634. pj_sock_t cs, ss;
  635. pj_status_t rc = 0, retval;
  636. PJ_LOG(3,("test", "...tcp_test()"));
  637. rc = app_socketpair(pj_AF_INET(), pj_SOCK_STREAM(), 0, &ss, &cs);
  638. if (rc != PJ_SUCCESS) {
  639. app_perror("...error: app_socketpair():", rc);
  640. return -2000;
  641. }
  642. /* Test send/recv with send() and recv() */
  643. retval = send_recv_test(pj_SOCK_STREAM(), ss, cs, NULL, NULL, 0);
  644. rc = pj_sock_close(cs);
  645. if (rc != PJ_SUCCESS) {
  646. app_perror("...error in closing socket", rc);
  647. return -2000;
  648. }
  649. rc = pj_sock_close(ss);
  650. if (rc != PJ_SUCCESS) {
  651. app_perror("...error in closing socket", rc);
  652. return -2010;
  653. }
  654. return retval;
  655. }
  656. static int ioctl_test(void)
  657. {
  658. return 0;
  659. }
  660. static int gethostbyname_test(void)
  661. {
  662. pj_str_t host;
  663. pj_hostent he;
  664. pj_status_t status;
  665. PJ_LOG(3,("test", "...gethostbyname_test()"));
  666. /* Testing pj_gethostbyname() with invalid host */
  667. host = pj_str("an-invalid-host-name");
  668. status = pj_gethostbyname(&host, &he);
  669. /* Must return failure! */
  670. if (status == PJ_SUCCESS)
  671. return -20100;
  672. else
  673. return 0;
  674. }
  675. #if 0
  676. #include "../pj/os_symbian.h"
  677. static int connect_test()
  678. {
  679. RSocketServ rSockServ;
  680. RSocket rSock;
  681. TInetAddr inetAddr;
  682. TRequestStatus reqStatus;
  683. char buffer[16];
  684. TPtrC8 data((const TUint8*)buffer, (TInt)sizeof(buffer));
  685. int rc;
  686. rc = rSockServ.Connect();
  687. if (rc != KErrNone)
  688. return rc;
  689. rc = rSock.Open(rSockServ, KAfInet, KSockDatagram, KProtocolInetUdp);
  690. if (rc != KErrNone)
  691. {
  692. rSockServ.Close();
  693. return rc;
  694. }
  695. inetAddr.Init(KAfInet);
  696. inetAddr.Input(_L("127.0.0.1"));
  697. inetAddr.SetPort(80);
  698. rSock.Connect(inetAddr, reqStatus);
  699. User::WaitForRequest(reqStatus);
  700. if (reqStatus != KErrNone) {
  701. rSock.Close();
  702. rSockServ.Close();
  703. return rc;
  704. }
  705. rSock.Send(data, 0, reqStatus);
  706. User::WaitForRequest(reqStatus);
  707. if (reqStatus!=KErrNone) {
  708. rSock.Close();
  709. rSockServ.Close();
  710. return rc;
  711. }
  712. rSock.Close();
  713. rSockServ.Close();
  714. return KErrNone;
  715. }
  716. #endif
  717. static const char *family2str(int f)
  718. {
  719. if (f == pj_AF_UNIX())
  720. return "AF_UNIX";
  721. if (f == pj_AF_INET())
  722. return "AF_INET";
  723. if (f == pj_AF_INET6())
  724. return "AF_INET6";
  725. return "?";
  726. }
  727. static const char *type2str(int type)
  728. {
  729. if (type == pj_SOCK_DGRAM())
  730. return "SOCK_DGRAM";
  731. if (type == pj_SOCK_STREAM())
  732. return "SOCK_STREAM";
  733. return "?";
  734. }
  735. static int do_sockpair_tst(int family, int type, int proto)
  736. {
  737. pj_status_t rc;
  738. pj_sock_t sv[2] = {-1, -1};
  739. char buf[64];
  740. pj_ssize_t len;
  741. PJ_LOG(3, ("test", "#Test socketpair, family: %s, type: %s",
  742. family2str(family), type2str(type)));
  743. rc = pj_sock_socketpair(family, type, proto, sv);
  744. if (rc != PJ_SUCCESS)
  745. goto on_error;
  746. /* sv[0] send text to sv[1] */
  747. len = pj_ansi_snprintf(buf, sizeof(buf), "hello, %ld->%ld", sv[0], sv[1]);
  748. rc = pj_sock_send(sv[0], buf, &len, 0);
  749. if (rc != PJ_SUCCESS)
  750. goto on_error;
  751. PJ_LOG(3, ("test", "send: %.*s", (int)len, buf));
  752. len = sizeof(buf);
  753. rc = pj_sock_recv(sv[1], buf, &len, 0);
  754. if (rc != PJ_SUCCESS)
  755. goto on_error;
  756. PJ_LOG(3, ("test", "recv: %.*s", (int)len, buf));
  757. /* sv[1] send text to sv[0] */
  758. len = pj_ansi_snprintf(buf, sizeof(buf), "hello, %ld->%ld", sv[1], sv[0]);
  759. rc = pj_sock_send(sv[1], buf, &len, 0);
  760. if (rc != PJ_SUCCESS)
  761. goto on_error;
  762. PJ_LOG(3, ("test", "send: %.*s", (int)len, buf));
  763. len = sizeof(buf);
  764. rc = pj_sock_recv(sv[0], buf, &len, 0);
  765. if (rc != PJ_SUCCESS)
  766. goto on_error;
  767. PJ_LOG(3, ("test", "recv: %.*s", (int)len, buf));
  768. on_error:
  769. if (sv[0] > 0)
  770. pj_sock_close(sv[0]);
  771. if (sv[1] > 0)
  772. pj_sock_close(sv[1]);
  773. if (rc != PJ_SUCCESS) {
  774. PJ_PERROR(1, ("test", rc, "error"));
  775. }
  776. return rc;
  777. }
  778. static int socketpair_test()
  779. {
  780. int rc;
  781. PJ_LOG(3, ("test", "...socketpair_test()"));
  782. /* AF_UNIX */
  783. #if (defined(PJ_SOCK_HAS_SOCKETPAIR) && PJ_SOCK_HAS_SOCKETPAIR)
  784. rc = do_sockpair_tst(pj_AF_UNIX(), pj_SOCK_DGRAM(), 0);
  785. if (rc != PJ_SUCCESS)
  786. return rc;
  787. rc = do_sockpair_tst(pj_AF_UNIX(), pj_SOCK_STREAM(), 0);
  788. if (rc != PJ_SUCCESS)
  789. return rc;
  790. #else
  791. PJ_LOG(2, ("test", "Not support AF_UNIX"));
  792. #endif
  793. /* AF_INET */
  794. rc = do_sockpair_tst(pj_AF_INET(), pj_SOCK_DGRAM(), 0);
  795. if (rc != PJ_SUCCESS)
  796. return rc;
  797. #if PJ_HAS_TCP
  798. rc = do_sockpair_tst(pj_AF_INET(), pj_SOCK_STREAM(), 0);
  799. if (rc != PJ_SUCCESS)
  800. return rc;
  801. #endif
  802. /* AF_INET6 */
  803. rc = do_sockpair_tst(pj_AF_INET6(), pj_SOCK_DGRAM(), 0);
  804. if (rc != PJ_SUCCESS)
  805. return rc;
  806. #if PJ_HAS_TCP
  807. rc = do_sockpair_tst(pj_AF_INET6(), pj_SOCK_STREAM(), 0);
  808. if (rc != PJ_SUCCESS)
  809. return rc;
  810. #endif
  811. return 0;
  812. }
  813. int sock_test()
  814. {
  815. int rc;
  816. pj_create_random_string(bigdata, BIG_DATA_LEN);
  817. // Enable this to demonstrate the error witn S60 3rd Edition MR2
  818. #if 0
  819. rc = connect_test();
  820. if (rc != 0)
  821. return rc;
  822. #endif
  823. rc = format_test();
  824. if (rc != 0)
  825. return rc;
  826. rc = parse_test();
  827. if (rc != 0)
  828. return rc;
  829. rc = purity_test();
  830. if (rc != 0)
  831. return rc;
  832. rc = gethostbyname_test();
  833. if (rc != 0)
  834. return rc;
  835. rc = simple_sock_test();
  836. if (rc != 0)
  837. return rc;
  838. rc = ioctl_test();
  839. if (rc != 0)
  840. return rc;
  841. rc = udp_test();
  842. if (rc != 0)
  843. return rc;
  844. rc = tcp_test();
  845. if (rc != 0)
  846. return rc;
  847. rc = socketpair_test();
  848. if (rc != 0)
  849. return rc;
  850. return 0;
  851. }
  852. #else
  853. /* To prevent warning about "translation unit is empty"
  854. * when this test is disabled.
  855. */
  856. int dummy_sock_test;
  857. #endif /* INCLUDE_SOCK_TEST */