client.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include "main.h"
  2. #include "client.h"
  3. /* The state machine */
  4. int state = CLIENT_STATE_INITIAL;
  5. /* Used in ping mode */
  6. struct timespec ping_sent_time;
  7. /* Client mode tunnel */
  8. tunnel client_tunnel;
  9. /* Sock representing the local port - call accept() on it */
  10. int bind_sockfd;
  11. fd_set client_master_fdset;
  12. int handle_pong_frame(protocol_frame *rcvd_frame)
  13. {
  14. struct timespec pong_rcvd_time;
  15. double secs1, secs2;
  16. clock_gettime(CLOCK_MONOTONIC, &pong_rcvd_time);
  17. secs1 = (1.0 * ping_sent_time.tv_sec) + (1e-9 * ping_sent_time.tv_nsec);
  18. secs2 = (1.0 * pong_rcvd_time.tv_sec) + (1e-9 * pong_rcvd_time.tv_nsec);
  19. printf("GOT PONG! Time = %.3fs\n", secs2-secs1);
  20. if(ping_mode)
  21. {
  22. // state = CLIENT_STATE_PONG_RECEIVED;
  23. state = CLIENT_STATE_SEND_PING;
  24. }
  25. }
  26. int local_bind()
  27. {
  28. struct addrinfo hints, *res;
  29. char port[6];
  30. int yes = 1;
  31. int flags;
  32. snprintf(port, 6, "%d", local_port);
  33. memset(&hints, 0, sizeof hints);
  34. hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
  35. hints.ai_socktype = SOCK_STREAM;
  36. hints.ai_flags = AI_PASSIVE; // fill in my IP for me
  37. getaddrinfo(NULL, port, &hints, &res);
  38. bind_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  39. if(bind_sockfd < 0)
  40. {
  41. fprintf(stderr, "Could not create a socket for local listening: %s\n", strerror(errno));
  42. exit(1);
  43. }
  44. setsockopt(bind_sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  45. /* Set O_NONBLOCK to make accept() non-blocking */
  46. if (-1 == (flags = fcntl(bind_sockfd, F_GETFL, 0)))
  47. {
  48. flags = 0;
  49. }
  50. fcntl(bind_sockfd, F_SETFL, flags | O_NONBLOCK);
  51. if(bind(bind_sockfd, res->ai_addr, res->ai_addrlen) < 0)
  52. {
  53. fprintf(stderr, "Bind to port %d failed: %s\n", local_port, strerror(errno));
  54. close(bind_sockfd);
  55. exit(1);
  56. }
  57. if(listen(bind_sockfd, 1) < 0)
  58. {
  59. fprintf(stderr, "Listening on port %d failed: %s\n", local_port, strerror(errno));
  60. close(bind_sockfd);
  61. exit(1);
  62. }
  63. fprintf(stderr, "Bound to local port %d\n", local_port);
  64. }
  65. /* Bind the client.sockfd to a tunnel */
  66. int handle_acktunnel_frame(protocol_frame *rcvd_frame)
  67. {
  68. tunnel *tun;
  69. if(!client_mode)
  70. {
  71. fprintf(stderr, "Got ACK tunnel frame when not in client mode!?\n");
  72. return -1;
  73. }
  74. tun = tunnel_create(
  75. client_tunnel.sockfd,
  76. rcvd_frame->connid,
  77. rcvd_frame->friendnumber
  78. );
  79. /* Mark that we can accept() another connection */
  80. client_tunnel.sockfd = -1;
  81. // printf("New tunnel ID: %d\n", tun->connid);
  82. if(client_local_port_mode || client_pipe_mode)
  83. {
  84. update_select_nfds(tun->sockfd);
  85. FD_SET(tun->sockfd, &client_master_fdset);
  86. if(client_local_port_mode)
  87. {
  88. fprintf(stderr, "Accepted a new connection on port %d\n", local_port);
  89. }
  90. }
  91. else
  92. {
  93. fprintf(stderr, "This tunnel mode is not supported yet\n");
  94. exit(1);
  95. }
  96. }
  97. /* Handle a TCP frame received from server */
  98. int handle_server_tcp_frame(protocol_frame *rcvd_frame)
  99. {
  100. int offset = 0;
  101. tunnel *tun = NULL;
  102. int tun_id = rcvd_frame->connid;
  103. HASH_FIND_INT(by_id, &tun_id, tun);
  104. if(!tun)
  105. {
  106. fprintf(stderr, "Got TCP frame with unknown tunnel ID %d\n", rcvd_frame->connid);
  107. return -1;
  108. }
  109. while(offset < rcvd_frame->data_length)
  110. {
  111. int sent_bytes;
  112. int write_sockfd;
  113. if(client_pipe_mode)
  114. {
  115. sent_bytes = write(
  116. 1, /* STDOUT */
  117. rcvd_frame->data + offset,
  118. rcvd_frame->data_length - offset
  119. );
  120. }
  121. else
  122. {
  123. sent_bytes = send(
  124. tun->sockfd,
  125. rcvd_frame->data + offset,
  126. rcvd_frame->data_length - offset,
  127. MSG_NOSIGNAL
  128. );
  129. }
  130. if(sent_bytes < 0)
  131. {
  132. char data[PROTOCOL_BUFFER_OFFSET];
  133. protocol_frame frame_st, *frame;
  134. fprintf(stderr, "Could not write to socket %d: %s\n", write_sockfd, strerror(errno));
  135. frame = &frame_st;
  136. memset(frame, 0, sizeof(protocol_frame));
  137. frame->friendnumber = tun->friendnumber;
  138. frame->packet_type = PACKET_TYPE_TCP_FIN;
  139. frame->connid = tun->connid;
  140. frame->data_length = 0;
  141. send_frame(frame, data);
  142. tunnel_delete(tun);
  143. return -1;
  144. }
  145. offset += sent_bytes;
  146. }
  147. // printf("Got %d bytes from server - wrote to fd %d\n", rcvd_frame->data_length, tun->sockfd);
  148. return 0;
  149. }
  150. /* Handle close-tunnel frame recived from the server */
  151. int handle_server_tcp_fin_frame(protocol_frame *rcvd_frame)
  152. {
  153. tunnel *tun=NULL;
  154. int offset = 0;
  155. int connid = rcvd_frame->connid;
  156. HASH_FIND_INT(by_id, &connid, tun);
  157. if(!tun)
  158. {
  159. fprintf(stderr, "Got TCP FIN frame with unknown tunnel ID %d\n", rcvd_frame->connid);
  160. return -1;
  161. }
  162. if(tun->friendnumber != rcvd_frame->friendnumber)
  163. {
  164. fprintf(stderr, "Friend #%d tried to close tunnel while server is #%d\n", rcvd_frame->friendnumber, tun->friendnumber);
  165. return -1;
  166. }
  167. tunnel_delete(tun);
  168. }
  169. /* Main loop for the client */
  170. int do_client_loop(char *tox_id_str)
  171. {
  172. unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE];
  173. unsigned char tox_id[TOX_FRIEND_ADDRESS_SIZE];
  174. uint32_t friendnumber;
  175. struct timeval tv;
  176. fd_set fds;
  177. client_tunnel.sockfd = 0;
  178. FD_ZERO(&client_master_fdset);
  179. if(!string_to_id(tox_id, tox_id_str))
  180. {
  181. fprintf(stderr, "Invalid Tox ID");
  182. exit(1);
  183. }
  184. if(!ping_mode && !client_pipe_mode)
  185. {
  186. local_bind();
  187. signal(SIGPIPE, SIG_IGN);
  188. }
  189. fprintf(stderr, "Connecting to Tox...\n");
  190. while(1)
  191. {
  192. /* Let tox do its stuff */
  193. tox_do(tox);
  194. switch(state)
  195. {
  196. /*
  197. * Send friend request
  198. */
  199. case CLIENT_STATE_INITIAL:
  200. if(tox_isconnected(tox))
  201. {
  202. state = CLIENT_STATE_CONNECTED;
  203. }
  204. break;
  205. case CLIENT_STATE_CONNECTED:
  206. {
  207. uint8_t data[] = "Hi, fellow tuntox instance!";
  208. uint16_t length = sizeof(data);
  209. fprintf(stderr, "Connected. Sending friend request.\n");
  210. friendnumber = tox_add_friend(
  211. tox,
  212. tox_id,
  213. data,
  214. length
  215. );
  216. if(friendnumber < 0)
  217. {
  218. fprintf(stderr, "Error %d adding friend %s\n", friendnumber, tox_id);
  219. exit(-1);
  220. }
  221. tox_lossless_packet_registerhandler(tox, friendnumber, (PROTOCOL_MAGIC_V1)>>8, parse_lossless_packet, (void*)&friendnumber);
  222. state = CLIENT_STATE_SENTREQUEST;
  223. fprintf(stderr, "Waiting for friend to accept us...\n");
  224. }
  225. break;
  226. case CLIENT_STATE_SENTREQUEST:
  227. if(tox_get_friend_connection_status(tox, friendnumber) == 1)
  228. {
  229. fprintf(stderr, "Friend request accepted!\n");
  230. state = CLIENT_STATE_REQUEST_ACCEPTED;
  231. }
  232. else
  233. {
  234. }
  235. break;
  236. case CLIENT_STATE_REQUEST_ACCEPTED:
  237. if(ping_mode)
  238. {
  239. state = CLIENT_STATE_SEND_PING;
  240. }
  241. else if(client_pipe_mode)
  242. {
  243. state = CLIENT_STATE_SETUP_PIPE;
  244. }
  245. else
  246. {
  247. state = CLIENT_STATE_BIND_PORT;
  248. }
  249. break;
  250. case CLIENT_STATE_SEND_PING:
  251. /* Send the ping packet */
  252. {
  253. uint8_t data[] = {
  254. 0xa2, 0x6a, 0x01, 0x08, 0x00, 0x00, 0x00, 0x05,
  255. 0x48, 0x65, 0x6c, 0x6c, 0x6f
  256. };
  257. clock_gettime(CLOCK_MONOTONIC, &ping_sent_time);
  258. tox_send_lossless_packet(
  259. tox,
  260. friendnumber,
  261. data,
  262. sizeof(data)
  263. );
  264. }
  265. state = CLIENT_STATE_PING_SENT;
  266. break;
  267. case CLIENT_STATE_PING_SENT:
  268. /* Just sit there and wait for pong */
  269. break;
  270. case CLIENT_STATE_BIND_PORT:
  271. if(bind_sockfd < 0)
  272. {
  273. fprintf(stderr, "Shutting down - could not bind to listening port\n");
  274. state = CLIENT_STATE_SHUTDOWN;
  275. }
  276. else
  277. {
  278. state = CLIENT_STATE_FORWARDING;
  279. }
  280. break;
  281. case CLIENT_STATE_SETUP_PIPE:
  282. send_tunnel_request_packet(
  283. remote_host,
  284. remote_port,
  285. friendnumber
  286. );
  287. state = CLIENT_STATE_FORWARDING;
  288. break;
  289. case CLIENT_STATE_REQUEST_TUNNEL:
  290. send_tunnel_request_packet(
  291. remote_host,
  292. remote_port,
  293. friendnumber
  294. );
  295. state = CLIENT_STATE_WAIT_FOR_ACKTUNNEL;
  296. break;
  297. case CLIENT_STATE_WAIT_FOR_ACKTUNNEL:
  298. client_tunnel.sockfd = 0;
  299. send_tunnel_request_packet(
  300. remote_host,
  301. remote_port,
  302. friendnumber
  303. );
  304. break;
  305. case CLIENT_STATE_FORWARDING:
  306. {
  307. int accept_fd = 0;
  308. tunnel *tmp = NULL;
  309. tunnel *tun = NULL;
  310. tv.tv_sec = 0;
  311. tv.tv_usec = 20000;
  312. fds = client_master_fdset;
  313. /* Handle accepting new connections */
  314. if(!client_pipe_mode &&
  315. client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */
  316. {
  317. accept_fd = accept(bind_sockfd, NULL, NULL);
  318. if(accept_fd != -1)
  319. {
  320. fprintf(stderr, "Accepting a new connection - requesting tunnel...\n");
  321. /* Open a new tunnel for this FD */
  322. client_tunnel.sockfd = accept_fd;
  323. send_tunnel_request_packet(
  324. remote_host,
  325. remote_port,
  326. friendnumber
  327. );
  328. }
  329. }
  330. /* Handle reading from sockets */
  331. select(select_nfds, &fds, NULL, NULL, &tv);
  332. HASH_ITER(hh, by_id, tun, tmp)
  333. {
  334. if(FD_ISSET(tun->sockfd, &fds))
  335. {
  336. int nbytes;
  337. if(client_local_port_mode)
  338. {
  339. nbytes = recv(tun->sockfd,
  340. tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
  341. READ_BUFFER_SIZE, 0);
  342. }
  343. else
  344. {
  345. nbytes = read(tun->sockfd,
  346. tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
  347. READ_BUFFER_SIZE
  348. );
  349. }
  350. /* Check if connection closed */
  351. if(nbytes == 0)
  352. {
  353. char data[PROTOCOL_BUFFER_OFFSET];
  354. protocol_frame frame_st, *frame;
  355. fprintf(stderr, "Connection closed\n");
  356. frame = &frame_st;
  357. memset(frame, 0, sizeof(protocol_frame));
  358. frame->friendnumber = tun->friendnumber;
  359. frame->packet_type = PACKET_TYPE_TCP_FIN;
  360. frame->connid = tun->connid;
  361. frame->data_length = 0;
  362. send_frame(frame, data);
  363. tunnel_delete(tun);
  364. }
  365. else
  366. {
  367. protocol_frame frame_st, *frame;
  368. frame = &frame_st;
  369. memset(frame, 0, sizeof(protocol_frame));
  370. frame->friendnumber = tun->friendnumber;
  371. frame->packet_type = PACKET_TYPE_TCP;
  372. frame->connid = tun->connid;
  373. frame->data_length = nbytes;
  374. send_frame(frame, tox_packet_buf);
  375. // printf("Wrote %d bytes from sock %d to tunnel %d\n", nbytes, tun->sockfd, tun->connid);
  376. }
  377. }
  378. }
  379. fds = client_master_fdset;
  380. }
  381. break;
  382. case CLIENT_STATE_SHUTDOWN:
  383. exit(0);
  384. break;
  385. }
  386. usleep(tox_do_interval(tox) * 1000);
  387. }
  388. }