diff options
| -rw-r--r-- | opentracker.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/opentracker.c b/opentracker.c index 8b440c5..15f4871 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -36,6 +36,8 @@ | |||
| 36 | #include "ot_stats.h" | 36 | #include "ot_stats.h" |
| 37 | #include "ot_sync.h" | 37 | #include "ot_sync.h" |
| 38 | #include "ot_udp.h" | 38 | #include "ot_udp.h" |
| 39 | #include "ot_fullscrape.h" | ||
| 40 | #include "ot_iovec.h" | ||
| 39 | 41 | ||
| 40 | /* Globals */ | 42 | /* Globals */ |
| 41 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; | 43 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; |
| @@ -105,6 +107,7 @@ static void httperror( const int64 s, const char *title, const char *message ); | |||
| 105 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM(size_t l ) ); | 107 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM(size_t l ) ); |
| 106 | 108 | ||
| 107 | static void sendmmapdata( const int64 s, char *buffer, const size_t size ); | 109 | static void sendmmapdata( const int64 s, char *buffer, const size_t size ); |
| 110 | static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector ); | ||
| 108 | static void senddata( const int64 s, char *buffer, const size_t size ); | 111 | static void senddata( const int64 s, char *buffer, const size_t size ); |
| 109 | 112 | ||
| 110 | static void server_mainloop( ); | 113 | static void server_mainloop( ); |
| @@ -188,6 +191,48 @@ static void sendmmapdata( const int64 s, char *buffer, size_t size ) { | |||
| 188 | io_wantwrite( s ); | 191 | io_wantwrite( s ); |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 194 | static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector ) { | ||
| 195 | struct http_data *h = io_getcookie( s ); | ||
| 196 | char *header; | ||
| 197 | int i; | ||
| 198 | size_t header_size, size = iovec_length( &iovec_entries, &iovector ); | ||
| 199 | tai6464 t; | ||
| 200 | |||
| 201 | if( !h ) { | ||
| 202 | iovec_free( &iovec_entries, &iovector ); | ||
| 203 | return; | ||
| 204 | } | ||
| 205 | if( h->flag & STRUCT_HTTP_FLAG_ARRAY_USED ) { | ||
| 206 | h->flag &= ~STRUCT_HTTP_FLAG_ARRAY_USED; | ||
| 207 | array_reset( &h->request ); | ||
| 208 | } | ||
| 209 | |||
| 210 | header = malloc( SUCCESS_HTTP_HEADER_LENGTH ); | ||
| 211 | if( !header ) { | ||
| 212 | iovec_free( &iovec_entries, &iovector ); | ||
| 213 | HTTPERROR_500; | ||
| 214 | } | ||
| 215 | |||
| 216 | header_size = sprintf( header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r\n", size ); | ||
| 217 | |||
| 218 | iob_reset( &h->batch ); | ||
| 219 | iob_addbuf_free( &h->batch, header, header_size ); | ||
| 220 | |||
| 221 | /* Will move to ot_iovec.c */ | ||
| 222 | for( i=0; i<iovec_entries; ++i ) | ||
| 223 | iob_addbuf_munmap( &h->batch, iovector[i].iov_base, iovector[i].iov_len ); | ||
| 224 | free( iovector ); | ||
| 225 | |||
| 226 | h->flag |= STRUCT_HTTP_FLAG_IOB_USED; | ||
| 227 | |||
| 228 | /* writeable sockets timeout after twice the pool timeout | ||
| 229 | which defaults to 5 minutes (e.g. after 10 minutes) */ | ||
| 230 | taia_now( &t ); taia_addsec( &t, &t, OT_CLIENT_TIMEOUT_SEND ); | ||
| 231 | io_timeout( s, t ); | ||
| 232 | io_dontwantread( s ); | ||
| 233 | io_wantwrite( s ); | ||
| 234 | } | ||
| 235 | |||
| 191 | static void senddata( const int64 s, char *buffer, size_t size ) { | 236 | static void senddata( const int64 s, char *buffer, size_t size ) { |
| 192 | struct http_data *h = io_getcookie( s ); | 237 | struct http_data *h = io_getcookie( s ); |
| 193 | ssize_t written_size; | 238 | ssize_t written_size; |
| @@ -225,7 +270,7 @@ static void senddata( const int64 s, char *buffer, size_t size ) { | |||
| 225 | 270 | ||
| 226 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size_t l ) ) { | 271 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size_t l ) ) { |
| 227 | struct http_data* h = io_getcookie( s ); | 272 | struct http_data* h = io_getcookie( s ); |
| 228 | char *c, *reply; | 273 | char *c; |
| 229 | ot_peer peer; | 274 | ot_peer peer; |
| 230 | ot_torrent *torrent; | 275 | ot_torrent *torrent; |
| 231 | ot_hash *hash = NULL; | 276 | ot_hash *hash = NULL; |
| @@ -349,16 +394,19 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); | |||
| 349 | 394 | ||
| 350 | /* Full scrape... you might want to limit that */ | 395 | /* Full scrape... you might want to limit that */ |
| 351 | if( !byte_diff( data, 12, "scrape HTTP/" ) ) { | 396 | if( !byte_diff( data, 12, "scrape HTTP/" ) ) { |
| 397 | int iovec_entries = 0; | ||
| 398 | struct iovec * iovector = NULL; | ||
| 399 | reply_size = return_fullscrape_for_tracker( &iovec_entries, &iovector ); | ||
| 352 | 400 | ||
| 353 | LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now - ot_start_time), h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); | 401 | LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now - ot_start_time), h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); |
| 354 | #ifdef _DEBUG_HTTPERROR | 402 | #ifdef _DEBUG_HTTPERROR |
| 355 | write( 2, debug_request, l ); | 403 | write( 2, debug_request, l ); |
| 356 | #endif | 404 | #endif |
| 357 | if( !( reply_size = return_fullscrape_for_tracker( &reply ) ) ) HTTPERROR_500; | 405 | if( !reply_size ) HTTPERROR_500; |
| 358 | 406 | ||
| 359 | /* Stat keeping */ | 407 | /* Stat keeping */ |
| 360 | stats_issue_event( EVENT_FULLSCRAPE, 1, reply_size); | 408 | stats_issue_event( EVENT_FULLSCRAPE, 1, reply_size); |
| 361 | return sendmmapdata( s, reply, reply_size ); | 409 | return sendiovecdata( s, iovec_entries, iovector ); |
| 362 | } | 410 | } |
| 363 | 411 | ||
| 364 | SCRAPE_WORKAROUND: | 412 | SCRAPE_WORKAROUND: |
