diff options
author | Coren[m] <Break@Ocean> | 2013-12-04 00:58:57 +0100 |
---|---|---|
committer | Coren[m] <Break@Ocean> | 2013-12-08 05:43:24 +0100 |
commit | ad9d20c08b59af8d07b646334fd07cbfcad15663 (patch) | |
tree | c80a249d74a2c31e5c2491571c31edbe6680ccfe /toxcore | |
parent | 632e69257731bf2be5bd6c444f096098e0d5d2c8 (diff) |
do_Assoc(): keep the data of the buckets somewhat current
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 9 | ||||
-rw-r--r-- | toxcore/DHT.h | 2 | ||||
-rw-r--r-- | toxcore/assoc.c | 112 | ||||
-rw-r--r-- | toxcore/assoc.h | 7 |
4 files changed, 130 insertions, 0 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index e7020a05..b07f2003 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -663,6 +663,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
663 | return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); | 663 | return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); |
664 | } | 664 | } |
665 | 665 | ||
666 | void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_id) | ||
667 | { | ||
668 | getnodes(dht, *from_ipp, from_id, which_id); | ||
669 | } | ||
670 | |||
666 | /* Send a send nodes response. */ | 671 | /* Send a send nodes response. */ |
667 | /* because of BINARY compatibility, the Node_format MUST BE Node4_format, | 672 | /* because of BINARY compatibility, the Node_format MUST BE Node4_format, |
668 | * IPv6 nodes are sent in a different message */ | 673 | * IPv6 nodes are sent in a different message */ |
@@ -1666,6 +1671,10 @@ void do_DHT(DHT *dht) | |||
1666 | do_DHT_friends(dht); | 1671 | do_DHT_friends(dht); |
1667 | do_NAT(dht); | 1672 | do_NAT(dht); |
1668 | do_toping(dht->ping); | 1673 | do_toping(dht->ping); |
1674 | |||
1675 | if (dht->assoc) | ||
1676 | do_Assoc(dht->assoc, dht); | ||
1677 | |||
1669 | dht->last_run = unix_time(); | 1678 | dht->last_run = unix_time(); |
1670 | } | 1679 | } |
1671 | void kill_DHT(DHT *dht) | 1680 | void kill_DHT(DHT *dht) |
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 5eddab09..d8e9a51e 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -151,6 +151,8 @@ typedef struct { | |||
151 | } DHT; | 151 | } DHT; |
152 | /*----------------------------------------------------------------------------------*/ | 152 | /*----------------------------------------------------------------------------------*/ |
153 | 153 | ||
154 | void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_id); | ||
155 | |||
154 | /* Add a new friend to the friends list. | 156 | /* Add a new friend to the friends list. |
155 | * client_id must be CLIENT_ID_SIZE bytes long. | 157 | * client_id must be CLIENT_ID_SIZE bytes long. |
156 | * | 158 | * |
diff --git a/toxcore/assoc.c b/toxcore/assoc.c index 6a7f7f94..eea01dfb 100644 --- a/toxcore/assoc.c +++ b/toxcore/assoc.c | |||
@@ -65,7 +65,9 @@ typedef struct Client_entry { | |||
65 | hash_t hash; | 65 | hash_t hash; |
66 | 66 | ||
67 | /* shortcuts & rumors: timers and data */ | 67 | /* shortcuts & rumors: timers and data */ |
68 | uint64_t getnodes; | ||
68 | uint64_t used_at; | 69 | uint64_t used_at; |
70 | |||
69 | uint64_t seen_at; | 71 | uint64_t seen_at; |
70 | uint64_t heard_at; | 72 | uint64_t heard_at; |
71 | 73 | ||
@@ -91,6 +93,7 @@ struct Assoc { | |||
91 | size_t candidates_bucket_count; | 93 | size_t candidates_bucket_count; |
92 | size_t candidates_bucket_size; | 94 | size_t candidates_bucket_size; |
93 | candidates_bucket *candidates; | 95 | candidates_bucket *candidates; |
96 | uint64_t getnodes; | ||
94 | }; | 97 | }; |
95 | 98 | ||
96 | /*****************************************************************************/ | 99 | /*****************************************************************************/ |
@@ -803,6 +806,7 @@ Assoc *new_Assoc(size_t bits, size_t entries, uint8_t *public_id) | |||
803 | } | 806 | } |
804 | 807 | ||
805 | assoc->candidates = lists; | 808 | assoc->candidates = lists; |
809 | assoc->getnodes = unix_time(); | ||
806 | 810 | ||
807 | id_copy(assoc->self_client_id, public_id); | 811 | id_copy(assoc->self_client_id, public_id); |
808 | client_id_self_update(assoc); | 812 | client_id_self_update(assoc); |
@@ -827,6 +831,114 @@ void Assoc_self_client_id_changed(Assoc *assoc, uint8_t *id) | |||
827 | } | 831 | } |
828 | } | 832 | } |
829 | 833 | ||
834 | #ifdef LOGGING | ||
835 | static char *idpart2str(uint8_t *id, size_t len); | ||
836 | #endif | ||
837 | |||
838 | /* refresh buckets */ | ||
839 | void do_Assoc(Assoc *assoc, DHT *dht) | ||
840 | { | ||
841 | if (is_timeout(assoc->getnodes, ASSOC_BUCKET_REFRESH)) { | ||
842 | assoc->getnodes = unix_time(); | ||
843 | |||
844 | size_t candidate = (rand() % assoc->candidates_bucket_count) + assoc->candidates_bucket_count; | ||
845 | |||
846 | /* in that bucket or the buckets closest to it: | ||
847 | * find the best heard candidate | ||
848 | * find the best seen candidate | ||
849 | * send getnode() requests to both */ | ||
850 | uint8_t *target_id = NULL; | ||
851 | Client_entry *heard = NULL, *seen = NULL; | ||
852 | size_t i, k, m, bckt; | ||
853 | |||
854 | for (i = 1; i < assoc->candidates_bucket_count; i++) { | ||
855 | if (i % 2) | ||
856 | k = - (i >> 1); | ||
857 | else | ||
858 | k = i >> 1; | ||
859 | |||
860 | bckt = (candidate + k) % assoc->candidates_bucket_count; | ||
861 | |||
862 | for (m = 0; m < assoc->candidates_bucket_size; m++) | ||
863 | if (assoc->candidates[bckt].list[m].hash) { | ||
864 | Client_entry *entry = &assoc->candidates[bckt].list[m]; | ||
865 | |||
866 | if (!is_timeout(entry->getnodes, CANDIDATES_SEEN_TIMEOUT)) | ||
867 | continue; | ||
868 | |||
869 | if (!target_id) | ||
870 | target_id = entry->client.client_id; | ||
871 | |||
872 | if (entry->seen_at) { | ||
873 | if (!seen) | ||
874 | if (!is_timeout(entry->seen_at, CANDIDATES_SEEN_TIMEOUT)) | ||
875 | seen = entry; | ||
876 | } | ||
877 | |||
878 | if (entry->heard_at) { | ||
879 | if (!heard) | ||
880 | if (!is_timeout(entry->heard_at, CANDIDATES_HEARD_TIMEOUT)) | ||
881 | heard = entry; | ||
882 | } | ||
883 | |||
884 | if (seen && heard) | ||
885 | break; | ||
886 | } | ||
887 | |||
888 | if (seen && heard) | ||
889 | break; | ||
890 | } | ||
891 | |||
892 | #ifdef LOGGING | ||
893 | size_t total = 0, written = sprintf(logbuffer, "assoc: [%u] => ", | ||
894 | (uint32_t)(candidate % assoc->candidates_bucket_count)); | ||
895 | |||
896 | if (written > 0) | ||
897 | total += written; | ||
898 | |||
899 | #endif | ||
900 | |||
901 | if (seen) { | ||
902 | IPPTsPng *ippts = seen->seen_family == AF_INET ? &seen->client.assoc4 : &seen->client.assoc6; | ||
903 | #ifdef LOGGING | ||
904 | written = sprintf(logbuffer + total, " S[%s...] %s:%u", idpart2str(seen->client.client_id, 8), | ||
905 | ip_ntoa(&ippts->ip_port.ip), htons(ippts->ip_port.port)); | ||
906 | |||
907 | if (written > 0) | ||
908 | total += written; | ||
909 | |||
910 | #endif | ||
911 | DHT_getnodes(dht, &ippts->ip_port, seen->client.client_id, target_id); | ||
912 | seen->getnodes = unix_time(); | ||
913 | } | ||
914 | |||
915 | if (heard && (heard != seen)) { | ||
916 | IP_Port *ipp = heard->heard_family == AF_INET ? &heard->assoc_heard4 : &heard->assoc_heard6; | ||
917 | #ifdef LOGGING | ||
918 | written = sprintf(logbuffer + total, " H[%s...] %s:%u", idpart2str(heard->client.client_id, 8), ip_ntoa(&ipp->ip), | ||
919 | htons(ipp->port)); | ||
920 | |||
921 | if (written > 0) | ||
922 | total += written; | ||
923 | |||
924 | #endif | ||
925 | DHT_getnodes(dht, ipp, heard->client.client_id, target_id); | ||
926 | heard->getnodes = unix_time(); | ||
927 | } | ||
928 | |||
929 | #ifdef LOGGING | ||
930 | |||
931 | if (!heard && !seen) | ||
932 | sprintf(logbuffer + total, "no nodes to talk to??\n"); | ||
933 | else | ||
934 | /* for arcane reasons, sprintf(str, "\n") doesn't function */ | ||
935 | sprintf(logbuffer + total, "%s", "\n"); | ||
936 | |||
937 | loglog(logbuffer); | ||
938 | #endif | ||
939 | } | ||
940 | } | ||
941 | |||
830 | /* destroy */ | 942 | /* destroy */ |
831 | void kill_Assoc(Assoc *assoc) | 943 | void kill_Assoc(Assoc *assoc) |
832 | { | 944 | { |
diff --git a/toxcore/assoc.h b/toxcore/assoc.h index 26ea3b91..91e4ef8c 100644 --- a/toxcore/assoc.h +++ b/toxcore/assoc.h | |||
@@ -76,6 +76,13 @@ Assoc *new_Assoc(size_t bits, size_t entries, uint8_t *public_id); | |||
76 | /* public_id changed (loaded), update which entry isn't stored */ | 76 | /* public_id changed (loaded), update which entry isn't stored */ |
77 | void Assoc_self_client_id_changed(Assoc *assoc, uint8_t *public_id); | 77 | void Assoc_self_client_id_changed(Assoc *assoc, uint8_t *public_id); |
78 | 78 | ||
79 | /* every 45s send out a getnodes() for a "random" bucket */ | ||
80 | #define ASSOC_BUCKET_REFRESH 45 | ||
81 | |||
82 | /* refresh bucket's data from time to time | ||
83 | * this must be called only from DHT */ | ||
84 | void do_Assoc(Assoc *assoc, DHT *dht); | ||
85 | |||
79 | /* destroy */ | 86 | /* destroy */ |
80 | void kill_Assoc(Assoc *assoc); | 87 | void kill_Assoc(Assoc *assoc); |
81 | 88 | ||