1 /* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2    It is considered beerware. Prost. Skol. Cheers or whatever.
3 
4    $id$ */
5 
6 #ifndef OT_TRACKERLOGIC_H__
7 #define OT_TRACKERLOGIC_H__
8 
9 #include <sys/types.h>
10 #include <sys/time.h>
11 #include <time.h>
12 #include <stdint.h>
13 
14 typedef uint8_t ot_hash[20];
15 typedef time_t  ot_time;
16 typedef char    ot_ip6[16];
17 typedef struct { ot_ip6 address; int bits; }
18                 ot_net;
19 #ifdef WANT_V6
20 #define OT_IP_SIZE 16
21 #define PEERS_BENCODED "6:peers6"
22 #else
23 #define OT_IP_SIZE 4
24 #define PEERS_BENCODED "5:peers"
25 #endif
26 
27 /* Some tracker behaviour tunable */
28 #define OT_CLIENT_TIMEOUT 30
29 #define OT_CLIENT_TIMEOUT_CHECKINTERVAL 10
30 #define OT_CLIENT_TIMEOUT_SEND (60*15)
31 #define OT_CLIENT_REQUEST_INTERVAL (60*30)
32 #define OT_CLIENT_REQUEST_VARIATION (60*6)
33 
34 #define OT_TORRENT_TIMEOUT_HOURS 24
35 #define OT_TORRENT_TIMEOUT      (60*OT_TORRENT_TIMEOUT_HOURS)
36 
37 #define OT_CLIENT_REQUEST_INTERVAL_RANDOM ( OT_CLIENT_REQUEST_INTERVAL - OT_CLIENT_REQUEST_VARIATION/2 + (int)( random( ) % OT_CLIENT_REQUEST_VARIATION ) )
38 
39 /* If WANT_MODEST_FULLSCRAPES is on, ip addresses may not
40    fullscrape more frequently than this amount in seconds */
41 #define OT_MODEST_PEER_TIMEOUT (60*5)
42 
43 /* If peers come back before 10 minutes, don't live sync them */
44 #define OT_CLIENT_SYNC_RENEW_BOUNDARY 10
45 
46 /* Number of tracker admin ip addresses allowed */
47 #define OT_ADMINIP_MAX 64
48 #define OT_MAX_THREADS 64
49 
50 #define OT_PEER_TIMEOUT 45
51 
52 /* We maintain a list of 1024 pointers to sorted list of ot_torrent structs
53  Sort key is, of course, its hash */
54 #define OT_BUCKET_COUNT_BITS 10
55 
56 #define OT_BUCKET_COUNT (1<<OT_BUCKET_COUNT_BITS)
57 #define OT_BUCKET_COUNT_SHIFT (32-OT_BUCKET_COUNT_BITS)
58 
59 /* From opentracker.c */
60 extern time_t g_now_seconds;
61 extern volatile int g_opentracker_running;
62 #define       g_now_minutes (g_now_seconds/60)
63 
64 extern uint32_t g_tracker_id;
65 typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA, FLAG_SELFPIPE } PROTO_FLAG;
66 
67 typedef struct {
68   uint8_t data[OT_IP_SIZE+2+2];
69 } ot_peer;
70 static const uint8_t PEER_FLAG_SEEDING   = 0x80;
71 static const uint8_t PEER_FLAG_COMPLETED = 0x40;
72 static const uint8_t PEER_FLAG_STOPPED   = 0x20;
73 static const uint8_t PEER_FLAG_FROM_SYNC = 0x10;
74 static const uint8_t PEER_FLAG_LEECHING  = 0x00;
75 
76 #ifdef WANT_V6
77 #define OT_SETIP(peer,ip)     memcpy((peer),(ip),(OT_IP_SIZE))
78 #else
79 #define OT_SETIP(peer,ip)     memcpy((peer),(((uint8_t*)ip)+12),(OT_IP_SIZE))
80 #endif
81 #define OT_SETPORT(peer,port) memcpy(((uint8_t*)(peer))+(OT_IP_SIZE),(port),2)
82 #define OT_PEERFLAG(peer)     (((uint8_t*)(peer))[(OT_IP_SIZE)+2])
83 #define OT_PEERTIME(peer)     (((uint8_t*)(peer))[(OT_IP_SIZE)+3])
84 
85 #define OT_HASH_COMPARE_SIZE (sizeof(ot_hash))
86 #define OT_PEER_COMPARE_SIZE ((OT_IP_SIZE)+2)
87 
88 struct ot_peerlist;
89 typedef struct ot_peerlist ot_peerlist;
90 typedef struct {
91   ot_hash      hash;
92   ot_peerlist *peer_list;
93 } ot_torrent;
94 
95 #include "ot_vector.h"
96 
97 struct ot_peerlist {
98   ot_time        base;
99   size_t         seed_count;
100   size_t         peer_count;
101   size_t         down_count;
102 /* normal peers vector or
103    pointer to ot_vector[32] buckets if data != NULL and space == 0
104 */
105   ot_vector      peers;
106 };
107 #define OT_PEERLIST_HASBUCKETS(peer_list) ((peer_list)->peers.size > (peer_list)->peers.space)
108 
109 struct ot_workstruct {
110   /* Thread specific, static */
111   char    *inbuf;
112 #define   G_INBUF_SIZE    8192
113   char    *outbuf;
114 #define   G_OUTBUF_SIZE   8192
115 #ifdef    _DEBUG_HTTPERROR
116   char    *debugbuf;
117 #define   G_DEBUGBUF_SIZE 8192
118 #endif
119 
120   /* The peer currently in the working */
121   ot_peer  peer;
122 
123   /* Pointers into the request buffer */
124   ot_hash *hash;
125   char    *peer_id;
126 
127   /* HTTP specific, non static */
128   int      keep_alive;
129   char    *request;
130   ssize_t  request_size;
131   ssize_t  header_size;
132   char    *reply;
133   ssize_t  reply_size;
134 };
135 
136 /*
137    Exported functions
138 */
139 
140 #ifdef WANT_SYNC_LIVE
141 #define WANT_SYNC
142 #endif
143 
144 #ifdef WANT_SYNC
145 #define WANT_SYNC_PARAM( param ) , param
146 #else
147 #define WANT_SYNC_PARAM( param )
148 #endif
149 
150 #ifdef WANT_LOG_NETWORKS
151 #error Live logging networks disabled at the moment.
152 #endif
153 
154 void trackerlogic_init( );
155 void trackerlogic_deinit( void );
156 void exerr( char * message );
157 
158 /* add_peer_to_torrent does only release the torrent bucket if from_sync is set,
159    otherwise it is released in return_peers_for_torrent */
160 size_t  add_peer_to_torrent_and_return_peers( PROTO_FLAG proto, struct ot_workstruct *ws, size_t amount );
161 size_t  remove_peer_from_torrent( PROTO_FLAG proto, struct ot_workstruct *ws );
162 size_t  return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
163 size_t  return_udp_scrape_for_torrent( ot_hash hash, char *reply );
164 void    add_torrent_from_saved_state( ot_hash hash, ot_time base, size_t down_count );
165 
166 /* torrent iterator */
167 void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data );
168 
169 /* Helper, before it moves to its own object */
170 void free_peerlist( ot_peerlist *peer_list );
171 
172 #endif
173