mirror of
				git://erdgeist.org/opentracker
				synced 2025-11-04 03:43:23 +08:00 
			
		
		
		
	Documentation improved, some reindenting (again), variable types checked, unnecessary defines removed
This commit is contained in:
		
							parent
							
								
									cb12e922d5
								
							
						
					
					
						commit
						805e46450c
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@ -2,7 +2,7 @@ CC?=gcc
 | 
				
			|||||||
FEATURES=-DWANT_IP_FROM_QUERY_STRING #-DWANT_BLACKLIST -DWANT_CLOSED_TRACKER
 | 
					FEATURES=-DWANT_IP_FROM_QUERY_STRING #-DWANT_BLACKLIST -DWANT_CLOSED_TRACKER
 | 
				
			||||||
#DEBUG_OPTS=-g -ggdb -pg # -fprofile-arcs -ftest-coverage
 | 
					#DEBUG_OPTS=-g -ggdb -pg # -fprofile-arcs -ftest-coverage
 | 
				
			||||||
DEBUG_OPTS=-s -Os
 | 
					DEBUG_OPTS=-s -Os
 | 
				
			||||||
CFLAGS+=-I../libowfat -Wall -pipe
 | 
					CFLAGS+=-I../libowfat -Wall -pipe # -pedantic -ansi
 | 
				
			||||||
LDFLAGS+=-L../libowfat/ -lowfat -lm
 | 
					LDFLAGS+=-L../libowfat/ -lowfat -lm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HEADERS=trackerlogic.h scan_urlencoded_query.h
 | 
					HEADERS=trackerlogic.h scan_urlencoded_query.h
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										394
									
								
								opentracker.c
									
									
									
									
									
								
							
							
						
						
									
										394
									
								
								opentracker.c
									
									
									
									
									
								
							@ -6,8 +6,8 @@
 | 
				
			|||||||
#include "socket.h"
 | 
					#include "socket.h"
 | 
				
			||||||
#include "io.h"
 | 
					#include "io.h"
 | 
				
			||||||
#include "buffer.h"
 | 
					#include "buffer.h"
 | 
				
			||||||
#include "ip6.h"
 | 
					 | 
				
			||||||
#include "array.h"
 | 
					#include "array.h"
 | 
				
			||||||
 | 
					#include "byte.h"
 | 
				
			||||||
#include "case.h"
 | 
					#include "case.h"
 | 
				
			||||||
#include "fmt.h"
 | 
					#include "fmt.h"
 | 
				
			||||||
#include "str.h"
 | 
					#include "str.h"
 | 
				
			||||||
@ -25,14 +25,14 @@
 | 
				
			|||||||
#include "trackerlogic.h"
 | 
					#include "trackerlogic.h"
 | 
				
			||||||
#include "scan_urlencoded_query.h"
 | 
					#include "scan_urlencoded_query.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long const OT_CLIENT_TIMEOUT = 15;
 | 
					unsigned int const OT_CLIENT_TIMEOUT = 15;
 | 
				
			||||||
unsigned long const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5;
 | 
					unsigned int const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int ot_overall_connections = 0;
 | 
					static unsigned int ot_overall_connections = 0;
 | 
				
			||||||
static time_t ot_start_time;
 | 
					static time_t ot_start_time;
 | 
				
			||||||
static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80;
 | 
					static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80;
 | 
				
			||||||
static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17;
 | 
					static const size_t SUCCESS_HTTP_SIZE_OFF = 17;
 | 
				
			||||||
// To always have space for error messages
 | 
					/* To always have space for error messages ;) */
 | 
				
			||||||
