diff options
Diffstat (limited to 'proxy.c')
| -rw-r--r-- | proxy.c | 81 |
1 files changed, 24 insertions, 57 deletions
| @@ -7,38 +7,33 @@ | |||
| 7 | #include <arpa/inet.h> | 7 | #include <arpa/inet.h> |
| 8 | #include <ctype.h> | 8 | #include <ctype.h> |
| 9 | #include <errno.h> | 9 | #include <errno.h> |
| 10 | #include <fcntl.h> | ||
| 11 | #include <pthread.h> | 10 | #include <pthread.h> |
| 12 | #include <stdint.h> | 11 | #include <stdint.h> |
| 13 | #include <stdio.h> | 12 | #include <stdio.h> |
| 14 | #include <stdlib.h> | 13 | #include <stdlib.h> |
| 15 | #include <string.h> | 14 | #include <string.h> |
| 16 | #include <sys/socket.h> | ||
| 17 | #include <unistd.h> | 15 | #include <unistd.h> |
| 18 | 16 | ||
| 19 | /* Libowfat */ | 17 | /* Libowfat */ |
| 20 | #include "io.h" | 18 | #include "io.h" |
| 21 | #include "iob.h" | 19 | #include "iob.h" |
| 22 | #include "socket.h" | ||
| 23 | 20 | ||
| 24 | /* Opentracker */ | 21 | /* Opentracker */ |
| 25 | #include "ot_ip.h" | 22 | #include "ot_ip.h" |
| 26 | #include "ot_mutex.h" | 23 | #include "ot_mutex.h" |
| 27 | #include "ot_random.h" | 24 | #include "ot_random.h" |
| 28 | #include "ot_scan.h" | 25 | #include "ot_scan.h" |
| 26 | #include "ot_socket.h" | ||
| 29 | #include "ot_stats.h" | 27 | #include "ot_stats.h" |
| 30 | #include "ot_vector.h" | 28 | #include "ot_vector.h" |
| 31 | #include "trackerlogic.h" | 29 | #include "trackerlogic.h" |
| 32 | 30 | ||
| 33 | #ifndef WANT_SYNC_LIVE | ||
| 34 | #define WANT_SYNC_LIVE | ||
| 35 | #endif | ||
| 36 | #include "ot_livesync.h" | 31 | #include "ot_livesync.h" |
| 37 | 32 | ||
| 38 | ot_ip6 g_serverip; | 33 | ot_ip6 g_serverip; |
| 39 | uint16_t g_serverport = 9009; | 34 | uint16_t g_serverport = 9009; |
| 40 | uint32_t g_tracker_id; | 35 | uint32_t g_tracker_id; |
| 41 | char groupip_1[4] = {224, 0, 23, 5}; | 36 | ot_ip6 groupip_1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 224, 0, 23, 5}; |
| 42 | int g_self_pipe[2]; | 37 | int g_self_pipe[2]; |
| 43 | 38 | ||
| 44 | /* If you have more than 10 peers, don't use this proxy | 39 | /* If you have more than 10 peers, don't use this proxy |
| @@ -63,11 +58,11 @@ enum { OT_SYNC_PEER4, OT_SYNC_PEER6 }; | |||
| 63 | enum { FLAG_SERVERSOCKET = 1 }; | 58 | enum { FLAG_SERVERSOCKET = 1 }; |
| 64 | 59 | ||
| 65 | /* For incoming packets */ | 60 | /* For incoming packets */ |
| 66 | static int64 g_socket_in = -1; | 61 | static int g_socket_in = -1; |
| 67 | static uint8_t g_inbuffer[LIVESYNC_INCOMING_BUFFSIZE]; | 62 | static uint8_t g_inbuffer[LIVESYNC_INCOMING_BUFFSIZE]; |
| 68 | 63 | ||
| 69 | /* For outgoing packets */ | 64 | /* For outgoing packets */ |
| 70 | static int64 g_socket_out = -1; | 65 | static int g_socket_out = -1; |
| 71 | static uint8_t g_peerbuffer_start[LIVESYNC_OUTGOING_BUFFSIZE_PEERS]; | 66 | static uint8_t g_peerbuffer_start[LIVESYNC_OUTGOING_BUFFSIZE_PEERS]; |
| 72 | static uint8_t *g_peerbuffer_pos; | 67 | static uint8_t *g_peerbuffer_pos; |
| 73 | static uint8_t *g_peerbuffer_highwater = g_peerbuffer_start + LIVESYNC_OUTGOING_BUFFSIZE_PEERS - LIVESYNC_OUTGOING_WATERMARK_PEERS; | 68 | static uint8_t *g_peerbuffer_highwater = g_peerbuffer_start + LIVESYNC_OUTGOING_BUFFSIZE_PEERS - LIVESYNC_OUTGOING_WATERMARK_PEERS; |
| @@ -89,34 +84,17 @@ void stats_issue_event(ot_status_event event, PROTO_FLAG proto, uintptr_t event_ | |||
| 89 | } | 84 | } |
| 90 | 85 | ||
| 91 | void livesync_bind_mcast(ot_ip6 ip, uint16_t port) { | 86 | void livesync_bind_mcast(ot_ip6 ip, uint16_t port) { |
| 92 | char tmpip[4] = {0, 0, 0, 0}; | ||
| 93 | char *v4ip; | ||
| 94 | |||
| 95 | if (!ip_is_v4mapped(ip)) | 87 | if (!ip_is_v4mapped(ip)) |
| 96 | exerr("v6 mcast support not yet available."); | 88 | exerr("v6 mcast support not yet available."); |
| 97 | v4ip = ip + 12; | ||
| 98 | 89 | ||
| 99 | if (g_socket_in != -1) | 90 | if (g_socket_in != -1) |
| 100 | exerr("Error: Livesync listen ip specified twice."); | 91 | exerr("Error: Livesync listen ip specified twice."); |
| 101 | 92 | ||
| 102 | if ((g_socket_in = socket_udp4()) < 0) | 93 | if ((g_socket_in = socket_mcast_join(groupip_1, ip, port)) == -1) |
| 103 | exerr("Error: Cant create live sync incoming socket."); | ||
| 104 | |||
| 105 | fcntl(g_socket_in, F_SETFL, fcntl(g_socket_in, F_GETFL, 0) & ~O_NONBLOCK); | ||
| 106 | |||
| 107 | if (socket_bind4_reuse(g_socket_in, tmpip, port) == -1) | ||
| 108 | exerr("Error: Cant bind live sync incoming socket."); | 94 | exerr("Error: Cant bind live sync incoming socket."); |
| 109 | 95 | ||
| 110 | if (socket_mcjoin4(g_socket_in, groupip_1, v4ip)) | 96 | if ((g_socket_out = socket_mcast_bind(ip, port, 1)) == -1) |
| 111 | exerr("Error: Cant make live sync incoming socket join mcast group."); | ||
| 112 | |||
| 113 | if ((g_socket_out = socket_udp4()) < 0) | ||
| 114 | exerr("Error: Cant create live sync outgoing socket."); | ||
| 115 | if (socket_bind4_reuse(g_socket_out, v4ip, port) == -1) | ||
| 116 | exerr("Error: Cant bind live sync outgoing socket."); | 97 | exerr("Error: Cant bind live sync outgoing socket."); |
| 117 | |||
| 118 | socket_mcttl4(g_socket_out, 1); | ||
| 119 | socket_mcloop4(g_socket_out, 1); | ||
| 120 | } | 98 | } |
| 121 | 99 | ||
| 122 | size_t add_peer_to_torrent_proxy(ot_hash hash, ot_peer *peer, size_t peer_size) { | 100 | size_t add_peer_to_torrent_proxy(ot_hash hash, ot_peer *peer, size_t peer_size) { |
| @@ -249,7 +227,7 @@ typedef struct { | |||
| 249 | uint8_t indata[8192 * 16]; /* Any data not processed yet */ | 227 | uint8_t indata[8192 * 16]; /* Any data not processed yet */ |
| 250 | size_t indata_length; /* Length of unprocessed data */ | 228 | size_t indata_length; /* Length of unprocessed data */ |
| 251 | uint32_t tracker_id; /* How the other end greeted */ | 229 | uint32_t tracker_id; /* How the other end greeted */ |
| 252 | int64 fd; /* A file handle, if connected, <= 0 is disconnected (0 initially, -1 else) */ | 230 | int64_t fd; /* A file handle, if connected, <= 0 is disconnected (0 initially, -1 else) */ |
| 253 | io_batch outdata; /* The iobatch containing our sync data */ | 231 | io_batch outdata; /* The iobatch containing our sync data */ |
| 254 | 232 | ||
| 255 | size_t packet_tcount; /* Number of unprocessed torrents in packet we currently receive */ | 233 | size_t packet_tcount; /* Number of unprocessed torrents in packet we currently receive */ |
| @@ -283,19 +261,11 @@ static void handle_reconnects(void) { | |||
| 283 | size_t i; | 261 | size_t i; |
| 284 | for (i = 0; i < g_connection_count; ++i) | 262 | for (i = 0; i < g_connection_count; ++i) |
| 285 | if (PROXYPEER_NEEDSCONNECT(g_connections[i].state)) { | 263 | if (PROXYPEER_NEEDSCONNECT(g_connections[i].state)) { |
| 286 | int64 newfd = socket_tcp6(); | 264 | int64_t newfd = socket_tcp_connect(g_serverip, g_serverport, g_connections[i].ip, g_connections[i].port); |
| 287 | fprintf(stderr, "(Re)connecting to peer..."); | 265 | fprintf(stderr, "(Re)connecting to peer..."); |
| 288 | if (newfd < 0) | 266 | if (newfd == -1) |
| 289 | continue; /* No socket for you */ | 267 | continue; /* No socket for you */ |
| 290 | io_fd(newfd); | 268 | io_fd(newfd); |
| 291 | if (socket_bind6_reuse(newfd, g_serverip, g_serverport, 0)) { | ||
| 292 | io_close(newfd); | ||
| 293 | continue; | ||
| 294 | } | ||
| 295 | if (socket_connect6(newfd, g_connections[i].ip, g_connections[i].port, 0) == -1 && errno != EINPROGRESS && errno != EWOULDBLOCK) { | ||
| 296 | close(newfd); | ||
| 297 | continue; | ||
| 298 | } | ||
| 299 | io_wantwrite(newfd); /* So we will be informed when it is connected */ | 269 | io_wantwrite(newfd); /* So we will be informed when it is connected */ |
| 300 | io_setcookie(newfd, g_connections + i); | 270 | io_setcookie(newfd, g_connections + i); |
| 301 | 271 | ||
| @@ -308,12 +278,12 @@ static void handle_reconnects(void) { | |||
| 308 | } | 278 | } |
| 309 | 279 | ||
| 310 | /* Handle incoming connection requests, check against whitelist */ | 280 | /* Handle incoming connection requests, check against whitelist */ |
| 311 | static void handle_accept(int64 serversocket) { | 281 | static void handle_accept(int64_t serversocket) { |
| 312 | int64 newfd; | 282 | int64_t newfd; |
| 313 | ot_ip6 ip; | 283 | ot_ip6 ip; |
| 314 | uint16 port; | 284 | uint16_t port; |
| 315 | 285 | ||
| 316 | while ((newfd = socket_accept6(serversocket, ip, &port, NULL)) != -1) { | 286 | while ((newfd = socket_accept(serversocket, ip, &port)) != -1) { |
| 317 | 287 | ||
| 318 | /* XXX some access control */ | 288 | /* XXX some access control */ |
| 319 | 289 | ||
| @@ -351,9 +321,9 @@ static void handle_accept(int64 serversocket) { | |||
| 351 | } | 321 | } |
| 352 | 322 | ||
| 353 | /* New sync data on the stream */ | 323 | /* New sync data on the stream */ |
| 354 | static void handle_read(int64 peersocket) { | 324 | static void handle_read(int64_t peersocket) { |
| 355 | int i; | 325 | int i; |
| 356 | int64 datalen; | 326 | int64_t datalen; |
| 357 | uint32_t tracker_id; | 327 | uint32_t tracker_id; |
| 358 | proxy_peer *peer = io_getcookie(peersocket); | 328 | proxy_peer *peer = io_getcookie(peersocket); |
| 359 | 329 | ||
| @@ -420,7 +390,7 @@ static void handle_read(int64 peersocket) { | |||
| 420 | } | 390 | } |
| 421 | 391 | ||
| 422 | /* Can write new sync data to the stream */ | 392 | /* Can write new sync data to the stream */ |
| 423 | static void handle_write(int64 peersocket) { | 393 | static void handle_write(int64_t peersocket) { |
| 424 | proxy_peer *peer = io_getcookie(peersocket); | 394 | proxy_peer *peer = io_getcookie(peersocket); |
| 425 | 395 | ||
| 426 | if (!peer) { | 396 | if (!peer) { |
| @@ -436,7 +406,7 @@ static void handle_write(int64 peersocket) { | |||
| 436 | break; | 406 | break; |
| 437 | case FLAG_CONNECTING: | 407 | case FLAG_CONNECTING: |
| 438 | /* Ensure that the connection is established and handle connection error */ | 408 | /* Ensure that the connection is established and handle connection error */ |
| 439 | if (peer->state & FLAG_OUTGOING && !socket_connected(peersocket)) { | 409 | if (peer->state & FLAG_OUTGOING && !socket_is_connected(peersocket)) { |
| 440 | fprintf(stderr, "failed\n"); | 410 | fprintf(stderr, "failed\n"); |
| 441 | reset_info_block(peer); | 411 | reset_info_block(peer); |
| 442 | io_close(peersocket); | 412 | io_close(peersocket); |
| @@ -472,7 +442,7 @@ static void handle_write(int64 peersocket) { | |||
| 472 | } | 442 | } |
| 473 | 443 | ||
| 474 | static void server_mainloop() { | 444 | static void server_mainloop() { |
| 475 | int64 sock; | 445 | int64_t sock; |
| 476 | uint32_t packet_type; | 446 | uint32_t packet_type; |
| 477 | 447 | ||
| 478 | /* inlined livesync_init() */ | 448 | /* inlined livesync_init() */ |
| @@ -515,13 +485,10 @@ static void panic(const char *routine) { | |||
| 515 | } | 485 | } |
| 516 | 486 | ||
| 517 | static int64_t ot_try_bind(ot_ip6 ip, uint16_t port) { | 487 | static int64_t ot_try_bind(ot_ip6 ip, uint16_t port) { |
| 518 | int64 sock = socket_tcp6(); | 488 | int64_t sock = socket_tcp_listen(ip, port); |
| 519 | |||
| 520 | if (socket_bind6_reuse(sock, ip, port, 0) == -1) | ||
| 521 | panic("socket_bind6_reuse"); | ||
| 522 | 489 | ||
| 523 | if (socket_listen(sock, SOMAXCONN) == -1) | 490 | if (sock == -1) |
| 524 | panic("socket_listen"); | 491 | panic("socket_tcp_listen"); |
| 525 | 492 | ||
| 526 | if (!io_fd(sock)) | 493 | if (!io_fd(sock)) |
| 527 | panic("io_fd"); | 494 | panic("io_fd"); |
| @@ -776,7 +743,7 @@ static void *streamsync_worker(void *args) { | |||
| 776 | } | 743 | } |
| 777 | 744 | ||
| 778 | static void livesync_issue_peersync() { | 745 | static void livesync_issue_peersync() { |
| 779 | socket_send4(g_socket_out, (char *)g_peerbuffer_start, g_peerbuffer_pos - g_peerbuffer_start, groupip_1, LIVESYNC_PORT); | 746 | socket_mcast_send(g_socket_out, g_peerbuffer_start, (size_t)(g_peerbuffer_pos - g_peerbuffer_start), groupip_1, LIVESYNC_PORT); |
| 780 | g_peerbuffer_pos = g_peerbuffer_start + sizeof(g_tracker_id) + sizeof(uint32_t); | 747 | g_peerbuffer_pos = g_peerbuffer_start + sizeof(g_tracker_id) + sizeof(uint32_t); |
| 781 | g_next_packet_time = time(NULL) + LIVESYNC_MAXDELAY; | 748 | g_next_packet_time = time(NULL) + LIVESYNC_MAXDELAY; |
| 782 | } | 749 | } |
| @@ -871,7 +838,7 @@ static void *livesync_worker(void *args) { | |||
| 871 | ot_ip6 in_ip; | 838 | ot_ip6 in_ip; |
| 872 | uint16_t in_port; | 839 | uint16_t in_port; |
| 873 | uint32_t packet_type; | 840 | uint32_t packet_type; |
| 874 | size_t datalen = socket_recv4(g_socket_in, (char *)g_inbuffer, LIVESYNC_INCOMING_BUFFSIZE, 12 + (char *)in_ip, &in_port); | 841 | ssize_t datalen = socket_recv(g_socket_in, g_inbuffer, LIVESYNC_INCOMING_BUFFSIZE, in_ip, &in_port); |
| 875 | 842 | ||
| 876 | /* Expect at least tracker id and packet type */ | 843 | /* Expect at least tracker id and packet type */ |
| 877 | if (datalen <= (ssize_t)(sizeof(g_tracker_id) + sizeof(uint32_t))) | 844 | if (datalen <= (ssize_t)(sizeof(g_tracker_id) + sizeof(uint32_t))) |
