summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGDR! <gdr@go2.pl>2014-11-25 23:09:45 +0100
committerGDR! <gdr@go2.pl>2014-11-25 23:09:45 +0100
commit16add85eb81629b07dd7bdb04fbe30be1410cc83 (patch)
treef2cc52d65a2deb0e8c1014f28d9926612c7cf074
parentc311fb3bdd2c26c347c2dd734f97003ac0538037 (diff)
Multi-connection support client-side.
Dealing with congestion control, too
-rw-r--r--client.c221
-rw-r--r--client.h1
-rw-r--r--main.c78
-rw-r--r--main.h8
4 files changed, 213 insertions, 95 deletions
diff --git a/client.c b/client.c
index 190c7e5..75d4b0d 100644
--- a/client.c
+++ b/client.c
@@ -10,6 +10,9 @@ struct timespec ping_sent_time;
10/* Client mode tunnel */ 10/* Client mode tunnel */
11tunnel client_tunnel; 11tunnel client_tunnel;
12 12
13/* Sock representing the local port - call accept() on it */
14int bind_sockfd;
15
13fd_set client_master_fdset; 16fd_set client_master_fdset;
14 17
15int handle_pong_frame(protocol_frame *rcvd_frame) 18int handle_pong_frame(protocol_frame *rcvd_frame)
@@ -31,17 +34,12 @@ int handle_pong_frame(protocol_frame *rcvd_frame)
31 } 34 }
32} 35}
33 36
34int local_bind(tunnel *tun) 37int local_bind()
35{ 38{
36 struct addrinfo hints, *res; 39 struct addrinfo hints, *res;
37 int sockfd;
38 char port[6]; 40 char port[6];
39 int yes = 1; 41 int yes = 1;
40 42 int flags;
41 /* accept() variables - TODO they should not be there */
42 int newfd;
43 struct sockaddr_storage remoteaddr; // client address
44 socklen_t addrlen;
45 43
46 snprintf(port, 6, "%d", local_port); 44 snprintf(port, 6, "%d", local_port);
47 45
@@ -52,69 +50,66 @@ int local_bind(tunnel *tun)
52 50
53 getaddrinfo(NULL, port, &hints, &res); 51 getaddrinfo(NULL, port, &hints, &res);
54 52
55 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 53 bind_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
56 if(sockfd < 0) 54 if(bind_sockfd < 0)
57 { 55 {
58 fprintf(stderr, "Could not create a socket for local listening\n"); 56 fprintf(stderr, "Could not create a socket for local listening: %s\n", strerror(errno));
59 exit(1); 57 exit(1);
60 } 58 }
61 59
62 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); 60 setsockopt(bind_sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
63 61
64 if(bind(sockfd, res->ai_addr, res->ai_addrlen) < 0) 62 /* Set O_NONBLOCK to make accept() non-blocking */
63 if (-1 == (flags = fcntl(bind_sockfd, F_GETFL, 0)))
65 { 64 {
66 fprintf(stderr, "Bind to port %d failed: %s", local_port, strerror(errno)); 65 flags = 0;
67 close(sockfd);
68 exit(1);
69 } 66 }
67 fcntl(bind_sockfd, F_SETFL, flags | O_NONBLOCK);
70 68
71 if(listen(sockfd, 1) < 0) 69 if(bind(bind_sockfd, res->ai_addr, res->ai_addrlen) < 0)
72 { 70 {
73 fprintf(stderr, "Listening on port %d failed: %s", local_port, strerror(errno)); 71 fprintf(stderr, "Bind to port %d failed: %s\n", local_port, strerror(errno));
74 close(sockfd); 72 close(bind_sockfd);
75 exit(1); 73 exit(1);
76 } 74 }
77 75
78 // TODO return sockfd 76 if(listen(bind_sockfd, 1) < 0)
79
80 /* TODO: make a proper accept loop and track tunnels, to handle more than 1 connection */
81 addrlen = sizeof(remoteaddr);
82 newfd = accept(sockfd,
83 (struct sockaddr *)&remoteaddr,
84 &addrlen);
85
86 if(newfd < 0)
87 { 77 {
88 fprintf(stderr, "Error when accepting a local connection: %s\n", strerror(errno)); 78 fprintf(stderr, "Listening on port %d failed: %s\n", local_port, strerror(errno));
89 close(sockfd); 79 close(bind_sockfd);
90 exit(0); 80 exit(1);
91 } 81 }
92 82
93// TODO close(sockfd); 83 fprintf(stderr, "Bound to local port %d\n", local_port);
94
95 return newfd;
96} 84}
97 85
86/* Bind the client.sockfd to a tunnel */
98int handle_acktunnel_frame(protocol_frame *rcvd_frame) 87int handle_acktunnel_frame(protocol_frame *rcvd_frame)
99{ 88{
89 tunnel *tun;
90
100 if(!client_mode) 91 if(!client_mode)
101 { 92 {
102 fprintf(stderr, "Got ACK tunnel frame when not in client mode!?\n"); 93 fprintf(stderr, "Got ACK tunnel frame when not in client mode!?\n");
103 return -1; 94 return -1;
104 } 95 }
105 96
106 client_tunnel.connid = rcvd_frame->connid; 97 tun = tunnel_create(
107 client_tunnel.friendnumber = rcvd_frame->friendnumber; 98 client_tunnel.sockfd,
108 // TODO open local port and fill client_tunnel.sockfd 99 rcvd_frame->connid,
109 printf("New tunnel ID: %d\n", client_tunnel.connid); 100 rcvd_frame->friendnumber
101 );
102
103 /* Mark that we can accept() another connection */
104 client_tunnel.sockfd = -1;
105
106 printf("New tunnel ID: %d\n", tun->connid);
110 107
111 if(client_local_port_mode) 108 if(client_local_port_mode)
112 { 109 {
113 client_tunnel.sockfd = local_bind(&client_tunnel); 110 update_select_nfds(tun->sockfd);
114 update_select_nfds(client_tunnel.sockfd); 111 FD_SET(tun->sockfd, &client_master_fdset);
115 FD_SET(client_tunnel.sockfd, &client_master_fdset); 112 fprintf(stderr, "Accepted a new connection on port %d\n", local_port);
116 fprintf(stderr, "Accepting connections on port %d\n", local_port);
117 state = CLIENT_STATE_FORWARDING;
118 } 113 }
119 else 114 else
120 { 115 {
@@ -126,9 +121,17 @@ int handle_acktunnel_frame(protocol_frame *rcvd_frame)
126/* Handle a TCP frame received from server */ 121/* Handle a TCP frame received from server */
127int handle_server_tcp_frame(protocol_frame *rcvd_frame) 122int handle_server_tcp_frame(protocol_frame *rcvd_frame)
128{ 123{
129 /* TODO find tunnel basing on ID */
130 int offset = 0; 124 int offset = 0;
131 tunnel *tun = &client_tunnel; 125 tunnel *tun = NULL;
126 int tun_id = rcvd_frame->connid;
127
128 HASH_FIND_INT(by_id, &tun_id, tun);
129
130 if(!tun)
131 {
132 fprintf(stderr, "Got TCP frame with unknown tunnel ID %d\n", rcvd_frame->connid);
133 return -1;
134 }
132 135
133 while(offset < rcvd_frame->data_length) 136 while(offset < rcvd_frame->data_length)
134 { 137 {
@@ -143,13 +146,27 @@ int handle_server_tcp_frame(protocol_frame *rcvd_frame)
143 146
144 if(sent_bytes < 0) 147 if(sent_bytes < 0)
145 { 148 {
149 char data[PROTOCOL_BUFFER_OFFSET];
150 protocol_frame frame_st, *frame;
151
146 fprintf(stderr, "Could not write to socket %d: %s\n", tun->sockfd, strerror(errno)); 152 fprintf(stderr, "Could not write to socket %d: %s\n", tun->sockfd, strerror(errno));
153
154 frame = &frame_st;
155 memset(frame, 0, sizeof(protocol_frame));
156 frame->friendnumber = tun->friendnumber;
157 frame->packet_type = PACKET_TYPE_TCP_FIN;
158 frame->connid = tun->connid;
159 frame->data_length = 0;
160 send_frame(frame, data);
161 tunnel_delete(tun);
162
147 return -1; 163 return -1;
148 } 164 }
149 165
150 offset += sent_bytes; 166 offset += sent_bytes;
151 } 167 }
152 168
169 printf("Got %d bytes from server - wrote to fd %d\n", rcvd_frame->data_length, tun->sockfd);
153 170
154 return 0; 171 return 0;
155} 172}
@@ -172,6 +189,12 @@ int do_client_loop(char *tox_id_str)
172 exit(1); 189 exit(1);
173 } 190 }
174 191
192 if(!ping_mode) /* TODO handle pipe mode */
193 {
194 local_bind();
195 signal(SIGPIPE, SIG_IGN);
196 }
197
175 fprintf(stderr, "Connecting to Tox...\n"); 198 fprintf(stderr, "Connecting to Tox...\n");
176 199
177 while(1) 200 while(1)
@@ -232,7 +255,7 @@ int do_client_loop(char *tox_id_str)
232 } 255 }
233 else 256 else
234 { 257 {
235 state = CLIENT_STATE_REQUEST_TUNNEL; 258 state = CLIENT_STATE_BIND_PORT;
236 } 259 }
237 break; 260 break;
238 case CLIENT_STATE_SEND_PING: 261 case CLIENT_STATE_SEND_PING:
@@ -256,9 +279,21 @@ int do_client_loop(char *tox_id_str)
256 case CLIENT_STATE_PING_SENT: 279 case CLIENT_STATE_PING_SENT:
257 /* Just sit there and wait for pong */ 280 /* Just sit there and wait for pong */
258 break; 281 break;
282
283 case CLIENT_STATE_BIND_PORT:
284 if(bind_sockfd < 0)
285 {
286 fprintf(stderr, "Shutting down - could not bind to listening port\n");
287 state = CLIENT_STATE_SHUTDOWN;
288 }
289 else
290 {
291 state = CLIENT_STATE_FORWARDING;
292 }
293 break;
259 case CLIENT_STATE_REQUEST_TUNNEL: 294 case CLIENT_STATE_REQUEST_TUNNEL:
260 send_tunnel_request_packet( 295 send_tunnel_request_packet(
261 "127.0.0.1", 296 remote_host,
262 remote_port, 297 remote_port,
263 friendnumber 298 friendnumber
264 ); 299 );
@@ -268,49 +303,73 @@ int do_client_loop(char *tox_id_str)
268 break; 303 break;
269 case CLIENT_STATE_FORWARDING: 304 case CLIENT_STATE_FORWARDING:
270 { 305 {
306 int accept_fd = 0;
307 tunnel *tmp = NULL;
308 tunnel *tun = NULL;
309
271 tv.tv_sec = 0; 310 tv.tv_sec = 0;
272 tv.tv_usec = 20000; 311 tv.tv_usec = 20000;
273 fds = client_master_fdset; 312 fds = client_master_fdset;
274
275 select(select_nfds, &fds, NULL, NULL, &tv);
276 313
277 if(FD_ISSET(client_tunnel.sockfd, &fds)) 314 /* Handle accepting new connections */
315 if(client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */
278 { 316 {
279 int nbytes = recv(client_tunnel.sockfd, 317 accept_fd = accept(bind_sockfd, NULL, NULL);
280 tox_packet_buf + PROTOCOL_BUFFER_OFFSET, 318 if(accept_fd != -1)
281 READ_BUFFER_SIZE, 0);
282
283 /* Check if connection closed */
284 if(nbytes == 0)
285 { 319 {
286 char data[PROTOCOL_BUFFER_OFFSET]; 320 fprintf(stderr, "Accepting a new connection - requesting tunnel...\n");
287 protocol_frame frame_st, *frame; 321
288 322 /* Open a new tunnel for this FD */
289 fprintf(stderr, "Connection closed\n"); 323 client_tunnel.sockfd = accept_fd;
290 324 send_tunnel_request_packet(
291 frame = &frame_st; 325 remote_host,
292 memset(frame, 0, sizeof(protocol_frame)); 326 remote_port,
293 frame->friendnumber = client_tunnel.friendnumber; 327 friendnumber
294 frame->packet_type = PACKET_TYPE_TCP_FIN; 328 );
295 frame->connid = client_tunnel.connid;
296 frame->data_length = 0;
297 send_frame(frame, data);
298
299 state = CLIENT_STATE_SHUTDOWN;
300
301// exit(1); // TODO handle it in a smarter way (accept() again?)
302 } 329 }
303 else 330 }
331
332 /* Handle reading from sockets */
333 select(select_nfds, &fds, NULL, NULL, &tv);
334 HASH_ITER(hh, by_id, tun, tmp)
335 {
336 if(FD_ISSET(tun->sockfd, &fds))
304 { 337 {
305 protocol_frame frame_st, *frame; 338 int nbytes = recv(tun->sockfd,
306 339 tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
307 frame = &frame_st; 340 READ_BUFFER_SIZE, 0);
308 memset(frame, 0, sizeof(protocol_frame)); 341
309 frame->friendnumber = client_tunnel.friendnumber; 342 /* Check if connection closed */
310 frame->packet_type = PACKET_TYPE_TCP; 343 if(nbytes == 0)
311 frame->connid = client_tunnel.connid; 344 {
312 frame->data_length = nbytes; 345 char data[PROTOCOL_BUFFER_OFFSET];
313 send_frame(frame, tox_packet_buf); 346 protocol_frame frame_st, *frame;
347
348 fprintf(stderr, "Connection closed\n");
349
350 frame = &frame_st;
351 memset(frame, 0, sizeof(protocol_frame));
352 frame->friendnumber = tun->friendnumber;
353 frame->packet_type = PACKET_TYPE_TCP_FIN;
354 frame->connid = tun->connid;
355 frame->data_length = 0;
356 send_frame(frame, data);
357 tunnel_delete(tun);
358 }
359 else
360 {
361 protocol_frame frame_st, *frame;
362
363 frame = &frame_st;
364 memset(frame, 0, sizeof(protocol_frame));
365 frame->friendnumber = tun->friendnumber;
366 frame->packet_type = PACKET_TYPE_TCP;
367 frame->connid = tun->connid;
368 frame->data_length = nbytes;
369 send_frame(frame, tox_packet_buf);
370
371 printf("Wrote %d bytes from sock %d to tunnel %d\n", nbytes, tun->sockfd, tun->connid);
372 }
314 } 373 }
315 } 374 }
316 375
diff --git a/client.h b/client.h
index bcbb205..7d5e50d 100644
--- a/client.h
+++ b/client.h
@@ -11,6 +11,7 @@
11#define CLIENT_STATE_WAIT_FOR_ACKTUNNEL 9 11#define CLIENT_STATE_WAIT_FOR_ACKTUNNEL 9
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 15
15int handle_pong_frame(protocol_frame *rcvd_frame); 16int handle_pong_frame(protocol_frame *rcvd_frame);
16int handle_acktunnel_frame(protocol_frame *rcvd_frame); 17int handle_acktunnel_frame(protocol_frame *rcvd_frame);
diff --git a/main.c b/main.c
index 77ef128..c3444ee 100644
--- a/main.c
+++ b/main.c
@@ -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 */
11int client_mode = 0; 11int client_mode = 0;
12
12/* Just send a ping and exit */ 13/* Just send a ping and exit */
13int ping_mode = 0; 14int ping_mode = 0;
15
14/* Open a local port and forward it */ 16/* Open a local port and forward it */
15int client_local_port_mode = 0; 17int 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 */
17int client_pipe_mode = 0; 20int client_pipe_mode = 0;
21
18/* Remote Tox ID in client mode */ 22/* Remote Tox ID in client mode */
19char *remote_tox_id = NULL; 23char *remote_tox_id = NULL;
24
20/* Ports and hostname for port forwarding */ 25/* Ports and hostname for port forwarding */
21int remote_port = 0; 26int remote_port = 0;
22char *remote_host = NULL; 27char *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" */
28tunnel *by_id = NULL; 33tunnel *by_id = NULL;
29tunnel *by_fd = NULL;
30 34
31/* Highest used fd + 1 for select() */ 35/* Highest used fd + 1 for select() */
32int select_nfds = 4; 36int 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. */
65static tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber) 69tunnel *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
86static void tunnel_delete(tunnel *t) 92void 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 */
217int send_frame(protocol_frame *frame, uint8_t *data) 226int 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 */
diff --git a/main.h b/main.h
index 4f2187d..ba0a6d0 100644
--- a/main.h
+++ b/main.h
@@ -3,8 +3,10 @@
3 3
4#include <arpa/inet.h> 4#include <arpa/inet.h>
5#include <errno.h> 5#include <errno.h>
6#include <fcntl.h>
6#include <netdb.h> 7#include <netdb.h>
7#include <netinet/in.h> 8#include <netinet/in.h>
9#include <signal.h>
8#include <stdio.h> 10#include <stdio.h>
9#include <stdlib.h> 11#include <stdlib.h>
10#include <string.h> 12#include <string.h>
@@ -18,7 +20,6 @@
18#include "util.h" 20#include "util.h"
19#include "uthash.h" 21#include "uthash.h"
20 22
21#define READ_BUFFER_SIZE 1024
22 23
23#define PROTOCOL_MAGIC_V1 0xa26a 24#define PROTOCOL_MAGIC_V1 0xa26a
24#define PROTOCOL_MAGIC PROTOCOL_MAGIC_V1 25#define PROTOCOL_MAGIC PROTOCOL_MAGIC_V1
@@ -37,8 +38,10 @@
37 38
38/* Offset of the data buffer in the packet */ 39/* Offset of the data buffer in the packet */
39#define PROTOCOL_BUFFER_OFFSET 8 40#define PROTOCOL_BUFFER_OFFSET 8
41#define READ_BUFFER_SIZE TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET
40#define PROTOCOL_MAX_PACKET_SIZE (READ_BUFFER_SIZE + PROTOCOL_BUFFER_OFFSET) 42#define PROTOCOL_MAX_PACKET_SIZE (READ_BUFFER_SIZE + PROTOCOL_BUFFER_OFFSET)
41 43
44
42typedef struct tunnel_t { 45typedef struct tunnel_t {
43 /* The forwarded socket fd */ 46 /* The forwarded socket fd */
44 int sockfd; 47 int sockfd;
@@ -80,6 +83,9 @@ extern char *remote_host;
80extern int local_port; 83extern int local_port;
81 84
82extern int select_nfds; 85extern int select_nfds;
86extern tunnel *by_id;
83 87
84int parse_lossless_packet(void *sender_uc, const uint8_t *data, uint32_t len); 88int parse_lossless_packet(void *sender_uc, const uint8_t *data, uint32_t len);
89tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber);
90void tunnel_delete(tunnel *t);
85#endif 91#endif