diff options
Diffstat (limited to 'proxy.c')
-rw-r--r-- | proxy.c | 67 |
1 files changed, 38 insertions, 29 deletions
@@ -61,7 +61,7 @@ int g_self_pipe[2]; | |||
61 | /* So after each bucket wait 1 / OT_BUCKET_COUNT intervals */ | 61 | /* So after each bucket wait 1 / OT_BUCKET_COUNT intervals */ |
62 | #define OT_SYNC_SLEEP ( ( ( OT_SYNC_INTERVAL_MINUTES ) * 60 * 1000000 ) / ( OT_BUCKET_COUNT ) ) | 62 | #define OT_SYNC_SLEEP ( ( ( OT_SYNC_INTERVAL_MINUTES ) * 60 * 1000000 ) / ( OT_BUCKET_COUNT ) ) |
63 | 63 | ||
64 | enum { OT_SYNC_PEER }; | 64 | enum { OT_SYNC_PEER4, OT_SYNC_PEER6 }; |
65 | enum { FLAG_SERVERSOCKET = 1 }; | 65 | enum { FLAG_SERVERSOCKET = 1 }; |
66 | 66 | ||
67 | /* For incoming packets */ | 67 | /* For incoming packets */ |
@@ -120,13 +120,15 @@ void livesync_bind_mcast( ot_ip6 ip, uint16_t port) { | |||
120 | socket_mcloop4(g_socket_out, 1); | 120 | socket_mcloop4(g_socket_out, 1); |
121 | } | 121 | } |
122 | 122 | ||
123 | size_t add_peer_to_torrent_proxy( ot_hash hash, ot_peer *peer ) { | 123 | size_t add_peer_to_torrent_proxy( ot_hash hash, ot_peer *peer, size_t peer_size ) { |
124 | int exactmatch; | 124 | int exactmatch; |
125 | ot_torrent *torrent; | 125 | ot_torrent *torrent; |
126 | ot_peer *peer_dest; | 126 | ot_peerlist *peer_list; |
127 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 127 | ot_peer *peer_dest; |
128 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | ||
129 | size_t compare_size = OT_PEER_COMPARE_SIZE_FROM_PEER_SIZE(peer_size); | ||
128 | 130 | ||
129 | torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 131 | torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), compare_size, &exactmatch ); |
130 | if( !torrent ) | 132 | if( !torrent ) |
131 | return -1; | 133 | return -1; |
132 | 134 | ||
@@ -134,43 +136,47 @@ size_t add_peer_to_torrent_proxy( ot_hash hash, ot_peer *peer ) { | |||
134 | /* Create a new torrent entry, then */ | 136 | /* Create a new torrent entry, then */ |
135 | memcpy( torrent->hash, hash, sizeof(ot_hash) ); | 137 | memcpy( torrent->hash, hash, sizeof(ot_hash) ); |
136 | 138 | ||
137 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { | 139 | if( !( torrent->peer_list6 = malloc( sizeof (ot_peerlist) ) ) || |
140 | !( torrent->peer_list4 = malloc( sizeof (ot_peerlist) ) ) ) { | ||
138 | vector_remove_torrent( torrents_list, torrent ); | 141 | vector_remove_torrent( torrents_list, torrent ); |
139 | mutex_bucket_unlock_by_hash( hash, 0 ); | 142 | mutex_bucket_unlock_by_hash( hash, 0 ); |
140 | return -1; | 143 | return -1; |
141 | } | 144 | } |
142 | 145 | ||
143 | byte_zero( torrent->peer_list, sizeof( ot_peerlist ) ); | 146 | byte_zero( torrent->peer_list6, sizeof( ot_peerlist ) ); |
147 | byte_zero( torrent->peer_list4, sizeof( ot_peerlist ) ); | ||
144 | } | 148 | } |
145 | 149 | ||
150 | peer_list = peer_size == OT_PEER_SIZE6 ? torrent->peer_list6 : torrent->peer_list4; | ||
151 | |||
146 | /* Check for peer in torrent */ | 152 | /* Check for peer in torrent */ |
147 | peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), peer, &exactmatch ); | 153 | peer_dest = vector_find_or_insert_peer( &(peer_list->peers), peer, peer_size, &exactmatch ); |
148 | if( !peer_dest ) { | 154 | if( !peer_dest ) { |
149 | mutex_bucket_unlock_by_hash( hash, 0 ); | 155 | mutex_bucket_unlock_by_hash( hash, 0 ); |
150 | return -1; | 156 | return -1; |
151 | } | 157 | } |
152 | /* Tell peer that it's fresh */ | 158 | /* Tell peer that it's fresh */ |
153 | OT_PEERTIME( peer ) = 0; | 159 | OT_PEERTIME( peer, peer_size ) = 0; |
154 | 160 | ||
155 | /* If we hadn't had a match create peer there */ | 161 | /* If we hadn't had a match create peer there */ |
156 | if( !exactmatch ) { | 162 | if( !exactmatch ) { |
157 | torrent->peer_list->peer_count++; | 163 | peer_list->peer_count++; |
158 | if( OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) | 164 | if( OT_PEERFLAG_D(peer, peer_size) & PEER_FLAG_SEEDING ) |
159 | torrent->peer_list->seed_count++; | 165 | peer_list->seed_count++; |
160 | } | 166 | } |
161 | memcpy( peer_dest, peer, sizeof(ot_peer) ); | 167 | memcpy( peer_dest, peer, peer_size ); |
162 | mutex_bucket_unlock_by_hash( hash, 0 ); | 168 | mutex_bucket_unlock_by_hash( hash, 0 ); |
163 | return 0; | 169 | return 0; |
164 | } | 170 | } |
165 | 171 | ||
166 | size_t remove_peer_from_torrent_proxy( ot_hash hash, ot_peer *peer ) { | 172 | size_t remove_peer_from_torrent_proxy( ot_hash hash, ot_peer *peer, size_t peer_size ) { |
167 | int exactmatch; | 173 | int exactmatch; |
168 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 174 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); |
169 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 175 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
170 | 176 | ||
171 | if( exactmatch ) { | 177 | if( exactmatch ) { |
172 | ot_peerlist *peer_list = torrent->peer_list; | 178 | ot_peerlist *peer_list = peer_list = peer_size == OT_PEER_SIZE6 ? torrent->peer_list6 : torrent->peer_list4; |
173 | switch( vector_remove_peer( &peer_list->peers, peer ) ) { | 179 | switch( vector_remove_peer( &peer_list->peers, peer, peer_size ) ) { |
174 | case 2: peer_list->seed_count--; /* Intentional fallthrough */ | 180 | case 2: peer_list->seed_count--; /* Intentional fallthrough */ |
175 | case 1: peer_list->peer_count--; /* Intentional fallthrough */ | 181 | case 1: peer_list->peer_count--; /* Intentional fallthrough */ |
176 | default: break; | 182 | default: break; |
@@ -194,21 +200,21 @@ void free_peerlist( ot_peerlist *peer_list ) { | |||
194 | free( peer_list ); | 200 | free( peer_list ); |
195 | } | 201 | } |
196 | 202 | ||
197 | static void livesync_handle_peersync( ssize_t datalen ) { | 203 | static void livesync_handle_peersync( ssize_t datalen, size_t peer_size ) { |
198 | int off = sizeof( g_tracker_id ) + sizeof( uint32_t ); | 204 | int off = sizeof( g_tracker_id ) + sizeof( uint32_t ); |
199 | 205 | ||
200 | fprintf( stderr, "." ); | 206 | fprintf( stderr, "." ); |
201 | 207 | ||
202 | while( off + (ssize_t)sizeof( ot_hash ) + (ssize_t)sizeof( ot_peer ) <= datalen ) { | 208 | while( (ssize_t)(off + sizeof( ot_hash ) + peer_size) <= datalen ) { |
203 | ot_peer *peer = (ot_peer*)(g_inbuffer + off + sizeof(ot_hash)); | 209 | ot_peer *peer = (ot_peer*)(g_inbuffer + off + sizeof(ot_hash)); |
204 | ot_hash *hash = (ot_hash*)(g_inbuffer + off); | 210 | ot_hash *hash = (ot_hash*)(g_inbuffer + off); |
205 | 211 | ||
206 | if( OT_PEERFLAG(peer) & PEER_FLAG_STOPPED ) | 212 | if( OT_PEERFLAG_D(peer, peer_size) & PEER_FLAG_STOPPED ) |
207 | remove_peer_from_torrent_proxy( *hash, peer ); | 213 | remove_peer_from_torrent_proxy( *hash, peer, peer_size ); |
208 | else | 214 | else |
209 | add_peer_to_torrent_proxy( *hash, peer ); | 215 | add_peer_to_torrent_proxy( *hash, peer, peer_size ); |
210 | 216 | ||
211 | off += sizeof( ot_hash ) + sizeof( ot_peer ); | 217 | off += sizeof( ot_hash ) + peer_size; |
212 | } | 218 | } |
213 | } | 219 | } |
214 | 220 | ||
@@ -469,7 +475,7 @@ static void server_mainloop() { | |||
469 | int64 sock; | 475 | int64 sock; |
470 | 476 | ||
471 | /* inlined livesync_init() */ | 477 | /* inlined livesync_init() */ |
472 | memset( g_peerbuffer_start, 0, sizeof( g_peerbuffer_start ) ); | 478 | memset( g_peerbuffer_start, 0, sizeof( g_peerbuffer_start ) ); |
473 | g_peerbuffer_pos = g_peerbuffer_start; | 479 | g_peerbuffer_pos = g_peerbuffer_start; |
474 | memcpy( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); | 480 | memcpy( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); |
475 | uint32_pack_big( (char*)g_peerbuffer_pos + sizeof( g_tracker_id ), OT_SYNC_PEER); | 481 | uint32_pack_big( (char*)g_peerbuffer_pos + sizeof( g_tracker_id ), OT_SYNC_PEER); |
@@ -477,7 +483,7 @@ static void server_mainloop() { | |||
477 | g_next_packet_time = time(NULL) + LIVESYNC_MAXDELAY; | 483 | g_next_packet_time = time(NULL) + LIVESYNC_MAXDELAY; |
478 | 484 | ||
479 | while(1) { | 485 | while(1) { |
480 | /* See, if we need to connect to anyone */ | 486 | /* See if we need to connect to anyone */ |
481 | if( time(NULL) > g_connection_reconn ) | 487 | if( time(NULL) > g_connection_reconn ) |
482 | handle_reconnects( ); | 488 | handle_reconnects( ); |
483 | 489 | ||
@@ -834,9 +840,12 @@ static void * livesync_worker( void * args ) { | |||
834 | /* drop packet coming from ourselves */ | 840 | /* drop packet coming from ourselves */ |
835 | continue; | 841 | continue; |
836 | } | 842 | } |
837 | switch( uint32_read_big( sizeof( g_tracker_id ) + (char*)g_inbuffer ) ) { | 843 | switch( uint32_read_big( (char*)g_inbuffer + sizeof( g_tracker_id ) ) ) { |
838 | case OT_SYNC_PEER: | 844 | case OT_SYNC_PEER4: |
839 | livesync_handle_peersync( datalen ); | 845 | livesync_handle_peersync( datalen, OT_PEER_SIZE4 ); |
846 | break; | ||
847 | case OT_SYNC_PEER6: | ||
848 | livesync_handle_peersync( datalen, OT_PEER_SIZE6 ); | ||
840 | break; | 849 | break; |
841 | default: | 850 | default: |
842 | // fprintf( stderr, "Received an unknown live sync packet type %u.\n", uint32_read_big( sizeof( g_tracker_id ) + (char*)g_inbuffer ) ); | 851 | // fprintf( stderr, "Received an unknown live sync packet type %u.\n", uint32_read_big( sizeof( g_tracker_id ) + (char*)g_inbuffer ) ); |