diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 78 |
1 files changed, 65 insertions, 13 deletions
@@ -9,14 +9,19 @@ int client_socket = 0; | |||
9 | /** CONFIGURATION OPTIONS **/ | 9 | /** CONFIGURATION OPTIONS **/ |
10 | /* Whether we're a client */ | 10 | /* Whether we're a client */ |
11 | int client_mode = 0; | 11 | int client_mode = 0; |
12 | |||
12 | /* Just send a ping and exit */ | 13 | /* Just send a ping and exit */ |
13 | int ping_mode = 0; | 14 | int ping_mode = 0; |
15 | |||
14 | /* Open a local port and forward it */ | 16 | /* Open a local port and forward it */ |
15 | int client_local_port_mode = 0; | 17 | int client_local_port_mode = 0; |
18 | |||
16 | /* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */ | 19 | /* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */ |
17 | int client_pipe_mode = 0; | 20 | int client_pipe_mode = 0; |
21 | |||
18 | /* Remote Tox ID in client mode */ | 22 | /* Remote Tox ID in client mode */ |
19 | char *remote_tox_id = NULL; | 23 | char *remote_tox_id = NULL; |
24 | |||
20 | /* Ports and hostname for port forwarding */ | 25 | /* Ports and hostname for port forwarding */ |
21 | int remote_port = 0; | 26 | int remote_port = 0; |
22 | char *remote_host = NULL; | 27 | char *remote_host = NULL; |
@@ -26,7 +31,6 @@ fd_set master_server_fds; | |||
26 | 31 | ||
27 | /* We keep two hash tables: one indexed by sockfd and another by "connection id" */ | 32 | /* We keep two hash tables: one indexed by sockfd and another by "connection id" */ |
28 | tunnel *by_id = NULL; | 33 | tunnel *by_id = NULL; |
29 | tunnel *by_fd = NULL; | ||
30 | 34 | ||
31 | /* Highest used fd + 1 for select() */ | 35 | /* Highest used fd + 1 for select() */ |
32 | int select_nfds = 4; | 36 | int select_nfds = 4; |
@@ -62,7 +66,7 @@ void update_select_nfds(int fd) | |||
62 | } | 66 | } |
63 | 67 | ||
64 | /* Constructor. Returns NULL on failure. */ | 68 | /* Constructor. Returns NULL on failure. */ |
65 | static tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) | 69 | tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) |
66 | { | 70 | { |
67 | tunnel *t = NULL; | 71 | tunnel *t = NULL; |
68 | 72 | ||
@@ -76,6 +80,8 @@ static tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) | |||
76 | t->connid = connid; | 80 | t->connid = connid; |
77 | t->friendnumber = friendnumber; | 81 | t->friendnumber = friendnumber; |
78 | 82 | ||
83 | fprintf(stderr, "Created a new tunnel object connid=%d sockfd=%d\n", connid, sockfd); | ||
84 | |||
79 | update_select_nfds(t->sockfd); | 85 | update_select_nfds(t->sockfd); |
80 | 86 | ||
81 | HASH_ADD_INT( by_id, connid, t ); | 87 | HASH_ADD_INT( by_id, connid, t ); |
@@ -83,7 +89,7 @@ static tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) | |||
83 | return t; | 89 | return t; |
84 | } | 90 | } |
85 | 91 | ||
86 | static void tunnel_delete(tunnel *t) | 92 | void tunnel_delete(tunnel *t) |
87 | { | 93 | { |
88 | printf("Deleting tunnel #%d\n", t->connid); | 94 | printf("Deleting tunnel #%d\n", t->connid); |
89 | if(t->sockfd) | 95 | if(t->sockfd) |
@@ -167,7 +173,7 @@ int get_client_socket(char *hostname, int port) | |||
167 | snprintf(port_str, 6, "%d", port); | 173 | snprintf(port_str, 6, "%d", port); |
168 | 174 | ||
169 | memset(&hints, 0, sizeof hints); | 175 | memset(&hints, 0, sizeof hints); |
170 | hints.ai_family = AF_UNSPEC; | 176 | hints.ai_family = AF_INET; |
171 | hints.ai_socktype = SOCK_STREAM; | 177 | hints.ai_socktype = SOCK_STREAM; |
172 | 178 | ||
173 | if ((rv = getaddrinfo(hostname, port_str, &hints, &servinfo)) != 0) { | 179 | if ((rv = getaddrinfo(hostname, port_str, &hints, &servinfo)) != 0) { |
@@ -177,6 +183,9 @@ int get_client_socket(char *hostname, int port) | |||
177 | 183 | ||
178 | // loop through all the results and connect to the first we can | 184 | // loop through all the results and connect to the first we can |
179 | for(p = servinfo; p != NULL; p = p->ai_next) { | 185 | for(p = servinfo; p != NULL; p = p->ai_next) { |
186 | if (p->ai_family != AF_INET && p->ai_family != AF_INET6) | ||
187 | continue; | ||
188 | |||
180 | if ((sockfd = socket(p->ai_family, p->ai_socktype, | 189 | if ((sockfd = socket(p->ai_family, p->ai_socktype, |
181 | p->ai_protocol)) == -1) { | 190 | p->ai_protocol)) == -1) { |
182 | perror("client: socket"); | 191 | perror("client: socket"); |
@@ -216,7 +225,8 @@ int get_client_socket(char *hostname, int port) | |||
216 | */ | 225 | */ |
217 | int send_frame(protocol_frame *frame, uint8_t *data) | 226 | int send_frame(protocol_frame *frame, uint8_t *data) |
218 | { | 227 | { |
219 | int rv; | 228 | int rv = -1; |
229 | int i; | ||
220 | 230 | ||
221 | data[0] = PROTOCOL_MAGIC_HIGH; | 231 | data[0] = PROTOCOL_MAGIC_HIGH; |
222 | data[1] = PROTOCOL_MAGIC_LOW; | 232 | data[1] = PROTOCOL_MAGIC_LOW; |
@@ -227,16 +237,40 @@ int send_frame(protocol_frame *frame, uint8_t *data) | |||
227 | data[6] = BYTE2(frame->data_length); | 237 | data[6] = BYTE2(frame->data_length); |
228 | data[7] = BYTE1(frame->data_length); | 238 | data[7] = BYTE1(frame->data_length); |
229 | 239 | ||
230 | rv = tox_send_lossless_packet( | 240 | for(i = 0; i < 17;) |
231 | tox, | 241 | { |
232 | frame->friendnumber, | 242 | int j; |
233 | data, | 243 | |
234 | frame->data_length + PROTOCOL_BUFFER_OFFSET | 244 | rv = tox_send_lossless_packet( |
235 | ); | 245 | tox, |
246 | frame->friendnumber, | ||
247 | data, | ||
248 | frame->data_length + PROTOCOL_BUFFER_OFFSET | ||
249 | ); | ||
236 | 250 | ||
237 | if(rv < 0) | 251 | if(rv < 0) |
252 | { | ||
253 | /* If this branch is ran, most likely we've hit congestion control. */ | ||
254 | fprintf(stderr, "[%d] Failed to send packet to friend %d\n", i, frame->friendnumber); | ||
255 | } | ||
256 | else | ||
257 | { | ||
258 | break; | ||
259 | } | ||
260 | |||
261 | if(i == 0) i = 2; | ||
262 | else i = i * 2; | ||
263 | |||
264 | for(j = 0; j < i; j++) | ||
265 | { | ||
266 | tox_do(tox); | ||
267 | usleep(j * 10000); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | if(i > 0 && rv >= 0) | ||
238 | { | 272 | { |
239 | fprintf(stderr, "Failed to send packet to friend %d\n", frame->friendnumber); | 273 | fprintf(stderr, "Packet succeeded at try %d", i+1); |
240 | } | 274 | } |
241 | 275 | ||
242 | return rv; | 276 | return rv; |
@@ -570,6 +604,7 @@ int do_server_loop() | |||
570 | unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE]; | 604 | unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE]; |
571 | tunnel *tun = NULL; | 605 | tunnel *tun = NULL; |
572 | tunnel *tmp = NULL; | 606 | tunnel *tmp = NULL; |
607 | int connected = 0; | ||
573 | 608 | ||
574 | tv.tv_sec = 0; | 609 | tv.tv_sec = 0; |
575 | tv.tv_usec = 20000; | 610 | tv.tv_usec = 20000; |
@@ -578,9 +613,26 @@ int do_server_loop() | |||
578 | 613 | ||
579 | while(1) | 614 | while(1) |
580 | { | 615 | { |
616 | int tmp_isconnected = 0; | ||
617 | |||
581 | /* Let tox do its stuff */ | 618 | /* Let tox do its stuff */ |
582 | tox_do(tox); | 619 | tox_do(tox); |
583 | 620 | ||
621 | /* Check change in connection state */ | ||
622 | tmp_isconnected = tox_isconnected(tox); | ||
623 | if(tmp_isconnected != connected) | ||
624 | { | ||
625 | connected = tmp_isconnected; | ||
626 | if(connected) | ||
627 | { | ||
628 | fprintf(stderr, "Connected to Tox network\n"); | ||
629 | } | ||
630 | else | ||
631 | { | ||
632 | fprintf(stderr, "Disconnected from Tox network\n"); | ||
633 | } | ||
634 | } | ||
635 | |||
584 | fds = master_server_fds; | 636 | fds = master_server_fds; |
585 | 637 | ||
586 | /* Poll for data from our client connection */ | 638 | /* Poll for data from our client connection */ |