PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/testing/selftests/net/mptcp/mptcp_connect.c

https://github.com/tiwai/sound
C | 1361 lines | 1079 code | 253 blank | 29 comment | 252 complexity | c9dc66260a8b08530f798d99f64c3369 MD5 | raw file
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define _GNU_SOURCE
  3. #include <errno.h>
  4. #include <limits.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7. #include <stdarg.h>
  8. #include <stdbool.h>
  9. #include <stdint.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <strings.h>
  13. #include <signal.h>
  14. #include <unistd.h>
  15. #include <time.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/poll.h>
  18. #include <sys/sendfile.h>
  19. #include <sys/stat.h>
  20. #include <sys/socket.h>
  21. #include <sys/types.h>
  22. #include <sys/mman.h>
  23. #include <netdb.h>
  24. #include <netinet/in.h>
  25. #include <linux/tcp.h>
  26. #include <linux/time_types.h>
  27. #include <linux/sockios.h>
  28. extern int optind;
  29. #ifndef IPPROTO_MPTCP
  30. #define IPPROTO_MPTCP 262
  31. #endif
  32. #ifndef TCP_ULP
  33. #define TCP_ULP 31
  34. #endif
  35. static int poll_timeout = 10 * 1000;
  36. static bool listen_mode;
  37. static bool quit;
  38. enum cfg_mode {
  39. CFG_MODE_POLL,
  40. CFG_MODE_MMAP,
  41. CFG_MODE_SENDFILE,
  42. };
  43. enum cfg_peek {
  44. CFG_NONE_PEEK,
  45. CFG_WITH_PEEK,
  46. CFG_AFTER_PEEK,
  47. };
  48. static enum cfg_mode cfg_mode = CFG_MODE_POLL;
  49. static enum cfg_peek cfg_peek = CFG_NONE_PEEK;
  50. static const char *cfg_host;
  51. static const char *cfg_port = "12000";
  52. static int cfg_sock_proto = IPPROTO_MPTCP;
  53. static int pf = AF_INET;
  54. static int cfg_sndbuf;
  55. static int cfg_rcvbuf;
  56. static bool cfg_join;
  57. static bool cfg_remove;
  58. static unsigned int cfg_time;
  59. static unsigned int cfg_do_w;
  60. static int cfg_wait;
  61. static uint32_t cfg_mark;
  62. static char *cfg_input;
  63. static int cfg_repeat = 1;
  64. struct cfg_cmsg_types {
  65. unsigned int cmsg_enabled:1;
  66. unsigned int timestampns:1;
  67. unsigned int tcp_inq:1;
  68. };
  69. struct cfg_sockopt_types {
  70. unsigned int transparent:1;
  71. };
  72. struct tcp_inq_state {
  73. unsigned int last;
  74. bool expect_eof;
  75. };
  76. static struct tcp_inq_state tcp_inq;
  77. static struct cfg_cmsg_types cfg_cmsg_types;
  78. static struct cfg_sockopt_types cfg_sockopt_types;
  79. static void die_usage(void)
  80. {
  81. fprintf(stderr, "Usage: mptcp_connect [-6] [-c cmsg] [-i file] [-I num] [-j] [-l] "
  82. "[-m mode] [-M mark] [-o option] [-p port] [-P mode] [-j] [-l] [-r num] "
  83. "[-s MPTCP|TCP] [-S num] [-r num] [-t num] [-T num] [-u] [-w sec] connect_address\n");
  84. fprintf(stderr, "\t-6 use ipv6\n");
  85. fprintf(stderr, "\t-c cmsg -- test cmsg type <cmsg>\n");
  86. fprintf(stderr, "\t-i file -- read the data to send from the given file instead of stdin");
  87. fprintf(stderr, "\t-I num -- repeat the transfer 'num' times. In listen mode accepts num "
  88. "incoming connections, in client mode, disconnect and reconnect to the server\n");
  89. fprintf(stderr, "\t-j -- add additional sleep at connection start and tear down "
  90. "-- for MPJ tests\n");
  91. fprintf(stderr, "\t-l -- listens mode, accepts incoming connection\n");
  92. fprintf(stderr, "\t-m [poll|mmap|sendfile] -- use poll(default)/mmap+write/sendfile\n");
  93. fprintf(stderr, "\t-M mark -- set socket packet mark\n");
  94. fprintf(stderr, "\t-o option -- test sockopt <option>\n");
  95. fprintf(stderr, "\t-p num -- use port num\n");
  96. fprintf(stderr,
  97. "\t-P [saveWithPeek|saveAfterPeek] -- save data with/after MSG_PEEK form tcp socket\n");
  98. fprintf(stderr, "\t-t num -- set poll timeout to num\n");
  99. fprintf(stderr, "\t-T num -- set expected runtime to num ms\n");
  100. fprintf(stderr, "\t-r num -- enable slow mode, limiting each write to num bytes "
  101. "-- for remove addr tests\n");
  102. fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n");
  103. fprintf(stderr, "\t-s [MPTCP|TCP] -- use mptcp(default) or tcp sockets\n");
  104. fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
  105. fprintf(stderr, "\t-w num -- wait num sec before closing the socket\n");
  106. exit(1);
  107. }
  108. static void xerror(const char *fmt, ...)
  109. {
  110. va_list ap;
  111. va_start(ap, fmt);
  112. vfprintf(stderr, fmt, ap);
  113. va_end(ap);
  114. exit(1);
  115. }
  116. static void handle_signal(int nr)
  117. {
  118. quit = true;
  119. }
  120. static const char *getxinfo_strerr(int err)
  121. {
  122. if (err == EAI_SYSTEM)
  123. return strerror(errno);
  124. return gai_strerror(err);
  125. }
  126. static void xgetnameinfo(const struct sockaddr *addr, socklen_t addrlen,
  127. char *host, socklen_t hostlen,
  128. char *serv, socklen_t servlen)
  129. {
  130. int flags = NI_NUMERICHOST | NI_NUMERICSERV;
  131. int err = getnameinfo(addr, addrlen, host, hostlen, serv, servlen,
  132. flags);
  133. if (err) {
  134. const char *errstr = getxinfo_strerr(err);
  135. fprintf(stderr, "Fatal: getnameinfo: %s\n", errstr);
  136. exit(1);
  137. }
  138. }
  139. static void xgetaddrinfo(const char *node, const char *service,
  140. const struct addrinfo *hints,
  141. struct addrinfo **res)
  142. {
  143. int err = getaddrinfo(node, service, hints, res);
  144. if (err) {
  145. const char *errstr = getxinfo_strerr(err);
  146. fprintf(stderr, "Fatal: getaddrinfo(%s:%s): %s\n",
  147. node ? node : "", service ? service : "", errstr);
  148. exit(1);
  149. }
  150. }
  151. static void set_rcvbuf(int fd, unsigned int size)
  152. {
  153. int err;
  154. err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
  155. if (err) {
  156. perror("set SO_RCVBUF");
  157. exit(1);
  158. }
  159. }
  160. static void set_sndbuf(int fd, unsigned int size)
  161. {
  162. int err;
  163. err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
  164. if (err) {
  165. perror("set SO_SNDBUF");
  166. exit(1);
  167. }
  168. }
  169. static void set_mark(int fd, uint32_t mark)
  170. {
  171. int err;
  172. err = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
  173. if (err) {
  174. perror("set SO_MARK");
  175. exit(1);
  176. }
  177. }
  178. static void set_transparent(int fd, int pf)
  179. {
  180. int one = 1;
  181. switch (pf) {
  182. case AF_INET:
  183. if (-1 == setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)))
  184. perror("IP_TRANSPARENT");
  185. break;
  186. case AF_INET6:
  187. if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)))
  188. perror("IPV6_TRANSPARENT");
  189. break;
  190. }
  191. }
  192. static int do_ulp_so(int sock, const char *name)
  193. {
  194. return setsockopt(sock, IPPROTO_TCP, TCP_ULP, name, strlen(name));
  195. }
  196. #define X(m) xerror("%s:%u: %s: failed for proto %d at line %u", __FILE__, __LINE__, (m), proto, line)
  197. static void sock_test_tcpulp(int sock, int proto, unsigned int line)
  198. {
  199. socklen_t buflen = 8;
  200. char buf[8] = "";
  201. int ret = getsockopt(sock, IPPROTO_TCP, TCP_ULP, buf, &buflen);
  202. if (ret != 0)
  203. X("getsockopt");
  204. if (buflen > 0) {
  205. if (strcmp(buf, "mptcp") != 0)
  206. xerror("unexpected ULP '%s' for proto %d at line %u", buf, proto, line);
  207. ret = do_ulp_so(sock, "tls");
  208. if (ret == 0)
  209. X("setsockopt");
  210. } else if (proto == IPPROTO_MPTCP) {
  211. ret = do_ulp_so(sock, "tls");
  212. if (ret != -1)
  213. X("setsockopt");
  214. }
  215. ret = do_ulp_so(sock, "mptcp");
  216. if (ret != -1)
  217. X("setsockopt");
  218. #undef X
  219. }
  220. #define SOCK_TEST_TCPULP(s, p) sock_test_tcpulp((s), (p), __LINE__)
  221. static int sock_listen_mptcp(const char * const listenaddr,
  222. const char * const port)
  223. {
  224. int sock;
  225. struct addrinfo hints = {
  226. .ai_protocol = IPPROTO_TCP,
  227. .ai_socktype = SOCK_STREAM,
  228. .ai_flags = AI_PASSIVE | AI_NUMERICHOST
  229. };
  230. hints.ai_family = pf;
  231. struct addrinfo *a, *addr;
  232. int one = 1;
  233. xgetaddrinfo(listenaddr, port, &hints, &addr);
  234. hints.ai_family = pf;
  235. for (a = addr; a; a = a->ai_next) {
  236. sock = socket(a->ai_family, a->ai_socktype, cfg_sock_proto);
  237. if (sock < 0)
  238. continue;
  239. SOCK_TEST_TCPULP(sock, cfg_sock_proto);
  240. if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one,
  241. sizeof(one)))
  242. perror("setsockopt");
  243. if (cfg_sockopt_types.transparent)
  244. set_transparent(sock, pf);
  245. if (bind(sock, a->ai_addr, a->ai_addrlen) == 0)
  246. break; /* success */
  247. perror("bind");
  248. close(sock);
  249. sock = -1;
  250. }
  251. freeaddrinfo(addr);
  252. if (sock < 0) {
  253. fprintf(stderr, "Could not create listen socket\n");
  254. return sock;
  255. }
  256. SOCK_TEST_TCPULP(sock, cfg_sock_proto);
  257. if (listen(sock, 20)) {
  258. perror("listen");
  259. close(sock);
  260. return -1;
  261. }
  262. SOCK_TEST_TCPULP(sock, cfg_sock_proto);
  263. return sock;
  264. }
  265. static int sock_connect_mptcp(const char * const remoteaddr,
  266. const char * const port, int proto,
  267. struct addrinfo **peer)
  268. {
  269. struct addrinfo hints = {
  270. .ai_protocol = IPPROTO_TCP,
  271. .ai_socktype = SOCK_STREAM,
  272. };
  273. struct addrinfo *a, *addr;
  274. int sock = -1;
  275. hints.ai_family = pf;
  276. xgetaddrinfo(remoteaddr, port, &hints, &addr);
  277. for (a = addr; a; a = a->ai_next) {
  278. sock = socket(a->ai_family, a->ai_socktype, proto);
  279. if (sock < 0) {
  280. perror("socket");
  281. continue;
  282. }
  283. SOCK_TEST_TCPULP(sock, proto);
  284. if (cfg_mark)
  285. set_mark(sock, cfg_mark);
  286. if (connect(sock, a->ai_addr, a->ai_addrlen) == 0) {
  287. *peer = a;
  288. break; /* success */
  289. }
  290. perror("connect()");
  291. close(sock);
  292. sock = -1;
  293. }
  294. freeaddrinfo(addr);
  295. if (sock != -1)
  296. SOCK_TEST_TCPULP(sock, proto);
  297. return sock;
  298. }
  299. static size_t do_rnd_write(const int fd, char *buf, const size_t len)
  300. {
  301. static bool first = true;
  302. unsigned int do_w;
  303. ssize_t bw;
  304. do_w = rand() & 0xffff;
  305. if (do_w == 0 || do_w > len)
  306. do_w = len;
  307. if (cfg_join && first && do_w > 100)
  308. do_w = 100;
  309. if (cfg_remove && do_w > cfg_do_w)
  310. do_w = cfg_do_w;
  311. bw = write(fd, buf, do_w);
  312. if (bw < 0)
  313. perror("write");
  314. /* let the join handshake complete, before going on */
  315. if (cfg_join && first) {
  316. usleep(200000);
  317. first = false;
  318. }
  319. if (cfg_remove)
  320. usleep(200000);
  321. return bw;
  322. }
  323. static size_t do_write(const int fd, char *buf, const size_t len)
  324. {
  325. size_t offset = 0;
  326. while (offset < len) {
  327. size_t written;
  328. ssize_t bw;
  329. bw = write(fd, buf + offset, len - offset);
  330. if (bw < 0) {
  331. perror("write");
  332. return 0;
  333. }
  334. written = (size_t)bw;
  335. offset += written;
  336. }
  337. return offset;
  338. }
  339. static void process_cmsg(struct msghdr *msgh)
  340. {
  341. struct __kernel_timespec ts;
  342. bool inq_found = false;
  343. bool ts_found = false;
  344. unsigned int inq = 0;
  345. struct cmsghdr *cmsg;
  346. for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) {
  347. if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW) {
  348. memcpy(&ts, CMSG_DATA(cmsg), sizeof(ts));
  349. ts_found = true;
  350. continue;
  351. }
  352. if (cmsg->cmsg_level == IPPROTO_TCP && cmsg->cmsg_type == TCP_CM_INQ) {
  353. memcpy(&inq, CMSG_DATA(cmsg), sizeof(inq));
  354. inq_found = true;
  355. continue;
  356. }
  357. }
  358. if (cfg_cmsg_types.timestampns) {
  359. if (!ts_found)
  360. xerror("TIMESTAMPNS not present\n");
  361. }
  362. if (cfg_cmsg_types.tcp_inq) {
  363. if (!inq_found)
  364. xerror("TCP_INQ not present\n");
  365. if (inq > 1024)
  366. xerror("tcp_inq %u is larger than one kbyte\n", inq);
  367. tcp_inq.last = inq;
  368. }
  369. }
  370. static ssize_t do_recvmsg_cmsg(const int fd, char *buf, const size_t len)
  371. {
  372. char msg_buf[8192];
  373. struct iovec iov = {
  374. .iov_base = buf,
  375. .iov_len = len,
  376. };
  377. struct msghdr msg = {
  378. .msg_iov = &iov,
  379. .msg_iovlen = 1,
  380. .msg_control = msg_buf,
  381. .msg_controllen = sizeof(msg_buf),
  382. };
  383. int flags = 0;
  384. unsigned int last_hint = tcp_inq.last;
  385. int ret = recvmsg(fd, &msg, flags);
  386. if (ret <= 0) {
  387. if (ret == 0 && tcp_inq.expect_eof)
  388. return ret;
  389. if (ret == 0 && cfg_cmsg_types.tcp_inq)
  390. if (last_hint != 1 && last_hint != 0)
  391. xerror("EOF but last tcp_inq hint was %u\n", last_hint);
  392. return ret;
  393. }
  394. if (tcp_inq.expect_eof)
  395. xerror("expected EOF, last_hint %u, now %u\n",
  396. last_hint, tcp_inq.last);
  397. if (msg.msg_controllen && !cfg_cmsg_types.cmsg_enabled)
  398. xerror("got %lu bytes of cmsg data, expected 0\n",
  399. (unsigned long)msg.msg_controllen);
  400. if (msg.msg_controllen == 0 && cfg_cmsg_types.cmsg_enabled)
  401. xerror("%s\n", "got no cmsg data");
  402. if (msg.msg_controllen)
  403. process_cmsg(&msg);
  404. if (cfg_cmsg_types.tcp_inq) {
  405. if ((size_t)ret < len && last_hint > (unsigned int)ret) {
  406. if (ret + 1 != (int)last_hint) {
  407. int next = read(fd, msg_buf, sizeof(msg_buf));
  408. xerror("read %u of %u, last_hint was %u tcp_inq hint now %u next_read returned %d/%m\n",
  409. ret, (unsigned int)len, last_hint, tcp_inq.last, next);
  410. } else {
  411. tcp_inq.expect_eof = true;
  412. }
  413. }
  414. }
  415. return ret;
  416. }
  417. static ssize_t do_rnd_read(const int fd, char *buf, const size_t len)
  418. {
  419. int ret = 0;
  420. char tmp[16384];
  421. size_t cap = rand();
  422. cap &= 0xffff;
  423. if (cap == 0)
  424. cap = 1;
  425. else if (cap > len)
  426. cap = len;
  427. if (cfg_peek == CFG_WITH_PEEK) {
  428. ret = recv(fd, buf, cap, MSG_PEEK);
  429. ret = (ret < 0) ? ret : read(fd, tmp, ret);
  430. } else if (cfg_peek == CFG_AFTER_PEEK) {
  431. ret = recv(fd, buf, cap, MSG_PEEK);
  432. ret = (ret < 0) ? ret : read(fd, buf, cap);
  433. } else if (cfg_cmsg_types.cmsg_enabled) {
  434. ret = do_recvmsg_cmsg(fd, buf, cap);
  435. } else {
  436. ret = read(fd, buf, cap);
  437. }
  438. return ret;
  439. }
  440. static void set_nonblock(int fd, bool nonblock)
  441. {
  442. int flags = fcntl(fd, F_GETFL);
  443. if (flags == -1)
  444. return;
  445. if (nonblock)
  446. fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  447. else
  448. fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
  449. }
  450. static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out)
  451. {
  452. struct pollfd fds = {
  453. .fd = peerfd,
  454. .events = POLLIN | POLLOUT,
  455. };
  456. unsigned int woff = 0, wlen = 0;
  457. char wbuf[8192];
  458. set_nonblock(peerfd, true);
  459. for (;;) {
  460. char rbuf[8192];
  461. ssize_t len;
  462. if (fds.events == 0)
  463. break;
  464. switch (poll(&fds, 1, poll_timeout)) {
  465. case -1:
  466. if (errno == EINTR)
  467. continue;
  468. perror("poll");
  469. return 1;
  470. case 0:
  471. fprintf(stderr, "%s: poll timed out (events: "
  472. "POLLIN %u, POLLOUT %u)\n", __func__,
  473. fds.events & POLLIN, fds.events & POLLOUT);
  474. return 2;
  475. }
  476. if (fds.revents & POLLIN) {
  477. len = do_rnd_read(peerfd, rbuf, sizeof(rbuf));
  478. if (len == 0) {
  479. /* no more data to receive:
  480. * peer has closed its write side
  481. */
  482. fds.events &= ~POLLIN;
  483. if ((fds.events & POLLOUT) == 0) {
  484. *in_closed_after_out = true;
  485. /* and nothing more to send */
  486. break;
  487. }
  488. /* Else, still have data to transmit */
  489. } else if (len < 0) {
  490. perror("read");
  491. return 3;
  492. }
  493. do_write(outfd, rbuf, len);
  494. }
  495. if (fds.revents & POLLOUT) {
  496. if (wlen == 0) {
  497. woff = 0;
  498. wlen = read(infd, wbuf, sizeof(wbuf));
  499. }
  500. if (wlen > 0) {
  501. ssize_t bw;
  502. bw = do_rnd_write(peerfd, wbuf + woff, wlen);
  503. if (bw < 0)
  504. return 111;
  505. woff += bw;
  506. wlen -= bw;
  507. } else if (wlen == 0) {
  508. /* We have no more data to send. */
  509. fds.events &= ~POLLOUT;
  510. if ((fds.events & POLLIN) == 0)
  511. /* ... and peer also closed already */
  512. break;
  513. /* ... but we still receive.
  514. * Close our write side, ev. give some time
  515. * for address notification and/or checking
  516. * the current status
  517. */
  518. if (cfg_wait)
  519. usleep(cfg_wait);
  520. shutdown(peerfd, SHUT_WR);
  521. } else {
  522. if (errno == EINTR)
  523. continue;
  524. perror("read");
  525. return 4;
  526. }
  527. }
  528. if (fds.revents & (POLLERR | POLLNVAL)) {
  529. fprintf(stderr, "Unexpected revents: "
  530. "POLLERR/POLLNVAL(%x)\n", fds.revents);
  531. return 5;
  532. }
  533. }
  534. /* leave some time for late join/announce */
  535. if (cfg_remove)
  536. usleep(cfg_wait);
  537. return 0;
  538. }
  539. static int do_recvfile(int infd, int outfd)
  540. {
  541. ssize_t r;
  542. do {
  543. char buf[16384];
  544. r = do_rnd_read(infd, buf, sizeof(buf));
  545. if (r > 0) {
  546. if (write(outfd, buf, r) != r)
  547. break;
  548. } else if (r < 0) {
  549. perror("read");
  550. }
  551. } while (r > 0);
  552. return (int)r;
  553. }
  554. static int do_mmap(int infd, int outfd, unsigned int size)
  555. {
  556. char *inbuf = mmap(NULL, size, PROT_READ, MAP_SHARED, infd, 0);
  557. ssize_t ret = 0, off = 0;
  558. size_t rem;
  559. if (inbuf == MAP_FAILED) {
  560. perror("mmap");
  561. return 1;
  562. }
  563. rem = size;
  564. while (rem > 0) {
  565. ret = write(outfd, inbuf + off, rem);
  566. if (ret < 0) {
  567. perror("write");
  568. break;
  569. }
  570. off += ret;
  571. rem -= ret;
  572. }
  573. munmap(inbuf, size);
  574. return rem;
  575. }
  576. static int get_infd_size(int fd)
  577. {
  578. struct stat sb;
  579. ssize_t count;
  580. int err;
  581. err = fstat(fd, &sb);
  582. if (err < 0) {
  583. perror("fstat");
  584. return -1;
  585. }
  586. if ((sb.st_mode & S_IFMT) != S_IFREG) {
  587. fprintf(stderr, "%s: stdin is not a regular file\n", __func__);
  588. return -2;
  589. }
  590. count = sb.st_size;
  591. if (count > INT_MAX) {
  592. fprintf(stderr, "File too large: %zu\n", count);
  593. return -3;
  594. }
  595. return (int)count;
  596. }
  597. static int do_sendfile(int infd, int outfd, unsigned int count)
  598. {
  599. while (count > 0) {
  600. ssize_t r;
  601. r = sendfile(outfd, infd, NULL, count);
  602. if (r < 0) {
  603. perror("sendfile");
  604. return 3;
  605. }
  606. count -= r;
  607. }
  608. return 0;
  609. }
  610. static int copyfd_io_mmap(int infd, int peerfd, int outfd,
  611. unsigned int size, bool *in_closed_after_out)
  612. {
  613. int err;
  614. if (listen_mode) {
  615. err = do_recvfile(peerfd, outfd);
  616. if (err)
  617. return err;
  618. err = do_mmap(infd, peerfd, size);
  619. } else {
  620. err = do_mmap(infd, peerfd, size);
  621. if (err)
  622. return err;
  623. shutdown(peerfd, SHUT_WR);
  624. err = do_recvfile(peerfd, outfd);
  625. *in_closed_after_out = true;
  626. }
  627. return err;
  628. }
  629. static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
  630. unsigned int size, bool *in_closed_after_out)
  631. {
  632. int err;
  633. if (listen_mode) {
  634. err = do_recvfile(peerfd, outfd);
  635. if (err)
  636. return err;
  637. err = do_sendfile(infd, peerfd, size);
  638. } else {
  639. err = do_sendfile(infd, peerfd, size);
  640. if (err)
  641. return err;
  642. err = do_recvfile(peerfd, outfd);
  643. *in_closed_after_out = true;
  644. }
  645. return err;
  646. }
  647. static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd)
  648. {
  649. bool in_closed_after_out = false;
  650. struct timespec start, end;
  651. int file_size;
  652. int ret;
  653. if (cfg_time && (clock_gettime(CLOCK_MONOTONIC, &start) < 0))
  654. xerror("can not fetch start time %d", errno);
  655. switch (cfg_mode) {
  656. case CFG_MODE_POLL:
  657. ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out);
  658. break;
  659. case CFG_MODE_MMAP:
  660. file_size = get_infd_size(infd);
  661. if (file_size < 0)
  662. return file_size;
  663. ret = copyfd_io_mmap(infd, peerfd, outfd, file_size, &in_closed_after_out);
  664. break;
  665. case CFG_MODE_SENDFILE:
  666. file_size = get_infd_size(infd);
  667. if (file_size < 0)
  668. return file_size;
  669. ret = copyfd_io_sendfile(infd, peerfd, outfd, file_size, &in_closed_after_out);
  670. break;
  671. default:
  672. fprintf(stderr, "Invalid mode %d\n", cfg_mode);
  673. die_usage();
  674. return 1;
  675. }
  676. if (ret)
  677. return ret;
  678. if (close_peerfd)
  679. close(peerfd);
  680. if (cfg_time) {
  681. unsigned int delta_ms;
  682. if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
  683. xerror("can not fetch end time %d", errno);
  684. delta_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
  685. if (delta_ms > cfg_time) {
  686. xerror("transfer slower than expected! runtime %d ms, expected %d ms",
  687. delta_ms, cfg_time);
  688. }
  689. /* show the runtime only if this end shutdown(wr) before receiving the EOF,
  690. * (that is, if this end got the longer runtime)
  691. */
  692. if (in_closed_after_out)
  693. fprintf(stderr, "%d", delta_ms);
  694. }
  695. return 0;
  696. }
  697. static void check_sockaddr(int pf, struct sockaddr_storage *ss,
  698. socklen_t salen)
  699. {
  700. struct sockaddr_in6 *sin6;
  701. struct sockaddr_in *sin;
  702. socklen_t wanted_size = 0;
  703. switch (pf) {
  704. case AF_INET:
  705. wanted_size = sizeof(*sin);
  706. sin = (void *)ss;
  707. if (!sin->sin_port)
  708. fprintf(stderr, "accept: something wrong: ip connection from port 0");
  709. break;
  710. case AF_INET6:
  711. wanted_size = sizeof(*sin6);
  712. sin6 = (void *)ss;
  713. if (!sin6->sin6_port)
  714. fprintf(stderr, "accept: something wrong: ipv6 connection from port 0");
  715. break;
  716. default:
  717. fprintf(stderr, "accept: Unknown pf %d, salen %u\n", pf, salen);
  718. return;
  719. }
  720. if (salen != wanted_size)
  721. fprintf(stderr, "accept: size mismatch, got %d expected %d\n",
  722. (int)salen, wanted_size);
  723. if (ss->ss_family != pf)
  724. fprintf(stderr, "accept: pf mismatch, expect %d, ss_family is %d\n",
  725. (int)ss->ss_family, pf);
  726. }
  727. static void check_getpeername(int fd, struct sockaddr_storage *ss, socklen_t salen)
  728. {
  729. struct sockaddr_storage peerss;
  730. socklen_t peersalen = sizeof(peerss);
  731. if (getpeername(fd, (struct sockaddr *)&peerss, &peersalen) < 0) {
  732. perror("getpeername");
  733. return;
  734. }
  735. if (peersalen != salen) {
  736. fprintf(stderr, "%s: %d vs %d\n", __func__, peersalen, salen);
  737. return;
  738. }
  739. if (memcmp(ss, &peerss, peersalen)) {
  740. char a[INET6_ADDRSTRLEN];
  741. char b[INET6_ADDRSTRLEN];
  742. char c[INET6_ADDRSTRLEN];
  743. char d[INET6_ADDRSTRLEN];
  744. xgetnameinfo((struct sockaddr *)ss, salen,
  745. a, sizeof(a), b, sizeof(b));
  746. xgetnameinfo((struct sockaddr *)&peerss, peersalen,
  747. c, sizeof(c), d, sizeof(d));
  748. fprintf(stderr, "%s: memcmp failure: accept %s vs peername %s, %s vs %s salen %d vs %d\n",
  749. __func__, a, c, b, d, peersalen, salen);
  750. }
  751. }
  752. static void check_getpeername_connect(int fd)
  753. {
  754. struct sockaddr_storage ss;
  755. socklen_t salen = sizeof(ss);
  756. char a[INET6_ADDRSTRLEN];
  757. char b[INET6_ADDRSTRLEN];
  758. if (getpeername(fd, (struct sockaddr *)&ss, &salen) < 0) {
  759. perror("getpeername");
  760. return;
  761. }
  762. xgetnameinfo((struct sockaddr *)&ss, salen,
  763. a, sizeof(a), b, sizeof(b));
  764. if (strcmp(cfg_host, a) || strcmp(cfg_port, b))
  765. fprintf(stderr, "%s: %s vs %s, %s vs %s\n", __func__,
  766. cfg_host, a, cfg_port, b);
  767. }
  768. static void maybe_close(int fd)
  769. {
  770. unsigned int r = rand();
  771. if (!(cfg_join || cfg_remove || cfg_repeat > 1) && (r & 1))
  772. close(fd);
  773. }
  774. int main_loop_s(int listensock)
  775. {
  776. struct sockaddr_storage ss;
  777. struct pollfd polls;
  778. socklen_t salen;
  779. int remotesock;
  780. int fd = 0;
  781. again:
  782. polls.fd = listensock;
  783. polls.events = POLLIN;
  784. switch (poll(&polls, 1, poll_timeout)) {
  785. case -1:
  786. perror("poll");
  787. return 1;
  788. case 0:
  789. fprintf(stderr, "%s: timed out\n", __func__);
  790. close(listensock);
  791. return 2;
  792. }
  793. salen = sizeof(ss);
  794. remotesock = accept(listensock, (struct sockaddr *)&ss, &salen);
  795. if (remotesock >= 0) {
  796. maybe_close(listensock);
  797. check_sockaddr(pf, &ss, salen);
  798. check_getpeername(remotesock, &ss, salen);
  799. if (cfg_input) {
  800. fd = open(cfg_input, O_RDONLY);
  801. if (fd < 0)
  802. xerror("can't open %s: %d", cfg_input, errno);
  803. }
  804. SOCK_TEST_TCPULP(remotesock, 0);
  805. copyfd_io(fd, remotesock, 1, true);
  806. } else {
  807. perror("accept");
  808. return 1;
  809. }
  810. if (--cfg_repeat > 0) {
  811. if (cfg_input)
  812. close(fd);
  813. goto again;
  814. }
  815. return 0;
  816. }
  817. static void init_rng(void)
  818. {
  819. int fd = open("/dev/urandom", O_RDONLY);
  820. unsigned int foo;
  821. if (fd > 0) {
  822. int ret = read(fd, &foo, sizeof(foo));
  823. if (ret < 0)
  824. srand(fd + foo);
  825. close(fd);
  826. }
  827. srand(foo);
  828. }
  829. static void xsetsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
  830. {
  831. int err;
  832. err = setsockopt(fd, level, optname, optval, optlen);
  833. if (err) {
  834. perror("setsockopt");
  835. exit(1);
  836. }
  837. }
  838. static void apply_cmsg_types(int fd, const struct cfg_cmsg_types *cmsg)
  839. {
  840. static const unsigned int on = 1;
  841. if (cmsg->timestampns)
  842. xsetsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS_NEW, &on, sizeof(on));
  843. if (cmsg->tcp_inq)
  844. xsetsockopt(fd, IPPROTO_TCP, TCP_INQ, &on, sizeof(on));
  845. }
  846. static void parse_cmsg_types(const char *type)
  847. {
  848. char *next = strchr(type, ',');
  849. unsigned int len = 0;
  850. cfg_cmsg_types.cmsg_enabled = 1;
  851. if (next) {
  852. parse_cmsg_types(next + 1);
  853. len = next - type;
  854. } else {
  855. len = strlen(type);
  856. }
  857. if (strncmp(type, "TIMESTAMPNS", len) == 0) {
  858. cfg_cmsg_types.timestampns = 1;
  859. return;
  860. }
  861. if (strncmp(type, "TCPINQ", len) == 0) {
  862. cfg_cmsg_types.tcp_inq = 1;
  863. return;
  864. }
  865. fprintf(stderr, "Unrecognized cmsg option %s\n", type);
  866. exit(1);
  867. }
  868. static void parse_setsock_options(const char *name)
  869. {
  870. char *next = strchr(name, ',');
  871. unsigned int len = 0;
  872. if (next) {
  873. parse_setsock_options(next + 1);
  874. len = next - name;
  875. } else {
  876. len = strlen(name);
  877. }
  878. if (strncmp(name, "TRANSPARENT", len) == 0) {
  879. cfg_sockopt_types.transparent = 1;
  880. return;
  881. }
  882. fprintf(stderr, "Unrecognized setsockopt option %s\n", name);
  883. exit(1);
  884. }
  885. void xdisconnect(int fd, int addrlen)
  886. {
  887. struct sockaddr_storage empty;
  888. int msec_sleep = 10;
  889. int queued = 1;
  890. int i;
  891. shutdown(fd, SHUT_WR);
  892. /* while until the pending data is completely flushed, the later
  893. * disconnect will bypass/ignore/drop any pending data.
  894. */
  895. for (i = 0; ; i += msec_sleep) {
  896. if (ioctl(fd, SIOCOUTQ, &queued) < 0)
  897. xerror("can't query out socket queue: %d", errno);
  898. if (!queued)
  899. break;
  900. if (i > poll_timeout)
  901. xerror("timeout while waiting for spool to complete");
  902. usleep(msec_sleep * 1000);
  903. }
  904. memset(&empty, 0, sizeof(empty));
  905. empty.ss_family = AF_UNSPEC;
  906. if (connect(fd, (struct sockaddr *)&empty, addrlen) < 0)
  907. xerror("can't disconnect: %d", errno);
  908. }
  909. int main_loop(void)
  910. {
  911. int fd, ret, fd_in = 0;
  912. struct addrinfo *peer;
  913. /* listener is ready. */
  914. fd = sock_connect_mptcp(cfg_host, cfg_port, cfg_sock_proto, &peer);
  915. if (fd < 0)
  916. return 2;
  917. again:
  918. check_getpeername_connect(fd);
  919. SOCK_TEST_TCPULP(fd, cfg_sock_proto);
  920. if (cfg_rcvbuf)
  921. set_rcvbuf(fd, cfg_rcvbuf);
  922. if (cfg_sndbuf)
  923. set_sndbuf(fd, cfg_sndbuf);
  924. if (cfg_cmsg_types.cmsg_enabled)
  925. apply_cmsg_types(fd, &cfg_cmsg_types);
  926. if (cfg_input) {
  927. fd_in = open(cfg_input, O_RDONLY);
  928. if (fd < 0)
  929. xerror("can't open %s:%d", cfg_input, errno);
  930. }
  931. /* close the client socket open only if we are not going to reconnect */
  932. ret = copyfd_io(fd_in, fd, 1, cfg_repeat == 1);
  933. if (ret)
  934. return ret;
  935. if (--cfg_repeat > 0) {
  936. xdisconnect(fd, peer->ai_addrlen);
  937. /* the socket could be unblocking at this point, we need the
  938. * connect to be blocking
  939. */
  940. set_nonblock(fd, false);
  941. if (connect(fd, peer->ai_addr, peer->ai_addrlen))
  942. xerror("can't reconnect: %d", errno);
  943. if (cfg_input)
  944. close(fd_in);
  945. goto again;
  946. }
  947. return 0;
  948. }
  949. int parse_proto(const char *proto)
  950. {
  951. if (!strcasecmp(proto, "MPTCP"))
  952. return IPPROTO_MPTCP;
  953. if (!strcasecmp(proto, "TCP"))
  954. return IPPROTO_TCP;
  955. fprintf(stderr, "Unknown protocol: %s\n.", proto);
  956. die_usage();
  957. /* silence compiler warning */
  958. return 0;
  959. }
  960. int parse_mode(const char *mode)
  961. {
  962. if (!strcasecmp(mode, "poll"))
  963. return CFG_MODE_POLL;
  964. if (!strcasecmp(mode, "mmap"))
  965. return CFG_MODE_MMAP;
  966. if (!strcasecmp(mode, "sendfile"))
  967. return CFG_MODE_SENDFILE;
  968. fprintf(stderr, "Unknown test mode: %s\n", mode);
  969. fprintf(stderr, "Supported modes are:\n");
  970. fprintf(stderr, "\t\t\"poll\" - interleaved read/write using poll()\n");
  971. fprintf(stderr, "\t\t\"mmap\" - send entire input file (mmap+write), then read response (-l will read input first)\n");
  972. fprintf(stderr, "\t\t\"sendfile\" - send entire input file (sendfile), then read response (-l will read input first)\n");
  973. die_usage();
  974. /* silence compiler warning */
  975. return 0;
  976. }
  977. int parse_peek(const char *mode)
  978. {
  979. if (!strcasecmp(mode, "saveWithPeek"))
  980. return CFG_WITH_PEEK;
  981. if (!strcasecmp(mode, "saveAfterPeek"))
  982. return CFG_AFTER_PEEK;
  983. fprintf(stderr, "Unknown: %s\n", mode);
  984. fprintf(stderr, "Supported MSG_PEEK mode are:\n");
  985. fprintf(stderr,
  986. "\t\t\"saveWithPeek\" - recv data with flags 'MSG_PEEK' and save the peek data into file\n");
  987. fprintf(stderr,
  988. "\t\t\"saveAfterPeek\" - read and save data into file after recv with flags 'MSG_PEEK'\n");
  989. die_usage();
  990. /* silence compiler warning */
  991. return 0;
  992. }
  993. static int parse_int(const char *size)
  994. {
  995. unsigned long s;
  996. errno = 0;
  997. s = strtoul(size, NULL, 0);
  998. if (errno) {
  999. fprintf(stderr, "Invalid sndbuf size %s (%s)\n",
  1000. size, strerror(errno));
  1001. die_usage();
  1002. }
  1003. if (s > INT_MAX) {
  1004. fprintf(stderr, "Invalid sndbuf size %s (%s)\n",
  1005. size, strerror(ERANGE));
  1006. die_usage();
  1007. }
  1008. return (int)s;
  1009. }
  1010. static void parse_opts(int argc, char **argv)
  1011. {
  1012. int c;
  1013. while ((c = getopt(argc, argv, "6c:hi:I:jlm:M:o:p:P:r:R:s:S:t:T:w:")) != -1) {
  1014. switch (c) {
  1015. case 'j':
  1016. cfg_join = true;
  1017. cfg_mode = CFG_MODE_POLL;
  1018. break;
  1019. case 'r':
  1020. cfg_remove = true;
  1021. cfg_mode = CFG_MODE_POLL;
  1022. cfg_wait = 400000;
  1023. cfg_do_w = atoi(optarg);
  1024. if (cfg_do_w <= 0)
  1025. cfg_do_w = 50;
  1026. break;
  1027. case 'i':
  1028. cfg_input = optarg;
  1029. break;
  1030. case 'I':
  1031. cfg_repeat = atoi(optarg);
  1032. break;
  1033. case 'l':
  1034. listen_mode = true;
  1035. break;
  1036. case 'p':
  1037. cfg_port = optarg;
  1038. break;
  1039. case 's':
  1040. cfg_sock_proto = parse_proto(optarg);
  1041. break;
  1042. case 'h':
  1043. die_usage();
  1044. break;
  1045. case '6':
  1046. pf = AF_INET6;
  1047. break;
  1048. case 't':
  1049. poll_timeout = atoi(optarg) * 1000;
  1050. if (poll_timeout <= 0)
  1051. poll_timeout = -1;
  1052. break;
  1053. case 'T':
  1054. cfg_time = atoi(optarg);
  1055. break;
  1056. case 'm':
  1057. cfg_mode = parse_mode(optarg);
  1058. break;
  1059. case 'S':
  1060. cfg_sndbuf = parse_int(optarg);
  1061. break;
  1062. case 'R':
  1063. cfg_rcvbuf = parse_int(optarg);
  1064. break;
  1065. case 'w':
  1066. cfg_wait = atoi(optarg)*1000000;
  1067. break;
  1068. case 'M':
  1069. cfg_mark = strtol(optarg, NULL, 0);
  1070. break;
  1071. case 'P':
  1072. cfg_peek = parse_peek(optarg);
  1073. break;
  1074. case 'c':
  1075. parse_cmsg_types(optarg);
  1076. break;
  1077. case 'o':
  1078. parse_setsock_options(optarg);
  1079. break;
  1080. }
  1081. }
  1082. if (optind + 1 != argc)
  1083. die_usage();
  1084. cfg_host = argv[optind];
  1085. if (strchr(cfg_host, ':'))
  1086. pf = AF_INET6;
  1087. }
  1088. int main(int argc, char *argv[])
  1089. {
  1090. init_rng();
  1091. signal(SIGUSR1, handle_signal);
  1092. parse_opts(argc, argv);
  1093. if (listen_mode) {
  1094. int fd = sock_listen_mptcp(cfg_host, cfg_port);
  1095. if (fd < 0)
  1096. return 1;
  1097. if (cfg_rcvbuf)
  1098. set_rcvbuf(fd, cfg_rcvbuf);
  1099. if (cfg_sndbuf)
  1100. set_sndbuf(fd, cfg_sndbuf);
  1101. if (cfg_mark)
  1102. set_mark(fd, cfg_mark);
  1103. if (cfg_cmsg_types.cmsg_enabled)
  1104. apply_cmsg_types(fd, &cfg_cmsg_types);
  1105. return main_loop_s(fd);
  1106. }
  1107. return main_loop();
  1108. }