diff options
author | GDR! <gdr@go2.pl> | 2014-12-11 23:27:26 +0100 |
---|---|---|
committer | GDR! <gdr@go2.pl> | 2014-12-11 23:27:26 +0100 |
commit | 99a66836911b804dce1455580cbf75dc99f23538 (patch) | |
tree | 2eee635f310b1dd9e39dbc45e74c60168a1fdce3 | |
parent | c9f51df320380a537843145ebbf4ceff7ef1c561 (diff) |
Pipe mode working, yay!
-rw-r--r-- | client.c | 82 | ||||
-rw-r--r-- | client.h | 1 | ||||
-rw-r--r-- | main.c | 31 | ||||
-rw-r--r-- | util.c | 22 |
4 files changed, 104 insertions, 32 deletions
@@ -103,17 +103,20 @@ int handle_acktunnel_frame(protocol_frame *rcvd_frame) | |||
103 | /* Mark that we can accept() another connection */ | 103 | /* Mark that we can accept() another connection */ |
104 | client_tunnel.sockfd = -1; | 104 | client_tunnel.sockfd = -1; |
105 | 105 | ||
106 | printf("New tunnel ID: %d\n", tun->connid); | 106 | // printf("New tunnel ID: %d\n", tun->connid); |
107 | 107 | ||
108 | if(client_local_port_mode) | 108 | if(client_local_port_mode || client_pipe_mode) |
109 | { | 109 | { |
110 | update_select_nfds(tun->sockfd); | 110 | update_select_nfds(tun->sockfd); |
111 | FD_SET(tun->sockfd, &client_master_fdset); | 111 | FD_SET(tun->sockfd, &client_master_fdset); |
112 | fprintf(stderr, "Accepted a new connection on port %d\n", local_port); | 112 | if(client_local_port_mode) |
113 | { | ||
114 | fprintf(stderr, "Accepted a new connection on port %d\n", local_port); | ||
115 | } | ||
113 | } | 116 | } |
114 | else | 117 | else |
115 | { | 118 | { |
116 | fprintf(stderr, "This tunnel mode is not supported yet"); | 119 | fprintf(stderr, "This tunnel mode is not supported yet\n"); |
117 | exit(1); | 120 | exit(1); |
118 | } | 121 | } |
119 | } | 122 | } |
@@ -136,20 +139,33 @@ int handle_server_tcp_frame(protocol_frame *rcvd_frame) | |||
136 | while(offset < rcvd_frame->data_length) | 139 | while(offset < rcvd_frame->data_length) |
137 | { | 140 | { |
138 | int sent_bytes; | 141 | int sent_bytes; |
142 | int write_sockfd; | ||
143 | |||
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 | } | ||
139 | 161 | ||
140 | sent_bytes = send( | ||
141 | tun->sockfd, | ||
142 | rcvd_frame->data + offset, | ||
143 | rcvd_frame->data_length - offset, | ||
144 | MSG_NOSIGNAL | ||
145 | ); | ||
146 | 162 | ||
147 | if(sent_bytes < 0) | 163 | if(sent_bytes < 0) |
148 | { | 164 | { |
149 | char data[PROTOCOL_BUFFER_OFFSET]; | 165 | char data[PROTOCOL_BUFFER_OFFSET]; |
150 | protocol_frame frame_st, *frame; | 166 | protocol_frame frame_st, *frame; |
151 | 167 | ||
152 | fprintf(stderr, "Could not write to socket %d: %s\n", tun->sockfd, strerror(errno)); | 168 | fprintf(stderr, "Could not write to socket %d: %s\n", write_sockfd, strerror(errno)); |
153 | 169 | ||
154 | frame = &frame_st; | 170 | frame = &frame_st; |
155 | memset(frame, 0, sizeof(protocol_frame)); | 171 | memset(frame, 0, sizeof(protocol_frame)); |
@@ -166,7 +182,7 @@ int handle_server_tcp_frame(protocol_frame *rcvd_frame) | |||
166 | offset += sent_bytes; | 182 | offset += sent_bytes; |
167 | } | 183 | } |
168 | 184 | ||
169 | printf("Got %d bytes from server - wrote to fd %d\n", rcvd_frame->data_length, tun->sockfd); | 185 | // printf("Got %d bytes from server - wrote to fd %d\n", rcvd_frame->data_length, tun->sockfd); |
170 | 186 | ||
171 | return 0; | 187 | return 0; |
172 | } | 188 | } |
@@ -213,7 +229,7 @@ int do_client_loop(char *tox_id_str) | |||
213 | exit(1); | 229 | exit(1); |
214 | } | 230 | } |
215 | 231 | ||
216 | if(!ping_mode) /* TODO handle pipe mode */ | 232 | if(!ping_mode && !client_pipe_mode) |
217 | { | 233 | { |
218 | local_bind(); | 234 | local_bind(); |
219 | signal(SIGPIPE, SIG_IGN); | 235 | signal(SIGPIPE, SIG_IGN); |
@@ -277,6 +293,10 @@ int do_client_loop(char *tox_id_str) | |||
277 | { | 293 | { |
278 | state = CLIENT_STATE_SEND_PING; | 294 | state = CLIENT_STATE_SEND_PING; |
279 | } | 295 | } |
296 | else if(client_pipe_mode) | ||
297 | { | ||
298 | state = CLIENT_STATE_SETUP_PIPE; | ||
299 | } | ||
280 | else | 300 | else |
281 | { | 301 | { |
282 | state = CLIENT_STATE_BIND_PORT; | 302 | state = CLIENT_STATE_BIND_PORT; |
@@ -315,6 +335,14 @@ int do_client_loop(char *tox_id_str) | |||
315 | state = CLIENT_STATE_FORWARDING; | 335 | state = CLIENT_STATE_FORWARDING; |
316 | } | 336 | } |
317 | break; | 337 | break; |
338 | case CLIENT_STATE_SETUP_PIPE: | ||
339 | send_tunnel_request_packet( | ||
340 | remote_host, | ||
341 | remote_port, | ||
342 | friendnumber | ||
343 | ); | ||
344 | state = CLIENT_STATE_FORWARDING; | ||
345 | break; | ||
318 | case CLIENT_STATE_REQUEST_TUNNEL: | 346 | case CLIENT_STATE_REQUEST_TUNNEL: |
319 | send_tunnel_request_packet( | 347 | send_tunnel_request_packet( |
320 | remote_host, | 348 | remote_host, |
@@ -324,6 +352,12 @@ int do_client_loop(char *tox_id_str) | |||
324 | state = CLIENT_STATE_WAIT_FOR_ACKTUNNEL; | 352 | state = CLIENT_STATE_WAIT_FOR_ACKTUNNEL; |
325 | break; | 353 | break; |
326 | case CLIENT_STATE_WAIT_FOR_ACKTUNNEL: | 354 | case CLIENT_STATE_WAIT_FOR_ACKTUNNEL: |
355 | client_tunnel.sockfd = 0; | ||
356 | send_tunnel_request_packet( | ||
357 | remote_host, | ||
358 | remote_port, | ||
359 | friendnumber | ||
360 | ); | ||
327 | break; | 361 | break; |
328 | case CLIENT_STATE_FORWARDING: | 362 | case CLIENT_STATE_FORWARDING: |
329 | { | 363 | { |
@@ -336,7 +370,8 @@ int do_client_loop(char *tox_id_str) | |||
336 | fds = client_master_fdset; | 370 | fds = client_master_fdset; |
337 | 371 | ||
338 | /* Handle accepting new connections */ | 372 | /* Handle accepting new connections */ |
339 | if(client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */ | 373 | if(!client_pipe_mode && |
374 | client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */ | ||
340 | { | 375 | { |
341 | accept_fd = accept(bind_sockfd, NULL, NULL); | 376 | accept_fd = accept(bind_sockfd, NULL, NULL); |
342 | if(accept_fd != -1) | 377 | if(accept_fd != -1) |
@@ -359,9 +394,20 @@ int do_client_loop(char *tox_id_str) | |||
359 | { | 394 | { |
360 | if(FD_ISSET(tun->sockfd, &fds)) | 395 | if(FD_ISSET(tun->sockfd, &fds)) |
361 | { | 396 | { |
362 | int nbytes = recv(tun->sockfd, | 397 | int nbytes; |
363 | tox_packet_buf + PROTOCOL_BUFFER_OFFSET, | 398 | if(client_local_port_mode) |
364 | READ_BUFFER_SIZE, 0); | 399 | { |
400 | nbytes = recv(tun->sockfd, | ||
401 | tox_packet_buf + PROTOCOL_BUFFER_OFFSET, | ||
402 | READ_BUFFER_SIZE, 0); | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | nbytes = read(tun->sockfd, | ||
407 | tox_packet_buf + PROTOCOL_BUFFER_OFFSET, | ||
408 | READ_BUFFER_SIZE | ||
409 | ); | ||
410 | } | ||
365 | 411 | ||
366 | /* Check if connection closed */ | 412 | /* Check if connection closed */ |
367 | if(nbytes == 0) | 413 | if(nbytes == 0) |
@@ -392,7 +438,7 @@ int do_client_loop(char *tox_id_str) | |||
392 | frame->data_length = nbytes; | 438 | frame->data_length = nbytes; |
393 | send_frame(frame, tox_packet_buf); | 439 | send_frame(frame, tox_packet_buf); |
394 | 440 | ||
395 | printf("Wrote %d bytes from sock %d to tunnel %d\n", nbytes, tun->sockfd, tun->connid); | 441 | // printf("Wrote %d bytes from sock %d to tunnel %d\n", nbytes, tun->sockfd, tun->connid); |
396 | } | 442 | } |
397 | } | 443 | } |
398 | } | 444 | } |
@@ -12,6 +12,7 @@ | |||
12 | #define CLIENT_STATE_FORWARDING 10 | 12 | #define CLIENT_STATE_FORWARDING 10 |
13 | #define CLIENT_STATE_SHUTDOWN 11 | 13 | #define CLIENT_STATE_SHUTDOWN 11 |
14 | #define CLIENT_STATE_BIND_PORT 12 | 14 | #define CLIENT_STATE_BIND_PORT 12 |
15 | #define CLIENT_STATE_SETUP_PIPE 13 | ||
15 | 16 | ||
16 | int handle_pong_frame(protocol_frame *rcvd_frame); | 17 | int handle_pong_frame(protocol_frame *rcvd_frame); |
17 | int handle_acktunnel_frame(protocol_frame *rcvd_frame); | 18 | int handle_acktunnel_frame(protocol_frame *rcvd_frame); |
@@ -94,7 +94,7 @@ tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) | |||
94 | 94 | ||
95 | void tunnel_delete(tunnel *t) | 95 | void tunnel_delete(tunnel *t) |
96 | { | 96 | { |
97 | printf("Deleting tunnel #%d\n", t->connid); | 97 | fprintf(stderr, "Deleting tunnel #%d\n", t->connid); |
98 | if(t->sockfd) | 98 | if(t->sockfd) |
99 | { | 99 | { |
100 | close(t->sockfd); | 100 | close(t->sockfd); |
@@ -331,10 +331,10 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame) | |||
331 | strncpy(hostname, rcvd_frame->data, rcvd_frame->data_length); | 331 | strncpy(hostname, rcvd_frame->data, rcvd_frame->data_length); |
332 | hostname[rcvd_frame->data_length] = '\0'; | 332 | hostname[rcvd_frame->data_length] = '\0'; |
333 | 333 | ||
334 | printf("Got a request to forward data from %s:%d\n", hostname, port); | 334 | fprintf(stderr, "Got a request to forward data from %s:%d\n", hostname, port); |
335 | 335 | ||
336 | tunnel_id = get_random_tunnel_id(); | 336 | tunnel_id = get_random_tunnel_id(); |
337 | printf("Tunnel ID: %d\n", tunnel_id); | 337 | fprintf(stderr, "Tunnel ID: %d\n", tunnel_id); |
338 | /* TODO make connection */ | 338 | /* TODO make connection */ |
339 | sockfd = get_client_socket(hostname, port); | 339 | sockfd = get_client_socket(hostname, port); |
340 | if(sockfd > 0) | 340 | if(sockfd > 0) |
@@ -509,7 +509,7 @@ int parse_lossless_packet(void *sender_uc, const uint8_t *data, uint32_t len) | |||
509 | frame->data_length = INT16_AT(data, 6); | 509 | frame->data_length = INT16_AT(data, 6); |
510 | frame->data = (uint8_t *)(data + PROTOCOL_BUFFER_OFFSET); | 510 | frame->data = (uint8_t *)(data + PROTOCOL_BUFFER_OFFSET); |
511 | frame->friendnumber = *((uint32_t*)sender_uc); | 511 | frame->friendnumber = *((uint32_t*)sender_uc); |
512 | printf("Got protocol frame magic 0x%x type 0x%x from friend %d\n", frame->magic, frame->packet_type, frame->friendnumber); | 512 | fprintf(stderr, "Got protocol frame magic 0x%x type 0x%x from friend %d\n", frame->magic, frame->packet_type, frame->friendnumber); |
513 | 513 | ||
514 | if(len < frame->data_length + PROTOCOL_BUFFER_OFFSET) | 514 | if(len < frame->data_length + PROTOCOL_BUFFER_OFFSET) |
515 | { | 515 | { |
@@ -639,13 +639,13 @@ void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *d | |||
639 | int32_t friendnumber; | 639 | int32_t friendnumber; |
640 | int32_t *friendnumber_ptr = NULL; | 640 | int32_t *friendnumber_ptr = NULL; |
641 | 641 | ||
642 | printf("Got friend request\n"); | 642 | fprintf(stderr, "Got friend request\n"); |
643 | 643 | ||
644 | friendnumber = tox_add_friend_norequest(tox, public_key); | 644 | friendnumber = tox_add_friend_norequest(tox, public_key); |
645 | 645 | ||
646 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); | 646 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); |
647 | id_to_string(tox_printable_id, public_key); | 647 | id_to_string(tox_printable_id, public_key); |
648 | printf("Accepted friend request from %s as %d\n", tox_printable_id, friendnumber); | 648 | fprintf(stderr, "Accepted friend request from %s as %d\n", tox_printable_id, friendnumber); |
649 | 649 | ||
650 | /* TODO: this is not freed right now, we're leaking 4 bytes per contact (OMG!) */ | 650 | /* TODO: this is not freed right now, we're leaking 4 bytes per contact (OMG!) */ |
651 | friendnumber_ptr = malloc(sizeof(int32_t)); | 651 | friendnumber_ptr = malloc(sizeof(int32_t)); |
@@ -662,7 +662,7 @@ void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *d | |||
662 | 662 | ||
663 | void cleanup(int status, void *tmp) | 663 | void cleanup(int status, void *tmp) |
664 | { | 664 | { |
665 | printf("kthxbye\n"); | 665 | fprintf(stderr, "kthxbye\n"); |
666 | fflush(stdout); | 666 | fflush(stdout); |
667 | tox_kill(tox); | 667 | tox_kill(tox); |
668 | if(client_socket) | 668 | if(client_socket) |
@@ -726,7 +726,7 @@ int do_server_loop() | |||
726 | char data[PROTOCOL_BUFFER_OFFSET]; | 726 | char data[PROTOCOL_BUFFER_OFFSET]; |
727 | protocol_frame frame_st, *frame; | 727 | protocol_frame frame_st, *frame; |
728 | 728 | ||
729 | printf("conn closed!\n"); | 729 | fprintf(stderr, "conn closed!\n"); |
730 | 730 | ||
731 | frame = &frame_st; | 731 | frame = &frame_st; |
732 | memset(frame, 0, sizeof(protocol_frame)); | 732 | memset(frame, 0, sizeof(protocol_frame)); |
@@ -738,7 +738,6 @@ int do_server_loop() | |||
738 | 738 | ||
739 | tunnel_delete(tun); | 739 | tunnel_delete(tun); |
740 | 740 | ||
741 | /* TODO remove tunnel? resume connection? */ | ||
742 | continue; | 741 | continue; |
743 | } | 742 | } |
744 | else | 743 | else |
@@ -775,7 +774,7 @@ int main(int argc, char *argv[]) | |||
775 | unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1]; | 774 | unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1]; |
776 | int oc; | 775 | int oc; |
777 | 776 | ||
778 | while ((oc = getopt(argc, argv, "L:pi:C:")) != -1) | 777 | while ((oc = getopt(argc, argv, "L:pi:C:P:")) != -1) |
779 | { | 778 | { |
780 | switch(oc) | 779 | switch(oc) |
781 | { | 780 | { |
@@ -794,8 +793,12 @@ int main(int argc, char *argv[]) | |||
794 | /* Pipe forwarding */ | 793 | /* Pipe forwarding */ |
795 | client_mode = 1; | 794 | client_mode = 1; |
796 | client_pipe_mode = 1; | 795 | client_pipe_mode = 1; |
797 | remote_port = atoi(optarg); | 796 | if(parse_pipe_port_forward(optarg, &remote_host, &remote_port) < 0) |
798 | fprintf(stderr, "Forwarding remote port %d\n", remote_port); | 797 | { |
798 | fprintf(stderr, "Invalid value for -P option - use something like -P 127.0.0.1:22\n"); | ||
799 | exit(1); | ||
800 | } | ||
801 | fprintf(stderr, "Forwarding remote port %d to stdin/out\n", remote_port); | ||
799 | break; | 802 | break; |
800 | case 'p': | 803 | case 'p': |
801 | /* Ping */ | 804 | /* Ping */ |
@@ -843,7 +846,7 @@ int main(int argc, char *argv[]) | |||
843 | tox_get_address(tox, tox_id); | 846 | tox_get_address(tox, tox_id); |
844 | id_to_string(tox_printable_id, tox_id); | 847 | id_to_string(tox_printable_id, tox_id); |
845 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; | 848 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; |
846 | printf("Generated Tox ID: %s\n", tox_printable_id); | 849 | fprintf(stderr, "Generated Tox ID: %s\n", tox_printable_id); |
847 | 850 | ||
848 | if(!remote_tox_id) | 851 | if(!remote_tox_id) |
849 | { | 852 | { |
@@ -866,7 +869,7 @@ int main(int argc, char *argv[]) | |||
866 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); | 869 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); |
867 | id_to_string(tox_printable_id, tox_id); | 870 | id_to_string(tox_printable_id, tox_id); |
868 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; | 871 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; |
869 | printf("Using Tox ID: %s\n", tox_printable_id); | 872 | fprintf(stderr, "Using Tox ID: %s\n", tox_printable_id); |
870 | 873 | ||
871 | tox_callback_friend_request(tox, accept_friend_request, NULL); | 874 | tox_callback_friend_request(tox, accept_friend_request, NULL); |
872 | do_server_loop(); | 875 | do_server_loop(); |
@@ -81,6 +81,7 @@ int string_to_id(char_t *w, char_t *a) | |||
81 | return 1; | 81 | return 1; |
82 | } | 82 | } |
83 | 83 | ||
84 | /* Parse the -L parameter */ | ||
84 | /* 0 = success */ | 85 | /* 0 = success */ |
85 | int parse_local_port_forward(char *string, int *local_port, char **hostname, int *remote_port) | 86 | int parse_local_port_forward(char *string, int *local_port, char **hostname, int *remote_port) |
86 | { | 87 | { |
@@ -104,6 +105,27 @@ int parse_local_port_forward(char *string, int *local_port, char **hostname, int | |||
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
106 | 107 | ||
108 | /* Parse the -P parameter */ | ||
109 | /* 0 = success */ | ||
110 | int parse_pipe_port_forward(char *string, char **hostname, int *remote_port) | ||
111 | { | ||
112 | char *host; | ||
113 | char *rport; | ||
114 | |||
115 | host = strtok(string, ":"); | ||
116 | rport = strtok(NULL, ":"); | ||
117 | |||
118 | if(!host || !rport) | ||
119 | { | ||
120 | return -1; | ||
121 | } | ||
122 | |||
123 | *hostname = host; | ||
124 | *remote_port = atoi(rport); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
107 | void* file_raw(char *path, uint32_t *size) | 129 | void* file_raw(char *path, uint32_t *size) |
108 | { | 130 | { |
109 | FILE *file; | 131 | FILE *file; |