summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
authorerdgeist <>2009-11-18 04:00:26 +0000
committererdgeist <>2009-11-18 04:00:26 +0000
commitf3c0359876b59aa8fc2f03fa61363ede9d2edc2f (patch)
treea7924f5d8ed72ac8f7c4d5f68987f2aea04f3450 /opentracker.c
parent90e7262d9d79b4098cbc52df549e138b77add193 (diff)
Make header parsing more efficient, prepare multithreading and keep-alive.
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c66
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 ) {
143static void handle_dead( const int64 sock ) { 143static 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
157static ssize_t handle_read( const int64 sock, struct ot_workstruct *ws ) { 155static 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
194static void handle_write( const int64 sock ) { 188static 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
236static void server_mainloop( ) { 227static 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
287static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { 281static 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}