ekr_loop_upcall.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. * Copyright (C) 2011-2013 Michael Tuexen
  3. * Copyright (C) 2018-2020 Felix Weinrank
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the project nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. */
  31. /*
  32. * Usage: ekr_loop [client_port] [server_port] [crc32c offloading <0/1>]
  33. */
  34. #ifdef _WIN32
  35. #define _CRT_SECURE_NO_WARNINGS
  36. #endif
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <stdarg.h>
  41. #include <sys/types.h>
  42. #ifndef _WIN32
  43. #include <sys/socket.h>
  44. #include <netinet/in.h>
  45. #include <arpa/inet.h>
  46. #include <errno.h>
  47. #include <pthread.h>
  48. #include <unistd.h>
  49. #else
  50. #include <winsock2.h>
  51. #include <ws2tcpip.h>
  52. #endif
  53. #include <usrsctp.h>
  54. #include "programs_helper.h"
  55. #define MAX_PACKET_SIZE (1<<16)
  56. #define LINE_LENGTH (1<<20)
  57. #define DISCARD_PPID 39
  58. #define NUMBER_OF_STEPS 10
  59. static uint8_t crc32c_offloading = 0;
  60. struct upcall_meta {
  61. uint8_t sender;
  62. void* addr;
  63. };
  64. #ifdef _WIN32
  65. static DWORD WINAPI
  66. #else
  67. static void *
  68. #endif
  69. handle_packets(void *arg)
  70. {
  71. #ifdef _WIN32
  72. SOCKET *fdp;
  73. #else
  74. int *fdp;
  75. #endif
  76. char *dump_buf;
  77. struct sctp_common_header *hdr;
  78. ssize_t length;
  79. char buf[MAX_PACKET_SIZE];
  80. uint32_t received_crc32c, computed_crc32c;
  81. #ifdef _WIN32
  82. fdp = (SOCKET *)arg;
  83. #else
  84. fdp = (int *)arg;
  85. #endif
  86. for (;;) {
  87. #if defined(__NetBSD__)
  88. pthread_testcancel();
  89. #endif
  90. length = recv(*fdp, buf, MAX_PACKET_SIZE, 0);
  91. if (length > 0) {
  92. if ((dump_buf = usrsctp_dumppacket(buf, (size_t)length, SCTP_DUMP_INBOUND)) != NULL) {
  93. //debug_printf_clean("%s\n", dump_buf);
  94. usrsctp_freedumpbuffer(dump_buf);
  95. }
  96. if (crc32c_offloading) {
  97. if ((size_t)length >= sizeof(struct sctp_common_header)) {
  98. hdr = (struct sctp_common_header *)buf;
  99. received_crc32c = hdr->crc32c;
  100. hdr->crc32c = htonl(0);
  101. computed_crc32c = usrsctp_crc32c(buf, (size_t)length);
  102. hdr->crc32c = received_crc32c;
  103. if (received_crc32c == computed_crc32c) {
  104. usrsctp_conninput(fdp, buf, (size_t)length, 0);
  105. } else {
  106. debug_printf("Wrong CRC32c: expected %08x received %08x\n",
  107. ntohl(computed_crc32c), ntohl(received_crc32c));
  108. }
  109. } else {
  110. debug_printf("Packet too short: length %zd", length);
  111. }
  112. } else {
  113. usrsctp_conninput(fdp, buf, (size_t)length, 0);
  114. }
  115. }
  116. }
  117. #ifdef _WIN32
  118. return 0;
  119. #else
  120. return (NULL);
  121. #endif
  122. }
  123. static int
  124. conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
  125. {
  126. char *dump_buf;
  127. struct sctp_common_header *hdr;
  128. #ifdef _WIN32
  129. SOCKET *fdp;
  130. #else
  131. int *fdp;
  132. #endif
  133. #ifdef _WIN32
  134. fdp = (SOCKET *)addr;
  135. #else
  136. fdp = (int *)addr;
  137. #endif
  138. if (crc32c_offloading && length >= sizeof(struct sctp_common_header)) {
  139. hdr = (struct sctp_common_header *)buf;
  140. hdr->crc32c = usrsctp_crc32c(buf, (size_t)length);
  141. }
  142. if ((dump_buf = usrsctp_dumppacket(buf, length, SCTP_DUMP_OUTBOUND)) != NULL) {
  143. //debug_printf_clean("%s\n", dump_buf);
  144. usrsctp_freedumpbuffer(dump_buf);
  145. }
  146. #ifdef _WIN32
  147. if (send(*fdp, buf, (int)length, 0) == SOCKET_ERROR) {
  148. return (WSAGetLastError());
  149. #else
  150. if (send(*fdp, buf, length, 0) < 0) {
  151. return (errno);
  152. #endif
  153. } else {
  154. return (0);
  155. }
  156. }
  157. static void
  158. handle_upcall(struct socket *sock, void *data, int flgs)
  159. {
  160. char *buf;
  161. int events;
  162. struct upcall_meta *meta;
  163. meta = data;
  164. buf = malloc(MAX_PACKET_SIZE);
  165. while ((events = usrsctp_get_events(sock)) && (events & SCTP_EVENT_READ)) {
  166. struct sctp_recvv_rn rn;
  167. ssize_t n;
  168. union sctp_sockstore addr;
  169. int flags = 0;
  170. socklen_t len = (socklen_t)sizeof(addr);
  171. unsigned int infotype = 0;
  172. socklen_t infolen = sizeof(struct sctp_recvv_rn);
  173. memset(&rn, 0, sizeof(struct sctp_recvv_rn));
  174. n = usrsctp_recvv(sock, buf, MAX_PACKET_SIZE, (struct sockaddr *) &addr, &len, (void *)&rn, &infolen, &infotype, &flags);
  175. if (n < 0) {
  176. perror("usrsctp_recvv");
  177. break;
  178. } else if (n > 0) {
  179. if (flags & MSG_NOTIFICATION) {
  180. debug_printf("MSG RCV: Notification of length %d received.\n", (int)n);
  181. } else {
  182. debug_printf("MSG RCV: Data length %d, addr %p:%u, stream %u, SSN %u, TSN %u, PPID %u, context %u, %s%s.\n",
  183. (int)n,
  184. addr.sconn.sconn_addr,
  185. ntohs(addr.sconn.sconn_port),
  186. rn.recvv_rcvinfo.rcv_sid,
  187. rn.recvv_rcvinfo.rcv_ssn,
  188. rn.recvv_rcvinfo.rcv_tsn,
  189. ntohl(rn.recvv_rcvinfo.rcv_ppid),
  190. rn.recvv_rcvinfo.rcv_context,
  191. (rn.recvv_rcvinfo.rcv_flags & SCTP_UNORDERED) ? "unordered" : "ordered",
  192. (flags & MSG_EOR) ? ", EOR" : "");
  193. }
  194. } else {
  195. debug_printf("Connection closed!\n");
  196. usrsctp_deregister_address(meta->addr);
  197. usrsctp_close(sock);
  198. break;
  199. }
  200. }
  201. free(buf);
  202. return;
  203. }
  204. static void
  205. print_addresses(struct socket *sock)
  206. {
  207. int i, n;
  208. struct sockaddr *addrs, *addr;
  209. #if !defined(HAVE_SA_LEN)
  210. int sa_len;
  211. #endif
  212. debug_printf("Addresses: ");
  213. n = usrsctp_getladdrs(sock, 0, &addrs);
  214. addr = addrs;
  215. for (i = 0; i < n; i++) {
  216. switch (addr->sa_family) {
  217. case AF_INET:
  218. {
  219. struct sockaddr_in *sin;
  220. char buf[INET_ADDRSTRLEN];
  221. const char *name;
  222. sin = (struct sockaddr_in *)addr;
  223. name = inet_ntop(AF_INET, &sin->sin_addr, buf, INET_ADDRSTRLEN);
  224. debug_printf_clean("%s:%d", name, ntohs(sin->sin_port));
  225. #if !defined(HAVE_SA_LEN)
  226. sa_len = (int)sizeof(struct sockaddr_in);
  227. #endif
  228. break;
  229. }
  230. case AF_INET6:
  231. {
  232. struct sockaddr_in6 *sin6;
  233. char buf[INET6_ADDRSTRLEN];
  234. const char *name;
  235. sin6 = (struct sockaddr_in6 *)addr;
  236. name = inet_ntop(AF_INET6, &sin6->sin6_addr, buf, INET6_ADDRSTRLEN);
  237. debug_printf_clean("%s:%d", name, ntohs(sin6->sin6_port));
  238. #if !defined(HAVE_SA_LEN)
  239. sa_len = (int)sizeof(struct sockaddr_in6);
  240. #endif
  241. break;
  242. }
  243. case AF_CONN:
  244. {
  245. struct sockaddr_conn *sconn;
  246. sconn = (struct sockaddr_conn *)addr;
  247. debug_printf_clean("%p:%d", sconn->sconn_addr, ntohs(sconn->sconn_port));
  248. #if !defined(HAVE_SA_LEN)
  249. sa_len = (int)sizeof(struct sockaddr_conn);
  250. #endif
  251. break;
  252. }
  253. default:
  254. debug_printf_clean("Unknown family: %d", addr->sa_family);
  255. #if !defined(HAVE_SA_LEN)
  256. sa_len = (int)sizeof(struct sockaddr);
  257. #endif
  258. break;
  259. }
  260. #if !defined(HAVE_SA_LEN)
  261. addr = (struct sockaddr *)((char *)addr + sa_len);
  262. #else
  263. addr = (struct sockaddr *)((caddr_t)addr + addr->sa_len);
  264. #endif
  265. if (i != n - 1) {
  266. debug_printf_clean(",");
  267. }
  268. }
  269. if (n > 0) {
  270. usrsctp_freeladdrs(addrs);
  271. }
  272. debug_printf_clean("<->");
  273. n = usrsctp_getpaddrs(sock, 0, &addrs);
  274. addr = addrs;
  275. for (i = 0; i < n; i++) {
  276. switch (addr->sa_family) {
  277. case AF_INET:
  278. {
  279. struct sockaddr_in *sin;
  280. char buf[INET_ADDRSTRLEN];
  281. const char *name;
  282. sin = (struct sockaddr_in *)addr;
  283. name = inet_ntop(AF_INET, &sin->sin_addr, buf, INET_ADDRSTRLEN);
  284. debug_printf_clean("%s:%d", name, ntohs(sin->sin_port));
  285. #if !defined(HAVE_SA_LEN)
  286. sa_len = (int)sizeof(struct sockaddr_in);
  287. #endif
  288. break;
  289. }
  290. case AF_INET6:
  291. {
  292. struct sockaddr_in6 *sin6;
  293. char buf[INET6_ADDRSTRLEN];
  294. const char *name;
  295. sin6 = (struct sockaddr_in6 *)addr;
  296. name = inet_ntop(AF_INET6, &sin6->sin6_addr, buf, INET6_ADDRSTRLEN);
  297. debug_printf_clean("%s:%d", name, ntohs(sin6->sin6_port));
  298. #if !defined(HAVE_SA_LEN)
  299. sa_len = (int)sizeof(struct sockaddr_in6);
  300. #endif
  301. break;
  302. }
  303. case AF_CONN:
  304. {
  305. struct sockaddr_conn *sconn;
  306. sconn = (struct sockaddr_conn *)addr;
  307. debug_printf_clean("%p:%d", sconn->sconn_addr, ntohs(sconn->sconn_port));
  308. #if !defined(HAVE_SA_LEN)
  309. sa_len = (int)sizeof(struct sockaddr_conn);
  310. #endif
  311. break;
  312. }
  313. default:
  314. debug_printf_clean("Unknown family: %d", addr->sa_family);
  315. #if !defined(HAVE_SA_LEN)
  316. sa_len = (int)sizeof(struct sockaddr);
  317. #endif
  318. break;
  319. }
  320. #if !defined(HAVE_SA_LEN)
  321. addr = (struct sockaddr *)((char *)addr + sa_len);
  322. #else
  323. addr = (struct sockaddr *)((caddr_t)addr + addr->sa_len);
  324. #endif
  325. if (i != n - 1) {
  326. debug_printf_clean(",");
  327. }
  328. }
  329. if (n > 0) {
  330. usrsctp_freepaddrs(addrs);
  331. }
  332. debug_printf_clean("\n");
  333. }
  334. int
  335. main(int argc, char *argv[])
  336. {
  337. struct sockaddr_in sin_s, sin_c;
  338. struct sockaddr_conn sconn;
  339. struct sctp_paddrparams paddrparams;
  340. #ifdef _WIN32
  341. SOCKET fd_c, fd_s;
  342. #else
  343. int fd_c, fd_s, rc;
  344. #endif
  345. struct socket *s_c, *s_s, *s_l;
  346. #ifdef _WIN32
  347. HANDLE tid_c, tid_s;
  348. #else
  349. pthread_t tid_c, tid_s;
  350. #endif
  351. int i, j, cur_buf_size, snd_buf_size, rcv_buf_size, sendv_retries_left, on;
  352. socklen_t opt_len;
  353. struct sctp_sndinfo sndinfo;
  354. char *line;
  355. #ifdef _WIN32
  356. WSADATA wsaData;
  357. #endif
  358. uint16_t client_port = 9900;
  359. uint16_t server_port = 9901;
  360. struct upcall_meta upcall_meta_client;
  361. struct upcall_meta upcall_meta_server;
  362. #ifdef OUTPUT_TO_LOGFILE
  363. FILE *logfile;
  364. logfile = fopen("ekr_loop_upcall.log", "a+");
  365. if (logfile == NULL) {
  366. debug_printf("Failed creating logfile\n");
  367. exit(EXIT_FAILURE);
  368. }
  369. debug_set_target(logfile);
  370. #endif
  371. if (argc > 1) {
  372. client_port = atoi(argv[1]);
  373. }
  374. if (argc > 2) {
  375. server_port = atoi(argv[2]);
  376. }
  377. if (argc > 3) {
  378. crc32c_offloading = atoi(argv[3]);
  379. }
  380. debug_printf("Starting program\n");
  381. debug_printf("Config:\n\tClient Port:\t%d\n\tServer Port:\t%d\n\tCRC32C Calc:\t%s\n", client_port, server_port, crc32c_offloading ? "offloaded" : "NOT offloaded");
  382. #ifdef _WIN32
  383. if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
  384. debug_printf("WSAStartup failed\n");
  385. exit (EXIT_FAILURE);
  386. }
  387. #endif
  388. usrsctp_init(0, conn_output, debug_printf_stack);
  389. #ifdef SCTP_DEBUG
  390. usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
  391. #endif // SCTP_DEBUG
  392. if (crc32c_offloading) {
  393. usrsctp_enable_crc32c_offload();
  394. }
  395. /* set up a connected UDP socket */
  396. #ifdef _WIN32
  397. if ((fd_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
  398. debug_printf("socket() failed with error: %d\n", WSAGetLastError());
  399. exit(EXIT_FAILURE);
  400. }
  401. if ((fd_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
  402. debug_printf("socket() failed with error: %d\n", WSAGetLastError());
  403. exit(EXIT_FAILURE);
  404. }
  405. #else
  406. if ((fd_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  407. perror("socket");
  408. exit(EXIT_FAILURE);
  409. }
  410. if ((fd_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  411. perror("socket");
  412. exit(EXIT_FAILURE);
  413. }
  414. #endif
  415. memset(&sin_c, 0, sizeof(struct sockaddr_in));
  416. sin_c.sin_family = AF_INET;
  417. #ifdef HAVE_SIN_LEN
  418. sin_c.sin_len = sizeof(struct sockaddr_in);
  419. #endif
  420. sin_c.sin_port = htons(client_port);
  421. sin_c.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  422. memset(&sin_s, 0, sizeof(struct sockaddr_in));
  423. sin_s.sin_family = AF_INET;
  424. #ifdef HAVE_SIN_LEN
  425. sin_s.sin_len = sizeof(struct sockaddr_in);
  426. #endif
  427. sin_s.sin_port = htons(server_port);
  428. sin_s.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  429. #ifdef _WIN32
  430. if (bind(fd_c, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
  431. debug_printf("bind() failed with error: %d\n", WSAGetLastError());
  432. exit(EXIT_FAILURE);
  433. }
  434. if (bind(fd_s, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
  435. debug_printf("bind() failed with error: %d\n", WSAGetLastError());
  436. exit(EXIT_FAILURE);
  437. }
  438. #else
  439. if (bind(fd_c, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) < 0) {
  440. perror("bind");
  441. exit(EXIT_FAILURE);
  442. }
  443. if (bind(fd_s, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) < 0) {
  444. perror("bind");
  445. exit(EXIT_FAILURE);
  446. }
  447. #endif
  448. #ifdef _WIN32
  449. if (connect(fd_c, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
  450. debug_printf("connect() failed with error: %d\n", WSAGetLastError());
  451. exit(EXIT_FAILURE);
  452. }
  453. if (connect(fd_s, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
  454. debug_printf("connect() failed with error: %d\n", WSAGetLastError());
  455. exit(EXIT_FAILURE);
  456. }
  457. #else
  458. if (connect(fd_c, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) < 0) {
  459. perror("connect");
  460. exit(EXIT_FAILURE);
  461. }
  462. if (connect(fd_s, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) < 0) {
  463. perror("connect");
  464. exit(EXIT_FAILURE);
  465. }
  466. #endif
  467. #ifdef _WIN32
  468. if ((tid_c = CreateThread(NULL, 0, &handle_packets, (void *)&fd_c, 0, NULL)) == NULL) {
  469. debug_printf("CreateThread() failed with error: %d\n", GetLastError());
  470. exit(EXIT_FAILURE);
  471. }
  472. if ((tid_s = CreateThread(NULL, 0, &handle_packets, (void *)&fd_s, 0, NULL)) == NULL) {
  473. debug_printf("CreateThread() failed with error: %d\n", GetLastError());
  474. exit(EXIT_FAILURE);
  475. }
  476. #else
  477. if ((rc = pthread_create(&tid_c, NULL, &handle_packets, (void *)&fd_c)) != 0) {
  478. debug_printf("pthread_create tid_c: %s\n", strerror(rc));
  479. exit(EXIT_FAILURE);
  480. }
  481. if ((rc = pthread_create(&tid_s, NULL, &handle_packets, (void *)&fd_s)) != 0) {
  482. debug_printf("pthread_create tid_s: %s\n", strerror(rc));
  483. exit(EXIT_FAILURE);
  484. };
  485. #endif
  486. usrsctp_sysctl_set_sctp_ecn_enable(0);
  487. usrsctp_register_address((void *)&fd_c);
  488. usrsctp_register_address((void *)&fd_s);
  489. if ((s_c = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL)) == NULL) {
  490. perror("usrsctp_socket");
  491. exit(EXIT_FAILURE);
  492. }
  493. upcall_meta_client.addr = &fd_c;
  494. upcall_meta_client.sender = 1;
  495. usrsctp_set_upcall(s_c, handle_upcall, &upcall_meta_client);
  496. opt_len = (socklen_t)sizeof(int);
  497. cur_buf_size = 0;
  498. if (usrsctp_getsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &cur_buf_size, &opt_len) < 0) {
  499. perror("usrsctp_getsockopt");
  500. exit(EXIT_FAILURE);
  501. }
  502. debug_printf("Change send socket buffer size from %d ", cur_buf_size);
  503. snd_buf_size = 1<<22; /* 4 MB */
  504. if (usrsctp_setsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &snd_buf_size, sizeof(int)) < 0) {
  505. perror("usrsctp_setsockopt");
  506. exit(EXIT_FAILURE);
  507. }
  508. opt_len = (socklen_t)sizeof(int);
  509. cur_buf_size = 0;
  510. if (usrsctp_getsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &cur_buf_size, &opt_len) < 0) {
  511. perror("usrsctp_getsockopt");
  512. exit(EXIT_FAILURE);
  513. }
  514. debug_printf_clean("to %d.\n", cur_buf_size);
  515. memset(&paddrparams, 0, sizeof(struct sctp_paddrparams));
  516. paddrparams.spp_address.ss_family = AF_CONN;
  517. #ifdef HAVE_SCONN_LEN
  518. paddrparams.spp_address.ss_len = sizeof(struct sockaddr_conn);
  519. #endif
  520. paddrparams.spp_flags = SPP_PMTUD_DISABLE;
  521. paddrparams.spp_pathmtu = 9000;
  522. if (usrsctp_setsockopt(s_c, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(struct sctp_paddrparams)) < 0) {
  523. perror("usrsctp_setsockopt");
  524. exit(EXIT_FAILURE);
  525. }
  526. if ((s_l = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL)) == NULL) {
  527. perror("usrsctp_socket");
  528. exit(EXIT_FAILURE);
  529. }
  530. opt_len = (socklen_t)sizeof(int);
  531. cur_buf_size = 0;
  532. if (usrsctp_getsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &cur_buf_size, &opt_len) < 0) {
  533. perror("usrsctp_getsockopt");
  534. exit(EXIT_FAILURE);
  535. }
  536. debug_printf("Change receive socket buffer size from %d ", cur_buf_size);
  537. rcv_buf_size = 1<<16; /* 64 KB */
  538. if (usrsctp_setsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(int)) < 0) {
  539. perror("usrsctp_setsockopt");
  540. exit(EXIT_FAILURE);
  541. }
  542. opt_len = (socklen_t)sizeof(int);
  543. cur_buf_size = 0;
  544. if (usrsctp_getsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &cur_buf_size, &opt_len) < 0) {
  545. perror("usrsctp_getsockopt");
  546. exit(EXIT_FAILURE);
  547. }
  548. debug_printf_clean("to %d.\n", cur_buf_size);
  549. on = 1;
  550. if (usrsctp_setsockopt(s_l, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) < 0) {
  551. perror("usrsctp_setsockopt");
  552. exit(EXIT_FAILURE);
  553. }
  554. /* Bind the client side. */
  555. memset(&sconn, 0, sizeof(struct sockaddr_conn));
  556. sconn.sconn_family = AF_CONN;
  557. #ifdef HAVE_SCONN_LEN
  558. sconn.sconn_len = sizeof(struct sockaddr_conn);
  559. #endif
  560. sconn.sconn_port = htons(5001);
  561. sconn.sconn_addr = &fd_c;
  562. if (usrsctp_bind(s_c, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
  563. perror("usrsctp_bind");
  564. exit(EXIT_FAILURE);
  565. }
  566. /* Bind the server side. */
  567. memset(&sconn, 0, sizeof(struct sockaddr_conn));
  568. sconn.sconn_family = AF_CONN;
  569. #ifdef HAVE_SCONN_LEN
  570. sconn.sconn_len = sizeof(struct sockaddr_conn);
  571. #endif
  572. sconn.sconn_port = htons(5001);
  573. sconn.sconn_addr = &fd_s;
  574. if (usrsctp_bind(s_l, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
  575. perror("usrsctp_bind");
  576. exit(EXIT_FAILURE);
  577. }
  578. /* Make server side passive... */
  579. if (usrsctp_listen(s_l, 1) < 0) {
  580. perror("usrsctp_listen");
  581. exit(EXIT_FAILURE);
  582. }
  583. /* Initiate the handshake */
  584. memset(&sconn, 0, sizeof(struct sockaddr_conn));
  585. sconn.sconn_family = AF_CONN;
  586. #ifdef HAVE_SCONN_LEN
  587. sconn.sconn_len = sizeof(struct sockaddr_conn);
  588. #endif
  589. sconn.sconn_port = htons(5001);
  590. sconn.sconn_addr = &fd_c;
  591. if (usrsctp_connect(s_c, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
  592. perror("usrsctp_connect");
  593. exit(EXIT_FAILURE);
  594. }
  595. if ((s_s = usrsctp_accept(s_l, NULL, NULL)) == NULL) {
  596. perror("usrsctp_accept");
  597. exit(EXIT_FAILURE);
  598. }
  599. upcall_meta_server.addr = &fd_s;
  600. upcall_meta_server.sender = 0;
  601. usrsctp_set_upcall(s_s, handle_upcall, &upcall_meta_server);
  602. usrsctp_close(s_l);
  603. print_addresses(s_s);
  604. if ((line = malloc(LINE_LENGTH)) == NULL) {
  605. exit(EXIT_FAILURE);
  606. }
  607. memset(line, 'A', LINE_LENGTH);
  608. sndinfo.snd_sid = 1;
  609. sndinfo.snd_ppid = htonl(DISCARD_PPID);
  610. sndinfo.snd_context = 0;
  611. sndinfo.snd_assoc_id = 0;
  612. for (i = 0; i < NUMBER_OF_STEPS; i++) {
  613. if (i % 2) {
  614. sndinfo.snd_flags = SCTP_UNORDERED;
  615. } else {
  616. sndinfo.snd_flags = 0;
  617. }
  618. for (j = 0; j < 2; j++) {
  619. /* Send a 1 MB message */
  620. sendv_retries_left = 120;
  621. debug_printf("usrscp_sendv - step %d - call %d flags %x\n", i, j + 1, sndinfo.snd_flags);
  622. while (usrsctp_sendv(s_c, line, LINE_LENGTH, NULL, 0, (void *)&sndinfo,
  623. (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
  624. debug_printf("usrsctp_sendv - errno: %d - %s\n", errno, strerror(errno));
  625. if (errno != EWOULDBLOCK || !sendv_retries_left) {
  626. exit(EXIT_FAILURE);
  627. }
  628. sendv_retries_left--;
  629. #ifdef _WIN32
  630. Sleep(1000);
  631. #else
  632. sleep(1);
  633. #endif
  634. }
  635. }
  636. debug_printf("Sending done, sleeping\n");
  637. #ifdef _WIN32
  638. Sleep(1000);
  639. #else
  640. sleep(1);
  641. #endif
  642. }
  643. free(line);
  644. usrsctp_shutdown(s_c, SHUT_WR);
  645. while (usrsctp_finish() != 0) {
  646. debug_printf("Waiting for usrsctp_finish()\n");
  647. #ifdef _WIN32
  648. Sleep(1000);
  649. #else
  650. sleep(1);
  651. #endif
  652. }
  653. #ifdef _WIN32
  654. TerminateThread(tid_c, 0);
  655. WaitForSingleObject(tid_c, INFINITE);
  656. TerminateThread(tid_s, 0);
  657. WaitForSingleObject(tid_s, INFINITE);
  658. if (closesocket(fd_c) == SOCKET_ERROR) {
  659. debug_printf("closesocket() failed with error: %d\n", WSAGetLastError());
  660. exit(EXIT_FAILURE);
  661. }
  662. if (closesocket(fd_s) == SOCKET_ERROR) {
  663. debug_printf("closesocket() failed with error: %d\n", WSAGetLastError());
  664. exit(EXIT_FAILURE);
  665. }
  666. WSACleanup();
  667. #else
  668. pthread_cancel(tid_c);
  669. pthread_join(tid_c, NULL);
  670. pthread_cancel(tid_s);
  671. pthread_join(tid_s, NULL);
  672. if (close(fd_c) < 0) {
  673. perror("close");
  674. exit(EXIT_FAILURE);
  675. }
  676. if (close(fd_s) < 0) {
  677. perror("close");
  678. exit(EXIT_FAILURE);
  679. }
  680. #endif
  681. return (0);
  682. }