aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/testbed/Makefile.am3
-rw-r--r--src/testbed/gnunet-service-testbed.c124
-rw-r--r--src/testbed/gnunet-service-testbed.h56
-rw-r--r--src/testbed/gnunet-service-testbed_hc.c194
4 files changed, 235 insertions, 142 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index f6e1d6972..841a7f992 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -38,7 +38,8 @@ noinst_PROGRAMS = \
38 38
39gnunet_service_testbed_SOURCES = \ 39gnunet_service_testbed_SOURCES = \
40 gnunet-service-testbed.c \ 40 gnunet-service-testbed.c \
41 gnunet-service-testbed.h 41 gnunet-service-testbed.h \
42 gnunet-service-testbed_hc.c
42gnunet_service_testbed_LDADD = $(XLIB) \ 43gnunet_service_testbed_LDADD = $(XLIB) \
43 $(top_builddir)/src/util/libgnunetutil.la \ 44 $(top_builddir)/src/util/libgnunetutil.la \
44 $(top_builddir)/src/core/libgnunetcore.la \ 45 $(top_builddir)/src/core/libgnunetcore.la \
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 282e5a4e8..d741b7fc1 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -24,7 +24,6 @@
24 * @author Sree Harsha Totakura 24 * @author Sree Harsha Totakura
25 */ 25 */
26 26
27#include "platform.h"
28#include "gnunet-service-testbed.h" 27#include "gnunet-service-testbed.h"
29 28
30#include <zlib.h> 29#include <zlib.h>
@@ -138,18 +137,6 @@ static struct ForwardedOperationContext *fopcq_head;
138static struct ForwardedOperationContext *fopcq_tail; 137static struct ForwardedOperationContext *fopcq_tail;
139 138
140/** 139/**
141 * DLL head for least recently used hello cache entries; least recently used
142 * cache items are at the head
143 */
144static struct HelloCacheEntry *lru_hcache_head;
145
146/**
147 * DLL tail for least recently used hello cache entries; recently used cache
148 * items are at the tail
149 */
150static struct HelloCacheEntry *lru_hcache_tail;
151
152/**
153 * Array of hosts 140 * Array of hosts
154 */ 141 */
155static struct GNUNET_TESTBED_Host **host_list; 142static struct GNUNET_TESTBED_Host **host_list;
@@ -175,11 +162,6 @@ static struct Peer **peer_list;
175static struct GNUNET_CONTAINER_MultiHashMap *ss_map; 162static struct GNUNET_CONTAINER_MultiHashMap *ss_map;
176 163
177/** 164/**
178 * Hashmap to maintain HELLO cache
179 */
180static struct GNUNET_CONTAINER_MultiHashMap *hello_cache;
181
182/**
183 * The event mask for the events we listen from sub-controllers 165 * The event mask for the events we listen from sub-controllers
184 */ 166 */
185static uint64_t event_mask; 167static uint64_t event_mask;
@@ -204,11 +186,6 @@ static unsigned int slave_list_size;
204 */ 186 */
205static unsigned int peer_list_size; 187static unsigned int peer_list_size;
206 188
207/**
208 * The size of hello cache
209 */
210static unsigned int hello_cache_size;
211
212/*********/ 189/*********/
213/* Tasks */ 190/* Tasks */
214/*********/ 191/*********/
@@ -225,87 +202,6 @@ static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id;
225 202
226 203
227/** 204/**
228 * Looks up in the hello cache and returns the HELLO of the given peer
229 *
230 * @param id the peer identity of the peer whose HELLO has to be looked up
231 * @return the HELLO message; NULL if not found
232 */
233static const struct GNUNET_MessageHeader *
234hello_cache_lookup (const struct GNUNET_PeerIdentity *id)
235{
236 struct HelloCacheEntry *entry;
237
238 if (NULL == hello_cache)
239 return NULL;
240 entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey);
241 if (NULL == entry)
242 return NULL;
243 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
244 GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry);
245 return entry->hello;
246}
247
248
249/**
250 * Removes the given hello cache centry from hello cache and frees its resources
251 *
252 * @param entry the entry to remove
253 */
254static void
255hello_cache_remove (struct HelloCacheEntry *entry)
256{
257 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
258 GNUNET_assert (GNUNET_YES ==
259 GNUNET_CONTAINER_multihashmap_remove (hello_cache,
260 &entry->key,
261 entry));
262 GNUNET_free (entry->hello);
263 GNUNET_free (entry);
264}
265
266
267/**
268 * Caches the HELLO of the given peer. Updates the HELLO if it was already
269 * cached before
270 *
271 * @param id the peer identity of the peer whose HELLO has to be cached
272 * @param hello the HELLO message
273 */
274static void
275hello_cache_add (const struct GNUNET_PeerIdentity *id,
276 const struct GNUNET_MessageHeader *hello)
277{
278 struct HelloCacheEntry *entry;
279
280 if (NULL == hello_cache)
281 return;
282 entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey);
283 if (NULL == entry)
284 {
285 entry = GNUNET_malloc (sizeof (struct HelloCacheEntry));
286 memcpy (&entry->key, &id->hashPubKey, sizeof (struct GNUNET_HashCode));
287 if (GNUNET_CONTAINER_multihashmap_size (hello_cache) == hello_cache_size)
288 {
289 GNUNET_assert (NULL != lru_hcache_head);
290 hello_cache_remove (lru_hcache_head);
291 }
292 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put
293 (hello_cache,
294 &entry->key,
295 entry,
296 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
297 }
298 else
299 {
300 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
301 GNUNET_free (entry->hello);
302 }
303 entry->hello = GNUNET_copy_message (hello);
304 GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry);
305}
306
307
308/**
309 * Function called to notify a client about the connection begin ready to queue 205 * Function called to notify a client about the connection begin ready to queue
310 * more data. "buf" will be NULL and "size" zero if the connection was closed 206 * more data. "buf" will be NULL and "size" zero if the connection was closed
311 * for writing in the meantime. 207 * for writing in the meantime.
@@ -2496,7 +2392,7 @@ hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello)
2496 LOG_DEBUG ("0x%llx: Received HELLO of %s\n", 2392 LOG_DEBUG ("0x%llx: Received HELLO of %s\n",
2497 occ->op_id, GNUNET_i2s (&occ->peer_identity)); 2393 occ->op_id, GNUNET_i2s (&occ->peer_identity));
2498 occ->hello = GNUNET_malloc (msize); 2394 occ->hello = GNUNET_malloc (msize);
2499 hello_cache_add (&occ->peer_identity, hello); 2395 TESTBED_hello_cache_add (&occ->peer_identity, hello);
2500 memcpy (occ->hello, hello, msize); 2396 memcpy (occ->hello, hello, msize);
2501 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh); 2397 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
2502 occ->ghh = NULL; 2398 occ->ghh = NULL;
@@ -2541,7 +2437,7 @@ core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server,
2541 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", 2437 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n",
2542 occ->op_id, GNUNET_i2s (&occ->peer_identity)); 2438 occ->op_id, GNUNET_i2s (&occ->peer_identity));
2543 /* Lookup for HELLO in hello cache */ 2439 /* Lookup for HELLO in hello cache */
2544 if (NULL != (hello = hello_cache_lookup (&occ->peer_identity))) 2440 if (NULL != (hello = TESTBED_hello_cache_lookup (&occ->peer_identity)))
2545 { 2441 {
2546 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n", 2442 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n",
2547 occ->op_id, GNUNET_i2s (&occ->peer_identity)); 2443 occ->op_id, GNUNET_i2s (&occ->peer_identity));
@@ -3429,16 +3325,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3429 GNUNET_free_non_null (hostname); 3325 GNUNET_free_non_null (hostname);
3430 GNUNET_CONFIGURATION_destroy (our_config); 3326 GNUNET_CONFIGURATION_destroy (our_config);
3431 /* Free hello cache */ 3327 /* Free hello cache */
3432 if (NULL != hello_cache) 3328 TESTBED_cache_clear ();
3433 GNUNET_assert
3434 (GNUNET_CONTAINER_multihashmap_size (hello_cache) <= hello_cache_size);
3435 while (NULL != lru_hcache_head)
3436 hello_cache_remove (lru_hcache_head);
3437 if (NULL != hello_cache)
3438 {
3439 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (hello_cache));
3440 GNUNET_CONTAINER_multihashmap_destroy (hello_cache);
3441 }
3442} 3329}
3443 3330
3444 3331
@@ -3516,16 +3403,13 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
3516 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", 3403 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED",
3517 "HELLO_CACHE_SIZE", 3404 "HELLO_CACHE_SIZE",
3518 &num)); 3405 &num));
3519 hello_cache_size = (unsigned int) num; 3406 TESTBED_cache_init ((unsigned int) num);
3520 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string 3407 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string
3521 (cfg, "testbed", "HOSTNAME", &hostname)); 3408 (cfg, "testbed", "HOSTNAME", &hostname));
3522 our_config = GNUNET_CONFIGURATION_dup (cfg); 3409 our_config = GNUNET_CONFIGURATION_dup (cfg);
3523 GNUNET_SERVER_add_handlers (server, message_handlers); 3410 GNUNET_SERVER_add_handlers (server, message_handlers);
3524 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); 3411 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL);
3525 ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO); 3412 ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO);
3526 if (1 < hello_cache_size)
3527 hello_cache = GNUNET_CONTAINER_multihashmap_create (hello_cache_size / 2,
3528 GNUNET_YES);
3529 shutdown_task_id = 3413 shutdown_task_id =
3530 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, 3414 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
3531 GNUNET_SCHEDULER_PRIORITY_IDLE, 3415 GNUNET_SCHEDULER_PRIORITY_IDLE,
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index 1ddc89540..4fa137780 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -24,6 +24,7 @@
24 * @author Sree Harsha Totakura 24 * @author Sree Harsha Totakura
25 */ 25 */
26 26
27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
28#include "gnunet_testbed_service.h" 29#include "gnunet_testbed_service.h"
29#include "gnunet_transport_service.h" 30#include "gnunet_transport_service.h"
@@ -783,28 +784,41 @@ struct LCFContextQueue
783 784
784 785
785/** 786/**
786 * Hello cache entry 787 * Looks up in the hello cache and returns the HELLO of the given peer
788 *
789 * @param id the peer identity of the peer whose HELLO has to be looked up
790 * @return the HELLO message; NULL if not found
787 */ 791 */
788struct HelloCacheEntry 792const struct GNUNET_MessageHeader *
789{ 793TESTBED_hello_cache_lookup (const struct GNUNET_PeerIdentity *id);
790 /** 794
791 * DLL next ptr for least recently used hello cache entries 795/**
792 */ 796 * Caches the HELLO of the given peer. Updates the HELLO if it was already
793 struct HelloCacheEntry *next; 797 * cached before
798 *
799 * @param id the peer identity of the peer whose HELLO has to be cached
800 * @param hello the HELLO message
801 */
802void
803TESTBED_hello_cache_add (const struct GNUNET_PeerIdentity *id,
804 const struct GNUNET_MessageHeader *hello);
805
806
807/**
808 * Initializes the cache
809 *
810 * @param size the size of the cache
811 */
812void
813TESTBED_cache_init (unsigned int size);
814
815
816/**
817 * Clear cache
818 */
819void
820TESTBED_cache_clear ();
794 821
795 /**
796 * DLL prev ptr for least recently used hello cache entries
797 */
798 struct HelloCacheEntry *prev;
799 822
800 /**
801 * The key for this entry
802 */
803 struct GNUNET_HashCode key;
804
805 /**
806 * The HELLO message
807 */
808 struct GNUNET_MessageHeader *hello;
809};
810 823
824/* End of gnunet-service-testbed.h */
diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c
new file mode 100644
index 000000000..569dc18f8
--- /dev/null
+++ b/src/testbed/gnunet-service-testbed_hc.c
@@ -0,0 +1,194 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file testbed/gnunet-service-testbed_hc.h
23 * @brief testbed cache implementation
24 * @author Sree Harsha Totakura
25 */
26
27#include "gnunet-service-testbed.h"
28
29/**
30 * Hello cache entry
31 */
32struct HelloCacheEntry
33{
34 /**
35 * DLL next ptr for least recently used hello cache entries
36 */
37 struct HelloCacheEntry *next;
38
39 /**
40 * DLL prev ptr for least recently used hello cache entries
41 */
42 struct HelloCacheEntry *prev;
43
44 /**
45 * The key for this entry
46 */
47 struct GNUNET_HashCode key;
48
49 /**
50 * The HELLO message
51 */
52 struct GNUNET_MessageHeader *hello;
53};
54
55/**
56 * Hashmap to maintain HELLO cache
57 */
58static struct GNUNET_CONTAINER_MultiHashMap *hello_cache;
59
60/**
61 * DLL head for least recently used hello cache entries; least recently used
62 * cache items are at the head
63 */
64static struct HelloCacheEntry *lru_hcache_head;
65
66/**
67 * DLL tail for least recently used hello cache entries; recently used cache
68 * items are at the tail
69 */
70static struct HelloCacheEntry *lru_hcache_tail;
71
72/**
73 * The size of HELLO cache
74 */
75static unsigned int hello_cache_size;
76
77
78/**
79 * Looks up in the hello cache and returns the HELLO of the given peer
80 *
81 * @param id the peer identity of the peer whose HELLO has to be looked up
82 * @return the HELLO message; NULL if not found
83 */
84const struct GNUNET_MessageHeader *
85TESTBED_hello_cache_lookup (const struct GNUNET_PeerIdentity *id)
86{
87 struct HelloCacheEntry *entry;
88
89 if (NULL == hello_cache)
90 return NULL;
91 entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey);
92 if (NULL == entry)
93 return NULL;
94 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
95 GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry);
96 return entry->hello;
97}
98
99
100/**
101 * Removes the given hello cache centry from hello cache and frees its resources
102 *
103 * @param entry the entry to remove
104 */
105static void
106TESTBED_hello_cache_remove (struct HelloCacheEntry *entry)
107{
108 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
109 GNUNET_assert (GNUNET_YES ==
110 GNUNET_CONTAINER_multihashmap_remove (hello_cache,
111 &entry->key,
112 entry));
113 GNUNET_free (entry->hello);
114 GNUNET_free (entry);
115}
116
117
118/**
119 * Caches the HELLO of the given peer. Updates the HELLO if it was already
120 * cached before
121 *
122 * @param id the peer identity of the peer whose HELLO has to be cached
123 * @param hello the HELLO message
124 */
125void
126TESTBED_hello_cache_add (const struct GNUNET_PeerIdentity *id,
127 const struct GNUNET_MessageHeader *hello)
128{
129 struct HelloCacheEntry *entry;
130
131 if (NULL == hello_cache)
132 return;
133 entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey);
134 if (NULL == entry)
135 {
136 entry = GNUNET_malloc (sizeof (struct HelloCacheEntry));
137 memcpy (&entry->key, &id->hashPubKey, sizeof (struct GNUNET_HashCode));
138 if (GNUNET_CONTAINER_multihashmap_size (hello_cache) == hello_cache_size)
139 {
140 GNUNET_assert (NULL != lru_hcache_head);
141 TESTBED_hello_cache_remove (lru_hcache_head);
142 }
143 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put
144 (hello_cache,
145 &entry->key,
146 entry,
147 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
148 }
149 else
150 {
151 GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry);
152 GNUNET_free (entry->hello);
153 }
154 entry->hello = GNUNET_copy_message (hello);
155 GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry);
156}
157
158
159/**
160 * Initializes the cache
161 *
162 * @param size the size of the cache
163 */
164void
165TESTBED_cache_init (unsigned int size)
166{
167 if (0 == size)
168 return;
169 hello_cache_size = size;
170 if (size > 1)
171 size = size / 2;
172 hello_cache = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_YES);
173}
174
175
176/**
177 * Clear cache
178 */
179void
180TESTBED_cache_clear ()
181{
182 if (NULL != hello_cache)
183 GNUNET_assert
184 (GNUNET_CONTAINER_multihashmap_size (hello_cache) <= hello_cache_size);
185 while (NULL != lru_hcache_head)
186 TESTBED_hello_cache_remove (lru_hcache_head);
187 if (NULL != hello_cache)
188 {
189 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (hello_cache));
190 GNUNET_CONTAINER_multihashmap_destroy (hello_cache);
191 }
192}
193
194/* end of gnunet-service-testbed_hc.c */