client.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. #include <time.h>
  2. /* MacOS related */
  3. #ifdef __MACH__
  4. #include "mach.h"
  5. #endif
  6. #include "log.h"
  7. #include "main.h"
  8. #include "client.h"
  9. /* The state machine */
  10. int state = CLIENT_STATE_INITIAL;
  11. /* Used in ping mode */
  12. struct timespec ping_sent_time;
  13. /* Client mode tunnel */
  14. tunnel client_tunnel;
  15. /* Sock representing the local port - call accept() on it */
  16. int bind_sockfd;
  17. fd_set client_master_fdset;
  18. int handle_pong_frame()
  19. {
  20. struct timespec pong_rcvd_time;
  21. double secs1, secs2;
  22. clock_gettime(CLOCK_MONOTONIC, &pong_rcvd_time);
  23. secs1 = (1.0 * ping_sent_time.tv_sec) + (1e-9 * ping_sent_time.tv_nsec);
  24. secs2 = (1.0 * pong_rcvd_time.tv_sec) + (1e-9 * pong_rcvd_time.tv_nsec);
  25. printf("GOT PONG! Time = %.3fs\n", secs2-secs1);
  26. if(ping_mode)
  27. {
  28. state = CLIENT_STATE_SEND_PING;
  29. }
  30. return 0;
  31. }
  32. int local_bind()
  33. {
  34. struct addrinfo hints, *res;
  35. char port[6];
  36. int yes = 1;
  37. int flags;
  38. int gai_status;
  39. int setsockopt_status;
  40. snprintf(port, 6, "%d", local_port);
  41. memset(&hints, 0, sizeof hints);
  42. hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
  43. hints.ai_socktype = SOCK_STREAM;
  44. hints.ai_flags = AI_PASSIVE; // fill in my IP for me
  45. gai_status = getaddrinfo(NULL, port, &hints, &res);
  46. if(gai_status != 0)
  47. {
  48. log_printf(L_ERROR, "getaddrinfo: %s\n", gai_strerror(gai_status));
  49. exit(1);
  50. }
  51. bind_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  52. if(bind_sockfd < 0)
  53. {
  54. log_printf(L_ERROR, "Could not create a socket for local listening: %s\n", strerror(errno));
  55. freeaddrinfo(res);
  56. exit(1);
  57. }
  58. setsockopt_status = setsockopt(bind_sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  59. if(setsockopt_status < 0)
  60. {
  61. log_printf(L_ERROR, "Could not set socket options: %s\n",
  62. strerror(errno));
  63. freeaddrinfo(res);
  64. exit(1);
  65. }
  66. /* Set O_NONBLOCK to make accept() non-blocking */
  67. if (-1 == (flags = fcntl(bind_sockfd, F_GETFL, 0)))
  68. {
  69. flags = 0;
  70. }
  71. if(fcntl(bind_sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
  72. {
  73. log_printf(L_ERROR, "Could not make the socket non-blocking: %s\n", strerror(errno));
  74. freeaddrinfo(res);
  75. exit(1);
  76. }
  77. if(bind(bind_sockfd, res->ai_addr, res->ai_addrlen) < 0)
  78. {
  79. log_printf(L_ERROR, "Bind to port %d failed: %s\n", local_port, strerror(errno));
  80. freeaddrinfo(res);
  81. close(bind_sockfd);
  82. exit(1);
  83. }
  84. freeaddrinfo(res);
  85. if(listen(bind_sockfd, 1) < 0)
  86. {
  87. log_printf(L_ERROR, "Listening on port %d failed: %s\n", local_port, strerror(errno));
  88. close(bind_sockfd);
  89. exit(1);
  90. }
  91. log_printf(L_DEBUG, "Bound to local port %d\n", local_port);
  92. return 0;
  93. }
  94. /* Bind the client.sockfd to a tunnel */
  95. int handle_acktunnel_frame(protocol_frame *rcvd_frame)
  96. {
  97. tunnel *tun;
  98. if(!client_mode)
  99. {
  100. log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n");
  101. return -1;
  102. }
  103. tun = tunnel_create(
  104. client_tunnel.sockfd,
  105. rcvd_frame->connid,
  106. rcvd_frame->friendnumber
  107. );
  108. /* Mark that we can accept() another connection */
  109. client_tunnel.sockfd = -1;
  110. // printf("New tunnel ID: %d\n", tun->connid);
  111. if(client_local_port_mode || client_pipe_mode)
  112. {
  113. update_select_nfds(tun->sockfd);
  114. FD_SET(tun->sockfd, &client_master_fdset);
  115. if(client_local_port_mode)
  116. {
  117. log_printf(L_INFO, "Accepted a new connection on port %d\n", local_port);
  118. }
  119. }
  120. else
  121. {
  122. log_printf(L_ERROR, "This tunnel mode is not supported yet\n");
  123. exit(1);
  124. }
  125. return 0;
  126. }
  127. /* Handle a TCP frame received from server */
  128. int handle_server_tcp_frame(protocol_frame *rcvd_frame)
  129. {
  130. int offset = 0;
  131. tunnel *tun = NULL;
  132. int tun_id = rcvd_frame->connid;
  133. HASH_FIND_INT(by_id, &tun_id, tun);
  134. if(!tun)
  135. {
  136. log_printf(L_WARNING, "Got TCP frame with unknown tunnel ID %d\n", rcvd_frame->connid);
  137. return -1;
  138. }
  139. while(offset < rcvd_frame->data_length)
  140. {
  141. int sent_bytes;
  142. if(client_pipe_mode)
  143. {
  144. sent_bytes = write(
  145. 1, /* STDOUT */
  146. rcvd_frame->data + offset,
  147. rcvd_frame->data_length - offset
  148. );
  149. }
  150. else
  151. {
  152. sent_bytes = send(
  153. tun->sockfd,
  154. rcvd_frame->data + offset,
  155. rcvd_frame->data_length - offset,
  156. MSG_NOSIGNAL
  157. );
  158. }
  159. if(sent_bytes < 0)
  160. {
  161. uint8_t data[PROTOCOL_BUFFER_OFFSET];
  162. protocol_frame frame_st, *frame;
  163. log_printf(L_INFO, "Could not write to socket: %s\n", strerror(errno));
  164. frame = &frame_st;
  165. memset(frame, 0, sizeof(protocol_frame));
  166. frame->friendnumber = tun->friendnumber;
  167. frame->packet_type = PACKET_TYPE_TCP_FIN;
  168. frame->connid = tun->connid;
  169. frame->data_length = 0;
  170. send_frame(frame, data);
  171. if(tun->sockfd)
  172. {
  173. FD_CLR(tun->sockfd, &client_master_fdset);
  174. }
  175. tunnel_delete(tun);
  176. return -1;
  177. }
  178. offset += sent_bytes;
  179. }
  180. // printf("Got %d bytes from server - wrote to fd %d\n", rcvd_frame->data_length, tun->sockfd);
  181. return 0;
  182. }
  183. /* Handle close-tunnel frame recived from the server */
  184. int handle_server_tcp_fin_frame(protocol_frame *rcvd_frame)
  185. {
  186. tunnel *tun=NULL;
  187. int connid = rcvd_frame->connid;
  188. HASH_FIND_INT(by_id, &connid, tun);
  189. if(!tun)
  190. {
  191. log_printf(L_WARNING, "Got TCP FIN frame with unknown tunnel ID %d\n", rcvd_frame->connid);
  192. return -1;
  193. }
  194. if(tun->friendnumber != rcvd_frame->friendnumber)
  195. {
  196. log_printf(L_WARNING, "Friend #%d tried to close tunnel while server is #%d\n", rcvd_frame->friendnumber, tun->friendnumber);
  197. return -1;
  198. }
  199. if(tun->sockfd)
  200. {
  201. FD_CLR(tun->sockfd, &client_master_fdset);
  202. }
  203. tunnel_delete(tun);
  204. return 0;
  205. }
  206. /* Main loop for the client */
  207. int do_client_loop(uint8_t *tox_id_str)
  208. {
  209. unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE];
  210. unsigned char tox_id[TOX_ADDRESS_SIZE];
  211. uint32_t friendnumber = 0;
  212. struct timeval tv;
  213. fd_set fds;
  214. static time_t invitation_sent_time = 0;
  215. uint32_t invitations_sent = 0;
  216. TOX_ERR_FRIEND_QUERY friend_query_error;
  217. TOX_ERR_FRIEND_CUSTOM_PACKET custom_packet_error;
  218. client_tunnel.sockfd = 0;
  219. FD_ZERO(&client_master_fdset);
  220. tox_callback_friend_lossless_packet(tox, parse_lossless_packet);
  221. if(!string_to_id(tox_id, tox_id_str))
  222. {
  223. log_printf(L_ERROR, "Invalid Tox ID");
  224. exit(1);
  225. }
  226. if(!ping_mode && !client_pipe_mode)
  227. {
  228. local_bind();
  229. signal(SIGPIPE, SIG_IGN);
  230. }
  231. log_printf(L_INFO, "Connecting to Tox...\n");
  232. while(1)
  233. {
  234. /* Let tox do its stuff */
  235. tox_iterate(tox, NULL);
  236. switch(state)
  237. {
  238. /*
  239. * Send friend request
  240. */
  241. case CLIENT_STATE_INITIAL:
  242. if(connection_status != TOX_CONNECTION_NONE)
  243. {
  244. state = CLIENT_STATE_CONNECTED;
  245. }
  246. break;
  247. case CLIENT_STATE_CONNECTED:
  248. {
  249. uint8_t* data = (uint8_t *)"Hi, fellow tuntox instance!";
  250. uint16_t length = sizeof(data);
  251. TOX_ERR_FRIEND_ADD add_error;
  252. if(use_shared_secret)
  253. {
  254. data = (uint8_t *)shared_secret;
  255. data[TOX_MAX_FRIEND_REQUEST_LENGTH-1] = '\0';
  256. length = strlen((char *)data)+1;
  257. log_printf(L_DEBUG, "Sent shared secret of length %u\n", length);
  258. }
  259. if(invitations_sent == 0)
  260. {
  261. log_printf(L_INFO, "Connected. Sending friend request.\n");
  262. }
  263. else
  264. {
  265. log_printf(L_INFO, "Sending another friend request.\n");
  266. }
  267. friendnumber = tox_friend_add(
  268. tox,
  269. tox_id,
  270. data,
  271. length,
  272. &add_error
  273. );
  274. if(add_error != TOX_ERR_FRIEND_ADD_OK)
  275. {
  276. unsigned char tox_printable_id[TOX_ADDRESS_SIZE * 2 + 1];
  277. id_to_string(tox_printable_id, tox_id);
  278. log_printf(L_ERROR, "Error %u adding friend %s\n", add_error, tox_printable_id);
  279. exit(-1);
  280. }
  281. invitation_sent_time = time(NULL);
  282. invitations_sent++;
  283. state = CLIENT_STATE_SENTREQUEST;
  284. log_printf(L_INFO, "Waiting for friend to accept us...\n");
  285. }
  286. break;
  287. case CLIENT_STATE_SENTREQUEST:
  288. {
  289. TOX_CONNECTION friend_connection_status;
  290. friend_connection_status = tox_friend_get_connection_status(tox, friendnumber, &friend_query_error);
  291. if(friend_query_error != TOX_ERR_FRIEND_QUERY_OK)
  292. {
  293. log_printf(L_DEBUG, "tox_friend_get_connection_status: error %u", friend_query_error);
  294. }
  295. else
  296. {
  297. if(friend_connection_status != TOX_CONNECTION_NONE)
  298. {
  299. const char* status = readable_connection_status(friend_connection_status);
  300. log_printf(L_INFO, "Friend request accepted (%s)!\n", status);
  301. state = CLIENT_STATE_REQUEST_ACCEPTED;
  302. }
  303. else
  304. {
  305. if(1 && (time(NULL) - invitation_sent_time > 45))
  306. {
  307. TOX_ERR_FRIEND_DELETE error = 0;
  308. log_printf(L_INFO, "Sending another friend request...");
  309. tox_friend_delete(
  310. tox,
  311. friendnumber,
  312. &error);
  313. if(error != TOX_ERR_FRIEND_DELETE_OK)
  314. {
  315. log_printf(L_ERROR, "Error %u deleting friend before reconnection\n", error);
  316. exit(-1);
  317. }
  318. state = CLIENT_STATE_CONNECTED;
  319. }
  320. }
  321. }
  322. break;
  323. }
  324. case CLIENT_STATE_REQUEST_ACCEPTED:
  325. if(ping_mode)
  326. {
  327. state = CLIENT_STATE_SEND_PING;
  328. }
  329. else if(client_pipe_mode)
  330. {
  331. state = CLIENT_STATE_SETUP_PIPE;
  332. }
  333. else
  334. {
  335. state = CLIENT_STATE_BIND_PORT;
  336. }
  337. break;
  338. case CLIENT_STATE_SEND_PING:
  339. /* Send the ping packet */
  340. {
  341. uint8_t data[] = {
  342. 0xa2, 0x6a, 0x01, 0x08, 0x00, 0x00, 0x00, 0x05,
  343. 0x48, 0x65, 0x6c, 0x6c, 0x6f
  344. };
  345. clock_gettime(CLOCK_MONOTONIC, &ping_sent_time);
  346. tox_friend_send_lossless_packet(
  347. tox,
  348. friendnumber,
  349. data,
  350. sizeof(data),
  351. &custom_packet_error
  352. );
  353. }
  354. if(custom_packet_error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK)
  355. {
  356. state = CLIENT_STATE_PING_SENT;
  357. }
  358. else
  359. {
  360. log_printf(L_WARNING, "When sending ping packet: %u", custom_packet_error);
  361. }
  362. break;
  363. case CLIENT_STATE_PING_SENT:
  364. /* Just sit there and wait for pong */
  365. break;
  366. case CLIENT_STATE_BIND_PORT:
  367. if(bind_sockfd < 0)
  368. {
  369. log_printf(L_ERROR, "Shutting down - could not bind to listening port\n");
  370. state = CLIENT_STATE_SHUTDOWN;
  371. }
  372. else
  373. {
  374. state = CLIENT_STATE_FORWARDING;
  375. }
  376. break;
  377. case CLIENT_STATE_SETUP_PIPE:
  378. send_tunnel_request_packet(
  379. remote_host,
  380. remote_port,
  381. friendnumber
  382. );
  383. state = CLIENT_STATE_FORWARDING;
  384. break;
  385. case CLIENT_STATE_REQUEST_TUNNEL:
  386. send_tunnel_request_packet(
  387. remote_host,
  388. remote_port,
  389. friendnumber
  390. );
  391. state = CLIENT_STATE_WAIT_FOR_ACKTUNNEL;
  392. break;
  393. case CLIENT_STATE_WAIT_FOR_ACKTUNNEL:
  394. client_tunnel.sockfd = 0;
  395. send_tunnel_request_packet(
  396. remote_host,
  397. remote_port,
  398. friendnumber
  399. );
  400. break;
  401. case CLIENT_STATE_FORWARDING:
  402. {
  403. int accept_fd = 0;
  404. int select_rv = 0;
  405. tunnel *tmp = NULL;
  406. tunnel *tun = NULL;
  407. tv.tv_sec = 0;
  408. tv.tv_usec = 20000;
  409. fds = client_master_fdset;
  410. /* Handle accepting new connections */
  411. if(!client_pipe_mode &&
  412. client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */
  413. {
  414. accept_fd = accept(bind_sockfd, NULL, NULL);
  415. if(accept_fd != -1)
  416. {
  417. log_printf(L_INFO, "Accepting a new connection - requesting tunnel...\n");
  418. /* Open a new tunnel for this FD */
  419. client_tunnel.sockfd = accept_fd;
  420. send_tunnel_request_packet(
  421. remote_host,
  422. remote_port,
  423. friendnumber
  424. );
  425. }
  426. }
  427. /* Handle reading from sockets */
  428. select_rv = select(select_nfds, &fds, NULL, NULL, &tv);
  429. if(select_rv == -1 || select_rv == 0)
  430. {
  431. if(select_rv == -1)
  432. {
  433. log_printf(L_DEBUG, "Reading from local socket failed: code=%d (%s)\n",
  434. errno, strerror(errno));
  435. }
  436. else
  437. {
  438. log_printf(L_DEBUG2, "Nothing to read...");
  439. }
  440. }
  441. else
  442. {
  443. HASH_ITER(hh, by_id, tun, tmp)
  444. {
  445. if(FD_ISSET(tun->sockfd, &fds))
  446. {
  447. int nbytes;
  448. if(client_local_port_mode)
  449. {
  450. nbytes = recv(tun->sockfd,
  451. tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
  452. READ_BUFFER_SIZE, 0);
  453. }
  454. else
  455. {
  456. nbytes = read(tun->sockfd,
  457. tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
  458. READ_BUFFER_SIZE
  459. );
  460. }
  461. /* Check if connection closed */
  462. if(nbytes == 0)
  463. {
  464. uint8_t data[PROTOCOL_BUFFER_OFFSET];
  465. protocol_frame frame_st, *frame;
  466. log_printf(L_INFO, "Connection closed\n");
  467. frame = &frame_st;
  468. memset(frame, 0, sizeof(protocol_frame));
  469. frame->friendnumber = tun->friendnumber;
  470. frame->packet_type = PACKET_TYPE_TCP_FIN;
  471. frame->connid = tun->connid;
  472. frame->data_length = 0;
  473. send_frame(frame, data);
  474. if(tun->sockfd)
  475. {
  476. FD_CLR(tun->sockfd, &client_master_fdset);
  477. }
  478. tunnel_delete(tun);
  479. }
  480. else
  481. {
  482. protocol_frame frame_st, *frame;
  483. frame = &frame_st;
  484. memset(frame, 0, sizeof(protocol_frame));
  485. frame->friendnumber = tun->friendnumber;
  486. frame->packet_type = PACKET_TYPE_TCP;
  487. frame->connid = tun->connid;
  488. frame->data_length = nbytes;
  489. send_frame(frame, tox_packet_buf);
  490. // printf("Wrote %d bytes from sock %d to tunnel %d\n", nbytes, tun->sockfd, tun->connid);
  491. }
  492. }
  493. }
  494. }
  495. fds = client_master_fdset;
  496. }
  497. break;
  498. case CLIENT_STATE_SHUTDOWN:
  499. exit(0);
  500. break;
  501. }
  502. usleep(tox_iteration_interval(tox) * 1000);
  503. }
  504. }