mptcp_connect.c 32 KB

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