summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c86
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
153static void handle_accept( const int64 serversocket ) { 153static 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
244static int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) { 238static 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
282static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { 279static 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
297int parse_configfile( char * config_filename ) { 300int 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
413int main( int argc, char **argv ) { 417int 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
418while( scanon ) { 424while( 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;