summaryrefslogtreecommitdiff
path: root/ot_fullscrape.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_fullscrape.c')
-rw-r--r--ot_fullscrape.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/ot_fullscrape.c b/ot_fullscrape.c
index 0571049..052777a 100644
--- a/ot_fullscrape.c
+++ b/ot_fullscrape.c
@@ -25,43 +25,75 @@
25 25
26size_t return_fullscrape_for_tracker( int *iovec_entries, struct iovec **iovector ) { 26size_t return_fullscrape_for_tracker( int *iovec_entries, struct iovec **iovector ) {
27 int bucket; 27 int bucket;
28 size_t j;
29 char *r, *re; 28 char *r, *re;
30 29
30 /* Setup return vector */
31 *iovec_entries = 0; 31 *iovec_entries = 0;
32 if( !( r = iovec_increase( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE ) ) ) 32 if( !( r = iovec_increase( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE ) ) )
33 return 0; 33 return 0;
34
35 /* ... and pointer end of current output buffer
36 this works as a low watermark */
34 re = r + OT_SCRAPE_CHUNK_SIZE; 37 re = r + OT_SCRAPE_CHUNK_SIZE;
35 38
39 /* Start reply dictionary */
36 memmove( r, "d5:filesd", 9 ); r += 9; 40 memmove( r, "d5:filesd", 9 ); r += 9;
41
42 /* For each bucket... */
37 for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { 43 for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) {
44 /* Get exclusive access to that bucket */
38 ot_vector *torrents_list = mutex_bucket_lock( bucket ); 45 ot_vector *torrents_list = mutex_bucket_lock( bucket );
39 for( j=0; j<torrents_list->size; ++j ) { 46 size_t tor_offset;
40 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; 47
41 ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[j] ).hash; 48 /* For each torrent in this bucket.. */
49 for( tor_offset=0; tor_offset<torrents_list->size; ++tor_offset ) {
50 /* Address torrents members */
51 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[tor_offset] ).peer_list;
52 ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[tor_offset] ).hash;
53
54 /* If torrent has peers or download count, its interesting */
42 if( peer_list->peer_count || peer_list->down_count ) { 55 if( peer_list->peer_count || peer_list->down_count ) {
56
57 /* push hash as bencoded string */
43 *r++='2'; *r++='0'; *r++=':'; 58 *r++='2'; *r++='0'; *r++=':';
44 memmove( r, hash, 20 ); r+=20; 59 memmove( r, hash, 20 ); r+=20;
60
61 /* push rest of the scrape string */
45 r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count ); 62 r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count );
46 } 63 }
47 64
65 /* If we reached our low watermark in buffer... */
48 if( re - r <= OT_FULLSCRAPE_MAXENTRYLEN ) { 66 if( re - r <= OT_FULLSCRAPE_MAXENTRYLEN ) {
67
68 /* crop current output buffer to the amount really used */
49 iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) ); 69 iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) );
70
71 /* And allocate a fresh output buffer at the end of our buffers list */
50 if( !( r = iovec_increase( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE ) ) ) { 72 if( !( r = iovec_increase( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE ) ) ) {
73
74 /* If this fails: free buffers */
51 iovec_free( iovec_entries, iovector ); 75 iovec_free( iovec_entries, iovector );
76
77 /* Release lock on current bucket and return */
52 mutex_bucket_unlock( bucket ); 78 mutex_bucket_unlock( bucket );
53 return 0; 79 return 0;
54 } 80 }
81
82 /* Adjust new end of output buffer */
55 re = r + OT_SCRAPE_CHUNK_SIZE; 83 re = r + OT_SCRAPE_CHUNK_SIZE;
56 } 84 }
57
58 } 85 }
86
87 /* All torrents done: release lock on currenct bucket */
59 mutex_bucket_unlock( bucket ); 88 mutex_bucket_unlock( bucket );
60 } 89 }
61 90
91 /* Close bencoded scrape dictionary */
62 *r++='e'; *r++='e'; 92 *r++='e'; *r++='e';
63 93
94 /* Release unused memory in current output buffer */
64 iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) ); 95 iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) );
65 96
97 /* Return answer size */
66 return iovec_length( iovec_entries, iovector ); 98 return iovec_length( iovec_entries, iovector );
67} 99}