summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-20 14:47:32 -0400
committerirungentoo <irungentoo@gmail.com>2013-08-20 14:47:32 -0400
commitac621d96d3139ca09eeebd509d6f6b92380f4f41 (patch)
tree497a4e5866f0f8d11f98b5e413b24cc650aab1df /core
parenta1c40d753ee8faf15aa0dd314bd4249aa3750b2e (diff)
Refactor of core done.
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c24
-rw-r--r--core/DHT.h2
-rw-r--r--core/Messenger.c18
-rw-r--r--core/Messenger.h20
-rw-r--r--core/net_crypto.c1
-rw-r--r--core/net_crypto.h2
-rw-r--r--core/ping.c95
-rw-r--r--core/ping.h11
-rw-r--r--core/timer.c290
-rw-r--r--core/timer.h104
10 files changed, 85 insertions, 482 deletions
diff --git a/core/DHT.c b/core/DHT.c
index d58c6d2c..a139f2c5 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -603,7 +603,7 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint
603 uint32_t i; 603 uint32_t i;
604 604
605 for (i = 0; i < num_nodes; ++i) { 605 for (i = 0; i < num_nodes; ++i) {
606 send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); 606 send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id);
607 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 607 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
608 } 608 }
609 609
@@ -709,7 +709,7 @@ static void do_DHT_friends(DHT * dht)
709 /* if node is not dead. */ 709 /* if node is not dead. */
710 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 710 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
711 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 711 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
712 send_ping_request( dht->friends_list[i].client_list[j].ip_port, 712 send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port,
713 (clientid_t *) &dht->friends_list[i].client_list[j].client_id ); 713 (clientid_t *) &dht->friends_list[i].client_list[j].client_id );
714 dht->friends_list[i].client_list[j].last_pinged = temp_time; 714 dht->friends_list[i].client_list[j].last_pinged = temp_time;
715 } 715 }
@@ -747,7 +747,7 @@ static void do_Close(DHT * dht)
747 /* if node is not dead. */ 747 /* if node is not dead. */
748 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 748 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
749 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 749 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
750 send_ping_request( dht->close_clientlist[i].ip_port, 750 send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port,
751 (clientid_t *) &dht->close_clientlist[i].client_id ); 751 (clientid_t *) &dht->close_clientlist[i].client_id );
752 dht->close_clientlist[i].last_pinged = temp_time; 752 dht->close_clientlist[i].last_pinged = temp_time;
753 } 753 }
@@ -772,8 +772,7 @@ static void do_Close(DHT * dht)
772void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key) 772void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key)
773{ 773{
774 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 774 getnodes(dht, ip_port, public_key, dht->c->self_public_key);
775 //send_ping_request(dht, ip_port, (clientid_t *) public_key); 775 send_ping_request(dht->ping, dht->c, ip_port, (clientid_t *) public_key);
776 send_ping_request(ip_port, (clientid_t *) public_key);
777} 776}
778 777
779/* send the given packet to node with client_id 778/* send the given packet to node with client_id
@@ -1039,8 +1038,7 @@ static void punch_holes(DHT * dht, IP ip, uint16_t *port_list, uint16_t numports
1039 /*TODO: improve port guessing algorithm*/ 1038 /*TODO: improve port guessing algorithm*/
1040 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); 1039 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1041 IP_Port pinging = {ip, htons(port)}; 1040 IP_Port pinging = {ip, htons(port)};
1042 //send_ping_request(dht, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); 1041 send_ping_request(dht->ping, dht->c, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id);
1043 send_ping_request(pinging, (clientid_t *) &dht->friends_list[friend_num].client_id);
1044 } 1042 }
1045 1043
1046 dht->friends_list[friend_num].punching_index = i; 1044 dht->friends_list[friend_num].punching_index = i;
@@ -1139,8 +1137,7 @@ static void do_toping(DHT * dht)
1139 if (dht->toping[i].ip_port.ip.i == 0) 1137 if (dht->toping[i].ip_port.ip.i == 0)
1140 return; 1138 return;
1141 1139
1142 //send_ping_request(dht, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); 1140 send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id);
1143 send_ping_request(dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id);
1144 dht->toping[i].ip_port.ip.i = 0; 1141 dht->toping[i].ip_port.ip.i = 0;
1145 } 1142 }
1146} 1143}
@@ -1151,13 +1148,17 @@ DHT * new_DHT(Net_Crypto *c)
1151 DHT * temp = calloc(1, sizeof(DHT)); 1148 DHT * temp = calloc(1, sizeof(DHT));
1152 if (temp == NULL) 1149 if (temp == NULL)
1153 return NULL; 1150 return NULL;
1151 temp->ping = new_ping();
1152 if (temp->ping == NULL){
1153 kill_DHT(temp);
1154 return NULL;
1155 }
1154 temp->c = c; 1156 temp->c = c;
1155 networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp); 1157 networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp);
1156 networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp); 1158 networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp);
1157 networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp); 1159 networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp);
1158 networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp); 1160 networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp);
1159 cryptopacket_registerhandler(c, 254, &handle_NATping, temp); 1161 cryptopacket_registerhandler(c, 254, &handle_NATping, temp);
1160 temp_DHT = temp;
1161 return temp; 1162 return temp;
1162} 1163}
1163 1164
@@ -1170,6 +1171,7 @@ void do_DHT(DHT * dht)
1170} 1171}
1171void kill_DHT(DHT * dht) 1172void kill_DHT(DHT * dht)
1172{ 1173{
1174 kill_ping(dht->ping);
1173 free(dht->friends_list); 1175 free(dht->friends_list);
1174 free(dht); 1176 free(dht);
1175} 1177}
@@ -1193,8 +1195,6 @@ void DHT_save(DHT * dht, uint8_t *data)
1193 */ 1195 */
1194int DHT_load(DHT * dht, uint8_t *data, uint32_t size) 1196int DHT_load(DHT * dht, uint8_t *data, uint32_t size)
1195{ 1197{
1196 init_ping();
1197
1198 if (size < sizeof(dht->close_clientlist)) 1198 if (size < sizeof(dht->close_clientlist))
1199 return -1; 1199 return -1;
1200 1200
diff --git a/core/DHT.h b/core/DHT.h
index 0ecc0b50..7d926b13 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -100,9 +100,9 @@ typedef struct {
100 Node_format toping[MAX_TOPING]; 100 Node_format toping[MAX_TOPING];
101 uint64_t last_toping; 101 uint64_t last_toping;
102 uint64_t close_lastgetnodes; 102 uint64_t close_lastgetnodes;
103 void * ping;
103} DHT; 104} DHT;
104/*----------------------------------------------------------------------------------*/ 105/*----------------------------------------------------------------------------------*/
105DHT * temp_DHT; //TODO: remove
106 106
107Client_data *DHT_get_close_list(DHT * dht); 107Client_data *DHT_get_close_list(DHT * dht);
108 108
diff --git a/core/Messenger.c b/core/Messenger.c
index 25a4ff98..a6cbb3ac 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -22,7 +22,6 @@
22 */ 22 */
23 23
24#include "Messenger.h" 24#include "Messenger.h"
25#include "timer.h"
26 25
27#define MIN(a,b) (((a)<(b))?(a):(b)) 26#define MIN(a,b) (((a)<(b))?(a):(b))
28 27
@@ -608,17 +607,17 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
608 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 607 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1);
609} 608}
610 609
611
612/*Interval in seconds between LAN discovery packet sending*/ 610/*Interval in seconds between LAN discovery packet sending*/
613#define LAN_DISCOVERY_INTERVAL 60 611#define LAN_DISCOVERY_INTERVAL 60
614#define PORT 33445 612#define PORT 33445
615 613
616/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 614/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
617int LANdiscovery(timer *t, void *arg) 615static void LANdiscovery(Messenger *m)
618{ 616{
619 send_LANdiscovery(htons(PORT), temp_net_crypto); 617 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
620 timer_start(t, LAN_DISCOVERY_INTERVAL); 618 send_LANdiscovery(htons(PORT), m->net_crypto);
621 return 0; 619 m->last_LANdiscovery = unix_time();
620 }
622} 621}
623 622
624/* run this at startup */ 623/* run this at startup */
@@ -655,9 +654,6 @@ Messenger *initMessenger(void)
655 set_nospam(&(m->fr), random_int()); 654 set_nospam(&(m->fr), random_int());
656 init_cryptopackets(m->dht); 655 init_cryptopackets(m->dht);
657 656
658 send_LANdiscovery(htons(PORT), m->net_crypto);
659 timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL);
660
661 return m; 657 return m;
662} 658}
663 659
@@ -885,7 +881,6 @@ void doInbound(Messenger *m)
885 } 881 }
886} 882}
887 883
888
889/* the main loop that needs to be run at least 20 times per second. */ 884/* the main loop that needs to be run at least 20 times per second. */
890void doMessenger(Messenger *m) 885void doMessenger(Messenger *m)
891{ 886{
@@ -895,8 +890,7 @@ void doMessenger(Messenger *m)
895 do_net_crypto(m->net_crypto); 890 do_net_crypto(m->net_crypto);
896 doInbound(m); 891 doInbound(m);
897 doFriends(m); 892 doFriends(m);
898 893 LANdiscovery(m);
899 timer_poll();
900} 894}
901 895
902/* returns the size of the messenger data (for saving) */ 896/* returns the size of the messenger data (for saving) */
diff --git a/core/Messenger.h b/core/Messenger.h
index c4e7cc1e..518becc9 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -128,6 +128,8 @@ typedef struct Messenger {
128 Friend *friendlist; 128 Friend *friendlist;
129 uint32_t numfriends; 129 uint32_t numfriends;
130 130
131 uint64_t last_LANdiscovery;
132
131 void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *); 133 void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
132 void *friend_message_userdata; 134 void *friend_message_userdata;
133 void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *); 135 void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
@@ -222,17 +224,13 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt
222 return -1 if failure */ 224 return -1 if failure */
223int setname(Messenger *m, uint8_t *name, uint16_t length); 225int setname(Messenger *m, uint8_t *name, uint16_t length);
224 226
225/** 227/*
226 * @brief Get your nickname. 228 Get your nickname.
227 * 229 m The messanger context to use.
228 * @param[in] m The messanger context to use. 230 name Pointer to a string for the name.
229 * 231 nlen The length of the string buffer.
230 * @param[inout] name Pointer to a string for the name. 232 returns Return the length of the name, 0 on error.
231 * 233*/
232 * @param[in] nlen The length of the string buffer.
233 *
234 * @return Return the length of the name, 0 on error.
235 */
236uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen); 234uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen);
237 235
238/* get name of friendnumber 236/* get name of friendnumber
diff --git a/core/net_crypto.c b/core/net_crypto.c
index 2e63d2f1..e36a1666 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -706,7 +706,6 @@ Net_Crypto * new_net_crypto(Networking_Core * net)
706 if (temp->lossless_udp == NULL) 706 if (temp->lossless_udp == NULL)
707 return NULL; 707 return NULL;
708 memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); 708 memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING);
709 temp_net_crypto = temp; //TODO remove
710 return temp; 709 return temp;
711} 710}
712 711
diff --git a/core/net_crypto.h b/core/net_crypto.h
index 887b432b..7b9e9b97 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -73,8 +73,6 @@ typedef struct {
73 73
74#include "DHT.h" 74#include "DHT.h"
75 75
76Net_Crypto * temp_net_crypto; //TODO: remove this
77
78#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 76#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
79 77
80/* returns zero if the buffer contains only zeros */ 78/* returns zero if the buffer contains only zeros */
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
diff --git a/core/ping.h b/core/ping.h
index 6d5a0ea6..1f30392c 100644
--- a/core/ping.h
+++ b/core/ping.h
@@ -7,10 +7,11 @@
7 7
8#include <stdbool.h> 8#include <stdbool.h>
9 9
10void init_ping(); 10void * new_ping(void);
11uint64_t add_ping(IP_Port ipp); 11void kill_ping(void * ping);
12bool is_pinging(IP_Port ipp, uint64_t ping_id); 12uint64_t add_ping(void * ping, IP_Port ipp);
13int send_ping_request(IP_Port ipp, clientid_t *client_id); 13bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id);
14int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); 14int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id);
15int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id);
15int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length); 16int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length);
16int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length); 17int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length);
diff --git a/core/timer.c b/core/timer.c
deleted file mode 100644
index 29190921..00000000
--- a/core/timer.c
+++ /dev/null
@@ -1,290 +0,0 @@
1#define __STDC_FORMAT_MACROS
2#include <inttypes.h>
3
4#include "timer.h"
5#include "network.h"
6
7/*
8A nested linked list increases efficiency of insertions.
9Depending on the number of timers we have, we might need to have nested linked lists
10in order to improve insertion efficiency.
11The code below is preperation for that end, should it be necessary.
12
13typedef struct {
14 struct timer_package* _next;
15 union {
16 timer_packet* _inner;
17 timer* queue;
18 };
19 uint64_t pkgtime;
20} timer_package;
21
22timer_package* timer_package_pool;
23
24static timer_package* new_package()
25{
26 timer_package* ret;
27 if (timer_package_pool) {
28 ret = timer_package_pool;
29 timer_package_pool = timer_package_pool->_next;
30 } else {
31 ret = calloc(1, sizeof(struct timer_package));
32 }
33 return ret;
34}
35
36static void delete_package(timer_package* p)
37{
38 p->_next = timer_package_pool;
39 timer_package_pool = p;
40}
41*/
42
43enum timer_state {
44 STATE_INACTIVE = 0,
45 STATE_ACTIVE,
46 STATE_CALLBACK
47};
48
49struct timer {
50 enum timer_state state;
51 timer *_prev;
52 timer *_next;
53 timer_callback cb;
54 void *userdata;
55 uint64_t deadline;
56};
57
58static timer *timer_main_queue;
59static timer *timer_us_queue; /* hi-speed queue */
60
61inline static void timer_dequeue(timer *t, timer **queue)
62{
63 if (t->state == STATE_INACTIVE) return; /* not in a queue */
64
65 if (t->_prev) {
66 t->_prev->_next = t->_next;
67 } else {
68 *queue = t->_next;
69 }
70
71 if (t->_next) t->_next->_prev = t->_prev;
72
73 t->state = STATE_INACTIVE;
74}
75
76static void timer_enqueue(timer *t, timer **queue, timer *prev)
77{
78 t->state = STATE_ACTIVE;
79
80 while (true) {
81 if (!*queue) {
82 t->_next = 0;
83 t->_prev = prev;
84 *queue = t;
85 return;
86 }
87
88 if ((*queue)->deadline > t->deadline) {
89 (*queue)->_prev = t;
90 t->_next = *queue;
91 t->_prev = prev;
92 *queue = t;
93 return;
94 }
95
96 prev = *queue;
97 queue = &((*queue)->_next);
98 }
99}
100
101/*** interface ***/
102
103void timer_init()
104{
105 /* Nothing needs to be done... yet. */
106}
107
108/* Do not depend on fields being zeroed */
109static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */
110
111timer *new_timer(void)
112{
113 timer *ret;
114
115 if (timer_pool) {
116 ret = timer_pool;
117 timer_pool = timer_pool->_next;
118 } else {
119 ret = calloc(1, sizeof(struct timer));
120 }
121
122 ret->state = STATE_INACTIVE;
123 return ret;
124}
125
126void delete_timer(timer *t)
127{
128 timer_dequeue(t, &timer_main_queue);
129 t->_next = timer_pool;
130 t->state = STATE_INACTIVE;
131 timer_pool = t;
132}
133
134void timer_setup(timer *t, timer_callback cb, void *userarg)
135{
136 t->cb = cb;
137 t->userdata = userarg;
138}
139
140void *timer_get_userdata(timer *t)
141{
142 return t->userdata;
143}
144
145static void timer_delay_us(timer *t, int us)
146{
147 t->deadline += us;
148 timer **queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue;
149 timer_dequeue(t, &timer_main_queue);
150 timer_enqueue(t, queue, t->_prev);
151}
152
153/* Starts the timer so that it's called in sec seconds in the future.
154 * A non-positive value of sec results in the callback being called immediately.
155 * This function may be called again after a timer has been started to adjust
156 * the expiry time. */
157void timer_start(timer *t, int sec)
158{
159 uint64_t newdeadline = current_time() + sec * US_PER_SECOND;
160
161 if (timer_is_active(t)) {
162 if (t->deadline < newdeadline) {
163 timer_delay_us(t, newdeadline - t->deadline);
164 return;
165 }
166
167 timer_dequeue(t, &timer_main_queue);
168 }
169
170 t->deadline = newdeadline;
171 timer_enqueue(t, &timer_main_queue, 0);
172}
173
174/* Stops the timer. Returns -1 if the timer was not active. */
175int timer_stop(timer *t)
176{
177 int ret = timer_is_active(t) ? -1 : 0;
178 timer_dequeue(t, &timer_main_queue);
179 return ret;
180}
181
182/* Adds additionalsec seconds to the timer.
183 * Returns -1 and does nothing if the timer was not active. */
184int timer_delay(timer *t, int additonalsec)
185{
186 if (!timer_is_active(t)) return -1;
187
188 timer_delay_us(t, additonalsec * US_PER_SECOND);
189 return 0;
190}
191
192static uint64_t timer_diff(timer *t, uint64_t time)
193{
194 if (t->deadline <= time) return 0;
195
196 return time - t->deadline;
197}
198
199/* Returns the time remaining on a timer in seconds.
200 * Returns -1 if the timer is not active.
201 * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */
202int timer_time_remaining(timer *t)
203{
204 if (!timer_is_active(t)) return -1;
205
206 return timer_diff(t, current_time()) / US_PER_SECOND;
207}
208
209bool timer_is_active(timer *t)
210{
211 return t->state != STATE_INACTIVE;
212}
213
214/* Single-use timer.
215 * Creates a new timer, preforms setup and starts it. */
216void timer_single(timer_callback cb, void *userarg, int sec)
217{
218 timer *t = new_timer();
219 timer_setup(t, cb, userarg);
220 timer_start(t, sec);
221}
222
223/* Single-use microsecond timer. */
224void timer_us(timer_callback cb, void *userarg, int us)
225{
226 timer *t = new_timer();
227 timer_setup(t, cb, userarg);
228 t->deadline = current_time() + us;
229 t->state = STATE_ACTIVE;
230 timer_enqueue(t, &timer_us_queue, 0);
231}
232
233uint64_t prevtime = 0;
234void timer_poll(void)
235{
236 uint64_t time = current_time();
237
238 /* Handle millisecond timers */
239 while (timer_us_queue) {
240 if (timer_diff(timer_us_queue, time) != 0) break;
241
242 timer *t = timer_us_queue;
243 timer_dequeue(t, &timer_us_queue);
244 t->cb(0, t->userdata);
245 delete_timer(t);
246 }
247
248 if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) {
249 /* time moving backwards is just a sanity check */
250 prevtime = time;
251
252 while (timer_main_queue) {
253 if (timer_diff(timer_main_queue, time) != 0) break;
254
255 timer *t = timer_main_queue;
256 t->state = STATE_CALLBACK;
257 int rv = t->cb(t, t->userdata);
258
259 if (rv != 0) {
260 timer_dequeue(t, &timer_main_queue);
261 delete_timer(t);
262 continue;
263 }
264
265 if (t->state != STATE_ACTIVE) {
266 timer_dequeue(t, &timer_main_queue);
267 }
268 }
269 }
270}
271
272/*** Internal Testing ***/
273
274/* I do not want to expose internals to the public,
275 * which is why internals testing is done this way. */
276void timer_internal_tests(bool (*assert)(bool, char *))
277{
278
279}
280
281void timer_debug_print()
282{
283 timer *t = timer_main_queue;
284 printf("Queue:\n");
285
286 while (t) {
287 printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline / US_PER_SECOND, (char *)t->userdata);
288 t = t->_next;
289 }
290}
diff --git a/core/timer.h b/core/timer.h
deleted file mode 100644
index 15491326..00000000
--- a/core/timer.h
+++ /dev/null
@@ -1,104 +0,0 @@
1/* timer.h
2 *
3 * Timing subsystem. Provides deadline timers.
4 * All times are aliased to a second for efficiency.
5 *
6 * Timer Guarantees:
7 * - The callback will not be called before the timer expires.
8 * - The callback will be called sometime after the timer expires,
9 * on a best effort basis.
10 * - If timer_poll is called at least once a second, the callback
11 * will be called at most one second after it expires.
12 *
13 * Copyright (C) 2013 Tox project All Rights Reserved.
14 *
15 * This file is part of Tox.
16 *
17 * Tox is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * Tox is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
29 *
30 */
31
32#ifndef TIMER_H
33#define TIMER_H
34
35#include <stdint.h>
36#include <stdbool.h>
37
38#define US_PER_SECOND 1000000 /* 1 s = 10^6 us */
39
40struct timer;
41typedef struct timer timer;
42
43/* If time_callback returns a non-zero value, timer t is deleted.
44 * You may call any of the timer functions within the callback:
45 * For example, you may call timer_start to restart the timer from
46 * within a callback. */
47typedef int (*timer_callback)(timer *t, void *userarg);
48
49/* Initisalise timer subsystem */
50void timer_init(void);
51
52/* Poll. (I will eventually replace all polling in Tox with an async system.) */
53void timer_poll(void);
54
55/* Creates a new timer. Does not enqueue/start it. */
56timer *new_timer(void);
57
58/* Destroys a timer instance. */
59void delete_timer(timer *t);
60
61/* Sets up the timer callback. */
62void timer_setup(timer *t, timer_callback cb, void *userarg);
63
64/* Accessor Function. */
65void *timer_get_userdata(timer *t);
66
67/* Starts the timer so that it's called in sec seconds in the future from now.
68 * A non-positive value of sec results in the callback being called immediately.
69 * This function may be called again after a timer has been started to adjust
70 * the expiry time. */
71void timer_start(timer *t, int sec);
72
73/* Stops the timer. Returns -1 if the timer was not active. */
74int timer_stop(timer *t);
75
76/* Adds additionalsec seconds to the timer.
77 * Returns -1 and does nothing if the timer was not active. */
78int timer_delay(timer *t, int additonalsec);
79
80/* Returns the time remaining on a timer in seconds.
81 * Returns -1 if the timer is not active.
82 * Returns 0 if the timer has expired and the callback hasn't been called yet. */
83int timer_time_remaining(timer *t);
84
85/* Determines if timer is active. Returns TRUE if it is active */
86bool timer_is_active(timer *t);
87
88/* Single-use timer.
89 * Creates a new timer, preforms setup and starts it.
90 * Callback must return a non-zero value to prevent memory leak. */
91void timer_single(timer_callback cb, void *userarg, int sec);
92
93/* Single-use microsecond timer.
94 * Creates a new timer, preforms setup and starts it.
95 * Please do not use this when accuracy is not absolutely required.
96 * Use when one needs to time a period < 1 s.
97 * Use the more coarse timers above for periods > 5 s.
98 * WARNING: the callback will be called with NULL as the first argument */
99void timer_us(timer_callback cb, void *userarg, int us);
100
101/* Internal Testing */
102void timer_internal_tests(bool( *)(bool, char *));
103
104#endif