diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-04-17 00:44:29 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-04-17 00:44:29 +0000 |
commit | 0555e4e107db9c0c1f0caa6c947881c32bf426f4 (patch) | |
tree | d9bbd740ad0f73c07cf56aad0650e6ded7d05229 /src | |
parent | e77e2db24ef3681f207521e539a2c1ca3584efda (diff) | |
download | gnunet-0555e4e107db9c0c1f0caa6c947881c32bf426f4.tar.gz gnunet-0555e4e107db9c0c1f0caa6c947881c32bf426f4.zip |
started implementing set api, draft for mq
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_protocols.h | 60 | ||||
-rw-r--r-- | src/include/gnunet_set_service.h | 257 | ||||
-rw-r--r-- | src/include/gnunet_testing_lib.h | 6 | ||||
-rw-r--r-- | src/set/Makefile.am | 3 | ||||
-rw-r--r-- | src/set/mq.c | 47 | ||||
-rw-r--r-- | src/set/mq.h | 94 | ||||
-rw-r--r-- | src/set/set.h | 189 | ||||
-rw-r--r-- | src/set/set_api.c | 395 | ||||
-rw-r--r-- | src/set/test_set_api.c | 22 |
9 files changed, 1011 insertions, 62 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 431542660..54e059907 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -1760,8 +1760,66 @@ extern "C" | |||
1760 | #define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ABORT 548 | 1760 | #define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ABORT 548 |
1761 | 1761 | ||
1762 | 1762 | ||
1763 | /******************************************************************************* | ||
1764 | * SET message types | ||
1765 | ******************************************************************************/ | ||
1766 | |||
1767 | /** | ||
1768 | * Cancel a set operation | ||
1769 | */ | ||
1770 | #define GNUNET_MESSAGE_TYPE_SET_CANCEL 570 | ||
1771 | |||
1772 | /** | ||
1773 | * Acknowledge results | ||
1774 | */ | ||
1775 | #define GNUNET_MESSAGE_TYPE_SET_ACK 571 | ||
1776 | |||
1777 | /** | ||
1778 | * Create an empty set | ||
1779 | */ | ||
1780 | #define GNUNET_MESSAGE_TYPE_SET_RESULT 572 | ||
1781 | |||
1782 | /** | ||
1783 | * Add element to set | ||
1784 | */ | ||
1785 | #define GNUNET_MESSAGE_TYPE_SET_ADD 573 | ||
1786 | |||
1787 | |||
1788 | /** | ||
1789 | * Remove element from set | ||
1790 | */ | ||
1791 | #define GNUNET_MESSAGE_TYPE_SET_REMOVE 574 | ||
1792 | |||
1793 | |||
1794 | /** | ||
1795 | * Listen for operation requests | ||
1796 | */ | ||
1797 | #define GNUNET_MESSAGE_TYPE_SET_LISTEN 575 | ||
1798 | |||
1799 | /** | ||
1800 | * Accept a set request | ||
1801 | */ | ||
1802 | #define GNUNET_MESSAGE_TYPE_SET_ACCEPT 576 | ||
1803 | |||
1804 | /** | ||
1805 | * Evaluate a set operation | ||
1806 | */ | ||
1807 | #define GNUNET_MESSAGE_TYPE_SET_EVALUATE 577 | ||
1808 | |||
1809 | /** | ||
1810 | * Evaluate a set operation | ||
1811 | */ | ||
1812 | #define GNUNET_MESSAGE_TYPE_SET_REQUEST 578 | ||
1813 | |||
1814 | |||
1815 | /** | ||
1816 | * Evaluate a set operation | ||
1817 | */ | ||
1818 | #define GNUNET_MESSAGE_TYPE_SET_CREATE 579 | ||
1819 | |||
1820 | |||
1763 | /** | 1821 | /** |
1764 | * Next available: 570 | 1822 | * Next available: 600 |
1765 | */ | 1823 | */ |
1766 | 1824 | ||
1767 | 1825 | ||
diff --git a/src/include/gnunet_set_service.h b/src/include/gnunet_set_service.h index 78dc7b7d0..cf782c841 100644 --- a/src/include/gnunet_set_service.h +++ b/src/include/gnunet_set_service.h | |||
@@ -1,9 +1,76 @@ | |||
1 | // FIXME: copyright, etc. | 1 | /* |
2 | This file is part of GNUnet | ||
3 | (C) 2013 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 include/gnunet_set_service.h | ||
23 | * @brief two-peer set operations | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | |||
27 | #ifndef GNUNET_SET_SERVICE_H | ||
28 | #define GNUNET_SET_SERVICE_H | ||
29 | |||
30 | #ifdef __cplusplus | ||
31 | extern "C" | ||
32 | { | ||
33 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
34 | } | ||
35 | #endif | ||
36 | #endif | ||
37 | |||
38 | #include "platform.h" | ||
39 | #include "gnunet_common.h" | ||
40 | #include "gnunet_time_lib.h" | ||
41 | #include "gnunet_configuration_lib.h" | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Opaque handle to a set. | ||
46 | */ | ||
47 | struct GNUNET_SET_Handle; | ||
48 | |||
49 | /** | ||
50 | * Opaque handle to a set operation request from another peer. | ||
51 | */ | ||
52 | struct GNUNET_SET_Request; | ||
53 | |||
54 | /** | ||
55 | * Opaque handle to a listen operation. | ||
56 | */ | ||
57 | struct GNUNET_SET_ListenHandle; | ||
58 | |||
59 | /** | ||
60 | * Opaque handle to a set operation. | ||
61 | */ | ||
62 | struct GNUNET_SET_OperationHandle; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Opaque handle to a listen operation. | ||
67 | */ | ||
68 | struct GNUNET_SET_ListenHandle; | ||
2 | 69 | ||
3 | /** | 70 | /** |
4 | * The operation that a set set supports. | 71 | * The operation that a set set supports. |
5 | */ | 72 | */ |
6 | enum GNUNET_SET_Operation | 73 | enum GNUNET_SET_OperationType |
7 | { | 74 | { |
8 | /** | 75 | /** |
9 | * Set intersection, only return elements that are in both sets. | 76 | * Set intersection, only return elements that are in both sets. |
@@ -31,10 +98,37 @@ enum GNUNET_SET_Status | |||
31 | /* | 98 | /* |
32 | * The other peer refused to to the operation with us | 99 | * The other peer refused to to the operation with us |
33 | */ | 100 | */ |
34 | GNUNET_SET_STATUS_REFUSED | 101 | GNUNET_SET_STATUS_REFUSED, |
102 | /* | ||
103 | * Success, all elements have been sent. | ||
104 | */ | ||
105 | GNUNET_SET_STATUS_DONE | ||
35 | }; | 106 | }; |
36 | 107 | ||
37 | // FIXME: comment | 108 | /** |
109 | * The way results are given to the client. | ||
110 | */ | ||
111 | enum GNUNET_SET_ResultMode | ||
112 | { | ||
113 | /** | ||
114 | * Client gets every element in the resulting set. | ||
115 | */ | ||
116 | GNUNET_SET_RESULT_FULL, | ||
117 | /** | ||
118 | * Client gets only elements that have been added to the set. | ||
119 | * Only works with set union. | ||
120 | */ | ||
121 | GNUNET_SET_RESULT_ADDED, | ||
122 | /** | ||
123 | * Client gets only elements that have been removed from the set. | ||
124 | * Only works with set intersection. | ||
125 | */ | ||
126 | GNUNET_SET_RESULT_REMOVED | ||
127 | }; | ||
128 | |||
129 | /** | ||
130 | * Element stored in a set. | ||
131 | */ | ||
38 | struct GNUNET_SET_Element | 132 | struct GNUNET_SET_Element |
39 | { | 133 | { |
40 | /** | 134 | /** |
@@ -53,8 +147,53 @@ struct GNUNET_SET_Element | |||
53 | 147 | ||
54 | 148 | ||
55 | /** | 149 | /** |
150 | * Continuation used for some of the set operations | ||
151 | * | ||
152 | * @cls closure | ||
153 | */ | ||
154 | typedef void (*GNUNET_SET_Continuation) (void *cls); | ||
155 | |||
156 | /** | ||
157 | * Callback for set operation results. Called for each element | ||
158 | * in the result set. | ||
159 | * | ||
160 | * @param cls closure | ||
161 | * @param element a result element, only valid if status is GNUNET_SET_STATUS_OK | ||
162 | * @param status see enum GNUNET_SET_Status | ||
163 | */ | ||
164 | typedef void | ||
165 | (*GNUNET_SET_ResultIterator) (void *cls, | ||
166 | struct GNUNET_SET_Element *element, | ||
167 | enum GNUNET_SET_Status status); | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Called when another peer wants to do a set operation with the | ||
172 | * local peer | ||
173 | * | ||
174 | * @param other_peer the other peer | ||
175 | * @param context_msg message with application specific information from | ||
176 | * the other peer | ||
177 | * @param request request from the other peer, use GNUNET_SET_accept | ||
178 | * to accept it, otherwise the request will be refused | ||
179 | * Note that we don't use a return value here, as it is also | ||
180 | * necessary to specify the set we want to do the operation with, | ||
181 | * whith sometimes can be derived from the context message. | ||
182 | * Also necessary to specify the timeout. | ||
183 | */ | ||
184 | typedef void | ||
185 | (*GNUNET_SET_ListenCallback) (void *cls, | ||
186 | const struct GNUNET_PeerIdentity *other_peer, | ||
187 | const struct GNUNET_MessageHeader *context_msg, | ||
188 | struct GNUNET_SET_Request *request); | ||
189 | |||
190 | |||
191 | |||
192 | /** | ||
56 | * Create an empty set, supporting the specified operation. | 193 | * Create an empty set, supporting the specified operation. |
57 | * | 194 | * |
195 | * @param cfg configuration to use for connecting to the | ||
196 | * set service | ||
58 | * @param op operation supported by the set | 197 | * @param op operation supported by the set |
59 | * Note that the operation has to be specified | 198 | * Note that the operation has to be specified |
60 | * beforehand, as certain set operations need to maintain | 199 | * beforehand, as certain set operations need to maintain |
@@ -62,10 +201,21 @@ struct GNUNET_SET_Element | |||
62 | * @return a handle to the set | 201 | * @return a handle to the set |
63 | */ | 202 | */ |
64 | struct GNUNET_SET_Handle * | 203 | struct GNUNET_SET_Handle * |
65 | GNUNET_SET_create (enum GNUNET_SET_Operation op); | 204 | GNUNET_SET_create (struct GNUNET_CONFIGURATION_Handle *cfg, |
205 | enum GNUNET_SET_OperationType op); | ||
66 | 206 | ||
67 | 207 | ||
68 | // FIXME: comment | 208 | /** |
209 | * Add an element to the given set. | ||
210 | * After the element has been added (in the sense of being | ||
211 | * transmitted to the set service), cont will be called. | ||
212 | * Calls to add_element can be queued | ||
213 | * | ||
214 | * @param set set to add element to | ||
215 | * @param element element to add to the set | ||
216 | * @param cont continuation called after the element has been added | ||
217 | * @param cont_cls closure for cont | ||
218 | */ | ||
69 | void | 219 | void |
70 | GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, | 220 | GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, |
71 | const struct GNUNET_SET_Element *element, | 221 | const struct GNUNET_SET_Element *element, |
@@ -73,7 +223,17 @@ GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, | |||
73 | void *cont_cls); | 223 | void *cont_cls); |
74 | 224 | ||
75 | 225 | ||
76 | // FIXME: comment | 226 | /** |
227 | * Remove an element to the given set. | ||
228 | * After the element has been removed (in the sense of the | ||
229 | * request being transmitted to the set service), cont will be called. | ||
230 | * Calls to remove_element can be queued | ||
231 | * | ||
232 | * @param set set to remove element from | ||
233 | * @param element element to remove from the set | ||
234 | * @param cont continuation called after the element has been removed | ||
235 | * @param cont_cls closure for cont | ||
236 | */ | ||
77 | void | 237 | void |
78 | GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, | 238 | GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, |
79 | const struct GNUNET_SET_Element *element, | 239 | const struct GNUNET_SET_Element *element, |
@@ -81,37 +241,17 @@ GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, | |||
81 | void *cont_cls); | 241 | void *cont_cls); |
82 | 242 | ||
83 | 243 | ||
84 | // FIXME: comment | ||
85 | struct GNUNET_SET_Handle * | ||
86 | GNUNET_SET_clone (struct GNUNET_SET_Handle *set); | ||
87 | |||
88 | |||
89 | // FIXME: comment | ||
90 | void | ||
91 | GNUNET_SET_destroy (struct GNUNET_SET_Handle *set); | ||
92 | |||
93 | |||
94 | |||
95 | /** | 244 | /** |
96 | * Callback for set operation results. Called for each element | 245 | * Destroy the set handle, and free all associated resources. |
97 | * in the result set. | ||
98 | // FIXME: might want a way to just get the 'additional/removd' elements | ||
99 | * | ||
100 | * @param cls closure | ||
101 | * @param element element, or NULL to indicate that all elements | ||
102 | * have been passed to the callback | ||
103 | * Only valid if (status==GNUNET_SET_STATUS_OK) holds. | ||
104 | * @param status see enum GNUNET_SET_Status | ||
105 | */ | 246 | */ |
106 | typedef void | 247 | void |
107 | (*GNUNET_SET_ResultIterator) (void *cls, | 248 | GNUNET_SET_destroy (struct GNUNET_SET_Handle *set); |
108 | struct GNUNET_SET_Element *element, | ||
109 | enum GNUNET_SET_ResultStatus status); | ||
110 | 249 | ||
111 | 250 | ||
112 | /** | 251 | /** |
113 | * Evaluate a set operation with our set and the set of another peer. | 252 | * Evaluate a set operation with our set and the set of another peer. |
114 | * | 253 | * |
254 | * @param set set to use | ||
115 | * @param other_peer peer with the other set | 255 | * @param other_peer peer with the other set |
116 | * @param app_id hash for the application using the set | 256 | * @param app_id hash for the application using the set |
117 | * @param context_msg additional information for the request | 257 | * @param context_msg additional information for the request |
@@ -120,38 +260,23 @@ typedef void | |||
120 | * @return a handle to cancel the operation | 260 | * @return a handle to cancel the operation |
121 | */ | 261 | */ |
122 | struct GNUNET_SET_OperationHandle * | 262 | struct GNUNET_SET_OperationHandle * |
123 | GNUNET_SET_evaluate (const struct GNUNET_PeerIdentity *other_peer, | 263 | GNUNET_SET_evaluate (struct GNUNET_SET_Handle *set, |
264 | const struct GNUNET_PeerIdentity *other_peer, | ||
124 | const struct GNUNET_HashCode *app_id, | 265 | const struct GNUNET_HashCode *app_id, |
125 | const struct GNUNET_MessageHeader *context_msg, | 266 | const struct GNUNET_MessageHeader *context_msg, |
126 | struct GNUNET_TIME_Relative timeout, | 267 | struct GNUNET_TIME_Relative timeout, |
268 | enum GNUNET_SET_ResultMode result_mode, | ||
127 | GNUNET_SET_ResultIterator result_cb, | 269 | GNUNET_SET_ResultIterator result_cb, |
128 | void *result_cls); | 270 | void *result_cls); |
129 | 271 | ||
130 | 272 | ||
131 | /** | ||
132 | * Called when another peer wants to do a set operation with the | ||
133 | * local peer | ||
134 | * | ||
135 | * @param other_peer the other peer | ||
136 | * @param context_msg message with application specific information from | ||
137 | * the other peer | ||
138 | * @param request request from the other peer, use GNUNET_SET_accept | ||
139 | * to accept it, otherwise the request will be refused | ||
140 | * Note that we don't use a return value here, as it is also | ||
141 | * necessary to specify the set we want to do the operation with, | ||
142 | * whith sometimes can be derived from the context message. | ||
143 | * Also necessary to specify the timeout. | ||
144 | */ | ||
145 | typedef void | ||
146 | (*GNUNET_SET_ListenCallback) (void *cls, | ||
147 | const struct GNUNET_PeerIdentity *other_peer, | ||
148 | const struct GNUNET_MessageHeader *context_msg, | ||
149 | struct GNUNET_SET_Request *request); | ||
150 | 273 | ||
151 | 274 | ||
152 | /** | 275 | /** |
153 | * Wait for set operation requests for the given application id | 276 | * Wait for set operation requests for the given application id |
154 | * | 277 | * |
278 | * @param cfg configuration to use for connecting to | ||
279 | * the set service | ||
155 | * @param operation operation we want to listen for | 280 | * @param operation operation we want to listen for |
156 | * @param app_id id of the application that handles set operation requests | 281 | * @param app_id id of the application that handles set operation requests |
157 | * @param listen_cb called for each incoming request matching the operation | 282 | * @param listen_cb called for each incoming request matching the operation |
@@ -160,14 +285,19 @@ typedef void | |||
160 | * @return a handle that can be used to cancel the listen operation | 285 | * @return a handle that can be used to cancel the listen operation |
161 | */ | 286 | */ |
162 | struct GNUNET_SET_ListenHandle * | 287 | struct GNUNET_SET_ListenHandle * |
163 | GNUNET_SET_listen (enum GNUNET_SET_Operation operation, | 288 | GNUNET_SET_listen (struct GNUNET_CONFIGURATION_Handle *cfg, |
289 | enum GNUNET_SET_OperationType op_type, | ||
164 | const struct GNUNET_HashCode *app_id, | 290 | const struct GNUNET_HashCode *app_id, |
165 | GNUNET_SET_ListenCallback listen_cb, | 291 | GNUNET_SET_ListenCallback listen_cb, |
166 | void *listen_cls); | 292 | void *listen_cls); |
167 | 293 | ||
168 | 294 | ||
169 | 295 | ||
170 | // FIXME: comment | 296 | /** |
297 | * Cancel the given listen operation. | ||
298 | * | ||
299 | * @param lh handle for the listen operation | ||
300 | */ | ||
171 | void | 301 | void |
172 | GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); | 302 | GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); |
173 | 303 | ||
@@ -185,12 +315,25 @@ struct GNUNET_SET_OperationHandle * | |||
185 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 315 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
186 | struct GNUNET_SET_Handle *set, | 316 | struct GNUNET_SET_Handle *set, |
187 | struct GNUNET_TIME_Relative timeout, | 317 | struct GNUNET_TIME_Relative timeout, |
318 | enum GNUNET_SET_ResultMode result_mode, | ||
188 | GNUNET_SET_ResultIterator result_cb, | 319 | GNUNET_SET_ResultIterator result_cb, |
189 | void *cls) | 320 | void *cls); |
190 | 321 | ||
191 | 322 | ||
192 | // FIXME: comment | 323 | /** |
324 | * Cancel the given set operation. | ||
325 | * | ||
326 | * @param op set operation to cancel | ||
327 | */ | ||
193 | void | 328 | void |
194 | GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *op); | 329 | GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh); |
195 | 330 | ||
331 | |||
332 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
333 | { | ||
334 | #endif | ||
335 | #ifdef __cplusplus | ||
336 | } | ||
337 | #endif | ||
196 | 338 | ||
339 | #endif | ||
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h index 7181b9ca1..d96743615 100644 --- a/src/include/gnunet_testing_lib.h +++ b/src/include/gnunet_testing_lib.h | |||
@@ -325,9 +325,9 @@ GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer, | |||
325 | * @param cfg configuration of the peer that was started | 325 | * @param cfg configuration of the peer that was started |
326 | * @param peer identity of the peer that was created | 326 | * @param peer identity of the peer that was created |
327 | */ | 327 | */ |
328 | typedef void (*GNUNET_TESTING_TestMain)(void *cls, | 328 | typedef void (*GNUNET_TESTING_TestMain) (void *cls, |
329 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 329 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
330 | struct GNUNET_TESTING_Peer *peer); | 330 | struct GNUNET_TESTING_Peer *peer); |
331 | 331 | ||
332 | 332 | ||
333 | /** | 333 | /** |
diff --git a/src/set/Makefile.am b/src/set/Makefile.am index fb6aa5b21..06f418465 100644 --- a/src/set/Makefile.am +++ b/src/set/Makefile.am | |||
@@ -46,7 +46,8 @@ gnunet_service_set_LDADD = \ | |||
46 | $(GN_LIBINTL) | 46 | $(GN_LIBINTL) |
47 | 47 | ||
48 | libgnunetset_la_SOURCES = \ | 48 | libgnunetset_la_SOURCES = \ |
49 | set_api.c | 49 | set_api.c \ |
50 | mq.c | ||
50 | libgnunetset_la_LIBADD = \ | 51 | libgnunetset_la_LIBADD = \ |
51 | $(top_builddir)/src/util/libgnunetutil.la \ | 52 | $(top_builddir)/src/util/libgnunetutil.la \ |
52 | $(LTLIBINTL) | 53 | $(LTLIBINTL) |
diff --git a/src/set/mq.c b/src/set/mq.c new file mode 100644 index 000000000..313e9ce0c --- /dev/null +++ b/src/set/mq.c | |||
@@ -0,0 +1,47 @@ | |||
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 | * @author Florian Dold | ||
23 | * @file mq/mq.c | ||
24 | * @brief general purpose request queue | ||
25 | */ | ||
26 | |||
27 | #include "mq.h" | ||
28 | |||
29 | |||
30 | struct GNUNET_MQ_Message | ||
31 | { | ||
32 | struct GNUNET_MessageHeader *mh; | ||
33 | }; | ||
34 | |||
35 | |||
36 | struct GNUNET_MQ_Message * | ||
37 | GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type) | ||
38 | { | ||
39 | struct GNUNET_MQ_Message *mqm; | ||
40 | mqm = GNUNET_malloc (sizeof *mqm + size); | ||
41 | mqm->mh = (struct GNUNET_MessageHeader *) &mqm[1]; | ||
42 | mqm->mh->size = htons (size); | ||
43 | mqm->mh->type = htons(type); | ||
44 | if (NULL != mhp) | ||
45 | *mhp = mqm->mh; | ||
46 | return mqm; | ||
47 | } | ||
diff --git a/src/set/mq.h b/src/set/mq.h new file mode 100644 index 000000000..a164ebb43 --- /dev/null +++ b/src/set/mq.h | |||
@@ -0,0 +1,94 @@ | |||
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 | * @author Florian Dold | ||
23 | * @file mq/mq.h | ||
24 | * @brief general purpose request queue | ||
25 | */ | ||
26 | #ifndef MQ_H | ||
27 | #define MQ_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_common.h" | ||
31 | #include "gnunet_util_lib.h" | ||
32 | #include "gnunet_connection_lib.h" | ||
33 | |||
34 | |||
35 | #define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_(((void) mvar->header, (struct GNUNET_MessageHeader**) &mvar), (esize) + sizeof *mvar, type) | ||
36 | |||
37 | #define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type) | ||
38 | |||
39 | #define GNUNET_MQ_msg_raw(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type) | ||
40 | |||
41 | #define GNUNET_MQ_HANDLERS_END {NULL, 0} | ||
42 | |||
43 | struct GNUNET_MQ_MessageQueue; | ||
44 | |||
45 | struct GNUNET_MQ_Message; | ||
46 | |||
47 | struct GNUNET_MQ_Handler | ||
48 | { | ||
49 | void *cb; | ||
50 | uint16_t type; | ||
51 | }; | ||
52 | |||
53 | struct GNUNET_MQ_Message * | ||
54 | GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type); | ||
55 | |||
56 | void | ||
57 | GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm); | ||
58 | |||
59 | void * | ||
60 | GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id); | ||
61 | |||
62 | uint32_t | ||
63 | GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq, | ||
64 | struct GNUNET_MQ_Message *mqm, | ||
65 | void *assoc_data); | ||
66 | |||
67 | |||
68 | struct GNUNET_MQ_MessageQueue * | ||
69 | GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection, | ||
70 | const struct GNUNET_MQ_Handler *handlers, | ||
71 | void *cls); | ||
72 | |||
73 | |||
74 | void | ||
75 | GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm, | ||
76 | void (*)(void*), | ||
77 | void *cls); | ||
78 | |||
79 | |||
80 | void | ||
81 | GNUNET_MQ_notify_timeout (struct GNUNET_MQ_Message *mqm, | ||
82 | void (*)(void*), | ||
83 | void *cls); | ||
84 | |||
85 | |||
86 | void | ||
87 | GNUNET_MQ_notify_destroy (struct GNUNET_MQ_Message *mqm, | ||
88 | void (*)(void*), | ||
89 | void *cls); | ||
90 | |||
91 | void | ||
92 | GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq); | ||
93 | |||
94 | #endif | ||
diff --git a/src/set/set.h b/src/set/set.h new file mode 100644 index 000000000..f10b25e4e --- /dev/null +++ b/src/set/set.h | |||
@@ -0,0 +1,189 @@ | |||
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 | * @author Florian Dold | ||
23 | * @file consensus/consensus.h | ||
24 | * @brief | ||
25 | */ | ||
26 | #ifndef SET_H | ||
27 | #define SET_H | ||
28 | |||
29 | #include "gnunet_common.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * The service sends up to GNUNET_SET_ACK_WINDOW messages per client handle, | ||
34 | * the client should send an ack every GNUNET_SET_ACK_WINDOW/2 messages. | ||
35 | */ | ||
36 | #define GNUNET_SET_ACK_WINDOW 8 | ||
37 | |||
38 | |||
39 | GNUNET_NETWORK_STRUCT_BEGIN | ||
40 | |||
41 | struct SetCreateMessage | ||
42 | { | ||
43 | /** | ||
44 | * Type: GNUNET_MESSAGE_TYPE_SET_CREATE | ||
45 | */ | ||
46 | struct GNUNET_MessageHeader header; | ||
47 | |||
48 | /** | ||
49 | * Operation type, values of enum GNUNET_SET_OperationType | ||
50 | */ | ||
51 | uint16_t operation GNUNET_PACKED; | ||
52 | }; | ||
53 | |||
54 | |||
55 | struct ListenMessage | ||
56 | { | ||
57 | /** | ||
58 | * Type: GNUNET_MESSAGE_TYPE_SET_LISTEN | ||
59 | */ | ||
60 | struct GNUNET_MessageHeader header; | ||
61 | |||
62 | /** | ||
63 | * application id | ||
64 | */ | ||
65 | struct GNUNET_HashCode app_id; | ||
66 | |||
67 | /** | ||
68 | * Operation type, values of enum GNUNET_SET_OperationType | ||
69 | */ | ||
70 | uint16_t operation GNUNET_PACKED; | ||
71 | |||
72 | /** | ||
73 | * Operation type, values of enum GNUNET_SET_OperationType | ||
74 | */ | ||
75 | uint16_t op GNUNET_PACKED; | ||
76 | |||
77 | }; | ||
78 | |||
79 | |||
80 | struct AcceptMessage | ||
81 | { | ||
82 | /** | ||
83 | * Type: GNUNET_MESSAGE_TYPE_SET_ACCEPT | ||
84 | */ | ||
85 | struct GNUNET_MessageHeader header; | ||
86 | |||
87 | /** | ||
88 | * request id of the request we want to accept | ||
89 | */ | ||
90 | uint32_t request_id GNUNET_PACKED; | ||
91 | |||
92 | |||
93 | struct GNUNET_TIME_RelativeNBO timeout; | ||
94 | }; | ||
95 | |||
96 | |||
97 | struct RequestMessage | ||
98 | { | ||
99 | /** | ||
100 | * Type: GNUNET_MESSAGE_TYPE_SET_Request | ||
101 | */ | ||
102 | struct GNUNET_MessageHeader header; | ||
103 | |||
104 | /** | ||
105 | * requesting peer | ||
106 | */ | ||
107 | struct GNUNET_PeerIdentity peer_id; | ||
108 | |||
109 | /** | ||
110 | * request id of the request we want to accept | ||
111 | */ | ||
112 | uint32_t request_id GNUNET_PACKED; | ||
113 | |||
114 | /* rest: inner message */ | ||
115 | }; | ||
116 | |||
117 | |||
118 | struct EvaluateMessage | ||
119 | { | ||
120 | /** | ||
121 | * Type: GNUNET_MESSAGE_TYPE_SET_EVALUATE | ||
122 | */ | ||
123 | struct GNUNET_MessageHeader header; | ||
124 | |||
125 | struct GNUNET_PeerIdentity other_peer; | ||
126 | |||
127 | struct GNUNET_HashCode app_id; | ||
128 | |||
129 | struct GNUNET_TIME_RelativeNBO timeout; | ||
130 | |||
131 | /** | ||
132 | * id of our evaluate | ||
133 | */ | ||
134 | uint32_t request_id GNUNET_PACKED; | ||
135 | |||
136 | /* rest: inner message */ | ||
137 | }; | ||
138 | |||
139 | |||
140 | struct ResultMessage | ||
141 | { | ||
142 | /** | ||
143 | * Type: GNUNET_MESSAGE_TYPE_SET_RESULT | ||
144 | */ | ||
145 | struct GNUNET_MessageHeader header; | ||
146 | |||
147 | /** | ||
148 | * id the result belongs to | ||
149 | */ | ||
150 | uint32_t request_id GNUNET_PACKED; | ||
151 | |||
152 | uint16_t result_status GNUNET_PACKED; | ||
153 | |||
154 | uint16_t element_type GNUNET_PACKED; | ||
155 | |||
156 | /* rest: the actual element */ | ||
157 | }; | ||
158 | |||
159 | |||
160 | struct ElementMessage | ||
161 | { | ||
162 | /** | ||
163 | * Type: GNUNET_MESSAGE_TYPE_SET_ADD or | ||
164 | * GNUNET_MESSAGE_TYPE_SET_REMOVE | ||
165 | */ | ||
166 | struct GNUNET_MessageHeader header; | ||
167 | |||
168 | uint16_t element_type GNUNET_PACKED; | ||
169 | |||
170 | /* rest: the actual element */ | ||
171 | }; | ||
172 | |||
173 | |||
174 | struct CancelMessage | ||
175 | { | ||
176 | /** | ||
177 | * Type: GNUNET_MESSAGE_TYPE_SET_CANCEL | ||
178 | */ | ||
179 | struct GNUNET_MessageHeader header; | ||
180 | |||
181 | /** | ||
182 | * id we want to cancel result belongs to | ||
183 | */ | ||
184 | uint32_t request_id GNUNET_PACKED; | ||
185 | }; | ||
186 | |||
187 | GNUNET_NETWORK_STRUCT_END | ||
188 | |||
189 | #endif | ||
diff --git a/src/set/set_api.c b/src/set/set_api.c index e69de29bb..d7898ab42 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -0,0 +1,395 @@ | |||
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 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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file set/set_api.c | ||
23 | * @brief api for the set service | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_protocols.h" | ||
29 | #include "gnunet_client_lib.h" | ||
30 | #include "gnunet_set_service.h" | ||
31 | #include "set.h" | ||
32 | #include "mq.h" | ||
33 | |||
34 | |||
35 | #define LOG(kind,...) GNUNET_log_from (kind, "set-api",__VA_ARGS__) | ||
36 | |||
37 | /** | ||
38 | * Opaque handle to a set. | ||
39 | */ | ||
40 | struct GNUNET_SET_Handle | ||
41 | { | ||
42 | struct GNUNET_CLIENT_Connection *client; | ||
43 | struct GNUNET_MQ_MessageQueue *mq; | ||
44 | unsigned int messages_since_ack; | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * Opaque handle to a set operation request from another peer. | ||
49 | */ | ||
50 | struct GNUNET_SET_Request | ||
51 | { | ||
52 | uint32_t request_id; | ||
53 | int accepted; | ||
54 | }; | ||
55 | |||
56 | |||
57 | struct GNUNET_SET_OperationHandle | ||
58 | { | ||
59 | GNUNET_SET_ResultIterator result_cb; | ||
60 | void *result_cls; | ||
61 | struct GNUNET_SET_Handle *set; | ||
62 | uint32_t request_id; | ||
63 | }; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Opaque handle to a listen operation. | ||
68 | */ | ||
69 | struct GNUNET_SET_ListenHandle | ||
70 | { | ||
71 | struct GNUNET_CLIENT_Connection *client; | ||
72 | struct GNUNET_MQ_MessageQueue* mq; | ||
73 | GNUNET_SET_ListenCallback listen_cb; | ||
74 | void *listen_cls; | ||
75 | }; | ||
76 | |||
77 | |||
78 | void | ||
79 | handle_result (void *cls, struct GNUNET_MessageHeader *mh) | ||
80 | { | ||
81 | struct ResultMessage *msg = (struct ResultMessage *) mh; | ||
82 | struct GNUNET_SET_Handle *set = cls; | ||
83 | struct GNUNET_SET_OperationHandle *oh; | ||
84 | struct GNUNET_SET_Element e; | ||
85 | |||
86 | if (set->messages_since_ack >= GNUNET_SET_ACK_WINDOW/2) | ||
87 | { | ||
88 | struct GNUNET_MQ_Message *mqm; | ||
89 | mqm = GNUNET_MQ_msg_raw (GNUNET_MESSAGE_TYPE_SET_ACK); | ||
90 | GNUNET_MQ_send (set->mq, mqm); | ||
91 | } | ||
92 | |||
93 | oh = GNUNET_MQ_assoc_remove (set->mq, ntohl (msg->request_id)); | ||
94 | GNUNET_break (NULL != oh); | ||
95 | if (htons (msg->result_status) != GNUNET_SET_STATUS_OK) | ||
96 | { | ||
97 | oh->result_cb (oh->result_cls, NULL, htons (msg->result_status)); | ||
98 | GNUNET_free (oh); | ||
99 | return; | ||
100 | } | ||
101 | e.data = &msg[1]; | ||
102 | e.size = ntohs (mh->size) - sizeof (struct ResultMessage); | ||
103 | e.type = msg->element_type; | ||
104 | oh->result_cb (oh->result_cls, &e, htons (msg->result_status)); | ||
105 | } | ||
106 | |||
107 | void | ||
108 | handle_request (void *cls, struct GNUNET_MessageHeader *mh) | ||
109 | { | ||
110 | struct RequestMessage *msg = (struct RequestMessage *) mh; | ||
111 | struct GNUNET_SET_ListenHandle *lh = cls; | ||
112 | struct GNUNET_SET_Request *req; | ||
113 | |||
114 | req = GNUNET_new (struct GNUNET_SET_Request); | ||
115 | req->request_id = ntohl (msg->request_id); | ||
116 | lh->listen_cb (lh->listen_cls, &msg->peer_id, &mh[1], req); | ||
117 | if (GNUNET_NO == req->accepted) | ||
118 | GNUNET_free (req); | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Create an empty set, supporting the specified operation. | ||
124 | * | ||
125 | * @param cfg configuration to use for connecting to the | ||
126 | * set service | ||
127 | * @param op operation supported by the set | ||
128 | * Note that the operation has to be specified | ||
129 | * beforehand, as certain set operations need to maintain | ||
130 | * data structures spefific to the operation | ||
131 | * @return a handle to the set | ||
132 | */ | ||
133 | struct GNUNET_SET_Handle * | ||
134 | GNUNET_SET_create (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
135 | enum GNUNET_SET_OperationType op) | ||
136 | { | ||
137 | struct GNUNET_SET_Handle *set; | ||
138 | struct GNUNET_MQ_Message *mqm; | ||
139 | struct SetCreateMessage *msg; | ||
140 | static const struct GNUNET_MQ_Handler mq_handlers[] = { | ||
141 | {handle_result, GNUNET_MESSAGE_TYPE_SET_RESULT}, | ||
142 | GNUNET_MQ_HANDLERS_END | ||
143 | }; | ||
144 | |||
145 | set = GNUNET_new (struct GNUNET_SET_Handle); | ||
146 | set->client = GNUNET_CLIENT_connect ("set", cfg); | ||
147 | GNUNET_assert (NULL != set->client); | ||
148 | set->mq = GNUNET_MQ_queue_for_connection_client (set->client, mq_handlers, set); | ||
149 | mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_CREATE); | ||
150 | msg->operation = htons (op); | ||
151 | GNUNET_MQ_send (set->mq, mqm); | ||
152 | return set; | ||
153 | } | ||
154 | |||
155 | |||
156 | /** | ||
157 | * Add an element to the given set. | ||
158 | * After the element has been added (in the sense of being | ||
159 | * transmitted to the set service), cont will be called. | ||
160 | * Calls to add_element can be queued | ||
161 | * | ||
162 | * @param set set to add element to | ||
163 | * @param element element to add to the set | ||
164 | * @param cont continuation called after the element has been added | ||
165 | * @param cont_cls closure for cont | ||
166 | */ | ||
167 | void | ||
168 | GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, | ||
169 | const struct GNUNET_SET_Element *element, | ||
170 | GNUNET_SET_Continuation cont, | ||
171 | void *cont_cls) | ||
172 | { | ||
173 | struct GNUNET_MQ_Message *mqm; | ||
174 | struct ElementMessage *msg; | ||
175 | |||
176 | mqm = GNUNET_MQ_msg_extra (msg, element->size, GNUNET_MESSAGE_TYPE_SET_ADD); | ||
177 | msg->element_type = element->type; | ||
178 | memcpy (&msg[1], element->data, element->size); | ||
179 | GNUNET_MQ_notify_sent (mqm, cont, cont_cls); | ||
180 | GNUNET_MQ_send (set->mq, mqm); | ||
181 | } | ||
182 | |||
183 | |||
184 | /** | ||
185 | * Remove an element to the given set. | ||
186 | * After the element has been removed (in the sense of the | ||
187 | * request being transmitted to the set service), cont will be called. | ||
188 | * Calls to remove_element can be queued | ||
189 | * | ||
190 | * @param set set to remove element from | ||
191 | * @param element element to remove from the set | ||
192 | * @param cont continuation called after the element has been removed | ||
193 | * @param cont_cls closure for cont | ||
194 | */ | ||
195 | void | ||
196 | GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, | ||
197 | const struct GNUNET_SET_Element *element, | ||
198 | GNUNET_SET_Continuation cont, | ||
199 | void *cont_cls) | ||
200 | { | ||
201 | struct GNUNET_MQ_Message *mqm; | ||
202 | struct ElementMessage *msg; | ||
203 | |||
204 | mqm = GNUNET_MQ_msg_extra (msg, element->size, GNUNET_MESSAGE_TYPE_SET_REMOVE); | ||
205 | msg->element_type = element->type; | ||
206 | memcpy (&msg[1], element->data, element->size); | ||
207 | GNUNET_MQ_notify_sent (mqm, cont, cont_cls); | ||
208 | GNUNET_MQ_send (set->mq, mqm); | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Destroy the set handle, and free all associated resources. | ||
214 | */ | ||
215 | void | ||
216 | GNUNET_SET_destroy (struct GNUNET_SET_Handle *set) | ||
217 | { | ||
218 | GNUNET_CLIENT_disconnect (set->client); | ||
219 | set->client = NULL; | ||
220 | GNUNET_MQ_destroy (set->mq); | ||
221 | set->mq = NULL; | ||
222 | } | ||
223 | |||
224 | static void | ||
225 | operation_destroy (void *cls) | ||
226 | { | ||
227 | struct GNUNET_SET_OperationHandle *oh = cls; | ||
228 | struct GNUNET_SET_OperationHandle *oh_assoc; | ||
229 | |||
230 | oh_assoc = GNUNET_MQ_assoc_remove (oh->set->mq, oh->request_id); | ||
231 | GNUNET_assert (oh_assoc == oh); | ||
232 | } | ||
233 | |||
234 | |||
235 | /** | ||
236 | * Evaluate a set operation with our set and the set of another peer. | ||
237 | * | ||
238 | * @param set set to use | ||
239 | * @param other_peer peer with the other set | ||
240 | * @param app_id hash for the application using the set | ||
241 | * @param context_msg additional information for the request | ||
242 | * @param result_cb called on error or success | ||
243 | * @param result_cls closure for result_cb | ||
244 | * @return a handle to cancel the operation | ||
245 | */ | ||
246 | struct GNUNET_SET_OperationHandle * | ||
247 | GNUNET_SET_evaluate (struct GNUNET_SET_Handle *set, | ||
248 | const struct GNUNET_PeerIdentity *other_peer, | ||
249 | const struct GNUNET_HashCode *app_id, | ||
250 | const struct GNUNET_MessageHeader *context_msg, | ||
251 | struct GNUNET_TIME_Relative timeout, | ||
252 | enum GNUNET_SET_ResultMode result_mode, | ||
253 | GNUNET_SET_ResultIterator result_cb, | ||
254 | void *result_cls) | ||
255 | { | ||
256 | struct GNUNET_MQ_Message *mqm; | ||
257 | struct EvaluateMessage *msg; | ||
258 | struct GNUNET_SET_OperationHandle *oh; | ||
259 | |||
260 | oh = GNUNET_new (struct GNUNET_SET_OperationHandle); | ||
261 | oh->result_cb = result_cb; | ||
262 | oh->result_cls = result_cls; | ||
263 | oh->set = set; | ||
264 | |||
265 | mqm = GNUNET_MQ_msg_extra (msg, htons(context_msg->size), GNUNET_MESSAGE_TYPE_SET_EVALUATE); | ||
266 | msg->request_id = htonl (GNUNET_MQ_assoc_add (set->mq, mqm, oh)); | ||
267 | msg->other_peer = *other_peer; | ||
268 | msg->app_id = *app_id; | ||
269 | msg->timeout = GNUNET_TIME_relative_hton (timeout); | ||
270 | memcpy (&msg[1], context_msg, htons (context_msg->size)); | ||
271 | GNUNET_MQ_notify_timeout (mqm, operation_destroy, oh); | ||
272 | GNUNET_MQ_notify_destroy (mqm, operation_destroy, oh); | ||
273 | GNUNET_MQ_send (set->mq, mqm); | ||
274 | |||
275 | return oh; | ||
276 | } | ||
277 | |||
278 | |||
279 | /** | ||
280 | * Wait for set operation requests for the given application id | ||
281 | * | ||
282 | * @param cfg configuration to use for connecting to | ||
283 | * the set service | ||
284 | * @param operation operation we want to listen for | ||
285 | * @param app_id id of the application that handles set operation requests | ||
286 | * @param listen_cb called for each incoming request matching the operation | ||
287 | * and application id | ||
288 | * @param listen_cls handle for listen_cb | ||
289 | * @return a handle that can be used to cancel the listen operation | ||
290 | */ | ||
291 | struct GNUNET_SET_ListenHandle * | ||
292 | GNUNET_SET_listen (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
293 | enum GNUNET_SET_OperationType operation, | ||
294 | const struct GNUNET_HashCode *app_id, | ||
295 | GNUNET_SET_ListenCallback listen_cb, | ||
296 | void *listen_cls) | ||
297 | { | ||
298 | struct GNUNET_SET_ListenHandle *lh; | ||
299 | struct GNUNET_MQ_Message *mqm; | ||
300 | struct ListenMessage *msg; | ||
301 | static const struct GNUNET_MQ_Handler mq_handlers[] = { | ||
302 | {handle_request, GNUNET_MESSAGE_TYPE_SET_REQUEST}, | ||
303 | GNUNET_MQ_HANDLERS_END | ||
304 | }; | ||
305 | |||
306 | lh = GNUNET_new (struct GNUNET_SET_ListenHandle); | ||
307 | lh->client = GNUNET_CLIENT_connect ("set", cfg); | ||
308 | lh->listen_cb = listen_cb; | ||
309 | lh->listen_cls = listen_cls; | ||
310 | GNUNET_assert (NULL != lh->client); | ||
311 | lh->mq = GNUNET_MQ_queue_for_connection_client (lh->client, mq_handlers, lh); | ||
312 | mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_LISTEN); | ||
313 | msg->operation = htons (operation); | ||
314 | msg->app_id = *app_id; | ||
315 | GNUNET_MQ_send (lh->mq, mqm); | ||
316 | |||
317 | return lh; | ||
318 | } | ||
319 | |||
320 | |||
321 | /** | ||
322 | * Cancel the given listen operation. | ||
323 | * | ||
324 | * @param lh handle for the listen operation | ||
325 | */ | ||
326 | void | ||
327 | GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) | ||
328 | { | ||
329 | GNUNET_MQ_destroy (lh->mq); | ||
330 | lh->mq = NULL; | ||
331 | GNUNET_CLIENT_disconnect (lh->client); | ||
332 | lh->client = NULL; | ||
333 | lh->listen_cb = NULL; | ||
334 | lh->listen_cls = NULL; | ||
335 | } | ||
336 | |||
337 | |||
338 | /** | ||
339 | * Accept a request we got via GNUNET_SET_listen | ||
340 | * | ||
341 | * @param request request to accept | ||
342 | * @param set set used for the requested operation | ||
343 | * @param timeout timeout for the set operation | ||
344 | * @param result_cb callback for the results | ||
345 | * @param cls closure for result_cb | ||
346 | */ | ||
347 | struct GNUNET_SET_OperationHandle * | ||
348 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | ||
349 | struct GNUNET_SET_Handle *set, | ||
350 | struct GNUNET_TIME_Relative timeout, | ||
351 | enum GNUNET_SET_ResultMode result_mode, | ||
352 | GNUNET_SET_ResultIterator result_cb, | ||
353 | void *result_cls) | ||
354 | { | ||
355 | struct GNUNET_MQ_Message *mqm; | ||
356 | struct AcceptMessage *msg; | ||
357 | struct GNUNET_SET_OperationHandle *oh; | ||
358 | |||
359 | /* don't accept a request twice! */ | ||
360 | GNUNET_assert (GNUNET_NO == request->accepted); | ||
361 | request->accepted = GNUNET_YES; | ||
362 | |||
363 | oh = GNUNET_new (struct GNUNET_SET_OperationHandle); | ||
364 | oh->result_cb = result_cb; | ||
365 | oh->result_cls = result_cls; | ||
366 | oh->set = set; | ||
367 | |||
368 | mqm = GNUNET_MQ_msg (msg , GNUNET_MESSAGE_TYPE_SET_ACCEPT); | ||
369 | msg->timeout = GNUNET_TIME_relative_hton (timeout); | ||
370 | msg->request_id = htonl (request->request_id); | ||
371 | GNUNET_MQ_notify_timeout (mqm, operation_destroy, oh); | ||
372 | GNUNET_MQ_notify_destroy (mqm, operation_destroy, oh); | ||
373 | GNUNET_MQ_send (set->mq, mqm); | ||
374 | |||
375 | return oh; | ||
376 | } | ||
377 | |||
378 | |||
379 | /** | ||
380 | * Cancel the given set operation. | ||
381 | * | ||
382 | * @param op set operation to cancel | ||
383 | */ | ||
384 | void | ||
385 | GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *h) | ||
386 | { | ||
387 | struct GNUNET_MQ_Message *mqm; | ||
388 | struct GNUNET_SET_OperationHandle *h_assoc; | ||
389 | |||
390 | h_assoc = GNUNET_MQ_assoc_remove (h->set->mq, h->request_id); | ||
391 | GNUNET_assert (h_assoc == h); | ||
392 | mqm = GNUNET_MQ_msg_raw (GNUNET_MESSAGE_TYPE_SET_CANCEL); | ||
393 | GNUNET_MQ_send (h->set->mq, mqm); | ||
394 | } | ||
395 | |||
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c index f9e027a86..7e2ed2b41 100644 --- a/src/set/test_set_api.c +++ b/src/set/test_set_api.c | |||
@@ -25,6 +25,28 @@ | |||
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "gnunet_util_lib.h" | 26 | #include "gnunet_util_lib.h" |
27 | #include "gnunet_testing_lib.h" | 27 | #include "gnunet_testing_lib.h" |
28 | #include "gnunet_set_service.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Signature of the 'main' function for a (single-peer) testcase that | ||
33 | * is run using 'GNUNET_TESTING_peer_run'. | ||
34 | * | ||
35 | * @param cls closure | ||
36 | * @param cfg configuration of the peer that was started | ||
37 | * @param peer identity of the peer that was created | ||
38 | */ | ||
39 | static void | ||
40 | run (void *cls, | ||
41 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
42 | struct GNUNET_TESTING_Peer *peer) | ||
43 | { | ||
44 | struct GNUNET_SET_Handle *set1; | ||
45 | struct GNUNET_SET_Handle *set2; | ||
46 | |||
47 | set1 = GNUNET_SET_create (GNUNET_SET_OPERATION_UNION); | ||
48 | set2 = GNUNET_SET_create (GNUNET_SET_OPERATION_UNION); | ||
49 | } | ||
28 | 50 | ||
29 | int | 51 | int |
30 | main (int argc, char **argv) | 52 | main (int argc, char **argv) |