aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2013-04-17 00:44:29 +0000
committerFlorian Dold <florian.dold@gmail.com>2013-04-17 00:44:29 +0000
commit0555e4e107db9c0c1f0caa6c947881c32bf426f4 (patch)
treed9bbd740ad0f73c07cf56aad0650e6ded7d05229 /src
parente77e2db24ef3681f207521e539a2c1ca3584efda (diff)
downloadgnunet-0555e4e107db9c0c1f0caa6c947881c32bf426f4.tar.gz
gnunet-0555e4e107db9c0c1f0caa6c947881c32bf426f4.zip
started implementing set api, draft for mq
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_protocols.h60
-rw-r--r--src/include/gnunet_set_service.h257
-rw-r--r--src/include/gnunet_testing_lib.h6
-rw-r--r--src/set/Makefile.am3
-rw-r--r--src/set/mq.c47
-rw-r--r--src/set/mq.h94
-rw-r--r--src/set/set.h189
-rw-r--r--src/set/set_api.c395
-rw-r--r--src/set/test_set_api.c22
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
31extern "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 */
47struct GNUNET_SET_Handle;
48
49/**
50 * Opaque handle to a set operation request from another peer.
51 */
52struct GNUNET_SET_Request;
53
54/**
55 * Opaque handle to a listen operation.
56 */
57struct GNUNET_SET_ListenHandle;
58
59/**
60 * Opaque handle to a set operation.
61 */
62struct GNUNET_SET_OperationHandle;
63
64
65/**
66 * Opaque handle to a listen operation.
67 */
68struct 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 */
6enum GNUNET_SET_Operation 73enum 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 */
111enum 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 */
38struct GNUNET_SET_Element 132struct 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 */
154typedef 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 */
164typedef 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 */
184typedef 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 */
64struct GNUNET_SET_Handle * 203struct GNUNET_SET_Handle *
65GNUNET_SET_create (enum GNUNET_SET_Operation op); 204GNUNET_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 */
69void 219void
70GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, 220GNUNET_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 */
77void 237void
78GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, 238GNUNET_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
85struct GNUNET_SET_Handle *
86GNUNET_SET_clone (struct GNUNET_SET_Handle *set);
87
88
89// FIXME: comment
90void
91GNUNET_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 */
106typedef void 247void
107(*GNUNET_SET_ResultIterator) (void *cls, 248GNUNET_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 */
122struct GNUNET_SET_OperationHandle * 262struct GNUNET_SET_OperationHandle *
123GNUNET_SET_evaluate (const struct GNUNET_PeerIdentity *other_peer, 263GNUNET_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 */
145typedef 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 */
162struct GNUNET_SET_ListenHandle * 287struct GNUNET_SET_ListenHandle *
163GNUNET_SET_listen (enum GNUNET_SET_Operation operation, 288GNUNET_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 */
171void 301void
172GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); 302GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh);
173 303
@@ -185,12 +315,25 @@ struct GNUNET_SET_OperationHandle *
185GNUNET_SET_accept (struct GNUNET_SET_Request *request, 315GNUNET_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 */
193void 328void
194GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *op); 329GNUNET_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 */
328typedef void (*GNUNET_TESTING_TestMain)(void *cls, 328typedef 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
48libgnunetset_la_SOURCES = \ 48libgnunetset_la_SOURCES = \
49 set_api.c 49 set_api.c \
50 mq.c
50libgnunetset_la_LIBADD = \ 51libgnunetset_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
30struct GNUNET_MQ_Message
31{
32 struct GNUNET_MessageHeader *mh;
33};
34
35
36struct GNUNET_MQ_Message *
37GNUNET_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
43struct GNUNET_MQ_MessageQueue;
44
45struct GNUNET_MQ_Message;
46
47struct GNUNET_MQ_Handler
48{
49 void *cb;
50 uint16_t type;
51};
52
53struct GNUNET_MQ_Message *
54GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
55
56void
57GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
58
59void *
60GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
61
62uint32_t
63GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
64 struct GNUNET_MQ_Message *mqm,
65 void *assoc_data);
66
67
68struct GNUNET_MQ_MessageQueue *
69GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
70 const struct GNUNET_MQ_Handler *handlers,
71 void *cls);
72
73
74void
75GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
76 void (*)(void*),
77 void *cls);
78
79
80void
81GNUNET_MQ_notify_timeout (struct GNUNET_MQ_Message *mqm,
82 void (*)(void*),
83 void *cls);
84
85
86void
87GNUNET_MQ_notify_destroy (struct GNUNET_MQ_Message *mqm,
88 void (*)(void*),
89 void *cls);
90
91void
92GNUNET_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
39GNUNET_NETWORK_STRUCT_BEGIN
40
41struct 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
55struct 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
80struct 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
97struct 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
118struct 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
140struct 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
160struct 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
174struct 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
187GNUNET_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 */
40struct 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 */
50struct GNUNET_SET_Request
51{
52 uint32_t request_id;
53 int accepted;
54};
55
56
57struct 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 */
69struct 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
78void
79handle_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
107void
108handle_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 */
133struct GNUNET_SET_Handle *
134GNUNET_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 */
167void
168GNUNET_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 */
195void
196GNUNET_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 */
215void
216GNUNET_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
224static void
225operation_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 */
246struct GNUNET_SET_OperationHandle *
247GNUNET_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 */
291struct GNUNET_SET_ListenHandle *
292GNUNET_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 */
326void
327GNUNET_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 */
347struct GNUNET_SET_OperationHandle *
348GNUNET_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 */
384void
385GNUNET_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 */
39static void
40run (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
29int 51int
30main (int argc, char **argv) 52main (int argc, char **argv)