diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 107 |
1 files changed, 55 insertions, 52 deletions
@@ -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); |
@@ -130,40 +130,21 @@ void set_tox_username(Tox *tox) | |||
130 | 130 | ||
131 | gethostname(hostname, 1024); | 131 | gethostname(hostname, 1024); |
132 | hostname[1023] = '\0'; | 132 | hostname[1023] = '\0'; |
133 | # if 0 | ||
134 | memset(&hints, 0, sizeof hints); | ||
135 | hints.ai_family = AF_UNSPEC; /*either IPV4 or IPV6*/ | ||
136 | hints.ai_socktype = SOCK_STREAM; | ||
137 | hints.ai_flags = AI_CANONNAME; | ||
138 | |||
139 | if ((gai_result = getaddrinfo(hostname, "ftp", &hints, &info)) != 0) | ||
140 | { | ||
141 | fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result)); | ||
142 | exit(1); | ||
143 | } | ||
144 | |||
145 | for(p = info; p != NULL; p = p->ai_next) | ||
146 | { | ||
147 | printf("hostname: %s\n", p->ai_canonname); | ||
148 | } | ||
149 | # endif | ||
150 | 133 | ||
151 | tox_set_name(tox, hostname, strlen(hostname)); | 134 | tox_set_name(tox, hostname, strlen(hostname)); |
152 | |||
153 | // freeaddrinfo(info); | ||
154 | } | 135 | } |
155 | // get sockaddr, IPv4 or IPv6: | 136 | |
156 | /* From Beej */ | 137 | /* Get sockaddr, IPv4 or IPv6 */ |
157 | void *get_in_addr(struct sockaddr *sa) | 138 | void *get_in_addr(struct sockaddr *sa) |
158 | { | 139 | { |
159 | if (sa->sa_family == AF_INET) { | 140 | if (sa->sa_family == AF_INET) |
141 | { | ||
160 | return &(((struct sockaddr_in*)sa)->sin_addr); | 142 | return &(((struct sockaddr_in*)sa)->sin_addr); |
161 | } | 143 | } |
162 | 144 | ||
163 | return &(((struct sockaddr_in6*)sa)->sin6_addr); | 145 | return &(((struct sockaddr_in6*)sa)->sin6_addr); |
164 | } | 146 | } |
165 | 147 | ||
166 | /* From Beej */ | ||
167 | int get_client_socket(char *hostname, int port) | 148 | int get_client_socket(char *hostname, int port) |
168 | { | 149 | { |
169 | int sockfd, numbytes; | 150 | int sockfd, numbytes; |
@@ -179,13 +160,27 @@ int get_client_socket(char *hostname, int port) | |||
179 | hints.ai_family = AF_INET; | 160 | hints.ai_family = AF_INET; |
180 | hints.ai_socktype = SOCK_STREAM; | 161 | hints.ai_socktype = SOCK_STREAM; |
181 | 162 | ||
182 | if ((rv = getaddrinfo(hostname, port_str, &hints, &servinfo)) != 0) { | 163 | if ((rv = getaddrinfo(hostname, port_str, &hints, &servinfo)) != 0) |
183 | fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); | 164 | { |
184 | return -1; | 165 | /* Add a special case for "localhost" when name resolution is broken */ |
166 | if(!strncmp("localhost", hostname, 256)) | ||
167 | { | ||
168 | const char localhostname[] = "127.0.0.1"; | ||
169 | if ((rv = getaddrinfo(localhostname, port_str, &hints, &servinfo)) != 0) { | ||
170 | fprintf(stderr, "getaddrinfo failed for 127.0.0.1: %s\n", gai_strerror(rv)); | ||
171 | return -1; | ||
172 | } | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); | ||
177 | return -1; | ||
178 | } | ||
185 | } | 179 | } |
186 | 180 | ||
187 | // loop through all the results and connect to the first we can | 181 | // loop through all the results and connect to the first we can |
188 | for(p = servinfo; p != NULL; p = p->ai_next) { | 182 | for(p = servinfo; p != NULL; p = p->ai_next) |
183 | { | ||
189 | if (p->ai_family != AF_INET && p->ai_family != AF_INET6) | 184 | if (p->ai_family != AF_INET && p->ai_family != AF_INET6) |
190 | continue; | 185 | continue; |
191 | 186 | ||
@@ -209,8 +204,7 @@ int get_client_socket(char *hostname, int port) | |||
209 | return -1; | 204 | return -1; |
210 | } | 205 | } |
211 | 206 | ||
212 | inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), | 207 | inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); |
213 | s, sizeof s); | ||
214 | fprintf(stderr, "connecting to %s\n", s); | 208 | fprintf(stderr, "connecting to %s\n", s); |
215 | 209 | ||
216 | freeaddrinfo(servinfo); // all done with this structure | 210 | freeaddrinfo(servinfo); // all done with this structure |
@@ -229,6 +223,7 @@ int get_client_socket(char *hostname, int port) | |||
229 | int send_frame(protocol_frame *frame, uint8_t *data) | 223 | int send_frame(protocol_frame *frame, uint8_t *data) |
230 | { | 224 | { |
231 | int rv = -1; | 225 | int rv = -1; |
226 | int try = 0; | ||
232 | int i; | 227 | int i; |
233 | 228 | ||
234 | data[0] = PROTOCOL_MAGIC_HIGH; | 229 | data[0] = PROTOCOL_MAGIC_HIGH; |
@@ -240,10 +235,12 @@ int send_frame(protocol_frame *frame, uint8_t *data) | |||
240 | data[6] = BYTE2(frame->data_length); | 235 | data[6] = BYTE2(frame->data_length); |
241 | data[7] = BYTE1(frame->data_length); | 236 | data[7] = BYTE1(frame->data_length); |
242 | 237 | ||
243 | for(i = 0; i < 17;) | 238 | for(i = 0; i < 65;) /* 1.27 seconds per packet max */ |
244 | { | 239 | { |
245 | int j; | 240 | int j; |
246 | 241 | ||
242 | try++; | ||
243 | |||
247 | rv = tox_send_lossless_packet( | 244 | rv = tox_send_lossless_packet( |
248 | tox, | 245 | tox, |
249 | frame->friendnumber, | 246 | frame->friendnumber, |
@@ -273,7 +270,7 @@ int send_frame(protocol_frame *frame, uint8_t *data) | |||
273 | 270 | ||
274 | if(i > 0 && rv >= 0) | 271 | if(i > 0 && rv >= 0) |
275 | { | 272 | { |
276 | fprintf(stderr, "Packet succeeded at try %d\n", i+1); | 273 | fprintf(stderr, "Packet succeeded at try %d\n", try); |
277 | } | 274 | } |
278 | 275 | ||
279 | return rv; | 276 | return rv; |
@@ -337,10 +334,10 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame) | |||
337 | strncpy(hostname, rcvd_frame->data, rcvd_frame->data_length); | 334 | strncpy(hostname, rcvd_frame->data, rcvd_frame->data_length); |
338 | hostname[rcvd_frame->data_length] = '\0'; | 335 | hostname[rcvd_frame->data_length] = '\0'; |
339 | 336 | ||
340 | printf("Got a request to forward data from %s:%d\n", hostname, port); | 337 | fprintf(stderr, "Got a request to forward data from %s:%d\n", hostname, port); |
341 | 338 | ||
342 | tunnel_id = get_random_tunnel_id(); | 339 | tunnel_id = get_random_tunnel_id(); |
343 | printf("Tunnel ID: %d\n", tunnel_id); | 340 | fprintf(stderr, "Tunnel ID: %d\n", tunnel_id); |
344 | /* TODO make connection */ | 341 | /* TODO make connection */ |
345 | sockfd = get_client_socket(hostname, port); | 342 | sockfd = get_client_socket(hostname, port); |
346 | if(sockfd > 0) | 343 | if(sockfd > 0) |
@@ -380,6 +377,12 @@ int handle_client_tcp_frame(protocol_frame *rcvd_frame) | |||
380 | return -1; | 377 | return -1; |
381 | } | 378 | } |
382 | 379 | ||
380 | if(tun->friendnumber != rcvd_frame->friendnumber) | ||
381 | { | ||
382 | fprintf(stderr, "Friend #%d tried to send packet to a tunnel which belongs to #%d\n", rcvd_frame->friendnumber, tun->friendnumber); | ||
383 | return -1; | ||
384 | } | ||
385 | |||
383 | while(offset < rcvd_frame->data_length) | 386 | while(offset < rcvd_frame->data_length) |
384 | { | 387 | { |
385 | int sent_bytes; | 388 | int sent_bytes; |
@@ -388,7 +391,7 @@ int handle_client_tcp_frame(protocol_frame *rcvd_frame) | |||
388 | tun->sockfd, | 391 | tun->sockfd, |
389 | rcvd_frame->data + offset, | 392 | rcvd_frame->data + offset, |
390 | rcvd_frame->data_length - offset, | 393 | rcvd_frame->data_length - offset, |
391 | 0 | 394 | MSG_NOSIGNAL |
392 | ); | 395 | ); |
393 | 396 | ||
394 | if(sent_bytes < 0) | 397 | if(sent_bytes < 0) |
@@ -403,11 +406,6 @@ int handle_client_tcp_frame(protocol_frame *rcvd_frame) | |||
403 | return 0; | 406 | return 0; |
404 | } | 407 | } |
405 | 408 | ||
406 | int handle_server_tcp_fin_frame(protocol_frame *rcvd_frame) | ||
407 | { | ||
408 | |||
409 | } | ||
410 | |||
411 | /* Handle close-tunnel frame received from the client */ | 409 | /* Handle close-tunnel frame received from the client */ |
412 | int handle_client_tcp_fin_frame(protocol_frame *rcvd_frame) | 410 | int handle_client_tcp_fin_frame(protocol_frame *rcvd_frame) |
413 | { | 411 | { |
@@ -520,9 +518,9 @@ int parse_lossless_packet(void *sender_uc, const uint8_t *data, uint32_t len) | |||
520 | frame->packet_type = INT16_AT(data, 2); | 518 | frame->packet_type = INT16_AT(data, 2); |
521 | frame->connid = INT16_AT(data, 4); | 519 | frame->connid = INT16_AT(data, 4); |
522 | frame->data_length = INT16_AT(data, 6); | 520 | frame->data_length = INT16_AT(data, 6); |
523 | frame->data = data + PROTOCOL_BUFFER_OFFSET; | 521 | frame->data = (uint8_t *)(data + PROTOCOL_BUFFER_OFFSET); |
524 | frame->friendnumber = *((uint32_t*)sender_uc); | 522 | frame->friendnumber = *((uint32_t*)sender_uc); |
525 | printf("Got protocol frame magic 0x%x type 0x%x from friend %d\n", frame->magic, frame->packet_type, frame->friendnumber); | 523 | fprintf(stderr, "Got protocol frame magic 0x%x type 0x%x from friend %d\n", frame->magic, frame->packet_type, frame->friendnumber); |
526 | 524 | ||
527 | if(len < frame->data_length + PROTOCOL_BUFFER_OFFSET) | 525 | if(len < frame->data_length + PROTOCOL_BUFFER_OFFSET) |
528 | { | 526 | { |
@@ -652,12 +650,13 @@ void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *d | |||
652 | int32_t friendnumber; | 650 | int32_t friendnumber; |
653 | int32_t *friendnumber_ptr = NULL; | 651 | int32_t *friendnumber_ptr = NULL; |
654 | 652 | ||
655 | printf("Got friend request\n"); | 653 | fprintf(stderr, "Got friend request\n"); |
656 | 654 | ||
657 | friendnumber = tox_add_friend_norequest(tox, public_key); | 655 | friendnumber = tox_add_friend_norequest(tox, public_key); |
658 | 656 | ||
657 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); | ||
659 | id_to_string(tox_printable_id, public_key); | 658 | id_to_string(tox_printable_id, public_key); |
660 | printf("Accepted friend request from %s as %d\n", tox_printable_id, friendnumber); | 659 | fprintf(stderr, "Accepted friend request from %s as %d\n", tox_printable_id, friendnumber); |
661 | 660 | ||
662 | /* TODO: this is not freed right now, we're leaking 4 bytes per contact (OMG!) */ | 661 | /* TODO: this is not freed right now, we're leaking 4 bytes per contact (OMG!) */ |
663 | friendnumber_ptr = malloc(sizeof(int32_t)); | 662 | friendnumber_ptr = malloc(sizeof(int32_t)); |
@@ -674,7 +673,7 @@ void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *d | |||
674 | 673 | ||
675 | void cleanup(int status, void *tmp) | 674 | void cleanup(int status, void *tmp) |
676 | { | 675 | { |
677 | printf("kthxbye\n"); | 676 | fprintf(stderr, "kthxbye\n"); |
678 | fflush(stdout); | 677 | fflush(stdout); |
679 | tox_kill(tox); | 678 | tox_kill(tox); |
680 | if(client_socket) | 679 | if(client_socket) |
@@ -738,7 +737,7 @@ int do_server_loop() | |||
738 | char data[PROTOCOL_BUFFER_OFFSET]; | 737 | char data[PROTOCOL_BUFFER_OFFSET]; |
739 | protocol_frame frame_st, *frame; | 738 | protocol_frame frame_st, *frame; |
740 | 739 | ||
741 | printf("conn closed!\n"); | 740 | fprintf(stderr, "conn closed!\n"); |
742 | 741 | ||
743 | frame = &frame_st; | 742 | frame = &frame_st; |
744 | memset(frame, 0, sizeof(protocol_frame)); | 743 | memset(frame, 0, sizeof(protocol_frame)); |
@@ -750,7 +749,6 @@ int do_server_loop() | |||
750 | 749 | ||
751 | tunnel_delete(tun); | 750 | tunnel_delete(tun); |
752 | 751 | ||
753 | /* TODO remove tunnel? resume connection? */ | ||
754 | continue; | 752 | continue; |
755 | } | 753 | } |
756 | else | 754 | else |
@@ -787,7 +785,7 @@ int main(int argc, char *argv[]) | |||
787 | unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1]; | 785 | unsigned char tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1]; |
788 | int oc; | 786 | int oc; |
789 | 787 | ||
790 | while ((oc = getopt(argc, argv, "L:pi:C:")) != -1) | 788 | while ((oc = getopt(argc, argv, "L:pi:C:P:")) != -1) |
791 | { | 789 | { |
792 | switch(oc) | 790 | switch(oc) |
793 | { | 791 | { |
@@ -806,8 +804,12 @@ int main(int argc, char *argv[]) | |||
806 | /* Pipe forwarding */ | 804 | /* Pipe forwarding */ |
807 | client_mode = 1; | 805 | client_mode = 1; |
808 | client_pipe_mode = 1; | 806 | client_pipe_mode = 1; |
809 | remote_port = atoi(optarg); | 807 | if(parse_pipe_port_forward(optarg, &remote_host, &remote_port) < 0) |
810 | fprintf(stderr, "Forwarding remote port %d\n", remote_port); | 808 | { |
809 | fprintf(stderr, "Invalid value for -P option - use something like -P 127.0.0.1:22\n"); | ||
810 | exit(1); | ||
811 | } | ||
812 | fprintf(stderr, "Forwarding remote port %d to stdin/out\n", remote_port); | ||
811 | break; | 813 | break; |
812 | case 'p': | 814 | case 'p': |
813 | /* Ping */ | 815 | /* Ping */ |
@@ -868,7 +870,7 @@ int main(int argc, char *argv[]) | |||
868 | tox_get_address(tox, tox_id); | 870 | tox_get_address(tox, tox_id); |
869 | id_to_string(tox_printable_id, tox_id); | 871 | id_to_string(tox_printable_id, tox_id); |
870 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; | 872 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; |
871 | printf("Generated Tox ID: %s\n", tox_printable_id); | 873 | fprintf(stderr, "Generated Tox ID: %s\n", tox_printable_id); |
872 | 874 | ||
873 | if(!remote_tox_id) | 875 | if(!remote_tox_id) |
874 | { | 876 | { |
@@ -888,9 +890,10 @@ int main(int argc, char *argv[]) | |||
888 | } | 890 | } |
889 | 891 | ||
890 | tox_get_address(tox, tox_id); | 892 | tox_get_address(tox, tox_id); |
893 | memset(tox_printable_id, '\0', sizeof(tox_printable_id)); | ||
891 | id_to_string(tox_printable_id, tox_id); | 894 | id_to_string(tox_printable_id, tox_id); |
892 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; | 895 | tox_printable_id[TOX_FRIEND_ADDRESS_SIZE * 2] = '\0'; |
893 | printf("Using Tox ID: %s\n", tox_printable_id); | 896 | fprintf(stderr, "Using Tox ID: %s\n", tox_printable_id); |
894 | 897 | ||
895 | tox_callback_friend_request(tox, accept_friend_request, NULL); | 898 | tox_callback_friend_request(tox, accept_friend_request, NULL); |
896 | do_server_loop(); | 899 | do_server_loop(); |