summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c61
-rw-r--r--trackerlogic.c24
-rw-r--r--trackerlogic.h14
3 files changed, 62 insertions, 37 deletions
diff --git a/opentracker.c b/opentracker.c
index 8313d90..d46858d 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -97,15 +97,20 @@ const char* http_header(struct http_data* r,const char* h)
97 if (*c==' ' || *c=='\t') ++c; 97 if (*c==' ' || *c=='\t') ++c;
98 return c; 98 return c;
99 } 99 }
100 return 0; 100 return 0;
101 } 101 }
102 return 0;
102} 103}
103 104
104void httpresponse(struct http_data* h,int64 s) 105void httpresponse(struct http_data* h,int64 s)
105{ 106{
106 char *c, *d, *data; 107 char *c, *d, *data, *reply = NULL;
107 struct ot_peer peer; 108 struct ot_peer peer;
109 ot_torrent torrent;
108 ot_hash *hash = NULL; 110 ot_hash *hash = NULL;
111 unsigned long numwant;
112 int compact;
113 size_t reply_size = 0;
109 114
110 array_cat0(&h->r); 115 array_cat0(&h->r);
111 116
@@ -128,10 +133,6 @@ e400:
128 while (c[1]=='/') ++c; 133 while (c[1]=='/') ++c;
129 134
130 switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { 135 switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) {
131 case 0:
132e404:
133 httperror(h,"404 Not Found","No such file or directory.");
134 goto bailout;
135 case 6: /* scrape ? */ 136 case 6: /* scrape ? */
136 if (!byte_diff(c,6,"scrape")) 137 if (!byte_diff(c,6,"scrape"))
137 goto e404; 138 goto e404;
@@ -142,6 +143,8 @@ e404:
142 143
143 byte_copy( peer.ip, 4, h->ip ); 144 byte_copy( peer.ip, 4, h->ip );
144 peer.port = 6881; 145 peer.port = 6881;
146 numwant = 50;
147 compact = 1;
145 148
146 while( 1 ) { 149 while( 1 ) {
147 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { 150 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
@@ -158,24 +161,42 @@ e404:
158 /* scan int */ c; 161 /* scan int */ c;
159 else if(!byte_diff(c,7,"compact")) 162 else if(!byte_diff(c,7,"compact"))
160 /* scan flag */ c; 163 /* scan flag */ c;
161 break; 164 break;
162 case 9: /* info_hash= */ 165 case 9:
163 if(!byte_diff(c,9,"info_hash")) { 166 if(byte_diff(c,9,"info_hash"))
164 /* ignore this, when we have less than 20 bytes */ 167 continue;
165 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) 168 /* ignore this, when we have less than 20 bytes */
166 case -1: 169 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) {
167 httperror(h,"404 Not Found","No such file or directory."); 170 case -1:
168 goto bailout; 171 goto e404;
169 case 20: 172 case 20:
170 hash = (ot_hash*)data; /* Fall through intended */ 173 hash = (ot_hash*)data; /* Fall through intended */
171 default: 174 default:
172 continue; 175 continue;
173 } 176 }
174 break; 177 default:
178 continue;
175 } 179 }
176 } 180 }
181
182 /* Scanned whole query string */
183 if( !hash || ( compact == 0 ) ) goto e404;
184 torrent = add_peer_to_torrent( hash, &peer );
185 if( !torrent ) {
186e500:
187 httperror(h,"500 Internal Server Error","A server error has occured. Please retry later.");
188 goto bailout;
189 }
190 reply = malloc( numwant*6+10 );
191 if( reply )
192 reply_size = return_peers_for_torrent( torrent, numwant, reply );
193 if( !reply || reply_size < 0 ) {
194 if( reply ) free( reply );
195 goto e500;
196 }
177 break; 197 break;
178 default: /* neither scrape nor announce */ 198 default: /* neither scrape nor announce */
199e404:
179 httperror(h,"404 Not Found","No such file or directory."); 200 httperror(h,"404 Not Found","No such file or directory.");
180 goto bailout; 201 goto bailout;
181 } 202 }
@@ -190,7 +211,7 @@ e404:
190 c+=fmt_httpdate(c,s.st_mtime); */ 211 c+=fmt_httpdate(c,s.st_mtime); */
191 c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); 212 c+=fmt_str(c,"\r\nConnection: close\r\n\r\n");
192 iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); 213 iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf);
193 iob_addbuf(&h->iob,tracker_answer, tracker_answer_size); 214 if( reply && reply_size ) iob_addbuf(&h->iob,reply, reply_size );
194 215
195bailout: 216bailout:
196 io_dontwantread(s); 217 io_dontwantread(s);
diff --git a/trackerlogic.c b/trackerlogic.c
index 6274c41..ab1f419 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -54,7 +54,7 @@ ot_byte *scratch_space = 0;
54#define TESTSET( i ) (scratch_space[index]) 54#define TESTSET( i ) (scratch_space[index])
55#define RANDOM random() 55#define RANDOM random()
56 56
57ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ) { 57ot_torrent add_peer_to_torrent( ot_hash *hash, ot_peer peer ) {
58 ot_torrent torrent; 58 ot_torrent torrent;
59 ot_peer peer_dest; 59 ot_peer peer_dest;
60 int exactmatch; 60 int exactmatch;
@@ -66,7 +66,7 @@ ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ) {
66 66
67 // Create a new torrent entry, then 67 // Create a new torrent entry, then
68 MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) ); 68 MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
69 torrent->peer_list = map_file( to_hex( hash ) ); 69 torrent->peer_list = map_file( to_hex( *hash ) );
70 torrent->peer_count = 0; 70 torrent->peer_count = 0;
71 torrent->seed_count = 0; 71 torrent->seed_count = 0;
72 } 72 }
@@ -106,8 +106,9 @@ inline int TESTVALIDPEER( ot_peer p ) { return p->death > NOW; }
106// * it is not guaranteed to see all peers, so no assumptions on active seeders/peers may be done 106// * it is not guaranteed to see all peers, so no assumptions on active seeders/peers may be done
107// * since compact format cannot handle v6 addresses, it must be enabled by OT_COMPACT_ONLY 107// * since compact format cannot handle v6 addresses, it must be enabled by OT_COMPACT_ONLY
108// 108//
109void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ) { 109size_t return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ) {
110 register ot_peer peer_base = torrent->peer_list; 110 register ot_peer peer_base = torrent->peer_list;
111 char *r = reply;
111 unsigned long peer_count = torrent->peer_count; 112 unsigned long peer_count = torrent->peer_count;
112 unsigned long selected_count = 0, invalid_count = 0; 113 unsigned long selected_count = 0, invalid_count = 0;
113 unsigned long index = 0; 114 unsigned long index = 0;
@@ -132,9 +133,9 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r
132 index = 0; 133 index = 0;
133 134
134#ifndef OT_COMPACT_ONLY 135#ifndef OT_COMPACT_ONLY
135 reply += FORMAT_FIXED_STRING( reply, "d5:peersl" ); 136 r += FORMAT_FIXED_STRING( r, "d5:peersl" );
136#else 137#else
137 reply += FORMAT_FORMAT_STRING( reply, "d5:peers%li:",6*selected_count ); 138 r += FORMAT_FORMAT_STRING( r, "d5:peers%li:",6*selected_count );
138#endif 139#endif
139 140
140 while( selected_count-- ) { 141 while( selected_count-- ) {
@@ -142,11 +143,11 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r
142 while( !TESTSELECTED( index ) ) ++index; 143 while( !TESTSELECTED( index ) ) ++index;
143 peer = peer_base + index; 144 peer = peer_base + index;
144#ifdef OT_COMPACT_ONLY 145#ifdef OT_COMPACT_ONLY
145 MEMMOVE( reply, &peer->ip, 4 ); 146 MEMMOVE( r, &peer->ip, 4 );
146 MEMMOVE( reply+4, &peer->port, 2 ); 147 MEMMOVE( r+4, &peer->port, 2 );
147 reply += 6; 148 r += 6;
148#else 149#else
149 reply += FORMAT_FORMAT_STRING( reply, "d2:ip%d:%s7:peer id20:%20c4:porti%ie", 150 r += FORMAT_FORMAT_STRING( r, "d2:ip%d:%s7:peer id20:%20c4:porti%ie",
150 peer->flags & PEER_IP_LENGTH_MASK, 151 peer->flags & PEER_IP_LENGTH_MASK,
151 peer->ip, 152 peer->ip,
152 peer->id, 153 peer->id,
@@ -154,10 +155,11 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r
154#endif 155#endif
155 } 156 }
156#ifndef OT_COMPACT_ONLY 157#ifndef OT_COMPACT_ONLY
157 reply += FORMAT_FIXED_STRING( reply, "ee" ); 158 r += FORMAT_FIXED_STRING( r, "ee" );
158#else 159#else
159 reply += FORMAT_FIXED_STRING( reply, "e" ); 160 r += FORMAT_FIXED_STRING( r, "e" );
160#endif 161#endif
162 return r - reply;
161} 163}
162 164
163// Compacts a torrents peer list 165// Compacts a torrents peer list
diff --git a/trackerlogic.h b/trackerlogic.h
index 03ed577..ad18cba 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -1,6 +1,8 @@
1#ifndef __TRACKERLOGIC_H__ 1#ifndef __TRACKERLOGIC_H__
2#define __TRACKERLOGIC_H__ 2#define __TRACKERLOGIC_H__
3 3
4#include <sys/types.h>
5
4/* Should be called BYTE, WORD, DWORD - but some OSs already have that and there's no #iftypedef */ 6/* Should be called BYTE, WORD, DWORD - but some OSs already have that and there's no #iftypedef */
5/* They mark memory used as data instead of integer or human readable string - 7/* They mark memory used as data instead of integer or human readable string -
6 they should be cast before used as integer/text */ 8 they should be cast before used as integer/text */
@@ -12,8 +14,8 @@ typedef unsigned long ot_time;
12typedef ot_byte ot_hash[20]; 14typedef ot_byte ot_hash[20];
13typedef ot_byte ot_ip[ 4/*0*/ ]; 15typedef ot_byte ot_ip[ 4/*0*/ ];
14// tunables 16// tunables
15const unsigned long OT_TIMEOUT = 2700; 17static const unsigned long OT_TIMEOUT = 2700;
16const unsigned long OT_HUGE_FILESIZE = 1024*1024*256; // Thats 256MB per file, enough for 204800 peers of 128 bytes 18static const unsigned long OT_HUGE_FILESIZE = 1024*1024*256; // Thats 256MB per file, enough for 204800 peers of 128 bytes
17 19
18// We will not service v6, yes 20// We will not service v6, yes
19#define OT_COMPACT_ONLY 21#define OT_COMPACT_ONLY
@@ -35,8 +37,8 @@ typedef struct ot_peer {
35 ot_time death; 37 ot_time death;
36 ot_byte flags; 38 ot_byte flags;
37} *ot_peer; 39} *ot_peer;
38ot_byte PEER_FLAG_SEEDING = 0x80; 40static const ot_byte PEER_FLAG_SEEDING = 0x80;
39ot_byte PEER_IP_LENGTH_MASK = 0x3f; 41static const ot_byte PEER_IP_LENGTH_MASK = 0x3f;
40 42
41typedef struct { 43typedef struct {
42 ot_hash hash; 44 ot_hash hash;
@@ -64,8 +66,8 @@ void *binary_search( const void *key, const void *base,
64int init_logic( char *chdir_directory ); 66int init_logic( char *chdir_directory );
65void deinit_logic( ); 67void deinit_logic( );
66 68
67ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ); 69ot_torrent add_peer_to_torrent( ot_hash *hash, ot_peer peer );
68void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ); 70size_t return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply );
69void heal_torrent( ot_torrent torrent ); 71void heal_torrent( ot_torrent torrent );
70 72
71#endif 73#endif