mptcp_connect.c 34 KB

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