diff options
author | Gabor X Toth <*@tg-x.net> | 2014-03-06 23:46:45 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2014-03-06 23:46:45 +0000 |
commit | 8a0b8a4604526e5f832c4971f9c3b1b48d79bea4 (patch) | |
tree | dfd18a61272a18381fe9ce9b09849a965480a303 /src/multicast | |
parent | a21beab58c1d2abc747359a98326f19aaad4e8cd (diff) | |
download | gnunet-8a0b8a4604526e5f832c4971f9c3b1b48d79bea4.tar.gz gnunet-8a0b8a4604526e5f832c4971f9c3b1b48d79bea4.zip |
PSYC: implement slave to master requests, tests, fixes, reorg
Multicast lib: handle member to origin requests.
Keep track of members and origins and call their callbacks when necessary.
Diffstat (limited to 'src/multicast')
-rw-r--r-- | src/multicast/gnunet-service-multicast.c | 84 | ||||
-rw-r--r-- | src/multicast/multicast.h | 46 | ||||
-rw-r--r-- | src/multicast/multicast_api.c | 435 |
3 files changed, 425 insertions, 140 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c index f9aa7fe2d..47c8bce36 100644 --- a/src/multicast/gnunet-service-multicast.c +++ b/src/multicast/gnunet-service-multicast.c | |||
@@ -41,6 +41,71 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
41 | 41 | ||
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Handle a connecting client starting an origin. | ||
45 | */ | ||
46 | static void | ||
47 | handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | ||
48 | const struct GNUNET_MessageHeader *msg) | ||
49 | { | ||
50 | |||
51 | } | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Handle a client stopping an origin. | ||
56 | */ | ||
57 | static void | ||
58 | handle_origin_stop (void *cls, struct GNUNET_SERVER_Client *client, | ||
59 | const struct GNUNET_MessageHeader *msg) | ||
60 | { | ||
61 | |||
62 | } | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Handle a connecting client joining a group. | ||
67 | */ | ||
68 | static void | ||
69 | handle_member_join (void *cls, struct GNUNET_SERVER_Client *client, | ||
70 | const struct GNUNET_MessageHeader *msg) | ||
71 | { | ||
72 | |||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Handle a client parting a group. | ||
78 | */ | ||
79 | static void | ||
80 | handle_member_part (void *cls, struct GNUNET_SERVER_Client *client, | ||
81 | const struct GNUNET_MessageHeader *msg) | ||
82 | { | ||
83 | |||
84 | } | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Incoming message from a client. | ||
89 | */ | ||
90 | static void | ||
91 | handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | ||
92 | const struct GNUNET_MessageHeader *msg) | ||
93 | { | ||
94 | |||
95 | } | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Incoming request from a client. | ||
100 | */ | ||
101 | static void | ||
102 | handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | ||
103 | const struct GNUNET_MessageHeader *msg) | ||
104 | { | ||
105 | |||
106 | } | ||
107 | |||
108 | /** | ||
44 | * Process multicast requests. | 109 | * Process multicast requests. |
45 | * | 110 | * |
46 | * @param cls closure | 111 | * @param cls closure |
@@ -52,7 +117,24 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
52 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 117 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
53 | { | 118 | { |
54 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 119 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
55 | /* FIXME: add handlers here! */ | 120 | { &handle_origin_start, NULL, |
121 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, | ||
122 | |||
123 | { &handle_origin_stop, NULL, | ||
124 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_STOP, 0 }, | ||
125 | |||
126 | { &handle_member_join, NULL, | ||
127 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, | ||
128 | |||
129 | { &handle_member_part, NULL, | ||
130 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_PART, 0 }, | ||
131 | |||
132 | { &handle_multicast_message, NULL, | ||
133 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, | ||
134 | |||
135 | { &handle_multicast_request, NULL, | ||
136 | GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, | ||
137 | |||
56 | {NULL, NULL, 0, 0} | 138 | {NULL, NULL, 0, 0} |
57 | }; | 139 | }; |
58 | /* FIXME: do setup here */ | 140 | /* FIXME: do setup here */ |
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h index 88cb2d99e..facf8f54e 100644 --- a/src/multicast/multicast.h +++ b/src/multicast/multicast.h | |||
@@ -22,6 +22,7 @@ | |||
22 | * @file multicast/multicast.h | 22 | * @file multicast/multicast.h |
23 | * @brief multicast IPC messages | 23 | * @brief multicast IPC messages |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * @author Gabor X Toth | ||
25 | */ | 26 | */ |
26 | #ifndef MULTICAST_H | 27 | #ifndef MULTICAST_H |
27 | #define MULTICAST_H | 28 | #define MULTICAST_H |
@@ -30,12 +31,52 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
30 | 31 | ||
31 | 32 | ||
32 | /** | 33 | /** |
34 | * Header of a join request sent to the origin or another member. | ||
35 | */ | ||
36 | struct GNUNET_MULTICAST_JoinRequest | ||
37 | { | ||
38 | /** | ||
39 | * Header for the join request. | ||
40 | */ | ||
41 | struct GNUNET_MessageHeader header; | ||
42 | |||
43 | /** | ||
44 | * ECC signature of the rest of the fields of the join request. | ||
45 | * | ||
46 | * Signature must match the public key of the joining member. | ||
47 | */ | ||
48 | struct GNUNET_CRYPTO_EddsaSignature signature; | ||
49 | |||
50 | /** | ||
51 | * Purpose for the signature and size of the signed data. | ||
52 | */ | ||
53 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
54 | |||
55 | /** | ||
56 | * Public key of the target group. | ||
57 | */ | ||
58 | struct GNUNET_CRYPTO_EddsaPublicKey group_key; | ||
59 | |||
60 | /** | ||
61 | * Public key of the joining member. | ||
62 | */ | ||
63 | struct GNUNET_CRYPTO_EddsaPublicKey member_key; | ||
64 | |||
65 | /** | ||
66 | * Peer identity of the joining member. | ||
67 | */ | ||
68 | struct GNUNET_PeerIdentity member_peer; | ||
69 | |||
70 | /* Followed by request body. */ | ||
71 | }; | ||
72 | |||
73 | |||
74 | /** | ||
33 | * Message sent from the client to the service to notify the service | 75 | * Message sent from the client to the service to notify the service |
34 | * about a join decision. | 76 | * about a join decision. |
35 | */ | 77 | */ |
36 | struct MulticastJoinDecisionMessage | 78 | struct MulticastJoinDecisionMessage |
37 | { | 79 | { |
38 | |||
39 | /** | 80 | /** |
40 | * | 81 | * |
41 | */ | 82 | */ |
@@ -329,9 +370,6 @@ struct MulticastUnicastToOriginCancelMessage | |||
329 | }; | 370 | }; |
330 | 371 | ||
331 | 372 | ||
332 | |||
333 | |||
334 | |||
335 | GNUNET_NETWORK_STRUCT_END | 373 | GNUNET_NETWORK_STRUCT_END |
336 | 374 | ||
337 | #endif | 375 | #endif |
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c index bb6a57b58..25af614af 100644 --- a/src/multicast/multicast_api.c +++ b/src/multicast/multicast_api.c | |||
@@ -34,6 +34,19 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Started origins. | ||
38 | * Group's pub_key_hash -> struct GNUNET_MULTICAST_Origin | ||
39 | */ | ||
40 | static struct GNUNET_CONTAINER_MultiHashMap *origins; | ||
41 | |||
42 | /** | ||
43 | * Joined members. | ||
44 | * group_key_hash -> struct GNUNET_MULTICAST_Member | ||
45 | */ | ||
46 | static struct GNUNET_CONTAINER_MultiHashMap *members; | ||
47 | |||
48 | |||
49 | /** | ||
37 | * Handle for a request to send a message to all multicast group members | 50 | * Handle for a request to send a message to all multicast group members |
38 | * (from the origin). | 51 | * (from the origin). |
39 | */ | 52 | */ |
@@ -49,13 +62,20 @@ struct GNUNET_MULTICAST_OriginMessageHandle | |||
49 | }; | 62 | }; |
50 | 63 | ||
51 | 64 | ||
65 | struct GNUNET_MULTICAST_Group | ||
66 | { | ||
67 | uint8_t is_origin; | ||
68 | }; | ||
69 | |||
52 | /** | 70 | /** |
53 | * Handle for the origin of a multicast group. | 71 | * Handle for the origin of a multicast group. |
54 | */ | 72 | */ |
55 | struct GNUNET_MULTICAST_Origin | 73 | struct GNUNET_MULTICAST_Origin |
56 | { | 74 | { |
57 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; | 75 | struct GNUNET_MULTICAST_Group grp; |
76 | |||
58 | struct GNUNET_MULTICAST_OriginMessageHandle msg_handle; | 77 | struct GNUNET_MULTICAST_OriginMessageHandle msg_handle; |
78 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; | ||
59 | 79 | ||
60 | GNUNET_MULTICAST_JoinCallback join_cb; | 80 | GNUNET_MULTICAST_JoinCallback join_cb; |
61 | GNUNET_MULTICAST_MembershipTestCallback mem_test_cb; | 81 | GNUNET_MULTICAST_MembershipTestCallback mem_test_cb; |
@@ -66,6 +86,9 @@ struct GNUNET_MULTICAST_Origin | |||
66 | void *cls; | 86 | void *cls; |
67 | 87 | ||
68 | uint64_t next_fragment_id; | 88 | uint64_t next_fragment_id; |
89 | |||
90 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | ||
91 | struct GNUNET_HashCode pub_key_hash; | ||
69 | }; | 92 | }; |
70 | 93 | ||
71 | 94 | ||
@@ -74,123 +97,176 @@ struct GNUNET_MULTICAST_Origin | |||
74 | */ | 97 | */ |
75 | struct GNUNET_MULTICAST_MemberRequestHandle | 98 | struct GNUNET_MULTICAST_MemberRequestHandle |
76 | { | 99 | { |
100 | GNUNET_MULTICAST_MemberTransmitNotify notify; | ||
101 | void *notify_cls; | ||
102 | struct GNUNET_MULTICAST_Member *member; | ||
103 | |||
104 | uint64_t request_id; | ||
105 | uint64_t fragment_offset; | ||
77 | }; | 106 | }; |
78 | 107 | ||
79 | 108 | ||
80 | /** | 109 | /** |
81 | * Opaque handle for a multicast group member. | 110 | * Handle for a multicast group member. |
82 | */ | 111 | */ |
83 | struct GNUNET_MULTICAST_Member | 112 | struct GNUNET_MULTICAST_Member |
84 | { | 113 | { |
114 | struct GNUNET_MULTICAST_Group grp; | ||
115 | |||
116 | struct GNUNET_MULTICAST_MemberRequestHandle req_handle; | ||
117 | |||
118 | struct GNUNET_CRYPTO_EddsaPublicKey group_key; | ||
119 | struct GNUNET_CRYPTO_EddsaPrivateKey member_key; | ||
120 | struct GNUNET_PeerIdentity origin; | ||
121 | struct GNUNET_PeerIdentity relays; | ||
122 | uint32_t relay_count; | ||
123 | struct GNUNET_MessageHeader *join_request; | ||
124 | GNUNET_MULTICAST_JoinCallback join_cb; | ||
125 | GNUNET_MULTICAST_MembershipTestCallback member_test_cb; | ||
126 | GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb; | ||
127 | GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb; | ||
128 | GNUNET_MULTICAST_MessageCallback message_cb; | ||
129 | void *cls; | ||
130 | |||
131 | uint64_t next_fragment_id; | ||
132 | struct GNUNET_HashCode group_key_hash; | ||
85 | }; | 133 | }; |
86 | 134 | ||
87 | 135 | ||
88 | GNUNET_NETWORK_STRUCT_BEGIN | 136 | /** |
137 | * Handle that identifies a join request. | ||
138 | * | ||
139 | * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the | ||
140 | * corresponding calls to #GNUNET_MULTICAST_join_decision(). | ||
141 | */ | ||
142 | struct GNUNET_MULTICAST_JoinHandle | ||
143 | { | ||
144 | }; | ||
145 | |||
89 | 146 | ||
90 | /** | 147 | /** |
91 | * Header of a request from a member to the origin. | 148 | * Handle to pass back for the answer of a membership test. |
92 | */ | 149 | */ |
93 | struct GNUNET_MULTICAST_RequestHeader | 150 | struct GNUNET_MULTICAST_MembershipTestHandle |
94 | { | 151 | { |
95 | /** | 152 | }; |
96 | * Header for all requests from a member to the origin. | ||
97 | */ | ||
98 | struct GNUNET_MessageHeader header; | ||
99 | 153 | ||
100 | /** | ||
101 | * Public key of the sending member. | ||
102 | */ | ||
103 | struct GNUNET_CRYPTO_EddsaPublicKey member_key; | ||
104 | 154 | ||
105 | /** | 155 | /** |
106 | * ECC signature of the request fragment. | 156 | * Opaque handle to a replay request from the multicast service. |
107 | * | 157 | */ |
108 | * Signature must match the public key of the multicast group. | 158 | struct GNUNET_MULTICAST_ReplayHandle |
109 | */ | 159 | { |
110 | struct GNUNET_CRYPTO_EddsaSignature signature; | 160 | }; |
111 | 161 | ||
112 | /** | ||
113 | * Purpose for the signature and size of the signed data. | ||
114 | */ | ||
115 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
116 | 162 | ||
117 | /** | 163 | /** |
118 | * Number of the request fragment, monotonically increasing. | 164 | * Handle for a replay request. |
119 | */ | 165 | */ |
120 | uint64_t fragment_id GNUNET_PACKED; | 166 | struct GNUNET_MULTICAST_MemberReplayHandle |
167 | { | ||
168 | }; | ||
121 | 169 | ||
122 | /** | ||
123 | * Byte offset of this @e fragment of the @e request. | ||
124 | */ | ||
125 | uint64_t fragment_offset GNUNET_PACKED; | ||
126 | 170 | ||
127 | /** | 171 | /** |
128 | * Number of the request this fragment belongs to. | 172 | * Iterator callback for calling message callbacks for all groups. |
129 | * | 173 | */ |
130 | * Set in GNUNET_MULTICAST_origin_to_all(). | 174 | static int |
131 | */ | 175 | message_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash, |
132 | uint64_t request_id GNUNET_PACKED; | 176 | void *group) |
177 | { | ||
178 | const struct GNUNET_MessageHeader *msg = cls; | ||
179 | struct GNUNET_MULTICAST_Group *grp = group; | ||
133 | 180 | ||
134 | /** | 181 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
135 | * Flags for this request. | 182 | "Calling message callback for a message of type %u and size %u.\n", |
136 | */ | 183 | ntohs (msg->type), ntohs (msg->size)); |
137 | enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED; | 184 | |
185 | if (GNUNET_YES == grp->is_origin) | ||
186 | { | ||
187 | struct GNUNET_MULTICAST_Origin *orig = (struct GNUNET_MULTICAST_Origin *) grp; | ||
188 | orig->message_cb (orig->cls, msg); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | struct GNUNET_MULTICAST_Member *mem = (struct GNUNET_MULTICAST_Member *) grp; | ||
193 | mem->message_cb (mem->cls, msg); | ||
194 | } | ||
195 | |||
196 | return GNUNET_YES; | ||
197 | } | ||
138 | 198 | ||
139 | /* Followed by request body. */ | ||
140 | }; | ||
141 | 199 | ||
142 | /** | 200 | /** |
143 | * Header of a join request sent to the origin or another member. | 201 | * Handle a multicast message from the service. |
202 | * | ||
203 | * Call message callbacks of all origins and members of the destination group. | ||
204 | * | ||
205 | * @param grp Destination group of the message. | ||
206 | * @param msg The message. | ||
144 | */ | 207 | */ |
145 | struct GNUNET_MULTICAST_JoinRequest | 208 | static void |
209 | handle_multicast_message (struct GNUNET_MULTICAST_Group *grp, | ||
210 | const struct GNUNET_MULTICAST_MessageHeader *msg) | ||
146 | { | 211 | { |
147 | /** | 212 | struct GNUNET_HashCode *hash; |
148 | * Header for the join request. | ||
149 | */ | ||
150 | struct GNUNET_MessageHeader header; | ||
151 | 213 | ||
152 | /** | 214 | if (GNUNET_YES == grp->is_origin) |
153 | * ECC signature of the rest of the fields of the join request. | 215 | { |
154 | * | 216 | struct GNUNET_MULTICAST_Origin *orig = (struct GNUNET_MULTICAST_Origin *) grp; |
155 | * Signature must match the public key of the joining member. | 217 | hash = &orig->pub_key_hash; |
156 | */ | 218 | } |
157 | struct GNUNET_CRYPTO_EddsaSignature signature; | 219 | else |
158 | 220 | { | |
159 | /** | 221 | struct GNUNET_MULTICAST_Member *mem = (struct GNUNET_MULTICAST_Member *) grp; |
160 | * Purpose for the signature and size of the signed data. | 222 | hash = &mem->group_key_hash; |
161 | */ | 223 | } |
162 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
163 | 224 | ||
164 | /** | 225 | if (origins != NULL) |
165 | * Public key of the target group. | 226 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, hash, message_callback, |
166 | */ | 227 | (void *) msg); |
167 | struct GNUNET_CRYPTO_EddsaPublicKey group_key; | 228 | if (members != NULL) |
229 | GNUNET_CONTAINER_multihashmap_get_multiple (members, hash, message_callback, | ||
230 | (void *) msg); | ||
231 | } | ||
168 | 232 | ||
169 | /** | ||
170 | * Public key of the joining member. | ||
171 | */ | ||
172 | struct GNUNET_CRYPTO_EddsaPublicKey member_key; | ||
173 | 233 | ||
174 | /** | 234 | /** |
175 | * Peer identity of the joining member. | 235 | * Iterator callback for calling request callbacks of origins. |
176 | */ | 236 | */ |
177 | struct GNUNET_PeerIdentity member_peer; | 237 | static int |
238 | request_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash, | ||
239 | void *origin) | ||
240 | { | ||
241 | const struct GNUNET_MULTICAST_RequestHeader *req = cls; | ||
242 | struct GNUNET_MULTICAST_Origin *orig = origin; | ||
178 | 243 | ||
179 | /* Followed by request body. */ | 244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
180 | }; | 245 | "Calling request callback for a request of type %u and size %u.\n", |
246 | ntohs (req->header.type), ntohs (req->header.size)); | ||
181 | 247 | ||
182 | GNUNET_NETWORK_STRUCT_END | 248 | orig->request_cb (orig->cls, &req->member_key, |
249 | (const struct GNUNET_MessageHeader *) req, 0); | ||
250 | return GNUNET_YES; | ||
251 | } | ||
183 | 252 | ||
184 | 253 | ||
185 | /** | 254 | /** |
186 | * Handle that identifies a join request. | 255 | * Handle a multicast request from the service. |
187 | * | 256 | * |
188 | * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the | 257 | * Call request callbacks of all origins of the destination group. |
189 | * corresponding calls to #GNUNET_MULTICAST_join_decision(). | 258 | * |
259 | * @param grp Destination group of the message. | ||
260 | * @param msg The message. | ||
190 | */ | 261 | */ |
191 | struct GNUNET_MULTICAST_JoinHandle | 262 | static void |
263 | handle_multicast_request (const struct GNUNET_HashCode *group_key_hash, | ||
264 | const struct GNUNET_MULTICAST_RequestHeader *req) | ||
192 | { | 265 | { |
193 | }; | 266 | if (NULL != origins) |
267 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, group_key_hash, | ||
268 | request_callback, (void *) req); | ||
269 | } | ||
194 | 270 | ||
195 | 271 | ||
196 | /** | 272 | /** |
@@ -227,14 +303,6 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh, | |||
227 | 303 | ||
228 | 304 | ||
229 | /** | 305 | /** |
230 | * Handle to pass back for the answer of a membership test. | ||
231 | */ | ||
232 | struct GNUNET_MULTICAST_MembershipTestHandle | ||
233 | { | ||
234 | }; | ||
235 | |||
236 | |||
237 | /** | ||
238 | * Call informing multicast about the decision taken for a membership test. | 306 | * Call informing multicast about the decision taken for a membership test. |
239 | * | 307 | * |
240 | * @param mth Handle that was given for the query. | 308 | * @param mth Handle that was given for the query. |
@@ -249,14 +317,6 @@ GNUNET_MULTICAST_membership_test_result (struct GNUNET_MULTICAST_MembershipTestH | |||
249 | 317 | ||
250 | 318 | ||
251 | /** | 319 | /** |
252 | * Opaque handle to a replay request from the multicast service. | ||
253 | */ | ||
254 | struct GNUNET_MULTICAST_ReplayHandle | ||
255 | { | ||
256 | }; | ||
257 | |||
258 | |||
259 | /** | ||
260 | * Replay a message fragment for the multicast group. | 320 | * Replay a message fragment for the multicast group. |
261 | * | 321 | * |
262 | * @param rh Replay handle identifying which replay operation was requested. | 322 | * @param rh Replay handle identifying which replay operation was requested. |
@@ -340,6 +400,7 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
340 | void *cls) | 400 | void *cls) |
341 | { | 401 | { |
342 | struct GNUNET_MULTICAST_Origin *orig = GNUNET_malloc (sizeof (*orig)); | 402 | struct GNUNET_MULTICAST_Origin *orig = GNUNET_malloc (sizeof (*orig)); |
403 | orig->grp.is_origin = GNUNET_YES; | ||
343 | orig->priv_key = *priv_key; | 404 | orig->priv_key = *priv_key; |
344 | orig->next_fragment_id = next_fragment_id; | 405 | orig->next_fragment_id = next_fragment_id; |
345 | orig->join_cb = join_cb; | 406 | orig->join_cb = join_cb; |
@@ -349,11 +410,38 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
349 | orig->request_cb = request_cb; | 410 | orig->request_cb = request_cb; |
350 | orig->message_cb = message_cb; | 411 | orig->message_cb = message_cb; |
351 | orig->cls = cls; | 412 | orig->cls = cls; |
413 | |||
414 | GNUNET_CRYPTO_eddsa_key_get_public (&orig->priv_key, &orig->pub_key); | ||
415 | GNUNET_CRYPTO_hash (&orig->pub_key, sizeof (orig->pub_key), | ||
416 | &orig->pub_key_hash); | ||
417 | |||
418 | if (NULL == origins) | ||
419 | origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | ||
420 | |||
421 | GNUNET_CONTAINER_multihashmap_put (origins, &orig->pub_key_hash, orig, | ||
422 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
423 | |||
424 | /* FIXME: send ORIGIN_START to service */ | ||
425 | |||
352 | return orig; | 426 | return orig; |
353 | } | 427 | } |
354 | 428 | ||
355 | 429 | ||
356 | /* FIXME: for now just send back to the client what it sent. */ | 430 | /** |
431 | * Stop a multicast group. | ||
432 | * | ||
433 | * @param origin Multicast group to stop. | ||
434 | */ | ||
435 | void | ||
436 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *orig) | ||
437 | { | ||
438 | GNUNET_CONTAINER_multihashmap_remove (origins, &orig->pub_key_hash, orig); | ||
439 | GNUNET_free (orig); | ||
440 | } | ||
441 | |||
442 | |||
443 | /* FIXME: for now just call clients' callbacks | ||
444 | * without sending anything to multicast. */ | ||
357 | static void | 445 | static void |
358 | schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 446 | schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
359 | { | 447 | { |
@@ -371,7 +459,7 @@ schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
371 | || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size) | 459 | || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size) |
372 | { | 460 | { |
373 | LOG (GNUNET_ERROR_TYPE_ERROR, | 461 | LOG (GNUNET_ERROR_TYPE_ERROR, |
374 | "MasterTransmitNotify() returned error or invalid message size.\n"); | 462 | "OriginTransmitNotify() returned error or invalid message size.\n"); |
375 | /* FIXME: handle error */ | 463 | /* FIXME: handle error */ |
376 | return; | 464 | return; |
377 | } | 465 | } |
@@ -401,19 +489,18 @@ schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
401 | return; | 489 | return; |
402 | } | 490 | } |
403 | 491 | ||
404 | /* FIXME: send msg to the service and only then call message_cb with the | 492 | /* FIXME: send msg to the service and only then call handle_multicast_message |
405 | * returned signed message. | 493 | * with the returned signed message. |
406 | * FIXME: Also send to local members in this group. | ||
407 | */ | 494 | */ |
408 | orig->message_cb (orig->cls, (const struct GNUNET_MessageHeader *) msg); | 495 | handle_multicast_message (&orig->grp, msg); |
409 | 496 | ||
410 | if (GNUNET_NO == ret) | 497 | if (GNUNET_NO == ret) |
411 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 498 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
412 | (GNUNET_TIME_UNIT_SECONDS, 1), | 499 | (GNUNET_TIME_UNIT_SECONDS, 1), |
413 | schedule_origin_to_all, orig); | 500 | schedule_origin_to_all, orig); |
414 | |||
415 | } | 501 | } |
416 | 502 | ||
503 | |||
417 | /** | 504 | /** |
418 | * Send a message to the multicast group. | 505 | * Send a message to the multicast group. |
419 | * | 506 | * |
@@ -439,6 +526,7 @@ GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin, | |||
439 | mh->notify = notify; | 526 | mh->notify = notify; |
440 | mh->notify_cls = notify_cls; | 527 | mh->notify_cls = notify_cls; |
441 | 528 | ||
529 | /* FIXME: remove delay, it's there only for testing */ | ||
442 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 530 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
443 | (GNUNET_TIME_UNIT_SECONDS, 1), | 531 | (GNUNET_TIME_UNIT_SECONDS, 1), |
444 | schedule_origin_to_all, origin); | 532 | schedule_origin_to_all, origin); |
@@ -470,18 +558,6 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHand | |||
470 | 558 | ||
471 | 559 | ||
472 | /** | 560 | /** |
473 | * Stop a multicast group. | ||
474 | * | ||
475 | * @param origin Multicast group to stop. | ||
476 | */ | ||
477 | void | ||
478 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin) | ||
479 | { | ||
480 | GNUNET_free (origin); | ||
481 | } | ||
482 | |||
483 | |||
484 | /** | ||
485 | * Join a multicast group. | 561 | * Join a multicast group. |
486 | * | 562 | * |
487 | * The entity joining is always the local peer. Further information about the | 563 | * The entity joining is always the local peer. Further information about the |
@@ -531,24 +607,61 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
531 | const struct GNUNET_PeerIdentity *relays, | 607 | const struct GNUNET_PeerIdentity *relays, |
532 | const struct GNUNET_MessageHeader *join_request, | 608 | const struct GNUNET_MessageHeader *join_request, |
533 | GNUNET_MULTICAST_JoinCallback join_cb, | 609 | GNUNET_MULTICAST_JoinCallback join_cb, |
534 | GNUNET_MULTICAST_MembershipTestCallback mem_test_cb, | 610 | GNUNET_MULTICAST_MembershipTestCallback member_test_cb, |
535 | GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, | 611 | GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, |
536 | GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, | 612 | GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, |
537 | GNUNET_MULTICAST_MessageCallback message_cb, | 613 | GNUNET_MULTICAST_MessageCallback message_cb, |
538 | void *cls) | 614 | void *cls) |
539 | { | 615 | { |
540 | struct GNUNET_MULTICAST_Member *mem = GNUNET_malloc (sizeof (*mem)); | 616 | struct GNUNET_MULTICAST_Member *mem = GNUNET_malloc (sizeof (*mem)); |
617 | mem->group_key = *group_key; | ||
618 | mem->member_key = *member_key; | ||
619 | mem->origin = *origin; | ||
620 | mem->relay_count = relay_count; | ||
621 | mem->relays = *relays; | ||
622 | mem->join_cb = join_cb; | ||
623 | mem->member_test_cb = member_test_cb; | ||
624 | mem->replay_frag_cb = replay_frag_cb; | ||
625 | mem->message_cb = message_cb; | ||
626 | mem->cls = cls; | ||
627 | |||
628 | if (NULL != join_request) | ||
629 | { | ||
630 | uint16_t size = ntohs (join_request->size); | ||
631 | mem->join_request = GNUNET_malloc (size); | ||
632 | memcpy (mem->join_request, join_request, size); | ||
633 | } | ||
634 | |||
635 | GNUNET_CRYPTO_hash (&mem->group_key, sizeof (mem->group_key), &mem->group_key_hash); | ||
636 | |||
637 | if (NULL == members) | ||
638 | members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | ||
639 | |||
640 | GNUNET_CONTAINER_multihashmap_put (members, &mem->group_key_hash, mem, | ||
641 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
642 | |||
643 | /* FIXME: send MEMBER_JOIN to service */ | ||
541 | 644 | ||
542 | return mem; | 645 | return mem; |
543 | } | 646 | } |
544 | 647 | ||
545 | 648 | ||
546 | /** | 649 | /** |
547 | * Handle for a replay request. | 650 | * Part a multicast group. |
651 | * | ||
652 | * Disconnects from all group members and invalidates the @a member handle. | ||
653 | * | ||
654 | * An application-dependent part message can be transmitted beforehand using | ||
655 | * #GNUNET_MULTICAST_member_to_origin()) | ||
656 | * | ||
657 | * @param member Membership handle. | ||
548 | */ | 658 | */ |
549 | struct GNUNET_MULTICAST_MemberReplayHandle | 659 | void |
660 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem) | ||
550 | { | 661 | { |
551 | }; | 662 | GNUNET_CONTAINER_multihashmap_remove (members, &mem->group_key_hash, mem); |
663 | GNUNET_free (mem); | ||
664 | } | ||
552 | 665 | ||
553 | 666 | ||
554 | /** | 667 | /** |
@@ -612,20 +725,62 @@ GNUNET_MULTICAST_member_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandl | |||
612 | } | 725 | } |
613 | 726 | ||
614 | 727 | ||
615 | /** | 728 | /* FIXME: for now just send back to the client what it sent. */ |
616 | * Part a multicast group. | 729 | static void |
617 | * | 730 | schedule_member_to_origin (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
618 | * Disconnects from all group members and invalidates the @a member handle. | ||
619 | * | ||
620 | * An application-dependent part message can be transmitted beforehand using | ||
621 | * #GNUNET_MULTICAST_member_to_origin()) | ||
622 | * | ||
623 | * @param member Membership handle. | ||
624 | */ | ||
625 | void | ||
626 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member) | ||
627 | { | 731 | { |
628 | GNUNET_free (member); | 732 | LOG (GNUNET_ERROR_TYPE_DEBUG, "schedule_member_to_origin()\n"); |
733 | struct GNUNET_MULTICAST_Member *mem = cls; | ||
734 | struct GNUNET_MULTICAST_MemberRequestHandle *rh = &mem->req_handle; | ||
735 | |||
736 | size_t buf_size = GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD; | ||
737 | char buf[GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD] = ""; | ||
738 | struct GNUNET_MULTICAST_RequestHeader *req | ||
739 | = (struct GNUNET_MULTICAST_RequestHeader *) buf; | ||
740 | int ret = rh->notify (rh->notify_cls, &buf_size, &req[1]); | ||
741 | |||
742 | if (! (GNUNET_YES == ret || GNUNET_NO == ret) | ||
743 | || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size) | ||
744 | { | ||
745 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
746 | "MemberTransmitNotify() returned error or invalid message size.\n"); | ||
747 | /* FIXME: handle error */ | ||
748 | return; | ||
749 | } | ||
750 | |||
751 | if (GNUNET_NO == ret && 0 == buf_size) | ||
752 | return; /* Transmission paused. */ | ||
753 | |||
754 | req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST); | ||
755 | req->header.size = htons (sizeof (*req) + buf_size); | ||
756 | req->request_id = GNUNET_htonll (rh->request_id); | ||
757 | |||
758 | /* FIXME: add fragment ID and signature in the service instead of here */ | ||
759 | req->fragment_id = GNUNET_ntohll (mem->next_fragment_id++); | ||
760 | req->fragment_offset = GNUNET_ntohll (rh->fragment_offset); | ||
761 | rh->fragment_offset += sizeof (*req) + buf_size; | ||
762 | req->purpose.size = htonl (sizeof (*req) + buf_size | ||
763 | - sizeof (req->header) | ||
764 | - sizeof (req->member_key) | ||
765 | - sizeof (req->signature)); | ||
766 | req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE); | ||
767 | |||
768 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_sign (&mem->member_key, &req->purpose, | ||
769 | &req->signature)) | ||
770 | { | ||
771 | /* FIXME: handle error */ | ||
772 | return; | ||
773 | } | ||
774 | |||
775 | /* FIXME: send req to the service and only then call handle_multicast_request | ||
776 | * with the returned request. | ||
777 | */ | ||
778 | handle_multicast_request (&mem->group_key_hash, req); | ||
779 | |||
780 | if (GNUNET_NO == ret) | ||
781 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
782 | (GNUNET_TIME_UNIT_SECONDS, 1), | ||
783 | schedule_member_to_origin, mem); | ||
629 | } | 784 | } |
630 | 785 | ||
631 | 786 | ||
@@ -633,18 +788,28 @@ GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member) | |||
633 | * Send a message to the origin of the multicast group. | 788 | * Send a message to the origin of the multicast group. |
634 | * | 789 | * |
635 | * @param member Membership handle. | 790 | * @param member Membership handle. |
636 | * @param message_id Application layer ID for the message. Opaque to multicast. | 791 | * @param request_id Application layer ID for the request. Opaque to multicast. |
637 | * @param notify Callback to call to get the message. | 792 | * @param notify Callback to call to get the message. |
638 | * @param notify_cls Closure for @a notify. | 793 | * @param notify_cls Closure for @a notify. |
639 | * @return Handle to cancel request, NULL on error (i.e. request already pending). | 794 | * @return Handle to cancel request, NULL on error (i.e. request already pending). |
640 | */ | 795 | */ |
641 | struct GNUNET_MULTICAST_MemberRequestHandle * | 796 | struct GNUNET_MULTICAST_MemberRequestHandle * |
642 | GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member, | 797 | GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member, |
643 | uint64_t message_id, | 798 | uint64_t request_id, |
644 | GNUNET_MULTICAST_MemberTransmitNotify notify, | 799 | GNUNET_MULTICAST_MemberTransmitNotify notify, |
645 | void *notify_cls) | 800 | void *notify_cls) |
646 | { | 801 | { |
647 | return NULL; | 802 | struct GNUNET_MULTICAST_MemberRequestHandle *rh = &member->req_handle; |
803 | rh->member = member; | ||
804 | rh->request_id = request_id; | ||
805 | rh->notify = notify; | ||
806 | rh->notify_cls = notify_cls; | ||
807 | |||
808 | /* FIXME: remove delay, it's there only for testing */ | ||
809 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
810 | (GNUNET_TIME_UNIT_SECONDS, 1), | ||
811 | schedule_member_to_origin, member); | ||
812 | return &member->req_handle; | ||
648 | } | 813 | } |
649 | 814 | ||
650 | 815 | ||