summaryrefslogtreecommitdiff
path: root/core/ping.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/ping.c')
-rw-r--r--core/ping.c127
1 files changed, 122 insertions, 5 deletions
diff --git a/core/ping.c b/core/ping.c
index ffabe221..6a1fbb7e 100644
--- a/core/ping.c
+++ b/core/ping.c
@@ -8,6 +8,9 @@
8#include <stdbool.h> 8#include <stdbool.h>
9#include <stdint.h> 9#include <stdint.h>
10 10
11#include "DHT.h"
12#include "net_crypto.h"
13#include "packets.h"
11#include "network.h" 14#include "network.h"
12#include "util.h" 15#include "util.h"
13 16
@@ -20,10 +23,12 @@ typedef struct {
20 uint64_t timestamp; 23 uint64_t timestamp;
21} pinged_t; 24} pinged_t;
22 25
23static pinged_t pings[PING_NUM_MAX]; 26static pinged_t pings[PING_NUM_MAX];
24static size_t num_pings; 27static size_t num_pings;
25static size_t pos_pings; 28static size_t pos_pings;
29static clientid_t* self_id = (clientid_t*) &self_public_key;
26 30
31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
27 32
28void init_ping() 33void init_ping()
29{ 34{
@@ -51,15 +56,16 @@ static void remove_timeouts() // O(n)
51 new_num--; 56 new_num--;
52 } 57 }
53 // Break here because list is sorted. 58 // Break here because list is sorted.
54 else 59 else {
55 break; 60 break;
61 }
56 } 62 }
57 63
58 num_pings = new_num; 64 num_pings = new_num;
59 pos_pings = new_pos % PING_NUM_MAX; 65 pos_pings = new_pos % PING_NUM_MAX;
60} 66}
61 67
62uint64_t add_ping(IP_Port ipp) // O(n) 68uint64_t add_ping(IP_Port ipp) // O(n)
63{ 69{
64 size_t p; 70 size_t p;
65 71
@@ -94,6 +100,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
94 for (i=0; i<num_pings; i++) { 100 for (i=0; i<num_pings; i++) {
95 id = (pos_pings + i) % PING_NUM_MAX; 101 id = (pos_pings + i) % PING_NUM_MAX;
96 102
103 // ping_id = 0 means match any id
97 if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { 104 if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) {
98 return true; 105 return true;
99 } 106 }
@@ -101,3 +108,113 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
101 108
102 return false; 109 return false;
103} 110}
111
112int send_ping_request(IP_Port ipp, clientid_t* client_id)
113{
114 pingreq_t pk;
115 int rc;
116 uint64_t ping_id;
117
118 if (is_pinging(ipp, 0) || id_eq(client_id, self_id))
119 return 1;
120
121 // Generate random ping_id
122 ping_id = add_ping(ipp);
123
124 pk.magic = PACKET_PING_REQ;
125 id_cpy(&pk.client_id, self_id); // Our pubkey
126 random_nonce((uint8_t*) &pk.nonce); // Generate random nonce
127
128 // Encrypt ping_id using recipient privkey
129 rc = encrypt_data((uint8_t*) client_id,
130 self_secret_key,
131 (uint8_t*) &pk.nonce,
132 (uint8_t*) &ping_id, sizeof(ping_id),
133 (uint8_t*) &pk.ping_id);
134
135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
136 return 1;
137
138 return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk));
139}
140
141int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id)
142{
143 pingres_t pk;
144 int rc;
145
146 if (id_eq(client_id, self_id))
147 return 1;
148
149 pk.magic = PACKET_PING_RES;
150 id_cpy(&pk.client_id, self_id); // Our pubkey
151 random_nonce((uint8_t*) &pk.nonce); // Generate random nonce
152
153 // Encrypt ping_id using recipient privkey
154 rc = encrypt_data((uint8_t*) client_id,
155 self_secret_key,
156 (uint8_t*) &pk.nonce,
157 (uint8_t*) &ping_id, sizeof(ping_id),
158 (uint8_t*) &pk.ping_id);
159
160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
161 return 1;
162
163 return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk));
164}
165
166int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source)
167{
168 pingreq_t* p = (pingreq_t*) packet;
169 int rc;
170 uint64_t ping_id;
171
172 if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id))
173 return 1;
174
175 // Decrypt ping_id
176 rc = decrypt_data((uint8_t*) &p->client_id,
177 self_secret_key,
178 (uint8_t*) &p->nonce,
179 (uint8_t*) &p->ping_id,
180 sizeof(ping_id) + ENCRYPTION_PADDING,
181 (uint8_t*) &ping_id);
182
183 if (rc != sizeof(ping_id))
184 return 1;
185
186 // Send response
187 send_ping_response(source, &p->client_id, ping_id);
188 send_ping_request(source, &p->client_id); // Make this smarter?
189
190 return 0;
191}
192
193int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source)
194{
195 pingres_t* p = (pingres_t*) packet;
196 int rc;
197 uint64_t ping_id;
198
199 if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id))
200 return 1;
201
202 // Decrypt ping_id
203 rc = decrypt_data((uint8_t*) &p->client_id,
204 self_secret_key,
205 (uint8_t*) &p->nonce,
206 (uint8_t*) &p->ping_id,
207 sizeof(ping_id) + ENCRYPTION_PADDING,
208 (uint8_t*) &ping_id);
209
210 if (rc != sizeof(ping_id))
211 return 1;
212
213 // Make sure ping_id is correct
214 if(!is_pinging(source, ping_id))
215 return 1;
216
217 // Associate source ip with client_id
218 addto_lists(source, (uint8_t*) &p->client_id);
219 return 0;
220}