diff options
| author | erdgeist <> | 2009-11-18 04:00:26 +0000 |
|---|---|---|
| committer | erdgeist <> | 2009-11-18 04:00:26 +0000 |
| commit | f3c0359876b59aa8fc2f03fa61363ede9d2edc2f (patch) | |
| tree | a7924f5d8ed72ac8f7c4d5f68987f2aea04f3450 /opentracker.c | |
| parent | 90e7262d9d79b4098cbc52df549e138b77add193 (diff) | |
Make header parsing more efficient, prepare multithreading and keep-alive.
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/opentracker.c b/opentracker.c index c1fe945..57eca12 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -143,10 +143,8 @@ static size_t header_complete( char * request, ssize_t byte_count ) { | |||
| 143 | static void handle_dead( const int64 sock ) { | 143 | static void handle_dead( const int64 sock ) { |
| 144 | struct http_data* cookie=io_getcookie( sock ); | 144 | struct http_data* cookie=io_getcookie( sock ); |
| 145 | if( cookie ) { | 145 | if( cookie ) { |
| 146 | if( cookie->flag & STRUCT_HTTP_FLAG_IOB_USED ) | 146 | iob_reset( &cookie->batch ); |
| 147 | iob_reset( &cookie->data.batch ); | 147 | array_reset( &cookie->request ); |
| 148 | if( cookie->flag & STRUCT_HTTP_FLAG_ARRAY_USED ) | ||
| 149 | array_reset( &cookie->data.request ); | ||
| 150 | if( cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK ) | 148 | if( cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK ) |
| 151 | mutex_workqueue_canceltask( sock ); | 149 | mutex_workqueue_canceltask( sock ); |
| 152 | free( cookie ); | 150 | free( cookie ); |
| @@ -154,46 +152,42 @@ static void handle_dead( const int64 sock ) { | |||
| 154 | io_close( sock ); | 152 | io_close( sock ); |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | static ssize_t handle_read( const int64 sock, struct ot_workstruct *ws ) { | 155 | static void handle_read( const int64 sock, struct ot_workstruct *ws ) { |
| 158 | struct http_data* cookie = io_getcookie( sock ); | 156 | struct http_data* cookie = io_getcookie( sock ); |
| 159 | ssize_t byte_count; | 157 | ssize_t byte_count; |
| 160 | 158 | ||
| 161 | if( ( byte_count = io_tryread( sock, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { | 159 | if( ( byte_count = io_tryread( sock, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { |
| 162 | handle_dead( sock ); | 160 | handle_dead( sock ); |
| 163 | return 0; | 161 | return; |
| 164 | } | 162 | } |
| 165 | 163 | ||
| 166 | /* If we get the whole request in one packet, handle it without copying */ | 164 | /* If we get the whole request in one packet, handle it without copying */ |
| 167 | if( !array_start( &cookie->data.request ) ) { | 165 | if( !array_start( &cookie->request ) ) { |
| 168 | if( memchr( ws->inbuf, '\n', byte_count ) ) { | 166 | if( ( ws->header_size = header_complete( ws->inbuf, byte_count ) ) ) { |
| 169 | ws->request = ws->inbuf; | 167 | ws->request = ws->inbuf; |
| 170 | ws->request_size = byte_count; | 168 | ws->request_size = byte_count; |
| 171 | return http_handle_request( sock, ws ); | 169 | http_handle_request( sock, ws ); |
| 172 | } | 170 | } else |
| 173 | 171 | array_catb( &cookie->request, ws->inbuf, byte_count ); | |
| 174 | /* ... else take a copy */ | 172 | return; |
| 175 | cookie->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; | ||
| 176 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); | ||
| 177 | return 0; | ||
| 178 | } | 173 | } |
| 179 | 174 | ||
| 180 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); | 175 | array_catb( &cookie->request, ws->inbuf, byte_count ); |
| 181 | 176 | if( array_failed( &cookie->request ) || array_bytes( &cookie->request ) > 8192 ) { | |
| 182 | if( array_failed( &cookie->data.request ) || | 177 | http_issue_error( sock, ws, CODE_HTTPERROR_500 ); |
| 183 | array_bytes( &cookie->data.request ) > 8192 ) | 178 | return; |
| 184 | return http_issue_error( sock, ws, CODE_HTTPERROR_500 ); | 179 | } |
| 185 | |||
| 186 | if( !memchr( array_start( &cookie->data.request ), '\n', array_bytes( &cookie->data.request ) ) ) | ||
| 187 | return 0; | ||
| 188 | 180 | ||
| 189 | ws->request = array_start( &cookie->data.request ); | 181 | while( ( ws->header_size = header_complete( array_start( &cookie->request ), array_bytes( &cookie->request ) ) ) ) { |
| 190 | ws->request_size = array_bytes( &cookie->data.request ); | 182 | ws->request = array_start( &cookie->request ); |
| 191 | return http_handle_request( sock, ws ); | 183 | ws->request_size = array_bytes( &cookie->request ); |
| 184 | http_handle_request( sock, ws ); | ||
| 185 | } | ||
| 192 | } | 186 | } |
| 193 | 187 | ||
| 194 | static void handle_write( const int64 sock ) { | 188 | static void handle_write( const int64 sock ) { |
| 195 | struct http_data* cookie=io_getcookie( sock ); | 189 | struct http_data* cookie=io_getcookie( sock ); |
| 196 | if( !cookie || ( iob_send( sock, &cookie->data.batch ) <= 0 ) ) | 190 | if( !cookie || ( iob_send( sock, &cookie->batch ) <= 0 ) ) |
| 197 | handle_dead( sock ); | 191 | handle_dead( sock ); |
| 198 | } | 192 | } |
| 199 | 193 | ||
| @@ -214,12 +208,12 @@ static void handle_accept( const int64 serversocket ) { | |||
| 214 | io_close( sock ); | 208 | io_close( sock ); |
| 215 | continue; | 209 | continue; |
| 216 | } | 210 | } |
| 217 | io_setcookie( sock, cookie ); | ||
| 218 | io_wantread( sock ); | ||
| 219 | |||
| 220 | memset(cookie, 0, sizeof( struct http_data ) ); | 211 | memset(cookie, 0, sizeof( struct http_data ) ); |
| 221 | memcpy(cookie->ip,ip,sizeof(ot_ip6)); | 212 | memcpy(cookie->ip,ip,sizeof(ot_ip6)); |
| 222 | 213 | ||
| 214 | io_setcookie( sock, cookie ); | ||
| 215 | io_wantread( sock ); | ||
| 216 | |||
| 223 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); | 217 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
| 224 | 218 | ||
| 225 | /* That breaks taia encapsulation. But there is no way to take system | 219 | /* That breaks taia encapsulation. But there is no way to take system |
| @@ -228,17 +222,16 @@ static void handle_accept( const int64 serversocket ) { | |||
| 228 | tai_unix( &(t.sec), (g_now_seconds + OT_CLIENT_TIMEOUT) ); | 222 | tai_unix( &(t.sec), (g_now_seconds + OT_CLIENT_TIMEOUT) ); |
| 229 | io_timeout( sock, t ); | 223 | io_timeout( sock, t ); |
| 230 | } | 224 | } |
| 231 | |||
| 232 | if( errno == EAGAIN ) | ||
| 233 | io_eagain( serversocket ); | ||
| 234 | } | 225 | } |
| 235 | 226 | ||
| 236 | static void server_mainloop( ) { | 227 | static void * server_mainloop( void * args ) { |
| 237 | struct ot_workstruct ws; | 228 | struct ot_workstruct ws; |
| 238 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 229 | time_t next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; |
| 239 | struct iovec *iovector; | 230 | struct iovec *iovector; |
| 240 | int iovec_entries; | 231 | int iovec_entries; |
| 241 | 232 | ||
| 233 | (void)args; | ||
| 234 | |||
| 242 | /* Initialize our "thread local storage" */ | 235 | /* Initialize our "thread local storage" */ |
| 243 | ws.inbuf = malloc( G_INBUF_SIZE ); | 236 | ws.inbuf = malloc( G_INBUF_SIZE ); |
| 244 | ws.outbuf = malloc( G_OUTBUF_SIZE ); | 237 | ws.outbuf = malloc( G_OUTBUF_SIZE ); |
| @@ -282,6 +275,7 @@ static void server_mainloop( ) { | |||
| 282 | /* Enforce setting the clock */ | 275 | /* Enforce setting the clock */ |
| 283 | signal_handler( SIGALRM ); | 276 | signal_handler( SIGALRM ); |
| 284 | } | 277 | } |
| 278 | return 0; | ||
| 285 | } | 279 | } |
| 286 | 280 | ||
| 287 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { | 281 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { |
| @@ -475,7 +469,7 @@ void load_state(const char * const state_filename ) { | |||
| 475 | if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue; | 469 | if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue; |
| 476 | add_torrent_from_saved_state( infohash, base, downcount ); | 470 | add_torrent_from_saved_state( infohash, base, downcount ); |
| 477 | } | 471 | } |
| 478 | 472 | ||
| 479 | fclose( state_filehandle ); | 473 | fclose( state_filehandle ); |
| 480 | } | 474 | } |
| 481 | 475 | ||
| @@ -606,7 +600,7 @@ int main( int argc, char **argv ) { | |||
| 606 | /* Kick off our initial clock setting alarm */ | 600 | /* Kick off our initial clock setting alarm */ |
| 607 | alarm(5); | 601 | alarm(5); |
| 608 | 602 | ||
| 609 | server_mainloop( ); | 603 | server_mainloop( 0 ); |
| 610 | 604 | ||
| 611 | return 0; | 605 | return 0; |
| 612 | } | 606 | } |
