client.c 19 KB

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