diff options
Diffstat (limited to 'opentracker.c')
-rw-r--r-- | opentracker.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/opentracker.c b/opentracker.c index 8a4126c..46456dd 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "iob.h" | 22 | #include "iob.h" |
23 | #include "byte.h" | 23 | #include "byte.h" |
24 | #include "scan.h" | 24 | #include "scan.h" |
25 | #include "ip4.h" | 25 | #include "ip6.h" |
26 | 26 | ||
27 | /* Opentracker */ | 27 | /* Opentracker */ |
28 | #include "trackerlogic.h" | 28 | #include "trackerlogic.h" |
@@ -108,7 +108,7 @@ static ssize_t handle_read( const int64 clientsocket, struct ot_workstruct *ws ) | |||
108 | struct http_data* h = io_getcookie( clientsocket ); | 108 | struct http_data* h = io_getcookie( clientsocket ); |
109 | ssize_t l; | 109 | ssize_t l; |
110 | 110 | ||
111 | if( ( l = io_tryread( clientsocket, ws->inbuf, ws->inbuf_size ) ) <= 0 ) { | 111 | if( ( l = io_tryread( clientsocket, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { |
112 | handle_dead( clientsocket ); | 112 | handle_dead( clientsocket ); |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
@@ -152,28 +152,28 @@ static void handle_write( const int64 clientsocket ) { | |||
152 | 152 | ||
153 | static void handle_accept( const int64 serversocket ) { | 153 | static void handle_accept( const int64 serversocket ) { |
154 | struct http_data *h; | 154 | struct http_data *h; |
155 | unsigned char ip[4]; | 155 | ot_ip6 ip; |
156 | uint16 port; | 156 | uint16 port; |
157 | tai6464 t; | 157 | tai6464 t; |
158 | int64 i; | 158 | int64 i; |
159 | 159 | ||
160 | while( ( i = socket_accept4( serversocket, (char*)ip, &port) ) != -1 ) { | 160 | while( ( i = socket_accept6( serversocket, ip, &port, NULL ) ) != -1 ) { |
161 | 161 | ||
162 | /* Put fd into a non-blocking mode */ | 162 | /* Put fd into a non-blocking mode */ |
163 | io_nonblock( i ); | 163 | io_nonblock( i ); |
164 | 164 | ||
165 | if( !io_fd( i ) || | 165 | if( !io_fd( i ) || |
166 | !( h = (struct http_data*)malloc( sizeof( struct http_data ) ) ) ) { | 166 | !( h = (struct http_data*)malloc( sizeof(struct http_data) ) ) ) { |
167 | io_close( i ); | 167 | io_close( i ); |
168 | continue; | 168 | continue; |
169 | } | 169 | } |
170 | io_setcookie( i, h ); | 170 | io_setcookie( i, h ); |
171 | io_wantread( i ); | 171 | io_wantread( i ); |
172 | 172 | ||
173 | memset( h, 0, sizeof( struct http_data ) ); | 173 | memset(h, 0, sizeof( struct http_data ) ); |
174 | WRITE32(h->ip,0,READ32(ip,0)); | 174 | memcpy(h->ip,ip,sizeof(ot_ip6)); |
175 | 175 | ||
176 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, ntohl(*(uint32_t*)ip)); | 176 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
177 | 177 | ||
178 | /* That breaks taia encapsulation. But there is no way to take system | 178 | /* That breaks taia encapsulation. But there is no way to take system |
179 | time this often in FreeBSD and libowfat does not allow to set unix time */ | 179 | time this often in FreeBSD and libowfat does not allow to set unix time */ |
@@ -193,20 +193,14 @@ static void server_mainloop( ) { | |||
193 | int iovec_entries; | 193 | int iovec_entries; |
194 | 194 | ||
195 | /* Initialize our "thread local storage" */ | 195 | /* Initialize our "thread local storage" */ |
196 | ws.inbuf = malloc( THREAD_INBUF_SIZE ); | 196 | ws.inbuf = malloc( G_INBUF_SIZE ); |
197 | ws.outbuf = malloc( THREAD_OUTBUF_SIZE ); | 197 | ws.outbuf = malloc( G_OUTBUF_SIZE ); |
198 | #ifdef _DEBUG_HTTPERROR | 198 | #ifdef _DEBUG_HTTPERROR |
199 | ws.debugbuf= malloc( THREAD_INBUF_SIZE ); | 199 | ws.debugbuf= malloc( G_INBUF_SIZE ); |
200 | #endif | 200 | #endif |
201 | if( !ws.inbuf || !ws.outbuf ) | 201 | if( !ws.inbuf || !ws.outbuf ) |
202 | panic( "Initializing worker failed" ); | 202 | panic( "Initializing worker failed" ); |
203 | 203 | ||
204 | ws.inbuf_size = THREAD_INBUF_SIZE; | ||
205 | ws.outbuf_size = THREAD_OUTBUF_SIZE; | ||
206 | #ifdef _DEBUG_HTTPERROR | ||
207 | ws.debugbuf_size= THREAD_INBUF_SIZE; | ||
208 | #endif | ||
209 | |||
210 | for( ; ; ) { | 204 | for( ; ; ) { |
211 | int64 i; | 205 | int64 i; |
212 | 206 | ||
@@ -217,7 +211,7 @@ static void server_mainloop( ) { | |||
217 | if( (intptr_t)cookie == FLAG_TCP ) | 211 | if( (intptr_t)cookie == FLAG_TCP ) |
218 | handle_accept( i ); | 212 | handle_accept( i ); |
219 | else if( (intptr_t)cookie == FLAG_UDP ) | 213 | else if( (intptr_t)cookie == FLAG_UDP ) |
220 | handle_udp4( i, &ws ); | 214 | handle_udp6( i, &ws ); |
221 | else | 215 | else |
222 | handle_read( i, &ws ); | 216 | handle_read( i, &ws ); |
223 | } | 217 | } |
@@ -241,17 +235,20 @@ static void server_mainloop( ) { | |||
241 | } | 235 | } |
242 | } | 236 | } |
243 | 237 | ||
244 | static int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) { | 238 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { |
245 | int64 s = proto == FLAG_TCP ? socket_tcp4( ) : socket_udp4( ); | 239 | int64 s = proto == FLAG_TCP ? socket_tcp6( ) : socket_udp6( ); |
246 | 240 | ||
247 | #ifdef _DEBUG | 241 | #ifdef _DEBUG |
248 | char *protos[] = {"TCP","UDP","UDP mcast"}; | 242 | char *protos[] = {"TCP","UDP","UDP mcast"}; |
249 | uint8_t *_ip = (uint8_t *)ip; | 243 | char _debug[512]; |
250 | fprintf( stderr, "Binding socket type %s to address %d.%d.%d.%d:%d...", protos[proto],_ip[0],_ip[1],_ip[2],_ip[3],port); | 244 | int off = snprintf( _debug, sizeof(_debug), "Binding socket type %s to address [", protos[proto] ); |
245 | off += fmt_ip6( _debug+off, ip); | ||
246 | off += snprintf( _debug + off, sizeof(_debug)-off, "]:%d...", port); | ||
247 | fputs( _debug, stderr ); | ||
251 | #endif | 248 | #endif |
252 | 249 | ||
253 | if( socket_bind4_reuse( s, ip, port ) == -1 ) | 250 | if( socket_bind6_reuse( s, ip, port, 0 ) == -1 ) |
254 | panic( "socket_bind4_reuse" ); | 251 | panic( "socket_bind6_reuse" ); |
255 | 252 | ||
256 | if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) ) | 253 | if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) ) |
257 | panic( "socket_listen" ); | 254 | panic( "socket_listen" ); |
@@ -279,16 +276,22 @@ char * set_config_option( char **option, char *value ) { | |||
279 | return *option = strdup( value ); | 276 | return *option = strdup( value ); |
280 | } | 277 | } |
281 | 278 | ||
282 | static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { | 279 | static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) { |
283 | const char *s = src; | 280 | const char *s = src; |
284 | int off; | 281 | int off, bracket = 0; |
285 | while( isspace(*s) ) ++s; | 282 | while( isspace(*s) ) ++s; |
286 | if( !(off = scan_ip4( s, ip ) ) ) | 283 | if( *s == '[' ) ++s, ++bracket; /* for v6 style notation */ |
284 | if( !(off = scan_ip6( s, ip ) ) ) | ||
287 | return 0; | 285 | return 0; |
288 | s += off; | 286 | s += off; |
289 | if( *s == 0 || isspace(*s)) return s-src; | 287 | if( *s == 0 || isspace(*s)) return s-src; |
290 | if( *(s++) != ':' ) | 288 | if( *s == ']' && bracket ) ++s; |
291 | return 0; | 289 | if( !ip6_isv4mapped(ip)){ |
290 | if( ( bracket && *(s) != ':' ) || ( *(s) != '.' ) ) return 0; | ||
291 | s++; | ||
292 | } else { | ||
293 | if( *(s++) != ':' ) return 0; | ||
294 | } | ||
292 | if( !(off = scan_ushort (s, port ) ) ) | 295 | if( !(off = scan_ushort (s, port ) ) ) |
293 | return 0; | 296 | return 0; |
294 | return off+s-src; | 297 | return off+s-src; |
@@ -296,7 +299,8 @@ static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { | |||
296 | 299 | ||
297 | int parse_configfile( char * config_filename ) { | 300 | int parse_configfile( char * config_filename ) { |
298 | FILE * accesslist_filehandle; | 301 | FILE * accesslist_filehandle; |
299 | char inbuf[512], tmpip[4]; | 302 | char inbuf[512]; |
303 | ot_ip6 tmpip; | ||
300 | int bound = 0; | 304 | int bound = 0; |
301 | 305 | ||
302 | accesslist_filehandle = fopen( config_filename, "r" ); | 306 | accesslist_filehandle = fopen( config_filename, "r" ); |
@@ -324,17 +328,17 @@ int parse_configfile( char * config_filename ) { | |||
324 | set_config_option( &g_serverdir, p+16 ); | 328 | set_config_option( &g_serverdir, p+16 ); |
325 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { | 329 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { |
326 | uint16_t tmpport = 6969; | 330 | uint16_t tmpport = 6969; |
327 | if( !scan_ip4_port( p+15, tmpip, &tmpport )) goto parse_error; | 331 | if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error; |
328 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); ++bound; | 332 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); ++bound; |
329 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); ++bound; | 333 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); ++bound; |
330 | } else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) { | 334 | } else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) { |
331 | uint16_t tmpport = 6969; | 335 | uint16_t tmpport = 6969; |
332 | if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error; | 336 | if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error; |
333 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); | 337 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); |
334 | ++bound; | 338 | ++bound; |
335 | } else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) { | 339 | } else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) { |
336 | uint16_t tmpport = 6969; | 340 | uint16_t tmpport = 6969; |
337 | if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error; | 341 | if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error; |
338 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); | 342 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); |
339 | ++bound; | 343 | ++bound; |
340 | #ifdef WANT_ACCESSLIST_WHITE | 344 | #ifdef WANT_ACCESSLIST_WHITE |
@@ -346,18 +350,18 @@ int parse_configfile( char * config_filename ) { | |||
346 | #endif | 350 | #endif |
347 | #ifdef WANT_RESTRICT_STATS | 351 | #ifdef WANT_RESTRICT_STATS |
348 | } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { | 352 | } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { |
349 | if( !scan_ip4( p+13, tmpip )) goto parse_error; | 353 | if( !scan_ip6( p+13, tmpip )) goto parse_error; |
350 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); | 354 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); |
351 | #endif | 355 | #endif |
352 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { | 356 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { |
353 | set_config_option( &g_redirecturl, p+21 ); | 357 | set_config_option( &g_redirecturl, p+21 ); |
354 | #ifdef WANT_SYNC_LIVE | 358 | #ifdef WANT_SYNC_LIVE |
355 | } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { | 359 | } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { |
356 | if( !scan_ip4( p+25, tmpip )) goto parse_error; | 360 | if( !scan_ip6( p+25, tmpip )) goto parse_error; |
357 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); | 361 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); |
358 | } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { | 362 | } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { |
359 | uint16_t tmpport = LIVESYNC_PORT; | 363 | uint16_t tmpport = LIVESYNC_PORT; |
360 | if( !scan_ip4_port( p+24, tmpip, &tmpport )) goto parse_error; | 364 | if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error; |
361 | livesync_bind_mcast( tmpip, tmpport ); | 365 | livesync_bind_mcast( tmpip, tmpport ); |
362 | #endif | 366 | #endif |
363 | } else | 367 | } else |
@@ -411,10 +415,12 @@ int drop_privileges (const char * const serverdir) { | |||
411 | } | 415 | } |
412 | 416 | ||
413 | int main( int argc, char **argv ) { | 417 | int main( int argc, char **argv ) { |
414 | char serverip[4] = {0,0,0,0}, tmpip[4]; | 418 | ot_ip6 serverip, tmpip; |
415 | int bound = 0, scanon = 1; | 419 | int bound = 0, scanon = 1; |
416 | uint16_t tmpport; | 420 | uint16_t tmpport; |
417 | 421 | ||
422 | memset( serverip, 0, sizeof(ot_ip6) ); | ||
423 | |||
418 | while( scanon ) { | 424 | while( scanon ) { |
419 | switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v" | 425 | switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v" |
420 | #ifdef WANT_ACCESSLIST_BLACK | 426 | #ifdef WANT_ACCESSLIST_BLACK |
@@ -425,7 +431,7 @@ while( scanon ) { | |||
425 | "h" ) ) { | 431 | "h" ) ) { |
426 | case -1 : scanon = 0; break; | 432 | case -1 : scanon = 0; break; |
427 | case 'i': | 433 | case 'i': |
428 | if( !scan_ip4( optarg, serverip )) { usage( argv[0] ); exit( 1 ); } | 434 | if( !scan_ip6( optarg, serverip )) { usage( argv[0] ); exit( 1 ); } |
429 | break; | 435 | break; |
430 | #ifdef WANT_ACCESSLIST_BLACK | 436 | #ifdef WANT_ACCESSLIST_BLACK |
431 | case 'b': set_config_option( &g_accesslist_filename, optarg); break; | 437 | case 'b': set_config_option( &g_accesslist_filename, optarg); break; |
@@ -446,7 +452,7 @@ while( scanon ) { | |||
446 | case 'd': set_config_option( &g_serverdir, optarg ); break; | 452 | case 'd': set_config_option( &g_serverdir, optarg ); break; |
447 | case 'r': set_config_option( &g_redirecturl, optarg ); break; | 453 | case 'r': set_config_option( &g_redirecturl, optarg ); break; |
448 | case 'A': | 454 | case 'A': |
449 | if( !scan_ip4( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } | 455 | if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } |
450 | accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ | 456 | accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ |
451 | break; | 457 | break; |
452 | case 'f': bound += parse_configfile( optarg ); break; | 458 | case 'f': bound += parse_configfile( optarg ); break; |