summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c142
1 files changed, 106 insertions, 36 deletions
diff --git a/opentracker.c b/opentracker.c
index bd8f5ca..6858f37 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -106,13 +106,12 @@ const char* http_header(struct http_data* r,const char* h)
106 106
107void httpresponse(struct http_data* h,int64 s) 107void httpresponse(struct http_data* h,int64 s)
108{ 108{
109 char *c, *d, *data, *reply = NULL; 109 char *c, *d, *data, *reply = NULL;
110 struct ot_peer peer; 110 ot_peer peer;
111 ot_torrent torrent; 111 ot_torrent *torrent;
112 ot_hash *hash = NULL; 112 ot_hash *hash = NULL;
113 unsigned long numwant; 113 int numwant, tmp, scanon;
114 int compact, scanon; 114 size_t reply_size = 0;
115 size_t reply_size = 0;
116 115
117 array_cat0(&h->r); 116 array_cat0(&h->r);
118 117
@@ -137,14 +136,57 @@ e400:
137 case 6: /* scrape ? */ 136 case 6: /* scrape ? */
138 if (byte_diff(data,6,"scrape")) 137 if (byte_diff(data,6,"scrape"))
139 goto e404; 138 goto e404;
139 scanon = 1;
140
141 while( scanon ) {
142 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
143 case -2: /* terminator */
144 scanon = 0;
145 break;
146 case -1: /* error */
147 goto e404;
148 case 9:
149 if(byte_diff(data,9,"info_hash")) {
150 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
151 continue;
152 }
153 /* ignore this, when we have less than 20 bytes */
154 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) {
155 case -1:
156 goto e404;
157 case 20:
158 hash = (ot_hash*)data; /* Fall through intended */
159 default:
160 continue;
161 }
162 default:
163 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
164 break;
165 }
166 }
167
168 /* Scanned whole query string, wo */
169 if( !hash ) {
170 httperror(h,"400 Invalid Request","This server only serves specific scrapes.");
171 goto bailout;
172 }
173
174 // Enough for whole scrape string
175 reply = malloc( 128 );
176 if( reply )
177 reply_size = return_scrape_for_torrent( hash, reply );
178 if( !reply || ( reply_size < 0 ) ) {
179 if( reply ) free( reply );
180 goto e500;
181 }
140 break; 182 break;
141 case 8: 183 case 8:
142 if( byte_diff(data,8,"announce")) 184 if( byte_diff(data,8,"announce"))
143 goto e404; 185 goto e404;
186
144 peer.ip = h->ip; 187 peer.ip = h->ip;
145 peer.port_flags = 6881 << 16; 188 peer.port_flags = 6881 << 16;
146 numwant = 50; 189 numwant = 50;
147 compact = 1;
148 scanon = 1; 190 scanon = 1;
149 191
150 while( scanon ) { 192 while( scanon ) {
@@ -155,19 +197,44 @@ e400:
155 case -1: /* error */ 197 case -1: /* error */
156 goto e404; 198 goto e404;
157 case 4: 199 case 4:
158 if(!byte_diff(data,4,"port")) 200 if(!byte_diff(data,4,"port")) {
159 /* scan int */ c; 201 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
160 else if(!byte_diff(data,4,"left")) 202 if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) || (tmp > 65536) ) goto e404;
161 /* scan int */ c; 203 peer.port_flags = ( tmp << 16 ) | ( peer.port_flags & 0xffff );
162 else 204 } else if(!byte_diff(data,4,"left")) {
205 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
206 if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e404;
207 if( !tmp ) peer.port_flags |= PEER_FLAG_SEEDING;
208 } else
163 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); 209 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
164 break; 210 break;
211 case 5:
212 if(byte_diff(data,5,"event"))
213 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
214 else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) {
215 case -1:
216 goto e404;
217 case 7:
218 if(!byte_diff(data,7,"stopped")) peer.port_flags |= PEER_FLAG_STOPPED;
219 break;
220 case 9:
221 if(!byte_diff(data,9,"complete")) peer.port_flags |= PEER_FLAG_COMPLETED;
222 default: // Fall through intended
223 break;
224 }
225 break;
165 case 7: 226 case 7:
166 if(!byte_diff(data,7,"numwant")) 227 if(!byte_diff(data,7,"numwant")) {
167 /* scan int */ c; 228 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
168 else if(!byte_diff(data,7,"compact")) 229 if( ( len <= 0 ) || scan_fixed_int( data, len, &numwant ) ) goto e404;
169 /* scan flag */ c; 230 } else if(!byte_diff(data,7,"compact")) {
170 else 231 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
232 if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e404;
233 if( !tmp ) {
234 httperror(h,"400 Invalid Request","This server only delivers compact results.");
235 goto bailout;
236 }
237 } else
171 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); 238 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
172 break; 239 break;
173 case 9: 240 case 9:
@@ -180,9 +247,8 @@ e400:
180 case -1: 247 case -1:
181 goto e404; 248 goto e404;
182 case 20: 249 case 20:
183 hash = (ot_hash*)data; /* Fall through intended */ 250 hash = (ot_hash*)data;
184 printf("hash: %s\n",*hash); 251 default: // Fall through intended
185 default:
186 continue; 252 continue;
187 } 253 }
188 default: 254 default:
@@ -192,20 +258,25 @@ e400:
192 } 258 }
193 259
194 /* Scanned whole query string */ 260 /* Scanned whole query string */
195 if( !hash || ( compact == 0 ) ) goto e404; 261 if( !hash ) goto e404;
196 262
197 torrent = add_peer_to_torrent( hash, &peer ); 263 if( peer.port_flags & PEER_FLAG_STOPPED ) {
198 if( !torrent ) { 264 remove_peer_from_torrent( hash, &peer );
265 reply = strdup( "d15:warning message4:Okaye" ); reply_size = 26;
266 } else {
267 torrent = add_peer_to_torrent( hash, &peer );
268 if( !torrent ) {
199e500: 269e500:
200 httperror(h,"500 Internal Server Error","A server error has occured. Please retry later."); 270 httperror(h,"500 Internal Server Error","A server error has occured. Please retry later.");
201 goto bailout; 271 goto bailout;
202 } 272 }
203 reply = malloc( numwant*6+24 ); 273 reply = malloc( numwant*6+64 ); // peerlist + seeder, peers and lametta
204 if( reply ) 274 if( reply )
205 reply_size = return_peers_for_torrent( torrent, numwant, reply ); 275 reply_size = return_peers_for_torrent( torrent, numwant, reply );
206 if( !reply || ( reply_size < 0 ) ) { 276 if( !reply || ( reply_size < 0 ) ) {
207 if( reply ) free( reply ); 277 if( reply ) free( reply );
208 goto e500; 278 goto e500;
279 }
209 } 280 }
210 break; 281 break;
211 default: /* neither scrape nor announce */ 282 default: /* neither scrape nor announce */
@@ -213,6 +284,7 @@ e404:
213 httperror(h,"404 Not Found","No such file or directory."); 284 httperror(h,"404 Not Found","No such file or directory.");
214 goto bailout; 285 goto bailout;
215 } 286 }
287
216 c=h->hdrbuf=(char*)malloc(500); 288 c=h->hdrbuf=(char*)malloc(500);
217 c+=fmt_str(c,"HTTP/1.1 200 OK\r\nContent-Type: text/plain"); 289 c+=fmt_str(c,"HTTP/1.1 200 OK\r\nContent-Type: text/plain");
218 c+=fmt_str(c,"\r\nContent-Length: "); 290 c+=fmt_str(c,"\r\nContent-Length: ");
@@ -239,7 +311,6 @@ void graceful( int s ) {
239int main() 311int main()
240{ 312{
241 int s=socket_tcp4(); 313 int s=socket_tcp4();
242 uint32 scope_id;
243 unsigned long ip; 314 unsigned long ip;
244 uint16 port; 315 uint16 port;
245 316
@@ -284,7 +355,6 @@ int main()
284 io_close(n); 355 io_close(n);
285 } else 356 } else
286 io_close(n); 357 io_close(n);
287 buffer_putnlflush(buffer_2);
288 } 358 }
289 if (errno==EAGAIN) 359 if (errno==EAGAIN)
290 io_eagain(s); 360 io_eagain(s);