summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2020-08-21 12:47:29 -0400
committerAndrew Cady <d@jerkface.net>2020-08-21 12:47:29 -0400
commitf2153aebaacc67e59311738f74f5b6f3b76347cf (patch)
tree0db6d671bef6737e8271c86ba2084757ea6738bd
parent127d2c239bb4c8d156154c5fb87e082ef22ed5a4 (diff)
represent program mode as a single enum
-rw-r--r--client.c87
-rw-r--r--main.c163
-rw-r--r--main.h20
3 files changed, 127 insertions, 143 deletions
diff --git a/client.c b/client.c
index 67d4fd3..0ce1cb0 100644
--- a/client.c
+++ b/client.c
@@ -35,7 +35,7 @@ int handle_pong_frame()
35 35
36 log_printf(L_INFO, "GOT PONG! Time = %.3fs\n", secs2-secs1); 36 log_printf(L_INFO, "GOT PONG! Time = %.3fs\n", secs2-secs1);
37 37
38 if(ping_mode) 38 if(program_mode == Mode_Client_Ping)
39 { 39 {
40 state = CLIENT_STATE_SHUTDOWN; 40 state = CLIENT_STATE_SHUTDOWN;
41 } 41 }
@@ -116,12 +116,24 @@ int local_bind()
116 return 0; 116 return 0;
117} 117}
118 118
119bool tunnel_client_mode()
120{
121 switch (program_mode) {
122 case Mode_Client_Local_Port_Forward:
123 case Mode_Client_Pipe:
124 return true;
125 case Mode_Client_Ping:
126 default:
127 return false;
128 }
129}
130
119/* Bind the client.sockfd to a tunnel */ 131/* Bind the client.sockfd to a tunnel */
120int handle_acktunnel_frame(protocol_frame *rcvd_frame) 132int handle_acktunnel_frame(protocol_frame *rcvd_frame)
121{ 133{
122 tunnel *tun; 134 tunnel *tun;
123 135
124 if(!client_mode) 136 if(!tunnel_client_mode())
125 { 137 {
126 log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n"); 138 log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n");
127 return -1; 139 return -1;
@@ -136,23 +148,12 @@ int handle_acktunnel_frame(protocol_frame *rcvd_frame)
136 /* Mark that we can accept() another connection */ 148 /* Mark that we can accept() another connection */
137 client_tunnel.sockfd = -1; 149 client_tunnel.sockfd = -1;
138 150
139// printf("New tunnel ID: %d\n", tun->connid); 151 update_select_nfds(tun->sockfd);
140 152 FD_SET(tun->sockfd, &client_master_fdset);
141 if(client_local_port_mode || client_pipe_mode) 153 if(program_mode == Mode_Client_Local_Port_Forward)
142 { 154 {
143 update_select_nfds(tun->sockfd); 155 log_printf(L_INFO, "Accepted a new connection on port %d\n", local_port);
144 FD_SET(tun->sockfd, &client_master_fdset);
145 if(client_local_port_mode)
146 {
147 log_printf(L_INFO, "Accepted a new connection on port %d\n", local_port);
148 }
149 } 156 }
150 else
151 {
152 log_printf(L_ERROR, "This tunnel mode is not supported yet\n");
153 exit(1);
154 }
155
156 return 0; 157 return 0;
157} 158}
158 159
@@ -175,25 +176,18 @@ int handle_server_tcp_frame(protocol_frame *rcvd_frame)
175 { 176 {
176 int sent_bytes; 177 int sent_bytes;
177 178
178 if(client_pipe_mode) 179 switch (program_mode) {
179 { 180 case Mode_Client_Pipe:
180 sent_bytes = write( 181 sent_bytes = write(1, rcvd_frame->data + offset, rcvd_frame->data_length - offset);
181 1, /* STDOUT */ 182 break;
182 rcvd_frame->data + offset, 183 case Mode_Client_Local_Port_Forward:
183 rcvd_frame->data_length - offset 184 sent_bytes = send(tun->sockfd, rcvd_frame->data + offset, rcvd_frame->data_length - offset, MSG_NOSIGNAL);
184 ); 185 break;
185 } 186 default:
186 else 187 log_printf(L_ERROR, "BUG: Impossible client mode at %s:%s", __FILE__, __LINE__);
187 { 188 return -1;
188 sent_bytes = send(
189 tun->sockfd,
190 rcvd_frame->data + offset,
191 rcvd_frame->data_length - offset,
192 MSG_NOSIGNAL
193 );
194 } 189 }
195 190
196
197 if(sent_bytes < 0) 191 if(sent_bytes < 0)
198 { 192 {
199 uint8_t data[PROTOCOL_BUFFER_OFFSET]; 193 uint8_t data[PROTOCOL_BUFFER_OFFSET];
@@ -296,7 +290,7 @@ int do_client_loop(uint8_t *tox_id_str)
296 exit(1); 290 exit(1);
297 } 291 }
298 292
299 if(!ping_mode && !client_pipe_mode) 293 if(program_mode == Mode_Client_Local_Port_Forward)
300 { 294 {
301 local_bind(); 295 local_bind();
302 signal(SIGPIPE, SIG_IGN); 296 signal(SIGPIPE, SIG_IGN);
@@ -400,17 +394,19 @@ int do_client_loop(uint8_t *tox_id_str)
400 break; 394 break;
401 } 395 }
402 case CLIENT_STATE_REQUEST_ACCEPTED: 396 case CLIENT_STATE_REQUEST_ACCEPTED:
403 if(ping_mode) 397 switch (program_mode) {
404 { 398 case Mode_Client_Ping:
405 state = CLIENT_STATE_SEND_PING; 399 state = CLIENT_STATE_SEND_PING;
406 } 400 break;
407 else if(client_pipe_mode) 401 case Mode_Client_Pipe:
408 {
409 state = CLIENT_STATE_SETUP_PIPE; 402 state = CLIENT_STATE_SETUP_PIPE;
410 } 403 break;
411 else 404 case Mode_Client_Local_Port_Forward:
412 {
413 state = CLIENT_STATE_BIND_PORT; 405 state = CLIENT_STATE_BIND_PORT;
406 break;
407 default:
408 log_printf(L_ERROR, "BUG: Impossible client mode at %s:%s", __FILE__, __LINE__);
409 exit(1);
414 } 410 }
415 break; 411 break;
416 case CLIENT_STATE_SEND_PING: 412 case CLIENT_STATE_SEND_PING:
@@ -490,8 +486,7 @@ int do_client_loop(uint8_t *tox_id_str)
490 fds = client_master_fdset; 486 fds = client_master_fdset;
491 487
492 /* Handle accepting new connections */ 488 /* Handle accepting new connections */
493 if(!client_pipe_mode && 489 if(program_mode != Mode_Client_Ping && client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */
494 client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */
495 { 490 {
496 accept_fd = accept(bind_sockfd, NULL, NULL); 491 accept_fd = accept(bind_sockfd, NULL, NULL);
497 if(accept_fd != -1) 492 if(accept_fd != -1)
@@ -529,7 +524,7 @@ int do_client_loop(uint8_t *tox_id_str)
529 if(FD_ISSET(tun->sockfd, &fds)) 524 if(FD_ISSET(tun->sockfd, &fds))
530 { 525 {
531 int nbytes; 526 int nbytes;
532 if(client_local_port_mode) 527 if(program_mode == Mode_Client_Local_Port_Forward)
533 { 528 {
534 nbytes = recv(tun->sockfd, 529 nbytes = recv(tun->sockfd,
535 tox_packet_buf + PROTOCOL_BUFFER_OFFSET, 530 tox_packet_buf + PROTOCOL_BUFFER_OFFSET,
diff --git a/main.c b/main.c
index 7e38022..8d00a62 100644
--- a/main.c
+++ b/main.c
@@ -3,6 +3,8 @@
3#include "tox_bootstrap.h" 3#include "tox_bootstrap.h"
4#include "log.h" 4#include "log.h"
5 5
6#define LOG_IP_ADDRESS
7
6#ifdef __MACH__ 8#ifdef __MACH__
7 #include "mach.h" 9 #include "mach.h"
8#endif 10#endif
@@ -14,19 +16,12 @@ TOX_CONNECTION connection_status = TOX_CONNECTION_NONE;
14TOX_CONNECTION friend_connection_status = TOX_CONNECTION_NONE; 16TOX_CONNECTION friend_connection_status = TOX_CONNECTION_NONE;
15/** CONFIGURATION OPTIONS **/ 17/** CONFIGURATION OPTIONS **/
16/* Whether we're a client */ 18/* Whether we're a client */
17int client_mode = 0; 19
18 20
19/* Don't bootstrap nodes */ 21/* Don't bootstrap nodes */
20int skip_bootstrap = 1; 22int skip_bootstrap = 1;
21 23
22/* Just send a ping and exit */ 24enum Mode program_mode = Mode_Unspecified;
23int ping_mode = 0;
24
25/* Open a local port and forward it */
26int client_local_port_mode = 0;
27
28/* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */
29int client_pipe_mode = 0;
30 25
31/* Remote Tox ID in client mode */ 26/* Remote Tox ID in client mode */
32uint8_t *remote_tox_id = NULL; 27uint8_t *remote_tox_id = NULL;
@@ -39,7 +34,7 @@ long int udp_start_port = 0;
39long int udp_end_port = 0; 34long int udp_end_port = 0;
40 35
41/* Directory with config and tox save */ 36/* Directory with config and tox save */
42char config_path[500] = "/etc/tuntox/"; 37char *config_path = "/etc/tuntox/";
43 38
44/* Limit hostname and port in server */ 39/* Limit hostname and port in server */
45int tunnel_target_whitelist_size = 0; 40int tunnel_target_whitelist_size = 0;
@@ -68,7 +63,7 @@ char shared_secret[TOX_MAX_FRIEND_REQUEST_LENGTH];
68int server_whitelist_mode = 0; 63int server_whitelist_mode = 0;
69allowed_toxid *allowed_toxids = NULL; 64allowed_toxid *allowed_toxids = NULL;
70 65
71int load_saved_toxid_in_client_mode = 0; 66bool config_path_modified = false;
72 67
73fd_set master_server_fds; 68fd_set master_server_fds;
74 69
@@ -452,9 +447,9 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame)
452 int sockfd = 0; 447 int sockfd = 0;
453 uint16_t tunnel_id; 448 uint16_t tunnel_id;
454 449
455 if(client_mode) 450 if(program_mode != Mode_Server)
456 { 451 {
457 log_printf(L_WARNING, "Got tunnel request frame from friend #%d when in client mode\n", rcvd_frame->friendnumber); 452 log_printf(L_WARNING, "Got tunnel request frame from friend #%d but not in server mode\n", rcvd_frame->friendnumber);
458 return -1; 453 return -1;
459 } 454 }
460 455
@@ -592,15 +587,9 @@ int handle_frame(protocol_frame *frame)
592 return handle_pong_frame(frame); 587 return handle_pong_frame(frame);
593 break; 588 break;
594 case PACKET_TYPE_TCP: 589 case PACKET_TYPE_TCP:
595 if(client_mode) 590 return program_mode != Mode_Server
596 { 591 ? handle_server_tcp_frame(frame)
597 return handle_server_tcp_frame(frame); 592 : handle_client_tcp_frame(frame);
598 }
599 else
600 {
601 return handle_client_tcp_frame(frame);
602 }
603 break;
604 case PACKET_TYPE_REQUESTTUNNEL: 593 case PACKET_TYPE_REQUESTTUNNEL:
605 handle_request_tunnel_frame(frame); 594 handle_request_tunnel_frame(frame);
606 break; 595 break;
@@ -608,15 +597,9 @@ int handle_frame(protocol_frame *frame)
608 handle_acktunnel_frame(frame); 597 handle_acktunnel_frame(frame);
609 break; 598 break;
610 case PACKET_TYPE_TCP_FIN: 599 case PACKET_TYPE_TCP_FIN:
611 if(client_mode) 600 return program_mode != Mode_Server
612 { 601 ? handle_server_tcp_fin_frame(frame)
613 return handle_server_tcp_fin_frame(frame); 602 : handle_client_tcp_fin_frame(frame);
614 }
615 else
616 {
617 return handle_client_tcp_fin_frame(frame);
618 }
619 break;
620 default: 603 default:
621 log_printf(L_DEBUG, "Got unknown packet type 0x%x from friend %d\n", 604 log_printf(L_DEBUG, "Got unknown packet type 0x%x from friend %d\n",
622 frame->packet_type, 605 frame->packet_type,
@@ -672,14 +655,16 @@ void parse_lossless_packet(Tox *tox, uint32_t friendnumber, const uint8_t *data,
672 655
673 if(len < (size_t)frame->data_length + PROTOCOL_BUFFER_OFFSET) 656 if(len < (size_t)frame->data_length + PROTOCOL_BUFFER_OFFSET)
674 { 657 {
675 log_printf(L_WARNING, "Received frame too small (attempted buffer overflow?): %d bytes, excepted at least %d bytes\n", len, frame->data_length + PROTOCOL_BUFFER_OFFSET); 658 log_printf(L_WARNING, "Received frame too small (attempted buffer overflow?): %d bytes, excepted at least %d bytes\n",
659 len, frame->data_length + PROTOCOL_BUFFER_OFFSET);
676 free(frame); 660 free(frame);
677 return; 661 return;
678 } 662 }
679 663
680 if(frame->data_length > (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)) 664 if(frame->data_length > (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET))
681 { 665 {
682 log_printf(L_WARNING, "Declared data length too big (attempted buffer overflow?): %d bytes, excepted at most %d bytes\n", frame->data_length, (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)); 666 log_printf(L_WARNING, "Declared data length too big (attempted buffer overflow?): %d bytes, excepted at most %d bytes\n",
667 frame->data_length, (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET));
683 free(frame); 668 free(frame);
684 return; 669 return;
685 } 670 }
@@ -772,12 +757,13 @@ static size_t load_save(uint8_t **out_data)
772{ 757{
773 void *data; 758 void *data;
774 uint32_t size; 759 uint32_t size;
775 uint8_t path_real[512], *p; 760 uint8_t path_real[PATH_MAX], *p;
776 761
777 strncpy((char *)path_real, config_path, sizeof(path_real)); 762 strncpy((char *)path_real, config_path, sizeof(path_real));
778 763
779 p = path_real + strlen((char *)path_real); 764 p = path_real + strlen((char *)path_real);
780 memcpy(p, "tox_save", sizeof("tox_save")); 765 char basename[] = "/tox_save";
766 memcpy(p, "/tox_save", sizeof(basename));
781 767
782 data = file_raw((char *)path_real, &size); 768 data = file_raw((char *)path_real, &size);
783 769
@@ -857,7 +843,7 @@ void tunnel_target_whitelist_load()
857 } 843 }
858 fclose(file); 844 fclose(file);
859 845
860 log_printf(L_INFO, "Loaded %d rules\n", tunnel_target_whitelist_size); 846 log_printf(L_INFO, "Loaded %d rule%s\n", tunnel_target_whitelist_size, tunnel_target_whitelist_size == 1 ? "" : "s");
861 if (tunnel_target_whitelist_size == 0 && tunnel_target_whitelist_enforced){ 847 if (tunnel_target_whitelist_size == 0 && tunnel_target_whitelist_enforced){
862 log_printf(L_WARNING, "No rules loaded! NO CONNECTIONS WILL BE ALLOWED!\n"); 848 log_printf(L_WARNING, "No rules loaded! NO CONNECTIONS WILL BE ALLOWED!\n");
863 } 849 }
@@ -969,7 +955,7 @@ void handle_friend_connection_status(Tox *tox, uint32_t friend_number, TOX_CONNE
969 if(connection_status == TOX_CONNECTION_UDP) 955 if(connection_status == TOX_CONNECTION_UDP)
970 log_friend_ip_address(tox, friend_number); 956 log_friend_ip_address(tox, friend_number);
971#endif 957#endif
972 if(client_mode) 958 if(program_mode != Mode_Server)
973 { 959 {
974 friend_connection_status = connection_status; 960 friend_connection_status = connection_status;
975 } 961 }
@@ -1306,29 +1292,22 @@ int main(int argc, char *argv[])
1306 1292
1307 log_init(); 1293 log_init();
1308 1294
1309 while ((oc = getopt(argc, argv, "L:pi:C:s:f:W:dqhSF:DU:t:u:")) != -1) 1295 while ((oc = getopt(argc, argv, "L:pi:C:s:f:W:vdqhSF:DU:t:u:")) != -1)
1310 { 1296 {
1311 switch(oc) 1297 switch(oc)
1312 { 1298 {
1313 case 'L': 1299 case 'L':
1314 /* Local port forwarding */ 1300 /* Local port forwarding */
1315 client_mode = 1; 1301 program_mode = Mode_Client_Local_Port_Forward;
1316 client_local_port_mode = 1;
1317 if(!parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port)) 1302 if(!parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port))
1318 { 1303 {
1319 log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n"); 1304 log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n");
1320 exit(1); 1305 exit(1);
1321 } 1306 }
1322 if(min_log_level == L_UNSET)
1323 {
1324 min_log_level = L_INFO;
1325 }
1326 log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port);
1327 break; 1307 break;
1328 case 'W': 1308 case 'W':
1329 /* Pipe forwarding */ 1309 /* Pipe forwarding */
1330 client_mode = 1; 1310 program_mode = Mode_Client_Pipe;
1331 client_pipe_mode = 1;
1332 if(!parse_pipe_port_forward(optarg, &remote_host, &remote_port) || remote_port == 0) 1311 if(!parse_pipe_port_forward(optarg, &remote_host, &remote_port) || remote_port == 0)
1333 { 1312 {
1334 log_printf(L_ERROR, "Invalid value for -W option - use something like -W 127.0.0.1:22\n"); 1313 log_printf(L_ERROR, "Invalid value for -W option - use something like -W 127.0.0.1:22\n");
@@ -1338,12 +1317,10 @@ int main(int argc, char *argv[])
1338 { 1317 {
1339 min_log_level = L_ERROR; 1318 min_log_level = L_ERROR;
1340 } 1319 }
1341 log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port);
1342 break; 1320 break;
1343 case 'p': 1321 case 'p':
1344 /* Ping */ 1322 /* Ping */
1345 client_mode = 1; 1323 program_mode = Mode_Client_Ping;
1346 ping_mode = 1;
1347 if(min_log_level == L_UNSET) 1324 if(min_log_level == L_UNSET)
1348 { 1325 {
1349 min_log_level = L_INFO; 1326 min_log_level = L_INFO;
@@ -1368,20 +1345,12 @@ int main(int argc, char *argv[])
1368 break; 1345 break;
1369 case 'C': 1346 case 'C':
1370 /* Config directory */ 1347 /* Config directory */
1371 strncpy(config_path, optarg, sizeof(config_path) - 1); 1348 config_path = strdup(optarg);
1372 if(optarg[strlen(optarg) - 1] != '/') 1349 config_path_modified = 1;
1373 {
1374 int optarg_len = strlen(optarg);
1375
1376 config_path[optarg_len] = '/';
1377 config_path[optarg_len + 1] = '\0';
1378 }
1379 load_saved_toxid_in_client_mode = 1;
1380 break; 1350 break;
1381 case 'f': 1351 case 'f':
1382 tunnel_target_whitelist_file = strdup(optarg); 1352 tunnel_target_whitelist_file = strdup(optarg);
1383 tunnel_target_whitelist_enforced = true; 1353 tunnel_target_whitelist_enforced = true;
1384 log_printf(L_INFO, "Whitelist enforced on outgoing connections: only matched hosts/ports will be allowed.\n");
1385 break; 1354 break;
1386 case 's': 1355 case 's':
1387 /* Shared secret */ 1356 /* Shared secret */
@@ -1389,6 +1358,7 @@ int main(int argc, char *argv[])
1389 memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH); 1358 memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH);
1390 strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1); 1359 strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1);
1391 break; 1360 break;
1361 case 'v':
1392 case 'd': 1362 case 'd':
1393 switch(++verbosity) 1363 switch(++verbosity)
1394 { 1364 {
@@ -1425,8 +1395,8 @@ int main(int argc, char *argv[])
1425 tcp_relay_port = strtol(optarg, NULL, 10); 1395 tcp_relay_port = strtol(optarg, NULL, 10);
1426 if(errno != 0 || tcp_relay_port < 0 || tcp_relay_port > 65535) 1396 if(errno != 0 || tcp_relay_port < 0 || tcp_relay_port > 65535)
1427 { 1397 {
1428 tcp_relay_port = 1024 + (rand() % 64511); 1398 tcp_relay_port = 1024 + (rand() % 64511);
1429 log_printf(L_WARNING, "Ignored -t %s: TCP port number needs to be a number between 0 and 65535."); 1399 log_printf(L_WARNING, "Ignored -t %s: TCP port number needs to be a number between 0 and 65535.");
1430 } 1400 }
1431 break; 1401 break;
1432 case 'u': 1402 case 'u':
@@ -1465,25 +1435,44 @@ int main(int argc, char *argv[])
1465 } 1435 }
1466 } 1436 }
1467 1437
1468 if(!client_mode && min_log_level == L_UNSET) 1438 switch (program_mode) {
1469 { 1439 case Mode_Client_Local_Port_Forward:
1470 min_log_level = L_INFO; 1440 case Mode_Client_Pipe:
1471 } 1441 case Mode_Client_Ping:
1472 1442 if(!remote_tox_id)
1473 if(client_mode && !remote_tox_id) 1443 {
1474 { 1444 log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n");
1475 log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n"); 1445 exit(1);
1476 exit(1); 1446 }
1477 } 1447 break;
1478 1448 case Mode_Unspecified:
1479 if(!client_mode && server_whitelist_mode) 1449 program_mode = Mode_Server;
1480 { 1450 case Mode_Server:
1481 log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); 1451 break;
1482 } 1452 }
1483 1453
1484 if(!client_mode && tunnel_target_whitelist_enforced) 1454 switch (program_mode) {
1485 { 1455 case Mode_Client_Local_Port_Forward:
1486 tunnel_target_whitelist_load(); 1456 log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port);
1457 break;
1458 case Mode_Client_Pipe:
1459 log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port);
1460 break;
1461 case Mode_Server:
1462 if(min_log_level == L_UNSET)
1463 {
1464 min_log_level = L_INFO;
1465 }
1466 if(tunnel_target_whitelist_enforced)
1467 {
1468 log_printf(L_INFO, "Whitelist enforced on outgoing connections: only matched hosts/ports will be allowed.\n");
1469 tunnel_target_whitelist_load();
1470 }
1471 if(server_whitelist_mode)
1472 {
1473 log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect");
1474 }
1475 default:;
1487 } 1476 }
1488 1477
1489 /* If shared secret has not been provided via -s, read from TUNTOX_SHARED_SECRET env variable */ 1478 /* If shared secret has not been provided via -s, read from TUNTOX_SHARED_SECRET env variable */
@@ -1525,7 +1514,7 @@ int main(int argc, char *argv[])
1525 tox_options.end_port 1514 tox_options.end_port
1526 ); 1515 );
1527 1516
1528 if((!client_mode) || load_saved_toxid_in_client_mode) 1517 if(program_mode == Mode_Server || config_path_modified)
1529 { 1518 {
1530 save_size = load_save(&save_data); 1519 save_size = load_save(&save_data);
1531 if(save_data && save_size) 1520 if(save_data && save_size)
@@ -1564,10 +1553,10 @@ int main(int argc, char *argv[])
1564 tox_callback_self_connection_status(tox, handle_connection_status_change); 1553 tox_callback_self_connection_status(tox, handle_connection_status_change);
1565 tox_callback_friend_connection_status(tox, handle_friend_connection_status); 1554 tox_callback_friend_connection_status(tox, handle_friend_connection_status);
1566 1555
1567 if (!skip_bootstrap) 1556 if(!skip_bootstrap)
1568 do_bootstrap(tox); 1557 do_bootstrap(tox);
1569 1558
1570 if((!client_mode) || load_saved_toxid_in_client_mode) 1559 if(program_mode == Mode_Server || config_path_modified)
1571 { 1560 {
1572 write_save(tox); 1561 write_save(tox);
1573 } 1562 }
@@ -1591,16 +1580,14 @@ int main(int argc, char *argv[])
1591 to_hex(readable_dht_key, dht_key, TOX_PUBLIC_KEY_SIZE); 1580 to_hex(readable_dht_key, dht_key, TOX_PUBLIC_KEY_SIZE);
1592 log_printf(L_DEBUG, "DHT key: %s\n", readable_dht_key); 1581 log_printf(L_DEBUG, "DHT key: %s\n", readable_dht_key);
1593 1582
1594 if (client_mode) 1583 if (program_mode == Mode_Server)
1595 { 1584 {
1596 do_client_loop(remote_tox_id); 1585 tox_callback_friend_request(tox, accept_friend_request);
1586 return do_server_loop();
1597 } 1587 }
1598 else 1588 else
1599 { 1589 {
1600 tox_callback_friend_request(tox, accept_friend_request); 1590 return do_client_loop(remote_tox_id);
1601 do_server_loop();
1602 } 1591 }
1603 } 1592 }
1604
1605 return 0;
1606} 1593}
diff --git a/main.h b/main.h
index b998acc..602f8e4 100644
--- a/main.h
+++ b/main.h
@@ -80,26 +80,28 @@ typedef struct protocol_frame_t {
80} protocol_frame; 80} protocol_frame;
81 81
82/* Rules policy */ 82/* Rules policy */
83enum rules_policy_enum { VALIDATE, NONE };
84typedef struct rule { 83typedef struct rule {
85 uint16_t port; 84 uint16_t port;
86 char * host; 85 char * host;
87 struct rule *next; 86 struct rule *next;
88} rule; 87} rule;
89 88
89enum Mode {
90 Mode_Unspecified,
91 Mode_Server,
92 Mode_Client_Local_Port_Forward,
93 Mode_Client_Pipe,
94 Mode_Client_Ping
95};
96
90/**** GLOBAL VARIABLES ****/ 97/**** GLOBAL VARIABLES ****/
91extern Tox *tox; 98extern Tox *tox;
92/* Whether we're a client */ 99
93extern int client_mode; 100/* Whether we're a server, client, etc. */
94/* Just send a ping and exit */ 101extern enum Mode program_mode;
95extern int ping_mode;
96/* TOX_CONNECTION global variable */ 102/* TOX_CONNECTION global variable */
97extern TOX_CONNECTION connection_status; 103extern TOX_CONNECTION connection_status;
98/* Open a local port and forward it */ 104/* Open a local port and forward it */
99extern int client_local_port_mode;
100/* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */
101extern int client_pipe_mode;
102/* Remote Tox ID in client mode */
103extern uint8_t *remote_tox_id; 105extern uint8_t *remote_tox_id;
104/* Ports and hostname for port forwarding */ 106/* Ports and hostname for port forwarding */
105extern int remote_port; 107extern int remote_port;