summaryrefslogtreecommitdiff
path: root/core/ping.c
diff options
context:
space:
mode:
authorplutooo <tfy12vbr@student.lu.se>2013-08-05 12:51:58 -0700
committerplutooo <tfy12vbr@student.lu.se>2013-08-05 12:51:58 -0700
commit071ac463082646189ade6e31bb3f6051516f81b2 (patch)
treeb9726cb351a9bcf21a0373bd561c72d72d543c60 /core/ping.c
parentf0397ebb2b85100e2ac1b2d3a377ba012ab53240 (diff)
core: Rewrote ping-module, better performance and cleaner code.
Diffstat (limited to 'core/ping.c')
-rw-r--r--core/ping.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/core/ping.c b/core/ping.c
new file mode 100644
index 00000000..8a7d534f
--- /dev/null
+++ b/core/ping.c
@@ -0,0 +1,95 @@
1/*
2 * ping.c -- Buffered pinging using cyclic arrays.
3 *
4 * This file is donated to the Tox Project.
5 * Copyright 2013 plutooo
6 */
7
8#include <stdbool.h>
9#include <stdint.h>
10
11#include "network.h"
12#include "util.h"
13
14#define PING_NUM_MAX 256
15#define PING_TIMEOUT 5 // 5s
16
17typedef struct {
18 IP_Port ipp;
19 uint64_t id;
20 uint64_t timestamp;
21} pinged_t;
22
23static pinged_t pings[PING_NUM_MAX];
24static size_t num_pings;
25static size_t pos_pings;
26
27
28void init_ping() {
29 num_pings = 0;
30 pos_pings = 0;
31}
32
33static bool is_timeout(uint64_t time) {
34 return (time + PING_TIMEOUT) < now();
35}
36
37static void remove_timeouts() { // O(n)
38 size_t i, id;
39 size_t new_pos = pos_pings;
40 size_t new_num = num_pings;
41
42 // Loop through buffer, oldest first
43 for(i=0; i<num_pings; i++) {
44 id = (pos_pings + i) % PING_NUM_MAX;
45
46 if(is_timeout(pings[id].timestamp)) {
47 new_pos++;
48 new_num--;
49 }
50 // Break here because list is sorted.
51 else
52 break;
53 }
54
55 num_pings = new_num;
56 pos_pings = new_pos % PING_NUM_MAX;
57}
58
59uint64_t add_ping(IP_Port ipp) { // O(n)
60 size_t p;
61
62 remove_timeouts();
63
64 // Remove oldest ping if full buffer
65 if(num_pings == PING_NUM_MAX) {
66 num_pings--;
67 pos_pings = (pos_pings + 1) % PING_NUM_MAX;
68 }
69
70 // Insert new ping at end of list
71 p = (pos_pings + num_pings) % PING_NUM_MAX;
72
73 pings[p].ipp = ipp;
74 pings[p].timestamp = now();
75 pings[p].id = random_64b();
76
77 num_pings++;
78 return pings[p].id;
79}
80
81bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n)
82 size_t i, id;
83
84 remove_timeouts();
85
86 for(i=0; i<num_pings; i++) {
87 id = (pos_pings + i) % PING_NUM_MAX;
88
89 if(ipp_eq(pings[id].ipp, ipp) && pings[id].id == ping_id) {
90 return true;
91 }
92 }
93
94 return false;
95}