-
Notifications
You must be signed in to change notification settings - Fork 20
/
swarm.hpp
92 lines (74 loc) · 2.08 KB
/
swarm.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef _SWARM_HPP_
#define _SWARM_HPP_
#include <time.h>
#include <vector>
#include <thread>
#include <unordered_map>
#include <chrono>
#include <random>
using std::chrono::steady_clock;
using std::chrono::seconds;
#include "messages.hpp"
struct peer_ip4
{
peer_ip4(uint32_t addr, uint16_t p)
{
// addr is always big endian (network byte order)
memcpy(&ip, &addr, sizeof(ip));
memcpy(&port, &p, sizeof(port));
}
uint32_t ip4() const
{
uint32_t ret;
memcpy(&ret, ip, sizeof(ip));
return ret;
}
// split up in uint16 to get
// the compact layout
uint16_t ip[2];
uint16_t port;
};
struct peer_entry
{
peer_entry(): index(0), complete(false), downloading(true), key(0), last_announce((steady_clock::time_point::min)()) {}
// index into the compact array of IPs
uint32_t index:30;
// true if we've received complete from this peer
bool complete:1;
// true while this peer's left > 0
bool downloading:1;
// the key this peer uses in its announces
// this is used to distinguish between peers
// on the same IP
uint32_t key;
// last time this peer announced
steady_clock::time_point last_announce;
};
struct swarm
{
swarm();
void announce(steady_clock::time_point now, udp_announce_message const* hdr
, char** buf, int* len
, uint32_t* downloaders, uint32_t* seeds
, std::mt19937& mt_engine);
void scrape(uint32_t* seeds, uint32_t* download_count, uint32_t* downloaders);
void purge_stale(steady_clock::time_point now);
private:
typedef std::unordered_map<uint32_t, peer_entry> hash_map4_t;
void erase_peer(swarm::hash_map4_t::iterator i);
uint32_t m_seeds;
uint32_t m_downloaders;
uint32_t m_download_count;
// the last time anyone announced to this swarm
// this is used to expire swarms
steady_clock::time_point m_last_announce;
// hash table of all peers keyed on their IP
hash_map4_t m_peers4;
// compact array of all peers' IPs
std::vector<peer_ip4> m_ips4;
// the last peer we checked for purgine stale peers
// this may be m_peers4.end(). It's used to not
// necessarily go through all peers in one go
hash_map4_t::iterator m_last_purge;
};
#endif