summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/packets.h30
-rw-r--r--core/ping.c179
-rw-r--r--core/util.c35
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
8typedef struct { 8typedef 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
12typedef enum { 13typedef 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
18typedef struct { 20typedef 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
27typedef struct { 30typedef 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;
31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c 31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
32 32
33 33
34void init_ping() { 34void init_ping()
35 num_pings = 0; 35{
36 pos_pings = 0; 36 num_pings = 0;
37 pos_pings = 0;
37} 38}
38 39
39static bool is_timeout(uint64_t time) { 40static bool is_timeout(uint64_t time)
40 return (time + PING_TIMEOUT) < now(); 41{
42 return (time + PING_TIMEOUT) < now();
41} 43}
42 44
43static void remove_timeouts() { // O(n) 45static 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
65uint64_t add_ping(IP_Port ipp) { // O(n) 69uint64_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
87bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n) 92bool 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
104int send_ping_request(IP_Port ipp, clientid_t* client_id) { 113int 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
132int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) { 142int 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
15uint64_t now() { 15uint64_t now()
16 return time(NULL); 16{
17 return time(NULL);
17} 18}
18 19
19uint64_t random_64b() { 20uint64_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
30bool ipp_eq(IP_Port a, IP_Port b) { 32bool 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
34bool id_eq(clientid_t* dest, clientid_t* src) { 37bool 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
38void id_cpy(clientid_t* dest, clientid_t* src) { 42void 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}