aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2015-11-29 20:44:44 +0000
committerJulius Bünger <buenger@mytum.de>2015-11-29 20:44:44 +0000
commitd72d8e05401ace44b57432463f136bcfe55cee03 (patch)
tree8d1374ae5ebd8aa7eb7b5be6ee4d88b7fa78c298 /src
parenta0e27c0bd09fc4b0d70295baa5d7e052c46fe4ff (diff)
downloadgnunet-d72d8e05401ace44b57432463f136bcfe55cee03.tar.gz
gnunet-d72d8e05401ace44b57432463f136bcfe55cee03.zip
added helper for handling the "view" in rps
Signed-off-by: Julius Bünger <buenger@mytum.de>
Diffstat (limited to 'src')
-rw-r--r--src/rps/Makefile.am5
-rw-r--r--src/rps/gnunet-service-rps_view.c256
-rw-r--r--src/rps/gnunet-service-rps_view.h124
-rw-r--r--src/rps/test_service_rps_view.c121
4 files changed, 506 insertions, 0 deletions
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am
index 9425c6e87..c0b60ee0b 100644
--- a/src/rps/Makefile.am
+++ b/src/rps/Makefile.am
@@ -69,6 +69,7 @@ gnunet_service_rps_LDADD = \
69 69
70if HAVE_TESTING 70if HAVE_TESTING
71check_PROGRAMS = \ 71check_PROGRAMS = \
72 test_service_rps_view \
72 test_service_rps_peers \ 73 test_service_rps_peers \
73 test_rps_malicious_1 \ 74 test_rps_malicious_1 \
74 test_rps_malicious_2 \ 75 test_rps_malicious_2 \
@@ -95,6 +96,10 @@ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PAT
95TESTS = $(check_PROGRAMS) 96TESTS = $(check_PROGRAMS)
96endif 97endif
97 98
99test_service_rps_view_SOURCES = gnunet-service-rps_view.h gnunet-service-rps_view.c \
100 test_service_rps_view.c
101test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la
102
98test_service_rps_peers_SOURCES = gnunet-service-rps_peers.h gnunet-service-rps_peers.c \ 103test_service_rps_peers_SOURCES = gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
99 test_service_rps_peers.c 104 test_service_rps_peers.c
100test_service_rps_peers_LDADD = $(top_builddir)/src/util/libgnunetutil.la 105test_service_rps_peers_LDADD = $(top_builddir)/src/util/libgnunetutil.la
diff --git a/src/rps/gnunet-service-rps_view.c b/src/rps/gnunet-service-rps_view.c
new file mode 100644
index 000000000..2cf0287bb
--- /dev/null
+++ b/src/rps/gnunet-service-rps_view.c
@@ -0,0 +1,256 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C)
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 3, 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file rps/gnunet-service-rps_view.c
23 * @brief wrapper around the "local view"
24 * @author Julius Bünger
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet-service-rps_view.h"
29#include <inttypes.h>
30
31
32/**
33 * Array containing the peers
34 */
35static struct GNUNET_PeerIdentity *array;
36
37/**
38 * (Maximum) length of the view
39 */
40static uint32_t length;
41
42/**
43 * Multipeermap containing the peers
44 */
45static struct GNUNET_CONTAINER_MultiPeerMap *mpm;
46
47
48/**
49 * Create an empty view.
50 *
51 * @param len the maximum length for the view
52 */
53void
54View_create (uint32_t len)
55{
56 length = len;
57 array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
58 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
59 * set to _YES */
60}
61
62/**
63 * Change length of view
64 *
65 * @param len the (maximum) length for the view
66 */
67void
68View_change_len (uint32_t len)
69{
70 uint32_t i;
71 uint32_t *index;
72
73 if (GNUNET_CONTAINER_multipeermap_size (mpm) < len)
74 { /* Simply shrink */
75 /* We might simply clear and free the left over space */
76 GNUNET_array_grow (array, length, len);
77 }
78 else /* We have to remove elements */
79 {
80 /* TODO find a way to preserve indices */
81 for (i = 0; i < len; i++)
82 {
83 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]);
84 GNUNET_assert (NULL != index);
85 GNUNET_free (index);
86 }
87 GNUNET_array_grow (array, length, len);
88 GNUNET_CONTAINER_multipeermap_destroy (mpm);
89 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO);
90 for (i = 0; i < len; i++)
91 {
92 index = GNUNET_new (uint32_t);
93 *index = i;
94 GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index,
95 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
96 }
97 }
98 GNUNET_assert (length == len);
99}
100
101/**
102 * Get the view as an array
103 *
104 * @return the view in array representation
105 */
106const struct GNUNET_PeerIdentity *
107View_get_as_array ()
108{
109 return array;
110}
111
112/**
113 * Get the size of the view
114 *
115 * @return current number of actually contained peers
116 */
117unsigned int
118View_size ()
119{
120 return GNUNET_CONTAINER_multipeermap_size (mpm);
121}
122
123/**
124 * Insert peer into the view
125 *
126 * @param peer the peer to insert
127 *
128 * @return GNUNET_OK if peer was actually inserted
129 * GNUNET_NO if peer was not inserted
130 */
131int
132View_put (const struct GNUNET_PeerIdentity *peer)
133{
134 uint32_t *index;
135
136 if ((length <= View_size ()) || /* If array is 'full' */
137 (GNUNET_YES == View_contains_peer (peer)))
138 {
139 return GNUNET_NO;
140 }
141 else
142 {
143 index = GNUNET_new (uint32_t);
144 *index = (uint32_t) View_size ();
145 array[*index] = *peer;
146 GNUNET_CONTAINER_multipeermap_put (mpm, peer, index,
147 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
148 return GNUNET_OK;
149 }
150}
151
152/**
153 * Check whether view contains a peer
154 *
155 * @param peer the peer to check for
156 *
157 * @return GNUNET_OK if view contains peer
158 * GNUNET_NO otherwise
159 */
160int
161View_contains_peer (const struct GNUNET_PeerIdentity *peer)
162{
163 return GNUNET_CONTAINER_multipeermap_contains (mpm, peer);
164}
165
166/**
167 * Remove peer from view
168 *
169 * @param peer the peer to remove
170 *
171 * @return GNUNET_OK if view contained peer and removed it successfully
172 * GNUNET_NO if view does not contain peer
173 */
174int
175View_remove_peer (const struct GNUNET_PeerIdentity *peer)
176{
177 uint32_t *index;
178
179 if (GNUNET_YES == View_contains_peer (peer))
180 {
181 index = GNUNET_CONTAINER_multipeermap_get (mpm, peer);
182 GNUNET_assert (NULL != index);
183 if (*index == GNUNET_CONTAINER_multipeermap_size (mpm) - 1)
184 { /* Last peer in array - simply remove */
185 }
186 else
187 { /* Fill the 'gap' in the array with the last peer */
188 array[*index] = array[View_size ()];
189 }
190 GNUNET_CONTAINER_multipeermap_remove_all (mpm, peer);
191 return GNUNET_OK;
192 }
193 else
194 {
195 return GNUNET_NO;
196 }
197}
198
199/**
200 * Get a peer by index
201 *
202 * @param index the index of the peer to get
203 *
204 * @return peer to the corresponding index.
205 * NULL if this index is not known
206 */
207const struct GNUNET_PeerIdentity *
208View_get_peer_by_index (uint32_t index)
209{
210 if (index < GNUNET_CONTAINER_multipeermap_size (mpm))
211 {
212 return &array[index];
213 }
214 else
215 {
216 return NULL;
217 }
218}
219
220/**
221 * Clear the custom peer map
222 *
223 * @param c_peer_map the custom peer map to look in
224 *
225 * @return size of the map
226 */
227void
228View_clear ()
229{
230 uint32_t i;
231 uint32_t *index;
232
233 for (i = 0; i < GNUNET_CONTAINER_multipeermap_size (mpm); i++)
234 { /* Need to free indices stored at peers */
235 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]);
236 GNUNET_assert (NULL != index);
237 GNUNET_free (index);
238 GNUNET_CONTAINER_multipeermap_remove_all (mpm, &array[i]);
239 }
240 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (mpm));
241}
242
243/**
244 * Destroy peermap.
245 *
246 * @param c_peer_map the map to destroy
247 */
248void
249View_destroy ()
250{
251 View_clear ();
252 GNUNET_free (array);
253 GNUNET_CONTAINER_multipeermap_destroy (mpm);
254}
255
256/* end of gnunet-service-rps_view.c */
diff --git a/src/rps/gnunet-service-rps_view.h b/src/rps/gnunet-service-rps_view.h
new file mode 100644
index 000000000..e05823013
--- /dev/null
+++ b/src/rps/gnunet-service-rps_view.h
@@ -0,0 +1,124 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C)
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 3, 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file rps/gnunet-service-rps_view.h
23 * @brief wrapper around the "local view"
24 * @author Julius Bünger
25 */
26#include "gnunet_util_lib.h"
27#include <inttypes.h>
28
29
30/**
31 * Create an empty view.
32 *
33 * @param len the maximum length for the view
34 */
35void
36View_create (unsigned int len);
37
38/**
39 * Change length of view
40 *
41 * @param len the (maximum) length for the view
42 */
43void
44View_change_len (unsigned int len);
45
46/**
47 * Get the view as an array
48 *
49 * @return the view in array representation
50 */
51const struct GNUNET_PeerIdentity *
52View_get_as_array ();
53
54/**
55 * Get the size of the view
56 *
57 * @return current number of actually contained peers
58 */
59unsigned int
60View_size ();
61
62/**
63 * Insert peer into the view
64 *
65 * @param peer the peer to insert
66 *
67 * @return GNUNET_OK if peer was actually inserted
68 * GNUNET_NO if peer was not inserted
69 */
70int
71View_put (const struct GNUNET_PeerIdentity *peer);
72
73/**
74 * Check whether view contains a peer
75 *
76 * @param peer the peer to check for
77 *
78 * @return GNUNET_OK if view contains peer
79 * GNUNET_NO otherwise
80 */
81int
82View_contains_peer (const struct GNUNET_PeerIdentity *peer);
83
84/**
85 * Remove peer from view
86 *
87 * @param peer the peer to remove
88 *
89 * @return GNUNET_OK if view contained peer and removed it successfully
90 * GNUNET_NO if view does not contain peer
91 */
92int
93View_remove_peer (const struct GNUNET_PeerIdentity *peer);
94
95/**
96 * Get a peer by index
97 *
98 * @param index the index of the peer to get
99 *
100 * @return peer to the corresponding index.
101 * NULL if this index is not known
102 */
103const struct GNUNET_PeerIdentity *
104View_get_peer_by_index (uint32_t index);
105
106/**
107 * Clear the custom peer map
108 *
109 * @param c_peer_map the custom peer map to look in
110 *
111 * @return size of the map
112 */
113void
114View_clear ();
115
116/**
117 * Destroy peermap.
118 *
119 * @param c_peer_map the map to destroy
120 */
121void
122View_destroy ();
123
124/* end of gnunet-service-rps_view.h */
diff --git a/src/rps/test_service_rps_view.c b/src/rps/test_service_rps_view.c
new file mode 100644
index 000000000..8e018cba5
--- /dev/null
+++ b/src/rps/test_service_rps_view.c
@@ -0,0 +1,121 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C)
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 3, 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file rps/test_service_rps_view.c
22 * @brief testcase for gnunet-service-rps_view.c
23 */
24#include <gnunet/platform.h>
25#include "gnunet-service-rps_view.h"
26
27#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); View_destroy(); return 1; }
28#define CHECK(c) { if (! (c)) ABORT(); }
29
30
31static int
32check ()
33{
34 struct GNUNET_PeerIdentity k1;
35 struct GNUNET_PeerIdentity k2;
36 const struct GNUNET_PeerIdentity *array;
37 int j;
38
39 View_create (3);
40 memset (&k1, 0, sizeof (k1));
41 memset (&k2, 1, sizeof (k2));
42 CHECK (GNUNET_NO == View_contains_peer (&k1));
43 CHECK (GNUNET_NO == View_contains_peer (&k2));
44 CHECK (GNUNET_NO == View_remove_peer (&k1));
45 CHECK (GNUNET_NO == View_remove_peer (&k2));
46 CHECK (NULL == View_get_peer_by_index (0));
47 CHECK (NULL == View_get_peer_by_index (1));
48 View_clear (); /* See if assertions trigger */
49 CHECK (0 == View_size ());
50
51 CHECK (GNUNET_OK == View_put (&k1));
52 CHECK (1 == View_size ());
53 CHECK (GNUNET_NO == View_put (&k1));
54 CHECK (1 == View_size ());
55 CHECK (GNUNET_YES == View_contains_peer (&k1));
56 CHECK (GNUNET_OK == View_remove_peer (&k1));
57 CHECK (0 == View_size ());
58 CHECK (GNUNET_NO == View_contains_peer (&k1));
59 CHECK (GNUNET_NO == View_contains_peer (&k2));
60
61 CHECK (GNUNET_OK == View_put (&k1));
62 CHECK (1 == View_size ());
63 for (j = 0; j < 16; j++)
64 {
65 CHECK (GNUNET_NO == View_put (&k1));
66 }
67 CHECK (1 == View_size ());
68 CHECK (GNUNET_OK == View_put (&k2));
69 CHECK (2 == View_size ());
70 for (j = 0; j < 16; j++)
71 {
72 CHECK (GNUNET_NO == View_put (&k2));
73 }
74 CHECK (2 == View_size ());
75
76 /* iterate */
77 for (j = 0; j < View_size (); j++)
78 {
79 CHECK (NULL != View_get_peer_by_index (j));
80 }
81 CHECK ((0 == memcmp (View_get_peer_by_index (0),
82 &k1, sizeof (k1))));
83 CHECK ((0 == memcmp (View_get_peer_by_index (1),
84 &k2, sizeof (k2))));
85 CHECK (GNUNET_OK == View_remove_peer (&k1));
86 CHECK (1 == View_size ());
87 CHECK (GNUNET_NO == View_contains_peer (&k1));
88 CHECK (GNUNET_YES == View_contains_peer (&k2));
89 CHECK (NULL != View_get_peer_by_index (0));
90
91 View_clear ();
92 CHECK (0 == View_size ());
93
94 CHECK (GNUNET_OK == View_put (&k1));
95 CHECK (1 == View_size ());
96 CHECK (GNUNET_OK == View_put (&k2));
97 CHECK (2 == View_size ());
98 array = View_get_as_array ();
99 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1)));
100 CHECK (0 == memcmp (&array[1], &k2, sizeof (k2)));
101 View_clear ();
102 CHECK (0 == View_size ());
103
104 /*View_change_len () */
105
106 View_destroy ();
107
108 return 0;
109}
110
111
112int
113main (int argc, char *argv[])
114{
115 GNUNET_log_setup ("test_service_rps_peers",
116 "WARNING",
117 NULL);
118 return check ();
119}
120
121/* end of test_service_rps_view.c */