static char static_reply[8192];
 | 
					static char static_reply[8192];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void carp(const char* routine) {
 | 
					static void carp(const char* routine) {
 | 
				
			||||||
@ -49,13 +49,12 @@ static void panic(const char* routine) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct http_data {
 | 
					struct http_data {
 | 
				
			||||||
  array r;
 | 
					  array r;
 | 
				
			||||||
  unsigned long ip;
 | 
					  unsigned char ip[4];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int header_complete(struct http_data* r) {
 | 
					int header_complete(struct http_data* r) {
 | 
				
			||||||
  long l = array_bytes(&r->r);
 | 
					  int l = array_bytes(&r->r), i;
 | 
				
			||||||
  const char* c = array_start(&r->r);
 | 
					  const char* c = array_start(&r->r);
 | 
				
			||||||
  long i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (i=0; i+1<l; ++i) {
 | 
					  for (i=0; i+1<l; ++i) {
 | 
				
			||||||
    if (c[i]=='\n' && c[i+1]=='\n') return i+2;
 | 
					    if (c[i]=='\n' && c[i+1]=='\n') return i+2;
 | 
				
			||||||
@ -64,7 +63,7 @@ int header_complete(struct http_data* r) {
 | 
				
			|||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// whoever sends data is not interested in its input-array
 | 
					/* whoever sends data is not interested in its input-array */
 | 
				
			||||||
void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) {
 | 
					void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) {
 | 
				
			||||||
  size_t written_size;
 | 
					  size_t written_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,7 +72,7 @@ void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) {
 | 
				
			|||||||
  if( ( written_size < 0 ) || ( written_size == size ) ) {
 | 
					  if( ( written_size < 0 ) || ( written_size == size ) ) {
 | 
				
			||||||
    free(h); io_close( s );
 | 
					    free(h); io_close( s );
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    // here we would take a copy of the buffer and remember it
 | 
					    /* here we would take a copy of the buffer and remember it */
 | 
				
			||||||
    fprintf( stderr, "Should have handled this.\n" );
 | 
					    fprintf( stderr, "Should have handled this.\n" );
 | 
				
			||||||
    free(h); io_close( s );
 | 
					    free(h); io_close( s );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -85,218 +84,225 @@ void httperror(int64 s,struct http_data* h,const char* title,const char* message
 | 
				
			|||||||
  senddata(s,h,static_reply,reply_size);
 | 
					  senddata(s,h,static_reply,reply_size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// bestimmten http parameter auslesen und adresse zurueckgeben
 | 
					 | 
				
			||||||
const char* http_header(struct http_data* r,const char* h) {
 | 
					const char* http_header(struct http_data* r,const char* h) {
 | 
				
			||||||
    long i;
 | 
					  int i, l = array_bytes(&r->r);
 | 
				
			||||||
 | 
					  int sl = strlen(h);
 | 
				
			||||||
 | 
					  const char* c = array_start(&r->r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    long l = array_bytes(&r->r);
 | 
					  for (i=0; i+sl+2<l; ++i) {
 | 
				
			||||||
    long sl = strlen(h);
 | 
					    if (c[i]=='\n' && case_equalb(c+i+1,sl,h) && c[i+sl+1]==':') {
 | 
				
			||||||
    const char* c = array_start(&r->r);
 | 
					      c+=i+sl+1;
 | 
				
			||||||
 | 
					      if (*c==' ' || *c=='\t') ++c;
 | 
				
			||||||
    for (i=0; i+sl+2<l; ++i)
 | 
					      return c;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (c[i]=='\n' && case_equalb(c+i+1,sl,h) && c[i+sl+1]==':')
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            c+=i+sl+1;
 | 
					 | 
				
			||||||
            if (*c==' ' || *c=='\t') ++c;
 | 
					 | 
				
			||||||
            return c;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void httpresponse(int64 s,struct http_data* h)
 | 
					void httpresponse(int64 s,struct http_data* h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char       *c, *data; // must be enough
 | 
					  char       *c, *data;
 | 
				
			||||||
    ot_peer     peer;
 | 
					  ot_peer     peer;
 | 
				
			||||||
    ot_torrent *torrent;
 | 
					  ot_torrent *torrent;
 | 
				
			||||||
    ot_hash    *hash = NULL;
 | 
					  ot_hash    *hash = NULL;
 | 
				
			||||||
    int         numwant, tmp, scanon;
 | 
					  int         numwant, tmp, scanon;
 | 
				
			||||||
    unsigned short port = htons(6881);
 | 
					  unsigned short port = htons(6881);
 | 
				
			||||||
    size_t      reply_size = 0;
 | 
					  size_t      reply_size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    array_cat0(&h->r);
 | 
					  array_cat0(&h->r);
 | 
				
			||||||
    c = array_start(&h->r);
 | 
					  c = array_start(&h->r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (byte_diff(c,4,"GET ")) {
 | 
					  if (byte_diff(c,4,"GET ")) {
 | 
				
			||||||
e400:
 | 
					e400:
 | 
				
			||||||
        return httperror(s,h,"400 Invalid Request","This server only understands GET.");
 | 
					    return httperror(s,h,"400 Invalid Request","This server only understands GET.");
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c+=4;
 | 
					  c+=4;
 | 
				
			||||||
    for (data=c; *data!=' '&&*data!='\t'&&*data!='\n'&&*data!='\r'; ++data) ;
 | 
					  for (data=c; *data!=' '&&*data!='\t'&&*data!='\n'&&*data!='\r'; ++data) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (*data!=' ') goto e400;
 | 
					  if (*data!=' ') goto e400;
 | 
				
			||||||
    *data=0;
 | 
					  *data=0;
 | 
				
			||||||
    if (c[0]!='/') goto e404;
 | 
					  if (c[0]!='/') goto e404;
 | 
				
			||||||
    while (*c=='/') ++c;
 | 
					  while (*c=='/') ++c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) )
 | 
					  switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) {
 | 
				
			||||||
    {
 | 
					  case 6: /* scrape ? */
 | 
				
			||||||
    case 6: /* scrape ? */
 | 
					    if (byte_diff(data,6,"scrape"))
 | 
				
			||||||
      if (byte_diff(data,6,"scrape"))
 | 
					      goto e404;
 | 
				
			||||||
 | 
					    scanon = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( scanon ) {
 | 
				
			||||||
 | 
					      switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
 | 
				
			||||||
 | 
					      case -2: /* terminator */
 | 
				
			||||||
 | 
					        scanon = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case -1: /* error */
 | 
				
			||||||
        goto e404;
 | 
					        goto e404;
 | 
				
			||||||
      scanon = 1;
 | 
					      case 9:
 | 
				
			||||||
 | 
					        if(byte_diff(data,9,"info_hash")) {
 | 
				
			||||||
      while( scanon ) {
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
        switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
 | 
					          continue;
 | 
				
			||||||
        case -2: /* terminator */
 | 
					        }
 | 
				
			||||||
          scanon = 0;
 | 
					        /* ignore this, when we have less than 20 bytes */
 | 
				
			||||||
          break;
 | 
					        if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) {
 | 
				
			||||||
        case -1: /* error */
 | 
					 | 
				
			||||||
          goto e404;
 | 
					 | 
				
			||||||
        case 9:
 | 
					 | 
				
			||||||
          if(byte_diff(data,9,"info_hash")) {
 | 
					 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          /* ignore this, when we have less than 20 bytes */
 | 
					 | 
				
			||||||
          if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) {
 | 
					 | 
				
			||||||
e400_param:
 | 
					e400_param:
 | 
				
			||||||
            return httperror(s,h,"400 Invalid Request","Invalid parameter");
 | 
					          return httperror(s,h,"400 Invalid Request","Invalid parameter");
 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          hash = (ot_hash*)data; /* Fall through intended */
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        hash = (ot_hash*)data; /* Fall through intended */
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* Scanned whole query string, wo */
 | 
					    /* Scanned whole query string, wo */
 | 
				
			||||||
      if( !hash )
 | 
					    if( !hash )
 | 
				
			||||||
        return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes.");
 | 
					      return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Enough for http header + whole scrape string
 | 
					    /* Enough for http header + whole scrape string */
 | 
				
			||||||
      if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
 | 
					    if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
 | 
				
			||||||
        goto e500;
 | 
					      goto e500;
 | 
				
			||||||
      break;
 | 
					    break;
 | 
				
			||||||
    case 8: 
 | 
					  case 8: 
 | 
				
			||||||
      if( byte_diff(data,8,"announce"))
 | 
					    if( byte_diff(data,8,"announce"))
 | 
				
			||||||
 | 
					      goto e404;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OT_SETIP( &peer, h->ip);
 | 
				
			||||||
 | 
					    OT_SETPORT( &peer, &port );
 | 
				
			||||||
 | 
					    OT_FLAG( &peer ) = 0;
 | 
				
			||||||
 | 
					    numwant = 50;
 | 
				
			||||||
 | 
					    scanon = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( scanon ) {
 | 
				
			||||||
 | 
					      switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
 | 
				
			||||||
 | 
					      case -2: /* terminator */
 | 
				
			||||||
 | 
					        scanon = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case -1: /* error */
 | 
				
			||||||
        goto e404;
 | 
					        goto e404;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      OT_SETIP( &peer, &h->ip);
 | 
					 | 
				
			||||||
      OT_SETPORT( &peer, &port );
 | 
					 | 
				
			||||||
      OT_FLAG( &peer ) = 0;
 | 
					 | 
				
			||||||
      numwant = 50;
 | 
					 | 
				
			||||||
      scanon = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      while( scanon ) {
 | 
					 | 
				
			||||||
        switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
 | 
					 | 
				
			||||||
        case -2: /* terminator */
 | 
					 | 
				
			||||||
          scanon = 0;
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case -1: /* error */
 | 
					 | 
				
			||||||
          goto e404;
 | 
					 | 
				
			||||||
#ifdef WANT_IP_FROM_QUERY_STRING
 | 
					#ifdef WANT_IP_FROM_QUERY_STRING
 | 
				
			||||||
        case 2:
 | 
					      case 2:
 | 
				
			||||||
          if(!byte_diff(data,2,"ip")) {
 | 
					        if(!byte_diff(data,2,"ip")) {
 | 
				
			||||||
            size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
					          size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
            unsigned char ip[4];
 | 
					          unsigned char ip[4];
 | 
				
			||||||
            if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) goto e400_param;
 | 
					          if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) goto e400_param;
 | 
				
			||||||
            OT_SETIP ( &peer, ip );
 | 
					          OT_SETIP ( &peer, ip );
 | 
				
			||||||
         } else
 | 
					       } else
 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
         break;
 | 
					       break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        case 4:
 | 
					      case 4:
 | 
				
			||||||
          if(!byte_diff(data,4,"port")) {
 | 
					        if(!byte_diff(data,4,"port")) {
 | 
				
			||||||
            size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
					          size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
            if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) || ( tmp > 0xffff ) ) goto e400_param;
 | 
					          if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) || ( tmp > 0xffff ) ) goto e400_param;
 | 
				
			||||||
            port = htons( tmp ); OT_SETPORT ( &peer, &port );
 | 
					          port = htons( tmp ); OT_SETPORT ( &peer, &port );
 | 
				
			||||||
          } else if(!byte_diff(data,4,"left")) {
 | 
					        } else if(!byte_diff(data,4,"left")) {
 | 
				
			||||||
            size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
					          size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
            if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param;
 | 
					          if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param;
 | 
				
			||||||
            if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING;
 | 
					          if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING;
 | 
				
			||||||
          } else
 | 
					        } else
 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
          break;
 | 
					        break;
 | 
				
			||||||
        case 5:
 | 
					      case 5:
 | 
				
			||||||
          if(byte_diff(data,5,"event"))
 | 
					        if(byte_diff(data,5,"event"))
 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
          else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) {
 | 
					        else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) {
 | 
				
			||||||
          case -1:
 | 
					        case -1:
 | 
				
			||||||
            goto e400_param;
 | 
					          goto e400_param;
 | 
				
			||||||
          case 7:
 | 
					 | 
				
			||||||
            if(!byte_diff(data,7,"stopped")) OT_FLAG( &peer ) |= PEER_FLAG_STOPPED;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          case 9:
 | 
					 | 
				
			||||||
            if(!byte_diff(data,9,"complete")) OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED;
 | 
					 | 
				
			||||||
          default: // Fall through intended
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 7:
 | 
					        case 7:
 | 
				
			||||||
          if(!byte_diff(data,7,"numwant")) {
 | 
					          if(!byte_diff(data,7,"stopped")) OT_FLAG( &peer ) |= PEER_FLAG_STOPPED;
 | 
				
			||||||
            size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
					 | 
				
			||||||
            if( ( len <= 0 ) || scan_fixed_int( data, len, &numwant ) ) goto e400_param;
 | 
					 | 
				
			||||||
            if( numwant > 200 ) numwant = 200;
 | 
					 | 
				
			||||||
          } else if(!byte_diff(data,7,"compact")) {
 | 
					 | 
				
			||||||
            size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
					 | 
				
			||||||
            if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param;
 | 
					 | 
				
			||||||
            if( !tmp )
 | 
					 | 
				
			||||||
              return httperror(s,h,"400 Invalid Request","This server only delivers compact results.");
 | 
					 | 
				
			||||||
          } else
 | 
					 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 9:
 | 
					        case 9:
 | 
				
			||||||
          if(byte_diff(data,9,"info_hash")) {
 | 
					          if(!byte_diff(data,9,"complete")) OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED;
 | 
				
			||||||
            scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					        default: /* Fall through intended */
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          /* ignore this, when we have less than 20 bytes */
 | 
					 | 
				
			||||||
          if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 )
 | 
					 | 
				
			||||||
            goto e400;
 | 
					 | 
				
			||||||
          hash = (ot_hash*)data;
 | 
					 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        default:
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 7:
 | 
				
			||||||
 | 
					        if(!byte_diff(data,7,"numwant")) {
 | 
				
			||||||
 | 
					          size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
 | 
					          if( ( len <= 0 ) || scan_fixed_int( data, len, &numwant ) ) goto e400_param;
 | 
				
			||||||
 | 
					          if( numwant > 200 ) numwant = 200;
 | 
				
			||||||
 | 
					        } else if(!byte_diff(data,7,"compact")) {
 | 
				
			||||||
 | 
					          size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
 | 
					          if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param;
 | 
				
			||||||
 | 
					          if( !tmp )
 | 
				
			||||||
 | 
					            return httperror(s,h,"400 Invalid Request","This server only delivers compact results.");
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
          break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case 9:
 | 
				
			||||||
 | 
					        if(byte_diff(data,9,"info_hash")) {
 | 
				
			||||||
 | 
					          scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        /* ignore this, when we have less than 20 bytes */
 | 
				
			||||||
 | 
					        if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 )
 | 
				
			||||||
 | 
					          goto e400;
 | 
				
			||||||
 | 
					        hash = (ot_hash*)data;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      /* Scanned whole query string */
 | 
					 | 
				
			||||||
      if( !hash ) goto e400;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
 | 
					 | 
				
			||||||
        remove_peer_from_torrent( hash, &peer );
 | 
					 | 
				
			||||||
        MEMMOVE( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 );
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        torrent = add_peer_to_torrent( hash, &peer );
 | 
					 | 
				
			||||||
        if( !torrent ) {
 | 
					 | 
				
			||||||
e500:
 | 
					 | 
				
			||||||
          return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later.");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
 | 
					 | 
				
			||||||
          goto e500;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 11:
 | 
					 | 
				
			||||||
      if( byte_diff(data,11,"mrtg_scrape"))
 | 
					 | 
				
			||||||
        goto e404;
 | 
					 | 
				
			||||||
      { 
 | 
					 | 
				
			||||||
        unsigned long seconds_elapsed = time( NULL ) - ot_start_time;
 | 
					 | 
				
			||||||
        reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH, 
 | 
					 | 
				
			||||||
                              "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.",
 | 
					 | 
				
			||||||
                              ot_overall_connections, ot_overall_connections, seconds_elapsed,
 | 
					 | 
				
			||||||
                              seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    default: /* neither *scrape nor announce */
 | 
					 | 
				
			||||||
e404:
 | 
					 | 
				
			||||||
      return httperror(s,h,"404 Not Found","No such file or directory.");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( reply_size ) {
 | 
					    /* Scanned whole query string */
 | 
				
			||||||
      size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size );
 | 
					    if( !hash ) goto e400;
 | 
				
			||||||
      reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size );
 | 
					
 | 
				
			||||||
      static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n';
 | 
					    if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
 | 
				
			||||||
      senddata( s, h, static_reply + reply_off, reply_size );
 | 
					      remove_peer_from_torrent( hash, &peer );
 | 
				
			||||||
 | 
					      memmove( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 );
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      if( h ) array_reset(&h->r);
 | 
					      torrent = add_peer_to_torrent( hash, &peer );
 | 
				
			||||||
      free( h ); io_close( s );
 | 
					      if( !torrent ) {
 | 
				
			||||||
 | 
					e500:
 | 
				
			||||||
 | 
					        return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later.");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
 | 
				
			||||||
 | 
					        goto e500;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case 11:
 | 
				
			||||||
 | 
					    if( byte_diff(data,11,"mrtg_scrape"))
 | 
				
			||||||
 | 
					      goto e404;
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      time_t seconds_elapsed = time( NULL ) - ot_start_time;
 | 
				
			||||||
 | 
					      reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH, 
 | 
				
			||||||
 | 
					                            "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.",
 | 
				
			||||||
 | 
					                            ot_overall_connections, ot_overall_connections, seconds_elapsed,
 | 
				
			||||||
 | 
					                            seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  default: /* neither *scrape nor announce */
 | 
				
			||||||
 | 
					e404:
 | 
				
			||||||
 | 
					    return httperror(s,h,"404 Not Found","No such file or directory.");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if( reply_size ) {
 | 
				
			||||||
 | 
					    /* This one is rather ugly, so I take you step by step through it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       1. In order to avoid having two buffers, one for header and one for content, we allow all above functions from trackerlogic to
 | 
				
			||||||
 | 
					       write to a fixed location, leaving SUCCESS_HTTP_HEADER_LENGTH bytes in our static buffer, which is enough for the static string
 | 
				
			||||||
 | 
					       plus dynamic space needed to expand our Content-Length value. We reserve SUCCESS_HTTP_SIZE_OFF for it expansion and calculate
 | 
				
			||||||
 | 
					       the space NOT needed to expand in reply_off
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete
 | 
				
			||||||
 | 
					       packet size is increased by size of header plus one byte '\n', we  will copy over '\0' in next step */
 | 
				
			||||||
 | 
					    reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 3. Finally we join both blocks neatly */
 | 
				
			||||||
 | 
					    static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    senddata( s, h, static_reply + reply_off, reply_size );
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if( h ) array_reset(&h->r);
 | 
				
			||||||
 | 
					    free( h ); io_close( s );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void graceful( int s ) {
 | 
					void graceful( int s ) {
 | 
				
			||||||
@ -346,10 +352,10 @@ void help( char *name ) {
 | 
				
			|||||||
int main( int argc, char **argv ) {
 | 
					int main( int argc, char **argv ) {
 | 
				
			||||||
  int s=socket_tcp4();
 | 
					  int s=socket_tcp4();
 | 
				
			||||||
  tai6464 t, next_timeout_check;
 | 
					  tai6464 t, next_timeout_check;
 | 
				
			||||||
  unsigned long ip;
 | 
					 | 
				
			||||||
  char *serverip = NULL;
 | 
					  char *serverip = NULL;
 | 
				
			||||||
  char *serverdir = ".";
 | 
					  char *serverdir = ".";
 | 
				
			||||||
  uint16 port = 6969;
 | 
					  uint16 port = 6969;
 | 
				
			||||||
 | 
					  unsigned char ip[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while( 1 ) {
 | 
					  while( 1 ) {
 | 
				
			||||||
    switch( getopt(argc,argv,":i:p:d:ocbBh") ) {
 | 
					    switch( getopt(argc,argv,":i:p:d:ocbBh") ) {
 | 
				
			||||||
@ -412,16 +418,16 @@ allparsed:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while( ( i = io_canread() ) != -1 ) {
 | 
					    while( ( i = io_canread() ) != -1 ) {
 | 
				
			||||||
      if( i == s ) { // ist es der serversocket?
 | 
					      if( i == s ) {
 | 
				
			||||||
        int n;
 | 
					        int n;
 | 
				
			||||||
        while( ( n = socket_accept4( s, (void*)&ip, &port) ) != -1 ) {
 | 
					        while( ( n = socket_accept4( s, (char*)ip, &port) ) != -1 ) {
 | 
				
			||||||
          if( io_fd( n ) ) {
 | 
					          if( io_fd( n ) ) {
 | 
				
			||||||
            struct http_data* h=(struct http_data*)malloc(sizeof(struct http_data));
 | 
					            struct http_data* h=(struct http_data*)malloc(sizeof(struct http_data));
 | 
				
			||||||
            io_wantread(n);
 | 
					            io_wantread(n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (h) {
 | 
					            if (h) {
 | 
				
			||||||
              byte_zero(h,sizeof(struct http_data));
 | 
					              byte_zero(h,sizeof(struct http_data));
 | 
				
			||||||
              h->ip=ip;
 | 
					              memmove(h->ip,ip,sizeof(ip));
 | 
				
			||||||
              taia_now(&t);
 | 
					              taia_now(&t);
 | 
				
			||||||
              taia_addsec(&t,&t,OT_CLIENT_TIMEOUT);
 | 
					              taia_addsec(&t,&t,OT_CLIENT_TIMEOUT);
 | 
				
			||||||
              io_timeout(n,t);
 | 
					              io_timeout(n,t);
 | 
				
			||||||
@ -437,7 +443,7 @@ allparsed:
 | 
				
			|||||||
        else
 | 
					        else
 | 
				
			||||||
          carp("socket_accept4");
 | 
					          carp("socket_accept4");
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        char buf[8192];
 | 
					        /* unsigned (sic!) */ char buf[8192];
 | 
				
			||||||
        struct http_data* h=io_getcookie(i);
 | 
					        struct http_data* h=io_getcookie(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int l=io_tryread(i,buf,sizeof buf);
 | 
					        int l=io_tryread(i,buf,sizeof buf);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,15 +4,15 @@
 | 
				
			|||||||
#include "scan.h"
 | 
					#include "scan.h"
 | 
				
			||||||
#include "scan_urlencoded_query.h"
 | 
					#include "scan_urlencoded_query.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Idea is to do a in place replacement or guarantee at least
 | 
					/* Idea is to do a in place replacement or guarantee at least
 | 
				
			||||||
// strlen( string ) bytes in deststring
 | 
					   strlen( string ) bytes in deststring
 | 
				
			||||||
// watch http://www.ietf.org/rfc/rfc2396.txt
 | 
					   watch http://www.ietf.org/rfc/rfc2396.txt
 | 
				
			||||||
//       unreserved    = alphanum | mark
 | 
					         unreserved    = alphanum | mark
 | 
				
			||||||
//       mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
 | 
					         mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
 | 
				
			||||||
// we add '%' to the matrix to not stop at encoded chars.
 | 
					   we add '%' to the matrix to not stop at encoded chars.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
static const unsigned char reserved_matrix[] = { 0xA2, 0x63, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x47};
 | 
					static const unsigned char reserved_matrix[] = { 0xA2, 0x63, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x47};
 | 
				
			||||||
inline int is_unreserved( unsigned char c ) {
 | 
					static int is_unreserved( unsigned char c ) {
 | 
				
			||||||
  if( ( c <= 32 ) || ( c >= 127 ) ) return 0; return 1&(reserved_matrix[(c-32)>>3]>>(c&7));
 | 
					  if( ( c <= 32 ) || ( c >= 127 ) ) return 0; return 1&(reserved_matrix[(c-32)>>3]>>(c&7));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,23 +8,26 @@
 | 
				
			|||||||
#define SCAN_SEARCHPATH_PARAM 1
 | 
					#define SCAN_SEARCHPATH_PARAM 1
 | 
				
			||||||
#define SCAN_SEARCHPATH_VALUE 2
 | 
					#define SCAN_SEARCHPATH_VALUE 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// string     pointer to source, pointer to after terminator on return
 | 
					/* string     pointer to source, pointer to after terminator on return
 | 
				
			||||||
// deststring pointer to destination
 | 
					   deststring pointer to destination
 | 
				
			||||||
// flags      determines, what to parse
 | 
					   flags      determines, what to parse
 | 
				
			||||||
// returns    number of valid converted characters in deststring
 | 
					   returns    number of valid converted characters in deststring
 | 
				
			||||||
//            or -1 for parse error
 | 
					              or -1 for parse error
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
size_t scan_urlencoded_query(char **string, char *deststring, int flags);
 | 
					size_t scan_urlencoded_query(char **string, char *deststring, int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// data       pointer to len chars of string
 | 
					/* data       pointer to len chars of string
 | 
				
			||||||
// len        length of chars in data to parse
 | 
					   len        length of chars in data to parse
 | 
				
			||||||
// number     number to receive result
 | 
					   number     number to receive result
 | 
				
			||||||
// returns    number of bytes not parsed, mostly !=0 means fail
 | 
					   returns    number of bytes not parsed, mostly !=0 means fail
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
size_t scan_fixed_int( char *data, size_t len, int *number );
 | 
					size_t scan_fixed_int( char *data, size_t len, int *number );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// data       pointer to len chars of string
 | 
					/* data       pointer to len chars of string
 | 
				
			||||||
// len        length of chars in data to parse
 | 
					   len        length of chars in data to parse
 | 
				
			||||||
// ip         buffer to receive result
 | 
					   ip         buffer to receive result
 | 
				
			||||||
// returns    number of bytes not parsed, mostly !=0 means fail
 | 
					   returns    number of bytes not parsed, mostly !=0 means fail
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] );
 | 
					size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										125
									
								
								trackerlogic.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								trackerlogic.c
									
									
									
									
									
								
							@ -22,8 +22,7 @@
 | 
				
			|||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GLOBAL VARIABLES
 | 
					/* GLOBAL VARIABLES */
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
static ot_vector all_torrents[256];
 | 
					static ot_vector all_torrents[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WANT_CLOSED_TRACKER
 | 
					#ifdef WANT_CLOSED_TRACKER
 | 
				
			||||||
@ -36,36 +35,37 @@ int g_check_blacklist = 1;
 | 
				
			|||||||
static ot_torrent* const OT_TORRENT_ON_BLACKLIST = (ot_torrent*)2;
 | 
					static ot_torrent* const OT_TORRENT_ON_BLACKLIST = (ot_torrent*)2;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This function gives us a binary search that returns a pointer, even if
 | 
					/* This function gives us a binary search that returns a pointer, even if
 | 
				
			||||||
// no exact match is found. In that case it sets exactmatch 0 and gives
 | 
					   no exact match is found. In that case it sets exactmatch 0 and gives
 | 
				
			||||||
// calling functions the chance to insert data
 | 
					   calling functions the chance to insert data
 | 
				
			||||||
//
 | 
					*/
 | 
				
			||||||
static void *binary_search( const void *key, const void *base, unsigned long member_count, const unsigned long member_size,
 | 
					static void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size,
 | 
				
			||||||
                            int compare_size, int *exactmatch ) {
 | 
					                            size_t compare_size, int *exactmatch ) {
 | 
				
			||||||
 | 
					  size_t mc = member_count;
 | 
				
			||||||
  ot_byte *lookat = ((ot_byte*)base) + member_size * (member_count >> 1);
 | 
					  ot_byte *lookat = ((ot_byte*)base) + member_size * (member_count >> 1);
 | 
				
			||||||
  *exactmatch = 1;
 | 
					  *exactmatch = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while( member_count ) {
 | 
					  while( mc ) {
 | 
				
			||||||
    int cmp = memcmp( lookat, key, compare_size);
 | 
					    int cmp = memcmp( lookat, key, compare_size);
 | 
				
			||||||
    if (cmp == 0) return (void *)lookat;
 | 
					    if (cmp == 0) return (void *)lookat;
 | 
				
			||||||
    if (cmp < 0) {
 | 
					    if (cmp < 0) {
 | 
				
			||||||
      base = (void*)(lookat + member_size);
 | 
					      base = (void*)(lookat + member_size);
 | 
				
			||||||
      --member_count;
 | 
					      --mc;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    member_count >>= 1;
 | 
					    mc >>= 1;
 | 
				
			||||||
    lookat = ((ot_byte*)base) + member_size * (member_count >> 1);
 | 
					    lookat = ((ot_byte*)base) + member_size * (mc >> 1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *exactmatch = 0;
 | 
					  *exactmatch = 0;
 | 
				
			||||||
  return (void*)lookat;
 | 
					  return (void*)lookat;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Converter function from memory to human readable hex strings
 | 
					/* Converter function from memory to human readable hex strings
 | 
				
			||||||
// * definitely not thread safe!!!
 | 
					   - definitely not thread safe!!!
 | 
				
			||||||
//
 | 
					*/
 | 
				
			||||||
char ths[2+2*20]="-";char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+41;char*t=ths+1;while(t<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths+1;}
 | 
					char ths[2+2*20]="-";char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+41;char*t=ths+1;while(t<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths+1;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int compare_size, int *exactmatch ) {
 | 
					static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int compare_size, int *exactmatch ) {
 | 
				
			||||||
  ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_size, exactmatch );
 | 
					  ot_byte *match = binary_search( key, vector->data, vector->size, member_size, compare_size, exactmatch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( *exactmatch ) return match;
 | 
					  if( *exactmatch ) return match;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,13 +74,13 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_
 | 
				
			|||||||
    ot_byte *new_data = realloc( vector->data, new_space * member_size );
 | 
					    ot_byte *new_data = realloc( vector->data, new_space * member_size );
 | 
				
			||||||
    if( !new_data ) return NULL;
 | 
					    if( !new_data ) return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Adjust pointer if it moved by realloc
 | 
					    /* Adjust pointer if it moved by realloc */
 | 
				
			||||||
    match = new_data + (match - (ot_byte*)vector->data);
 | 
					    match = new_data + (match - (ot_byte*)vector->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vector->data = new_data;
 | 
					    vector->data = new_data;
 | 
				
			||||||
    vector->space = new_space;
 | 
					    vector->space = new_space;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
 | 
					  memmove( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
 | 
				
			||||||
  vector->size++;
 | 
					  vector->size++;
 | 
				
			||||||
  return match;
 | 
					  return match;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -91,11 +91,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
 | 
				
			|||||||
  ot_peer *match;
 | 
					  ot_peer *match;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !vector->size ) return 0;
 | 
					  if( !vector->size ) return 0;
 | 
				
			||||||
  match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
 | 
					  match = binary_search( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !exactmatch ) return 0;
 | 
					  if( !exactmatch ) return 0;
 | 
				
			||||||
  exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1;
 | 
					  exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1;
 | 
				
			||||||
  MEMMOVE( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) );
 | 
					  memmove( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) );
 | 
				
			||||||
  if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
 | 
					  if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
 | 
				
			||||||
    vector->space /= OT_VECTOR_SHRINK_RATIO;
 | 
					    vector->space /= OT_VECTOR_SHRINK_RATIO;
 | 
				
			||||||
    vector->data = realloc( vector->data, vector->space * sizeof( ot_peer ) );
 | 
					    vector->data = realloc( vector->data, vector->space * sizeof( ot_peer ) );
 | 
				
			||||||
@ -117,15 +117,15 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
 | 
				
			|||||||
  ot_torrent *match;
 | 
					  ot_torrent *match;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !vector->size ) return 0;
 | 
					  if( !vector->size ) return 0;
 | 
				
			||||||
  match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
					  match = binary_search( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !exactmatch ) return 0;
 | 
					  if( !exactmatch ) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // If this is being called after a unsuccessful malloc() for peer_list
 | 
					  /* If this is being called after a unsuccessful malloc() for peer_list
 | 
				
			||||||
  // in add_peer_to_torrent, match->peer_list actually might be NULL
 | 
					     in add_peer_to_torrent, match->peer_list actually might be NULL */
 | 
				
			||||||
  if( match->peer_list) free_peerlist( match->peer_list );
 | 
					  if( match->peer_list) free_peerlist( match->peer_list );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MEMMOVE( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) );
 | 
					  memmove( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) );
 | 
				
			||||||
  if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
 | 
					  if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
 | 
				
			||||||
    vector->space /= OT_VECTOR_SHRINK_RATIO;
 | 
					    vector->space /= OT_VECTOR_SHRINK_RATIO;
 | 
				
			||||||
    vector->data = realloc( vector->data, vector->space * sizeof( ot_torrent ) );
 | 
					    vector->data = realloc( vector->data, vector->space * sizeof( ot_torrent ) );
 | 
				
			||||||
@ -133,22 +133,21 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
 | 
				
			|||||||
  return 1;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 1, if torrent is gone, 0 otherwise
 | 
					/* Returns 1, if torrent is gone, 0 otherwise */
 | 
				
			||||||
static int clean_peerlist( ot_peerlist *peer_list ) {
 | 
					static int clean_peerlist( ot_peerlist *peer_list ) {
 | 
				
			||||||
  long timedout = NOW-peer_list->base;
 | 
					  int i, timedout = (int)( NOW - peer_list->base );
 | 
				
			||||||
  int i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !timedout ) return 0;
 | 
					  if( !timedout ) return 0;
 | 
				
			||||||
  if( timedout > OT_POOLS_COUNT ) timedout = OT_POOLS_COUNT;
 | 
					  if( timedout > OT_POOLS_COUNT ) timedout = OT_POOLS_COUNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for( i=OT_POOLS_COUNT-timedout; i<OT_POOLS_COUNT; ++i )
 | 
					  for( i = OT_POOLS_COUNT - timedout; i < OT_POOLS_COUNT; ++i )
 | 
				
			||||||
    free( peer_list->peers[i].data);
 | 
					    free( peer_list->peers[i].data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MEMMOVE( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * (OT_POOLS_COUNT-timedout) );
 | 
					  memmove( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * (OT_POOLS_COUNT-timedout) );
 | 
				
			||||||
  byte_zero( peer_list->peers, sizeof( ot_vector ) * timedout );
 | 
					  byte_zero( peer_list->peers, sizeof( ot_vector ) * timedout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MEMMOVE( peer_list->seed_count + timedout, peer_list->seed_count, sizeof( unsigned long ) * (OT_POOLS_COUNT-timedout) );
 | 
					  memmove( peer_list->seed_count + timedout, peer_list->seed_count, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout) );
 | 
				
			||||||
  byte_zero( peer_list->seed_count, sizeof( unsigned long ) * timedout );
 | 
					  byte_zero( peer_list->seed_count, sizeof( size_t ) * timedout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  peer_list->base = NOW;
 | 
					  peer_list->base = NOW;
 | 
				
			||||||
  return timedout == OT_POOLS_COUNT;
 | 
					  return timedout == OT_POOLS_COUNT;
 | 
				
			||||||
@ -178,8 +177,8 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
 | 
				
			|||||||
  if( !torrent ) return NULL;
 | 
					  if( !torrent ) return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !exactmatch ) {
 | 
					  if( !exactmatch ) {
 | 
				
			||||||
    // Create a new torrent entry, then
 | 
					    /* Create a new torrent entry, then */
 | 
				
			||||||
    MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
 | 
					    memmove( &torrent->hash, hash, sizeof( ot_hash ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    torrent->peer_list = malloc( sizeof (ot_peerlist) );
 | 
					    torrent->peer_list = malloc( sizeof (ot_peerlist) );
 | 
				
			||||||
    if( !torrent->peer_list ) {
 | 
					    if( !torrent->peer_list ) {
 | 
				
			||||||
@ -195,11 +194,11 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
 | 
				
			|||||||
  peer_pool = &torrent->peer_list->peers[0];
 | 
					  peer_pool = &torrent->peer_list->peers[0];
 | 
				
			||||||
  peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
 | 
					  peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // If we hadn't had a match in current pool, create peer there and
 | 
					  /* If we hadn't had a match in current pool, create peer there and
 | 
				
			||||||
  // remove it from all older pools
 | 
					     remove it from all older pools */
 | 
				
			||||||
  if( !exactmatch ) {
 | 
					  if( !exactmatch ) {
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    MEMMOVE( peer_dest, peer, sizeof( ot_peer ) );
 | 
					    memmove( peer_dest, peer, sizeof( ot_peer ) );
 | 
				
			||||||
    if( OT_FLAG(peer) & PEER_FLAG_SEEDING )
 | 
					    if( OT_FLAG(peer) & PEER_FLAG_SEEDING )
 | 
				
			||||||
      torrent->peer_list->seed_count[0]++;
 | 
					      torrent->peer_list->seed_count[0]++;
 | 
				
			||||||
    for( i=1; i<OT_POOLS_COUNT; ++i ) {
 | 
					    for( i=1; i<OT_POOLS_COUNT; ++i ) {
 | 
				
			||||||
@ -221,27 +220,30 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
 | 
				
			|||||||
  return torrent;
 | 
					  return torrent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Compiles a list of random peers for a torrent
 | 
					/* Compiles a list of random peers for a torrent
 | 
				
			||||||
// * reply must have enough space to hold 24+6*amount bytes
 | 
					   * reply must have enough space to hold 24+6*amount bytes
 | 
				
			||||||
// * Selector function can be anything, maybe test for seeds, etc.
 | 
					   * Selector function can be anything, maybe test for seeds, etc.
 | 
				
			||||||
// * RANDOM may return huge values
 | 
					   * RANDOM may return huge values
 | 
				
			||||||
// * does not yet check not to return self
 | 
					   * does not yet check not to return self
 | 
				
			||||||
//
 | 
					*/
 | 
				
			||||||
size_t return_peers_for_torrent( ot_torrent *torrent, unsigned long amount, char *reply ) {
 | 
					size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char *reply ) {
 | 
				
			||||||
  char           *r = reply;
 | 
					  char        *r = reply;
 | 
				
			||||||
  unsigned long  peer_count, seed_count, index;
 | 
					  unsigned int peer_count, seed_count, index;
 | 
				
			||||||
  signed   long  pool_offset = -1, pool_index = 0;
 | 
					  int          pool_offset = -1, pool_index = 0, wert = -1;
 | 
				
			||||||
  signed   long  wert = -1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WANT_CLOSED_TRACKER
 | 
					#ifdef WANT_CLOSED_TRACKER
 | 
				
			||||||
  if( torrent == OT_TORRENT_NOT_ON_WHITELIST ) {
 | 
					  if( torrent == OT_TORRENT_NOT_ON_WHITELIST ) {
 | 
				
			||||||
    return( FORMAT_FORMAT_STRING( reply, "d14:failure reason43:This torrent is not served by this tracker.e" ) );
 | 
					    const char * const notvalid = "d14:failure reason43:This torrent is not served by this tracker.e";
 | 
				
			||||||
 | 
					    memmove( reply, notvalid, sizeof(notvalid));
 | 
				
			||||||
 | 
					    return sizeof(notvalid);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WANT_BLACKLIST
 | 
					#ifdef WANT_BLACKLIST
 | 
				
			||||||
  if( torrent == OT_TORRENT_ON_BLACKLIST ) {
 | 
					  if( torrent == OT_TORRENT_ON_BLACKLIST ) {
 | 
				
			||||||
    return( FORMAT_FORMAT_STRING( reply, "d14:failure reason29:This torrent is black listed.e" ) );
 | 
					    const char * const blacklisted = "d14:failure reason29:This torrent is black listed.e";
 | 
				
			||||||
 | 
					    memmove( reply, blacklisted, sizeof(blacklisted));
 | 
				
			||||||
 | 
					    return sizeof(blacklisted);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -251,23 +253,19 @@ size_t return_peers_for_torrent( ot_torrent *torrent, unsigned long amount, char
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  if( peer_count < amount ) amount = peer_count;
 | 
					  if( peer_count < amount ) amount = peer_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  r += FORMAT_FORMAT_STRING( r, "d8:completei%lie10:incompletei%lie8:intervali600e5:peers%li:", seed_count, peer_count-seed_count, 6*amount );
 | 
					  r += sprintf( r, "d8:completei%ie10:incompletei%ie8:intervali600e5:peers%i:", seed_count, peer_count-seed_count, 6*amount );
 | 
				
			||||||
  for( index = 0; index < amount; ++index ) {
 | 
					  for( index = 0; index < amount; ++index ) {
 | 
				
			||||||
    double step = 1.8*((double)( peer_count - wert - 1 ))/((double)( amount - index ));
 | 
					    double step = 1.8*((double)( peer_count - wert - 1 ))/((double)( amount - index ));
 | 
				
			||||||
    int off = random() % (int)floor( step );
 | 
					    int off = random() % (int)floor( step );
 | 
				
			||||||
    off = 1 + ( off % ( peer_count - wert - 1 ));
 | 
					    off = 1 + ( off % ( peer_count - wert - 1 ));
 | 
				
			||||||
    wert += off; pool_offset += off;
 | 
					    wert += off; pool_offset += off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // In some rare occasions random gets the last peer a round to early
 | 
					 | 
				
			||||||
    // correct that and return last peer twice
 | 
					 | 
				
			||||||
    // if( wert >= peer_count ) { wert--; pool_offset--; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while( pool_offset >= torrent->peer_list->peers[pool_index].size ) {
 | 
					    while( pool_offset >= torrent->peer_list->peers[pool_index].size ) {
 | 
				
			||||||
      pool_offset -= torrent->peer_list->peers[pool_index].size;
 | 
					      pool_offset -= torrent->peer_list->peers[pool_index].size;
 | 
				
			||||||
      pool_index++;
 | 
					      pool_index++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MEMMOVE( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 );
 | 
					    memmove( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 );
 | 
				
			||||||
    r += 6;
 | 
					    r += 6;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *r++ = 'e';
 | 
					  *r++ = 'e';
 | 
				
			||||||
@ -275,12 +273,12 @@ size_t return_peers_for_torrent( ot_torrent *torrent, unsigned long amount, char
 | 
				
			|||||||
  return r - reply;
 | 
					  return r - reply;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fetches scrape info for a specific torrent
 | 
					/* Fetches scrape info for a specific torrent */
 | 
				
			||||||
size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) {
 | 
					size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) {
 | 
				
			||||||
  char        *r = reply;
 | 
					  char        *r = reply;
 | 
				
			||||||
  int          exactmatch, peers = 0, seeds = 0, i;
 | 
					  int          exactmatch, peers = 0, seeds = 0, i;
 | 
				
			||||||
  ot_vector   *torrents_list = &all_torrents[*hash[0]];
 | 
					  ot_vector   *torrents_list = &all_torrents[*hash[0]];
 | 
				
			||||||
  ot_torrent  *torrent = BINARY_FIND( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
					  ot_torrent  *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( !exactmatch ) return 0;
 | 
					  if( !exactmatch ) return 0;
 | 
				
			||||||
  clean_peerlist( torrent->peer_list );
 | 
					  clean_peerlist( torrent->peer_list );
 | 
				
			||||||
@ -290,8 +288,8 @@ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) {
 | 
				
			|||||||
    seeds += torrent->peer_list->seed_count[i];
 | 
					    seeds += torrent->peer_list->seed_count[i];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MEMMOVE( r, "d5:filesd20:", 12 ); MEMMOVE( r+12, hash, 20 );
 | 
					  memmove( r, "d5:filesd20:", 12 ); memmove( r+12, hash, 20 );
 | 
				
			||||||
  r += FORMAT_FORMAT_STRING( r+32, "d8:completei%de10:downloadedi%lde10:incompletei%deeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32;
 | 
					  r += sprintf( r+32, "d8:completei%de10:downloadedi%de10:incompletei%deeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return r - reply;
 | 
					  return r - reply;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -299,11 +297,11 @@ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) {
 | 
				
			|||||||
void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) {
 | 
					void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) {
 | 
				
			||||||
  int          exactmatch, i;
 | 
					  int          exactmatch, i;
 | 
				
			||||||
  ot_vector   *torrents_list = &all_torrents[*hash[0]];
 | 
					  ot_vector   *torrents_list = &all_torrents[*hash[0]];
 | 
				
			||||||
  ot_torrent  *torrent = BINARY_FIND( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
					  ot_torrent  *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if( !exactmatch ) return;
 | 
					  if( !exactmatch ) return;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Maybe this does the job
 | 
					  /* Maybe this does the job */
 | 
				
			||||||
  if( clean_peerlist( torrent->peer_list ) ) {
 | 
					  if( clean_peerlist( torrent->peer_list ) ) {
 | 
				
			||||||
#ifdef WANT_CLOSED_TRACKER
 | 
					#ifdef WANT_CLOSED_TRACKER
 | 
				
			||||||
    if( !g_closedtracker ) 
 | 
					    if( !g_closedtracker ) 
 | 
				
			||||||
@ -332,7 +330,7 @@ int init_logic( char *serverdir ) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  srandom( time(NULL));
 | 
					  srandom( time(NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Initialize control structures
 | 
					  /* Initialize control structures */
 | 
				
			||||||
  byte_zero( all_torrents, sizeof (all_torrents));
 | 
					  byte_zero( all_torrents, sizeof (all_torrents));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
@ -340,7 +338,8 @@ int init_logic( char *serverdir ) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void deinit_logic( ) {
 | 
					void deinit_logic( ) {
 | 
				
			||||||
  int i, j;
 | 
					  int i, j;
 | 
				
			||||||
  // Free all torrents...
 | 
					
 | 
				
			||||||
 | 
					  /* Free all torrents... */
 | 
				
			||||||
  for(i=0; i<256; ++i ) {
 | 
					  for(i=0; i<256; ++i ) {
 | 
				
			||||||
    if( all_torrents[i].size ) {
 | 
					    if( all_torrents[i].size ) {
 | 
				
			||||||
      ot_torrent *torrents_list = (ot_torrent*)all_torrents[i].data;
 | 
					      ot_torrent *torrents_list = (ot_torrent*)all_torrents[i].data;
 | 
				
			||||||
 | 
				
			|||||||
@ -18,18 +18,12 @@ typedef ot_byte        ot_hash[20];
 | 
				
			|||||||
typedef ot_dword       ot_ip;
 | 
					typedef ot_dword       ot_ip;
 | 
				
			||||||
typedef time_t         ot_time;
 | 
					typedef time_t         ot_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MEMMOVE              memmove
 | 
					/* We maintain a list of 256 pointers to sorted list of ot_torrent structs
 | 
				
			||||||
#define BZERO                bzero
 | 
					   Sort key is, of course, its hash */
 | 
				
			||||||
#define FORMAT_FIXED_STRING  sprintf
 | 
					 | 
				
			||||||
#define FORMAT_FORMAT_STRING sprintf
 | 
					 | 
				
			||||||
#define BINARY_FIND          binary_search
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// We maintain a list of 256 pointers to sorted list of ot_torrent structs
 | 
					/* This list points to 9 pools of peers each grouped in five-minute-intervals
 | 
				
			||||||
// Sort key is, of course, its hash
 | 
					   thus achieving a timeout of 2700s or 45 minutes
 | 
				
			||||||
 | 
					   These pools are sorted by its binary content */
 | 
				
			||||||
// This list points to 9 pools of peers each grouped in five-minute-intervals
 | 
					 | 
				
			||||||
// thus achieving a timeout of 2700s or 45 minutes
 | 
					 | 
				
			||||||
// These pools are sorted by its binary content
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OT_POOLS_COUNT   9
 | 
					#define OT_POOLS_COUNT   9
 | 
				
			||||||
#define OT_POOLS_TIMEOUT 300
 | 
					#define OT_POOLS_TIMEOUT 300
 | 
				
			||||||
@ -52,8 +46,8 @@ static const ot_byte PEER_FLAG_SEEDING   = 0x80;
 | 
				
			|||||||
static const ot_byte PEER_FLAG_COMPLETED = 0x40;
 | 
					static const ot_byte PEER_FLAG_COMPLETED = 0x40;
 | 
				
			||||||
static const ot_byte PEER_FLAG_STOPPED   = 0x20;
 | 
					static const ot_byte PEER_FLAG_STOPPED   = 0x20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OT_SETIP( peer, ip ) MEMMOVE((peer),(ip),4);
 | 
					#define OT_SETIP( peer, ip ) memmove((peer),(ip),4);
 | 
				
			||||||
#define OT_SETPORT( peer, port ) MEMMOVE(((ot_byte*)peer)+4,(port),2);
 | 
					#define OT_SETPORT( peer, port ) memmove(((ot_byte*)peer)+4,(port),2);
 | 
				
			||||||
#define OT_FLAG(peer) (((ot_byte*)(peer))[6])
 | 
					#define OT_FLAG(peer) (((ot_byte*)(peer))[6])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OT_PEER_COMPARE_SIZE ((size_t)6)
 | 
					#define OT_PEER_COMPARE_SIZE ((size_t)6)
 | 
				
			||||||
@ -61,8 +55,8 @@ static const ot_byte PEER_FLAG_STOPPED   = 0x20;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  ot_time        base;
 | 
					  ot_time        base;
 | 
				
			||||||
  unsigned long  seed_count[ OT_POOLS_COUNT ];
 | 
					  size_t         seed_count[ OT_POOLS_COUNT ];
 | 
				
			||||||
  unsigned long  downloaded;
 | 
					  unsigned int   downloaded;
 | 
				
			||||||
  ot_vector      peers[ OT_POOLS_COUNT ];
 | 
					  ot_vector      peers[ OT_POOLS_COUNT ];
 | 
				
			||||||
} ot_peerlist;
 | 
					} ot_peerlist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -71,9 +65,9 @@ typedef struct {
 | 
				
			|||||||
  ot_peerlist *peer_list;
 | 
					  ot_peerlist *peer_list;
 | 
				
			||||||
} ot_torrent;
 | 
					} ot_torrent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					/*
 | 
				
			||||||
// Exported functions
 | 
					   Exported functions
 | 
				
			||||||
//
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int  init_logic( char *serverdir );
 | 
					int  init_logic( char *serverdir );
 | 
				
			||||||
void deinit_logic( );
 | 
					void deinit_logic( );
 | 
				
			||||||
@ -86,7 +80,7 @@ extern int g_check_blacklist;
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer );
 | 
					ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer );
 | 
				
			||||||
size_t return_peers_for_torrent( ot_torrent *torrent, unsigned long amount, char *reply );
 | 
					size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char *reply );
 | 
				
			||||||
size_t return_scrape_for_torrent( ot_hash *hash, char *reply );
 | 
					size_t return_scrape_for_torrent( ot_hash *hash, char *reply );
 | 
				
			||||||
void  remove_peer_from_torrent( ot_hash *hash, ot_peer *peer );
 | 
					void  remove_peer_from_torrent( ot_hash *hash, ot_peer *peer );
 | 
				
			||||||
void cleanup_torrents( void );
 | 
					void cleanup_torrents( void );
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user