diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 24 | ||||
-rw-r--r-- | core/DHT.h | 2 | ||||
-rw-r--r-- | core/Messenger.c | 18 | ||||
-rw-r--r-- | core/Messenger.h | 20 | ||||
-rw-r--r-- | core/net_crypto.c | 1 | ||||
-rw-r--r-- | core/net_crypto.h | 2 | ||||
-rw-r--r-- | core/ping.c | 95 | ||||
-rw-r--r-- | core/ping.h | 11 | ||||
-rw-r--r-- | core/timer.c | 290 | ||||
-rw-r--r-- | core/timer.h | 104 |
10 files changed, 85 insertions, 482 deletions
@@ -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) | |||
772 | void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key) | 772 | void 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 | } |
1171 | void kill_DHT(DHT * dht) | 1172 | void 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 | */ |
1194 | int DHT_load(DHT * dht, uint8_t *data, uint32_t size) | 1196 | int 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 | ||
@@ -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 | /*----------------------------------------------------------------------------------*/ |
105 | DHT * temp_DHT; //TODO: remove | ||
106 | 106 | ||
107 | Client_data *DHT_get_close_list(DHT * dht); | 107 | Client_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*/ |
617 | int LANdiscovery(timer *t, void *arg) | 615 | static 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. */ |
890 | void doMessenger(Messenger *m) | 885 | void 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 */ |
223 | int setname(Messenger *m, uint8_t *name, uint16_t length); | 225 | int 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 | */ | ||
236 | uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen); | 234 | uint16_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 | ||
76 | Net_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 | ||
26 | static pinged_t pings[PING_NUM_MAX]; | 26 | typedef struct { |
27 | static size_t num_pings; | 27 | pinged_t pings[PING_NUM_MAX]; |
28 | static size_t pos_pings; | 28 | size_t num_pings; |
29 | size_t pos_pings; | ||
30 | } PING; | ||
29 | 31 | ||
30 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 32 | void * new_ping(void) |
33 | { | ||
34 | return calloc(1, sizeof(PING)); | ||
35 | } | ||
31 | 36 | ||
32 | void init_ping() | 37 | void kill_ping(void * ping) |
33 | { | 38 | { |
34 | num_pings = 0; | 39 | free(ping); |
35 | pos_pings = 0; | ||
36 | } | 40 | } |
37 | 41 | ||
38 | static bool is_timeout(uint64_t time) | 42 | static 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 | ||
43 | static void remove_timeouts() // O(n) | 47 | static 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 | ||
67 | uint64_t add_ping(IP_Port ipp) // O(n) | 72 | uint64_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 | ||
90 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. | 96 | bool 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 | ||
111 | int send_ping_request(IP_Port ipp, clientid_t *client_id) | 118 | int 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 | ||
140 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | 147 | int 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 | ||
165 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 172 | int 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 | ||
10 | void init_ping(); | 10 | void * new_ping(void); |
11 | uint64_t add_ping(IP_Port ipp); | 11 | void kill_ping(void * ping); |
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | 12 | uint64_t add_ping(void * ping, IP_Port ipp); |
13 | int send_ping_request(IP_Port ipp, clientid_t *client_id); | 13 | bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id); |
14 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); | 14 | int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id); |
15 | int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id); | ||
15 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length); | 16 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length); |
16 | int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length); | 17 | int 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 | /* | ||
8 | A nested linked list increases efficiency of insertions. | ||
9 | Depending on the number of timers we have, we might need to have nested linked lists | ||
10 | in order to improve insertion efficiency. | ||
11 | The code below is preperation for that end, should it be necessary. | ||
12 | |||
13 | typedef struct { | ||
14 | struct timer_package* _next; | ||
15 | union { | ||
16 | timer_packet* _inner; | ||
17 | timer* queue; | ||
18 | }; | ||
19 | uint64_t pkgtime; | ||
20 | } timer_package; | ||
21 | |||
22 | timer_package* timer_package_pool; | ||
23 | |||
24 | static 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 | |||
36 | static void delete_package(timer_package* p) | ||
37 | { | ||
38 | p->_next = timer_package_pool; | ||
39 | timer_package_pool = p; | ||
40 | } | ||
41 | */ | ||
42 | |||
43 | enum timer_state { | ||
44 | STATE_INACTIVE = 0, | ||
45 | STATE_ACTIVE, | ||
46 | STATE_CALLBACK | ||
47 | }; | ||
48 | |||
49 | struct 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 | |||
58 | static timer *timer_main_queue; | ||
59 | static timer *timer_us_queue; /* hi-speed queue */ | ||
60 | |||
61 | inline 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 | |||
76 | static 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 | |||
103 | void timer_init() | ||
104 | { | ||
105 | /* Nothing needs to be done... yet. */ | ||
106 | } | ||
107 | |||
108 | /* Do not depend on fields being zeroed */ | ||
109 | static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */ | ||
110 | |||
111 | timer *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 | |||
126 | void 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 | |||
134 | void timer_setup(timer *t, timer_callback cb, void *userarg) | ||
135 | { | ||
136 | t->cb = cb; | ||
137 | t->userdata = userarg; | ||
138 | } | ||
139 | |||
140 | void *timer_get_userdata(timer *t) | ||
141 | { | ||
142 | return t->userdata; | ||
143 | } | ||
144 | |||
145 | static 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. */ | ||
157 | void 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. */ | ||
175 | int 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. */ | ||
184 | int 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 | |||
192 | static 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. */ | ||
202 | int 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 | |||
209 | bool 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. */ | ||
216 | void 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. */ | ||
224 | void 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 | |||
233 | uint64_t prevtime = 0; | ||
234 | void 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. */ | ||
276 | void timer_internal_tests(bool (*assert)(bool, char *)) | ||
277 | { | ||
278 | |||
279 | } | ||
280 | |||
281 | void 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 | |||
40 | struct timer; | ||
41 | typedef 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. */ | ||
47 | typedef int (*timer_callback)(timer *t, void *userarg); | ||
48 | |||
49 | /* Initisalise timer subsystem */ | ||
50 | void timer_init(void); | ||
51 | |||
52 | /* Poll. (I will eventually replace all polling in Tox with an async system.) */ | ||
53 | void timer_poll(void); | ||
54 | |||
55 | /* Creates a new timer. Does not enqueue/start it. */ | ||
56 | timer *new_timer(void); | ||
57 | |||
58 | /* Destroys a timer instance. */ | ||
59 | void delete_timer(timer *t); | ||
60 | |||
61 | /* Sets up the timer callback. */ | ||
62 | void timer_setup(timer *t, timer_callback cb, void *userarg); | ||
63 | |||
64 | /* Accessor Function. */ | ||
65 | void *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. */ | ||
71 | void timer_start(timer *t, int sec); | ||
72 | |||
73 | /* Stops the timer. Returns -1 if the timer was not active. */ | ||
74 | int timer_stop(timer *t); | ||
75 | |||
76 | /* Adds additionalsec seconds to the timer. | ||
77 | * Returns -1 and does nothing if the timer was not active. */ | ||
78 | int 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. */ | ||
83 | int timer_time_remaining(timer *t); | ||
84 | |||
85 | /* Determines if timer is active. Returns TRUE if it is active */ | ||
86 | bool 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. */ | ||
91 | void 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 */ | ||
99 | void timer_us(timer_callback cb, void *userarg, int us); | ||
100 | |||
101 | /* Internal Testing */ | ||
102 | void timer_internal_tests(bool( *)(bool, char *)); | ||
103 | |||
104 | #endif | ||