diff options
Diffstat (limited to 'trackerlogic.c')
-rw-r--r-- | trackerlogic.c | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/trackerlogic.c b/trackerlogic.c index 5348927..7ae9bb1 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
@@ -71,36 +71,35 @@ void add_torrent_from_saved_state( ot_hash hash, ot_time base, size_t down_count | |||
71 | return mutex_bucket_unlock_by_hash( hash, 1 ); | 71 | return mutex_bucket_unlock_by_hash( hash, 1 ); |
72 | } | 72 | } |
73 | 73 | ||
74 | size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) { | 74 | size_t add_peer_to_torrent_and_return_peers( PROTO_FLAG proto, struct ot_workstruct *ws, size_t amount ) { |
75 | int exactmatch, delta_torrentcount = 0; | 75 | int exactmatch, delta_torrentcount = 0; |
76 | size_t reply_size; | ||
77 | ot_torrent *torrent; | 76 | ot_torrent *torrent; |
78 | ot_peer *peer_dest; | 77 | ot_peer *peer_dest; |
79 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 78 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( *ws->hash ); |
80 | 79 | ||
81 | if( !accesslist_hashisvalid( hash ) ) { | 80 | if( !accesslist_hashisvalid( *ws->hash ) ) { |
82 | mutex_bucket_unlock_by_hash( hash, 0 ); | 81 | mutex_bucket_unlock_by_hash( *ws->hash, 0 ); |
83 | if( proto == FLAG_TCP ) { | 82 | if( proto == FLAG_TCP ) { |
84 | const char invalid_hash[] = "d14:failure reason63:Requested download is not authorized for use with this tracker.e"; | 83 | const char invalid_hash[] = "d14:failure reason63:Requested download is not authorized for use with this tracker.e"; |
85 | memcpy( reply, invalid_hash, strlen( invalid_hash ) ); | 84 | memcpy( ws->reply, invalid_hash, strlen( invalid_hash ) ); |
86 | return strlen( invalid_hash ); | 85 | return strlen( invalid_hash ); |
87 | } | 86 | } |
88 | return 0; | 87 | return 0; |
89 | } | 88 | } |
90 | 89 | ||
91 | torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 90 | torrent = vector_find_or_insert( torrents_list, (void*)ws->hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
92 | if( !torrent ) { | 91 | if( !torrent ) { |
93 | mutex_bucket_unlock_by_hash( hash, 0 ); | 92 | mutex_bucket_unlock_by_hash( *ws->hash, 0 ); |
94 | return 0; | 93 | return 0; |
95 | } | 94 | } |
96 | 95 | ||
97 | if( !exactmatch ) { | 96 | if( !exactmatch ) { |
98 | /* Create a new torrent entry, then */ | 97 | /* Create a new torrent entry, then */ |
99 | memcpy( torrent->hash, hash, sizeof(ot_hash) ); | 98 | memcpy( torrent->hash, *ws->hash, sizeof(ot_hash) ); |
100 | 99 | ||
101 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { | 100 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { |
102 | vector_remove_torrent( torrents_list, torrent ); | 101 | vector_remove_torrent( torrents_list, torrent ); |
103 | mutex_bucket_unlock_by_hash( hash, 0 ); | 102 | mutex_bucket_unlock_by_hash( *ws->hash, 0 ); |
104 | return 0; | 103 | return 0; |
105 | } | 104 | } |
106 | 105 | ||
@@ -112,76 +111,76 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_ | |||
112 | torrent->peer_list->base = g_now_minutes; | 111 | torrent->peer_list->base = g_now_minutes; |
113 | 112 | ||
114 | /* Check for peer in torrent */ | 113 | /* Check for peer in torrent */ |
115 | peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), peer, &exactmatch ); | 114 | peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), &ws->peer, &exactmatch ); |
116 | if( !peer_dest ) { | 115 | if( !peer_dest ) { |
117 | mutex_bucket_unlock_by_hash( hash, delta_torrentcount ); | 116 | mutex_bucket_unlock_by_hash( *ws->hash, delta_torrentcount ); |
118 | return 0; | 117 | return 0; |
119 | } | 118 | } |
120 | 119 | ||
121 | /* Tell peer that it's fresh */ | 120 | /* Tell peer that it's fresh */ |
122 | OT_PEERTIME( peer ) = 0; | 121 | OT_PEERTIME( &ws->peer ) = 0; |
123 | 122 | ||
124 | /* Sanitize flags: Whoever claims to have completed download, must be a seeder */ | 123 | /* Sanitize flags: Whoever claims to have completed download, must be a seeder */ |
125 | if( ( OT_PEERFLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) | 124 | if( ( OT_PEERFLAG( &ws->peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) |
126 | OT_PEERFLAG( peer ) ^= PEER_FLAG_COMPLETED; | 125 | OT_PEERFLAG( &ws->peer ) ^= PEER_FLAG_COMPLETED; |
127 | 126 | ||
128 | /* If we hadn't had a match create peer there */ | 127 | /* If we hadn't had a match create peer there */ |
129 | if( !exactmatch ) { | 128 | if( !exactmatch ) { |
130 | 129 | ||
131 | #ifdef WANT_SYNC_LIVE | 130 | #ifdef WANT_SYNC_LIVE |
132 | if( proto == FLAG_MCA ) | 131 | if( proto == FLAG_MCA ) |
133 | OT_PEERFLAG( peer ) |= PEER_FLAG_FROM_SYNC; | 132 | OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_FROM_SYNC; |
134 | else | 133 | else |
135 | livesync_tell( hash, peer ); | 134 | livesync_tell( ws ); |
136 | #endif | 135 | #endif |
137 | 136 | ||
138 | torrent->peer_list->peer_count++; | 137 | torrent->peer_list->peer_count++; |
139 | if( OT_PEERFLAG(peer) & PEER_FLAG_COMPLETED ) { | 138 | if( OT_PEERFLAG(&ws->peer) & PEER_FLAG_COMPLETED ) { |
140 | torrent->peer_list->down_count++; | 139 | torrent->peer_list->down_count++; |
141 | stats_issue_event( EVENT_COMPLETED, 0, (uintptr_t)torrent->hash ); | 140 | stats_issue_event( EVENT_COMPLETED, 0, (uintptr_t)ws ); |
142 | } | 141 | } |
143 | if( OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) | 142 | if( OT_PEERFLAG(&ws->peer) & PEER_FLAG_SEEDING ) |
144 | torrent->peer_list->seed_count++; | 143 | torrent->peer_list->seed_count++; |
145 | 144 | ||
146 | } else { | 145 | } else { |
147 | stats_issue_event( EVENT_RENEW, 0, OT_PEERTIME( peer_dest ) ); | 146 | stats_issue_event( EVENT_RENEW, 0, OT_PEERTIME( peer_dest ) ); |
148 | #ifdef WANT_SPOT_WOODPECKER | 147 | #ifdef WANT_SPOT_WOODPECKER |
149 | if( ( OT_PEERTIME(peer_dest) > 0 ) && ( OT_PEERTIME(peer_dest) < 20 ) ) | 148 | if( ( OT_PEERTIME(peer_dest) > 0 ) && ( OT_PEERTIME(peer_dest) < 20 ) ) |
150 | stats_issue_event( EVENT_WOODPECKER, 0, (uintptr_t)peer ); | 149 | stats_issue_event( EVENT_WOODPECKER, 0, (uintptr_t)&ws->peer ); |
151 | #endif | 150 | #endif |
152 | #ifdef WANT_SYNC_LIVE | 151 | #ifdef WANT_SYNC_LIVE |
153 | /* Won't live sync peers that come back too fast. Only exception: | 152 | /* Won't live sync peers that come back too fast. Only exception: |
154 | fresh "completed" reports */ | 153 | fresh "completed" reports */ |
155 | if( proto != FLAG_MCA ) { | 154 | if( proto != FLAG_MCA ) { |
156 | if( OT_PEERTIME( peer_dest ) > OT_CLIENT_SYNC_RENEW_BOUNDARY || | 155 | if( OT_PEERTIME( peer_dest ) > OT_CLIENT_SYNC_RENEW_BOUNDARY || |
157 | ( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) && (OT_PEERFLAG(peer) & PEER_FLAG_COMPLETED ) ) ) | 156 | ( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) && (OT_PEERFLAG(&ws->peer) & PEER_FLAG_COMPLETED ) ) ) |
158 | livesync_tell( hash, peer ); | 157 | livesync_tell( ws ); |
159 | } | 158 | } |
160 | #endif | 159 | #endif |
161 | 160 | ||
162 | if( (OT_PEERFLAG(peer_dest) & PEER_FLAG_SEEDING ) && !(OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) ) | 161 | if( (OT_PEERFLAG(peer_dest) & PEER_FLAG_SEEDING ) && !(OT_PEERFLAG(&ws->peer) & PEER_FLAG_SEEDING ) ) |
163 | torrent->peer_list->seed_count--; | 162 | torrent->peer_list->seed_count--; |
164 | if( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) ) | 163 | if( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_PEERFLAG(&ws->peer) & PEER_FLAG_SEEDING ) ) |
165 | torrent->peer_list->seed_count++; | 164 | torrent->peer_list->seed_count++; |
166 | if( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) && (OT_PEERFLAG(peer) & PEER_FLAG_COMPLETED ) ) { | 165 | if( !(OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) && (OT_PEERFLAG(&ws->peer) & PEER_FLAG_COMPLETED ) ) { |
167 | torrent->peer_list->down_count++; | 166 | torrent->peer_list->down_count++; |
168 | stats_issue_event( EVENT_COMPLETED, 0, (uintptr_t)torrent->hash ); | 167 | stats_issue_event( EVENT_COMPLETED, 0, (uintptr_t)ws ); |
169 | } | 168 | } |
170 | if( OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) | 169 | if( OT_PEERFLAG(peer_dest) & PEER_FLAG_COMPLETED ) |
171 | OT_PEERFLAG( peer ) |= PEER_FLAG_COMPLETED; | 170 | OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_COMPLETED; |
172 | } | 171 | } |
173 | 172 | ||
174 | memcpy( peer_dest, peer, sizeof(ot_peer) ); | 173 | memcpy( peer_dest, &ws->peer, sizeof(ot_peer) ); |
175 | #ifdef WANT_SYNC | 174 | #ifdef WANT_SYNC |
176 | if( proto == FLAG_MCA ) { | 175 | if( proto == FLAG_MCA ) { |
177 | mutex_bucket_unlock_by_hash( hash, delta_torrentcount ); | 176 | mutex_bucket_unlock_by_hash( *ws->hash, delta_torrentcount ); |
178 | return 0; | 177 | return 0; |
179 | } | 178 | } |
180 | #endif | 179 | #endif |
181 | 180 | ||
182 | reply_size = return_peers_for_torrent( torrent, amount, reply, proto ); | 181 | ws->reply_size = return_peers_for_torrent( torrent, amount, ws->reply, proto ); |
183 | mutex_bucket_unlock_by_hash( torrent->hash, delta_torrentcount ); | 182 | mutex_bucket_unlock_by_hash( *ws->hash, delta_torrentcount ); |
184 | return reply_size; | 183 | return ws->reply_size; |
185 | } | 184 | } |
186 | 185 | ||
187 | static size_t return_peers_all( ot_peerlist *peer_list, char *reply ) { | 186 | static size_t return_peers_all( ot_peerlist *peer_list, char *reply ) { |
@@ -350,23 +349,22 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl | |||
350 | } | 349 | } |
351 | 350 | ||
352 | static ot_peerlist dummy_list; | 351 | static ot_peerlist dummy_list; |
353 | size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) { | 352 | size_t remove_peer_from_torrent( PROTO_FLAG proto, struct ot_workstruct *ws ) { |
354 | int exactmatch; | 353 | int exactmatch; |
355 | size_t reply_size = 0; | 354 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( *ws->hash ); |
356 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 355 | ot_torrent *torrent = binary_search( ws->hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
357 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | ||
358 | ot_peerlist *peer_list = &dummy_list; | 356 | ot_peerlist *peer_list = &dummy_list; |
359 | 357 | ||
360 | #ifdef WANT_SYNC_LIVE | 358 | #ifdef WANT_SYNC_LIVE |
361 | if( proto != FLAG_MCA ) { | 359 | if( proto != FLAG_MCA ) { |
362 | OT_PEERFLAG( peer ) |= PEER_FLAG_STOPPED; | 360 | OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_STOPPED; |
363 | livesync_tell( hash, peer ); | 361 | livesync_tell( ws ); |
364 | } | 362 | } |
365 | #endif | 363 | #endif |
366 | 364 | ||
367 | if( exactmatch ) { | 365 | if( exactmatch ) { |
368 | peer_list = torrent->peer_list; | 366 | peer_list = torrent->peer_list; |
369 | switch( vector_remove_peer( &peer_list->peers, peer ) ) { | 367 | switch( vector_remove_peer( &peer_list->peers, &ws->peer ) ) { |
370 | case 2: peer_list->seed_count--; /* Fall throughs intended */ | 368 | case 2: peer_list->seed_count--; /* Fall throughs intended */ |
371 | case 1: peer_list->peer_count--; /* Fall throughs intended */ | 369 | case 1: peer_list->peer_count--; /* Fall throughs intended */ |
372 | default: break; | 370 | default: break; |
@@ -375,19 +373,19 @@ size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO | |||
375 | 373 | ||
376 | if( proto == FLAG_TCP ) { | 374 | if( proto == FLAG_TCP ) { |
377 | int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM; | 375 | int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM; |
378 | reply_size = sprintf( reply, "d8:completei%zde10:incompletei%zde8:intervali%ie12:min intervali%ie" PEERS_BENCODED "0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, erval, erval / 2 ); | 376 | ws->reply_size = sprintf( ws->reply, "d8:completei%zde10:incompletei%zde8:intervali%ie12:min intervali%ie" PEERS_BENCODED "0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, erval, erval / 2 ); |
379 | } | 377 | } |
380 | 378 | ||
381 | /* Handle UDP reply */ | 379 | /* Handle UDP reply */ |
382 | if( proto == FLAG_UDP ) { | 380 | if( proto == FLAG_UDP ) { |
383 | ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 381 | ((uint32_t*)ws->reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
384 | ((uint32_t*)reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count ); | 382 | ((uint32_t*)ws->reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count ); |
385 | ((uint32_t*)reply)[4] = htonl( peer_list->seed_count); | 383 | ((uint32_t*)ws->reply)[4] = htonl( peer_list->seed_count); |
386 | reply_size = 20; | 384 | ws->reply_size = 20; |
387 | } | 385 | } |
388 | 386 | ||
389 | mutex_bucket_unlock_by_hash( hash, 0 ); | 387 | mutex_bucket_unlock_by_hash( *ws->hash, 0 ); |
390 | return reply_size; | 388 | return ws->reply_size; |
391 | } | 389 | } |
392 | 390 | ||
393 | void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data ) { | 391 | void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data ) { |