diff options
-rw-r--r-- | core/packets.h | 30 | ||||
-rw-r--r-- | core/ping.c | 179 | ||||
-rw-r--r-- | core/util.c | 35 |
3 files changed, 132 insertions, 112 deletions
diff --git a/core/packets.h b/core/packets.h index b6d3d364..222b1425 100644 --- a/core/packets.h +++ b/core/packets.h | |||
@@ -6,28 +6,32 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | typedef struct { | 8 | typedef struct { |
9 | uint8_t id[CLIENT_ID_SIZE]; | 9 | uint8_t id[CLIENT_ID_SIZE]; |
10 | |||
10 | } __attribute__((packed)) clientid_t; | 11 | } __attribute__((packed)) clientid_t; |
11 | 12 | ||
12 | typedef enum { | 13 | typedef enum { |
13 | PACKET_PING_REQ = 0, | 14 | PACKET_PING_REQ = 0, |
14 | PACKET_PING_RES = 1 | 15 | PACKET_PING_RES = 1 |
16 | |||
15 | } packetid_t; | 17 | } packetid_t; |
16 | 18 | ||
17 | // Ping packet | 19 | // Ping packet |
18 | typedef struct { | 20 | typedef struct { |
19 | uint8_t magic; | 21 | uint8_t magic; |
20 | clientid_t client_id; | 22 | clientid_t client_id; |
21 | uint8_t nonce[crypto_box_NONCEBYTES]; | 23 | uint8_t nonce[crypto_box_NONCEBYTES]; |
22 | uint64_t ping_id; | 24 | uint64_t ping_id; |
23 | uint8_t padding[ENCRYPTION_PADDING]; | 25 | uint8_t padding[ENCRYPTION_PADDING]; |
26 | |||
24 | } __attribute__((packed)) pingreq_t; | 27 | } __attribute__((packed)) pingreq_t; |
25 | 28 | ||
26 | // Pong packet | 29 | // Pong packet |
27 | typedef struct { | 30 | typedef struct { |
28 | uint8_t magic; | 31 | uint8_t magic; |
29 | clientid_t client_id; | 32 | clientid_t client_id; |
30 | uint8_t nonce[crypto_box_NONCEBYTES]; | 33 | uint8_t nonce[crypto_box_NONCEBYTES]; |
31 | uint64_t ping_id; | 34 | uint64_t ping_id; |
32 | uint8_t padding[ENCRYPTION_PADDING]; | 35 | uint8_t padding[ENCRYPTION_PADDING]; |
36 | |||
33 | } __attribute__((packed)) pingres_t; | 37 | } __attribute__((packed)) pingres_t; |
diff --git a/core/ping.c b/core/ping.c index 646b0839..37f1b7ae 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -31,124 +31,135 @@ static clientid_t* self_id = (clientid_t*) &self_public_key; | |||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c |
32 | 32 | ||
33 | 33 | ||
34 | void init_ping() { | 34 | void init_ping() |
35 | num_pings = 0; | 35 | { |
36 | pos_pings = 0; | 36 | num_pings = 0; |
37 | pos_pings = 0; | ||
37 | } | 38 | } |
38 | 39 | ||
39 | static bool is_timeout(uint64_t time) { | 40 | static bool is_timeout(uint64_t time) |
40 | return (time + PING_TIMEOUT) < now(); | 41 | { |
42 | return (time + PING_TIMEOUT) < now(); | ||
41 | } | 43 | } |
42 | 44 | ||
43 | static void remove_timeouts() { // O(n) | 45 | static void remove_timeouts() // O(n) |
44 | size_t i, id; | 46 | { |
45 | size_t new_pos = pos_pings; | 47 | size_t i, id; |
46 | size_t new_num = num_pings; | 48 | size_t new_pos = pos_pings; |
47 | 49 | size_t new_num = num_pings; | |
48 | // Loop through buffer, oldest first | 50 | |
49 | for(i=0; i<num_pings; i++) { | 51 | // Loop through buffer, oldest first |
50 | id = (pos_pings + i) % PING_NUM_MAX; | 52 | for (i=0; i<num_pings; i++) { |
51 | 53 | id = (pos_pings + i) % PING_NUM_MAX; | |
52 | if(is_timeout(pings[id].timestamp)) { | 54 | |
53 | new_pos++; | 55 | if(is_timeout(pings[id].timestamp)) { |
54 | new_num--; | 56 | new_pos++; |
57 | new_num--; | ||
58 | } | ||
59 | // Break here because list is sorted. | ||
60 | else { | ||
61 | break; | ||
62 | } | ||
55 | } | 63 | } |
56 | // Break here because list is sorted. | ||
57 | else | ||
58 | break; | ||
59 | } | ||
60 | 64 | ||
61 | num_pings = new_num; | 65 | num_pings = new_num; |
62 | pos_pings = new_pos % PING_NUM_MAX; | 66 | pos_pings = new_pos % PING_NUM_MAX; |
63 | } | 67 | } |
64 | 68 | ||
65 | uint64_t add_ping(IP_Port ipp) { // O(n) | 69 | uint64_t add_ping(IP_Port ipp) // O(n) |
66 | size_t p; | 70 | { |
67 | 71 | size_t p; | |
68 | remove_timeouts(); | ||
69 | 72 | ||
70 | // Remove oldest ping if full buffer | 73 | remove_timeouts(); |
71 | if(num_pings == PING_NUM_MAX) { | ||
72 | num_pings--; | ||
73 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
74 | } | ||
75 | 74 | ||
76 | // Insert new ping at end of list | 75 | // Remove oldest ping if full buffer |
77 | p = (pos_pings + num_pings) % PING_NUM_MAX; | 76 | if (num_pings == PING_NUM_MAX) { |
77 | num_pings--; | ||
78 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
79 | } | ||
78 | 80 | ||
79 | pings[p].ipp = ipp; | 81 | // Insert new ping at end of list |
80 | pings[p].timestamp = now(); | 82 | p = (pos_pings + num_pings) % PING_NUM_MAX; |
81 | pings[p].id = random_64b(); | ||
82 | 83 | ||
83 | num_pings++; | 84 | pings[p].ipp = ipp; |
84 | return pings[p].id; | 85 | pings[p].timestamp = now(); |
86 | pings[p].id = random_64b(); | ||
87 | |||
88 | num_pings++; | ||
89 | return pings[p].id; | ||
85 | } | 90 | } |
86 | 91 | ||
87 | bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n) | 92 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) |
88 | size_t i, id; | 93 | { |
94 | size_t i, id; | ||
95 | |||
96 | if (ipp.ip.i == 0 && ping_id == 0) | ||
97 | return false; | ||
89 | 98 | ||
90 | remove_timeouts(); | 99 | remove_timeouts(); |
91 | 100 | ||
92 | for(i=0; i<num_pings; i++) { | 101 | for (i=0; i<num_pings; i++) { |
93 | id = (pos_pings + i) % PING_NUM_MAX; | 102 | id = (pos_pings + i) % PING_NUM_MAX; |
94 | 103 | ||
95 | // ping_id = 0 means match any id | 104 | // ping_id = 0 means match any id |
96 | if(ipp_eq(pings[id].ipp, ipp) && (ping_id == 0 || pings[id].id == ping_id)) { | 105 | if(ipp_eq(pings[id].ipp, ipp) && (ping_id == 0 || pings[id].id == ping_id)) { |
97 | return true; | 106 | return true; |
107 | } | ||
98 | } | 108 | } |
99 | } | ||
100 | 109 | ||
101 | return false; | 110 | return false; |
102 | } | 111 | } |
103 | 112 | ||
104 | int send_ping_request(IP_Port ipp, clientid_t* client_id) { | 113 | int send_ping_request(IP_Port ipp, clientid_t* client_id) |
105 | pingreq_t pk; | 114 | { |
106 | int rc; | 115 | pingreq_t pk; |
107 | uint64_t ping_id; | 116 | int rc; |
117 | uint64_t ping_id; | ||
108 | 118 | ||
109 | if(is_pinging(ipp, 0) || id_eq(client_id, self_id)) | 119 | if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) |
110 | return 1; | 120 | return 1; |
111 | 121 | ||
112 | // Generate random ping_id | 122 | // Generate random ping_id |
113 | ping_id = add_ping(ipp); | 123 | ping_id = add_ping(ipp); |
114 | 124 | ||
115 | pk.magic = PACKET_PING_REQ; | 125 | pk.magic = PACKET_PING_REQ; |
116 | id_cpy(&pk.client_id, self_id); // Our pubkey | 126 | id_cpy(&pk.client_id, self_id); // Our pubkey |
117 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | 127 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce |
118 | 128 | ||
119 | // Encrypt ping_id using recipient privkey | 129 | // Encrypt ping_id using recipient privkey |
120 | rc = encrypt_data((uint8_t*) client_id, | 130 | rc = encrypt_data((uint8_t*) client_id, |
121 | self_secret_key, | 131 | self_secret_key, |
122 | (uint8_t*) &pk.nonce, | 132 | (uint8_t*) &pk.nonce, |
123 | (uint8_t*) &ping_id, sizeof(ping_id), | 133 | (uint8_t*) &ping_id, sizeof(ping_id), |
124 | (uint8_t*) &pk.ping_id); | 134 | (uint8_t*) &pk.ping_id); |
125 | 135 | ||
126 | if(rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 136 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
127 | return 1; | 137 | return 1; |
128 | 138 | ||
129 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | 139 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); |
130 | } | 140 | } |
131 | 141 | ||
132 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) { | 142 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) |
133 | pingres_t pk; | 143 | { |
134 | int rc; | 144 | pingres_t pk; |
145 | int rc; | ||
135 | 146 | ||
136 | if(id_eq(client_id, self_id)) | 147 | if (id_eq(client_id, self_id)) |
137 | return 1; | 148 | return 1; |
138 | 149 | ||
139 | pk.magic = PACKET_PING_RES; | 150 | pk.magic = PACKET_PING_RES; |
140 | id_cpy(&pk.client_id, self_id); // Our pubkey | 151 | id_cpy(&pk.client_id, self_id); // Our pubkey |
141 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | 152 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce |
142 | 153 | ||
143 | // Encrypt ping_id using recipient privkey | 154 | // Encrypt ping_id using recipient privkey |
144 | rc = encrypt_data((uint8_t*) client_id, | 155 | rc = encrypt_data((uint8_t*) client_id, |
145 | self_secret_key, | 156 | self_secret_key, |
146 | (uint8_t*) &pk.nonce, | 157 | (uint8_t*) &pk.nonce, |
147 | (uint8_t*) &ping_id, sizeof(ping_id), | 158 | (uint8_t*) &ping_id, sizeof(ping_id), |
148 | (uint8_t*) &pk.ping_id); | 159 | (uint8_t*) &pk.ping_id); |
149 | 160 | ||
150 | if(rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 161 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
151 | return 1; | 162 | return 1; |
152 | 163 | ||
153 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | 164 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); |
154 | } | 165 | } |
diff --git a/core/util.c b/core/util.c index 5b560171..d201bcb4 100644 --- a/core/util.c +++ b/core/util.c | |||
@@ -12,29 +12,34 @@ | |||
12 | #include "DHT.h" | 12 | #include "DHT.h" |
13 | #include "packets.h" | 13 | #include "packets.h" |
14 | 14 | ||
15 | uint64_t now() { | 15 | uint64_t now() |
16 | return time(NULL); | 16 | { |
17 | return time(NULL); | ||
17 | } | 18 | } |
18 | 19 | ||
19 | uint64_t random_64b() { | 20 | uint64_t random_64b() |
20 | uint64_t r; | 21 | { |
22 | uint64_t r; | ||
21 | 23 | ||
22 | // This is probably not random enough? | 24 | // This is probably not random enough? |
23 | r = random_int(); | 25 | r = random_int(); |
24 | r <<= 32; | 26 | r <<= 32; |
25 | r |= random_int(); | 27 | r |= random_int(); |
26 | 28 | ||
27 | return r; | 29 | return r; |
28 | } | 30 | } |
29 | 31 | ||
30 | bool ipp_eq(IP_Port a, IP_Port b) { | 32 | bool ipp_eq(IP_Port a, IP_Port b) |
31 | return (a.ip.i == b.ip.i) && (a.port == b.port); | 33 | { |
34 | return (a.ip.i == b.ip.i) && (a.port == b.port); | ||
32 | } | 35 | } |
33 | 36 | ||
34 | bool id_eq(clientid_t* dest, clientid_t* src) { | 37 | bool id_eq(clientid_t* dest, clientid_t* src) |
35 | return memcmp(dest, src, sizeof(clientid_t)) == 0; | 38 | { |
39 | return memcmp(dest, src, sizeof(clientid_t)) == 0; | ||
36 | } | 40 | } |
37 | 41 | ||
38 | void id_cpy(clientid_t* dest, clientid_t* src) { | 42 | void id_cpy(clientid_t* dest, clientid_t* src) |
39 | memcpy(dest, src, sizeof(clientid_t)); | 43 | { |
44 | memcpy(dest, src, sizeof(clientid_t)); | ||
40 | } | 45 | } |