summaryrefslogtreecommitdiff
path: root/core/ping.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/ping.c')
-rw-r--r--core/ping.c95
1 files changed, 51 insertions, 44 deletions
diff --git a/core/ping.c b/core/ping.c
index 10b9b19f..5da3c0ca 100644
--- a/core/ping.c
+++ b/core/ping.c
@@ -23,16 +23,20 @@ typedef struct {
23 uint64_t timestamp; 23 uint64_t timestamp;
24} pinged_t; 24} pinged_t;
25 25
26static pinged_t pings[PING_NUM_MAX]; 26typedef struct {
27static size_t num_pings; 27 pinged_t pings[PING_NUM_MAX];
28static size_t pos_pings; 28 size_t num_pings;
29 size_t pos_pings;
30} PING;
29 31
30extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c 32void * new_ping(void)
33{
34 return calloc(1, sizeof(PING));
35}
31 36
32void init_ping() 37void kill_ping(void * ping)
33{ 38{
34 num_pings = 0; 39 free(ping);
35 pos_pings = 0;
36} 40}
37 41
38static bool is_timeout(uint64_t time) 42static bool is_timeout(uint64_t time)
@@ -40,17 +44,18 @@ static bool is_timeout(uint64_t time)
40 return (time + PING_TIMEOUT) < now(); 44 return (time + PING_TIMEOUT) < now();
41} 45}
42 46
43static void remove_timeouts() // O(n) 47static void remove_timeouts(void * ping) // O(n)
44{ 48{
49 PING * png = ping;
45 size_t i, id; 50 size_t i, id;
46 size_t new_pos = pos_pings; 51 size_t new_pos = png->pos_pings;
47 size_t new_num = num_pings; 52 size_t new_num = png->num_pings;
48 53
49 // Loop through buffer, oldest first 54 // Loop through buffer, oldest first
50 for (i = 0; i < num_pings; i++) { 55 for (i = 0; i < png->num_pings; i++) {
51 id = (pos_pings + i) % PING_NUM_MAX; 56 id = (png->pos_pings + i) % PING_NUM_MAX;
52 57
53 if (is_timeout(pings[id].timestamp)) { 58 if (is_timeout(png->pings[id].timestamp)) {
54 new_pos++; 59 new_pos++;
55 new_num--; 60 new_num--;
56 } 61 }
@@ -60,47 +65,49 @@ static void remove_timeouts() // O(n)
60 } 65 }
61 } 66 }
62 67
63 num_pings = new_num; 68 png->num_pings = new_num;
64 pos_pings = new_pos % PING_NUM_MAX; 69 png->pos_pings = new_pos % PING_NUM_MAX;
65} 70}
66 71
67uint64_t add_ping(IP_Port ipp) // O(n) 72uint64_t add_ping(void * ping, IP_Port ipp) // O(n)
68{ 73{
74 PING * png = ping;
69 size_t p; 75 size_t p;
70 76
71 remove_timeouts(); 77 remove_timeouts(ping);
72 78
73 // Remove oldest ping if full buffer 79 // Remove oldest ping if full buffer
74 if (num_pings == PING_NUM_MAX) { 80 if (png->num_pings == PING_NUM_MAX) {
75 num_pings--; 81 png->num_pings--;
76 pos_pings = (pos_pings + 1) % PING_NUM_MAX; 82 png->pos_pings = (png->pos_pings + 1) % PING_NUM_MAX;
77 } 83 }
78 84
79 // Insert new ping at end of list 85 // Insert new ping at end of list
80 p = (pos_pings + num_pings) % PING_NUM_MAX; 86 p = (png->pos_pings + png->num_pings) % PING_NUM_MAX;
81 87
82 pings[p].ipp = ipp; 88 png->pings[p].ipp = ipp;
83 pings[p].timestamp = now(); 89 png->pings[p].timestamp = now();
84 pings[p].id = random_64b(); 90 png->pings[p].id = random_64b();
85 91
86 num_pings++; 92 png->num_pings++;
87 return pings[p].id; 93 return png->pings[p].id;
88} 94}
89 95
90bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. 96bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else.
91{ 97{
98 PING * png = ping;
92 if (ipp.ip.i == 0 && ping_id == 0) 99 if (ipp.ip.i == 0 && ping_id == 0)
93 return false; 100 return false;
94 101
95 size_t i, id; 102 size_t i, id;
96 103
97 remove_timeouts(); 104 remove_timeouts(ping);
98 105
99 for (i = 0; i < num_pings; i++) { 106 for (i = 0; i < png->num_pings; i++) {
100 id = (pos_pings + i) % PING_NUM_MAX; 107 id = (png->pos_pings + i) % PING_NUM_MAX;
101 108
102 // ping_id = 0 means match any id 109 // ping_id = 0 means match any id
103 if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { 110 if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.i == 0) && (png->pings[id].id == ping_id || ping_id == 0)) {
104 return true; 111 return true;
105 } 112 }
106 } 113 }
@@ -108,25 +115,25 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
108 return false; 115 return false;
109} 116}
110 117
111int send_ping_request(IP_Port ipp, clientid_t *client_id) 118int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id)
112{ 119{
113 pingreq_t pk; 120 pingreq_t pk;
114 int rc; 121 int rc;
115 uint64_t ping_id; 122 uint64_t ping_id;
116 123
117 if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) 124 if (is_pinging(ping, ipp, 0) || id_eq(client_id, (clientid_t *)c->self_public_key))
118 return 1; 125 return 1;
119 126
120 // Generate random ping_id 127 // Generate random ping_id
121 ping_id = add_ping(ipp); 128 ping_id = add_ping(ping, ipp);
122 129
123 pk.magic = PACKET_PING_REQ; 130 pk.magic = PACKET_PING_REQ;
124 id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey 131 id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey
125 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce 132 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
126 133
127 // Encrypt ping_id using recipient privkey 134 // Encrypt ping_id using recipient privkey
128 rc = encrypt_data((uint8_t *) client_id, 135 rc = encrypt_data((uint8_t *) client_id,
129 temp_net_crypto->self_secret_key, 136 c->self_secret_key,
130 (uint8_t *) &pk.nonce, 137 (uint8_t *) &pk.nonce,
131 (uint8_t *) &ping_id, sizeof(ping_id), 138 (uint8_t *) &ping_id, sizeof(ping_id),
132 (uint8_t *) &pk.ping_id); 139 (uint8_t *) &pk.ping_id);
@@ -134,24 +141,24 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
134 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 141 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
135 return 1; 142 return 1;
136 143
137 return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); 144 return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
138} 145}
139 146
140int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) 147int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
141{ 148{
142 pingres_t pk; 149 pingres_t pk;
143 int rc; 150 int rc;
144 151
145 if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) 152 if (id_eq(client_id, (clientid_t *)c->self_public_key))
146 return 1; 153 return 1;
147 154
148 pk.magic = PACKET_PING_RES; 155 pk.magic = PACKET_PING_RES;
149 id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey 156 id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey
150 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce 157 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
151 158
152 // Encrypt ping_id using recipient privkey 159 // Encrypt ping_id using recipient privkey
153 rc = encrypt_data((uint8_t *) client_id, 160 rc = encrypt_data((uint8_t *) client_id,
154 temp_net_crypto->self_secret_key, 161 c->self_secret_key,
155 (uint8_t *) &pk.nonce, 162 (uint8_t *) &pk.nonce,
156 (uint8_t *) &ping_id, sizeof(ping_id), 163 (uint8_t *) &ping_id, sizeof(ping_id),
157 (uint8_t *) &pk.ping_id); 164 (uint8_t *) &pk.ping_id);
@@ -159,7 +166,7 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
159 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 166 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
160 return 1; 167 return 1;
161 168
162 return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); 169 return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
163} 170}
164 171
165int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) 172int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -184,7 +191,7 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t
184 return 1; 191 return 1;
185 192
186 // Send response 193 // Send response
187 send_ping_response(source, &p->client_id, ping_id); 194 send_ping_response(dht->c, source, &p->client_id, ping_id);
188 add_toping(dht, (uint8_t *) &p->client_id, source); 195 add_toping(dht, (uint8_t *) &p->client_id, source);
189 196
190 return 0; 197 return 0;
@@ -212,7 +219,7 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_
212 return 1; 219 return 1;
213 220
214 // Make sure ping_id is correct 221 // Make sure ping_id is correct
215 if (!is_pinging(source, ping_id)) 222 if (!is_pinging(dht->ping, source, ping_id))
216 return 1; 223 return 1;
217 224
218 // Associate source ip with client_id 225 // Associate source ip with client_id