diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-05-16 13:15:30 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-05-16 13:15:30 +0000 |
commit | f1d701c55b497773d7abda7b75c97012c0abab28 (patch) | |
tree | 4b8ae8f43d9e8826267b0293ba1bd2fe11ae03d5 /src/mesh/mesh_api_new.c | |
parent | 480f5966b1e07e53fc07bdc2adc556352b82eec9 (diff) | |
download | gnunet-f1d701c55b497773d7abda7b75c97012c0abab28.tar.gz gnunet-f1d701c55b497773d7abda7b75c97012c0abab28.zip |
WiP
Diffstat (limited to 'src/mesh/mesh_api_new.c')
-rw-r--r-- | src/mesh/mesh_api_new.c | 204 |
1 files changed, 164 insertions, 40 deletions
diff --git a/src/mesh/mesh_api_new.c b/src/mesh/mesh_api_new.c index c435f878a..e466bca94 100644 --- a/src/mesh/mesh_api_new.c +++ b/src/mesh/mesh_api_new.c | |||
@@ -22,6 +22,13 @@ | |||
22 | * @file mesh/mesh_api_new.c | 22 | * @file mesh/mesh_api_new.c |
23 | * @brief mesh api: client implementation of mesh service | 23 | * @brief mesh api: client implementation of mesh service |
24 | * @author Bartlomiej Polot | 24 | * @author Bartlomiej Polot |
25 | * | ||
26 | * STRUCTURE: | ||
27 | * - CONSTANTS | ||
28 | * - DATA STRUCTURES | ||
29 | * - SEND CALLBACKS | ||
30 | * - RECEIVE HANDLERS | ||
31 | * - API CALL DEFINITIONS | ||
25 | */ | 32 | */ |
26 | 33 | ||
27 | #ifdef __cplusplus | 34 | #ifdef __cplusplus |
@@ -41,6 +48,16 @@ extern "C" | |||
41 | #include "gnunet_mesh_service_new.h" | 48 | #include "gnunet_mesh_service_new.h" |
42 | #include "mesh.h" | 49 | #include "mesh.h" |
43 | 50 | ||
51 | /******************************************************************************/ | ||
52 | /************************** CONSTANTS ******************************/ | ||
53 | /******************************************************************************/ | ||
54 | |||
55 | #define GNUNET_MESH_LOCAL_TUNNEL_ID_MARK 0x80000000 | ||
56 | |||
57 | /******************************************************************************/ | ||
58 | /************************ DATA STRUCTURES ****************************/ | ||
59 | /******************************************************************************/ | ||
60 | |||
44 | /** | 61 | /** |
45 | * Opaque handle to the service. | 62 | * Opaque handle to the service. |
46 | */ | 63 | */ |
@@ -68,8 +85,13 @@ struct GNUNET_MESH_Handle { | |||
68 | /** | 85 | /** |
69 | * Double linked list of the tunnels this client is connected to. | 86 | * Double linked list of the tunnels this client is connected to. |
70 | */ | 87 | */ |
71 | struct GNUNET_MESH_Tunnel *head; | 88 | struct GNUNET_MESH_Tunnel *tunnels_head; |
72 | struct GNUNET_MESH_Tunnel *tail; | 89 | struct GNUNET_MESH_Tunnel *tunnels_tail; |
90 | |||
91 | /** | ||
92 | * tid of the next tunnel to create (to avoid reusing IDs often) | ||
93 | */ | ||
94 | MESH_TunnelID next_tid; | ||
73 | 95 | ||
74 | /** | 96 | /** |
75 | * Callback for tunnel disconnection | 97 | * Callback for tunnel disconnection |
@@ -91,12 +113,24 @@ struct GNUNET_MESH_Handle { | |||
91 | * Opaque handle to a tunnel. | 113 | * Opaque handle to a tunnel. |
92 | */ | 114 | */ |
93 | struct GNUNET_MESH_Tunnel { | 115 | struct GNUNET_MESH_Tunnel { |
116 | |||
117 | /** | ||
118 | * DLL | ||
119 | */ | ||
120 | struct GNUNET_MESH_Tunnel *next; | ||
121 | struct GNUNET_MESH_Tunnel *prev; | ||
122 | |||
94 | /** | 123 | /** |
95 | * Owner of the tunnel, either local or remote | 124 | * Owner of the tunnel, either local or remote |
96 | */ | 125 | */ |
97 | GNUNET_PEER_Id owner; | 126 | GNUNET_PEER_Id owner; |
98 | 127 | ||
99 | /** | 128 | /** |
129 | * Local ID of the tunnel | ||
130 | */ | ||
131 | MESH_TunnelID tid; | ||
132 | |||
133 | /** | ||
100 | * Callback to execute when peers connect to the tunnel | 134 | * Callback to execute when peers connect to the tunnel |
101 | */ | 135 | */ |
102 | GNUNET_MESH_TunnelConnectHandler connect_handler; | 136 | GNUNET_MESH_TunnelConnectHandler connect_handler; |
@@ -126,15 +160,44 @@ struct GNUNET_MESH_TransmitHandle { | |||
126 | // TODO | 160 | // TODO |
127 | }; | 161 | }; |
128 | 162 | ||
163 | /******************************************************************************/ | ||
164 | /*********************** AUXILIARY FUNCTIONS *************************/ | ||
165 | /******************************************************************************/ | ||
129 | 166 | ||
130 | /** | 167 | /** |
131 | * Function called to notify a client about the socket begin ready to queue more | 168 | * Get the tunnel handler for the tunnel specified by id from the given handle |
132 | * data. "buf" will be NULL and "size" zero if the socket was closed for | 169 | * @param h Mesh handle |
133 | * writing in the meantime. | 170 | * @param tid ID of the wanted tunnel |
171 | * @return handle to the required tunnel or NULL if not found | ||
172 | */ | ||
173 | static struct GNUNET_MESH_Tunnel * | ||
174 | retrieve_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelID tid) | ||
175 | { | ||
176 | struct GNUNET_MESH_Tunnel *t; | ||
177 | |||
178 | t = h->tunnels_head; | ||
179 | while (t != NULL) { | ||
180 | if (t->tid == tid) return t; | ||
181 | t = t->next; | ||
182 | } | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | |||
187 | /******************************************************************************/ | ||
188 | /************************ SEND CALLBACKS ****************************/ | ||
189 | /******************************************************************************/ | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Function called to send a connect message to the service, specifying the | ||
194 | * types and applications that the client is interested in. | ||
195 | * "buf" will be NULL and "size" zero if the socket was closed for writing in | ||
196 | * the meantime. | ||
134 | * | 197 | * |
135 | * @param cls closure | 198 | * @param cls closure, the mesh handle |
136 | * @param size number of bytes available in buf | 199 | * @param size number of bytes available in buf |
137 | * @param buf where the callee should write the message | 200 | * @param buf where the callee should write the connect message |
138 | * @return number of bytes written to buf | 201 | * @return number of bytes written to buf |
139 | */ | 202 | */ |
140 | static size_t | 203 | static size_t |
@@ -200,13 +263,14 @@ send_connect_packet (void *cls, size_t size, void *buf) | |||
200 | 263 | ||
201 | 264 | ||
202 | /** | 265 | /** |
203 | * Function called to notify a client about the socket begin ready to queue more | 266 | * Function called to send a create tunnel message, specifying the tunnel |
204 | * data. "buf" will be NULL and "size" zero if the socket was closed for | 267 | * number chosen by the client. |
268 | * "buf" will be NULL and "size" zero if the socket was closed for | ||
205 | * writing in the meantime. | 269 | * writing in the meantime. |
206 | * | 270 | * |
207 | * @param cls closure | 271 | * @param cls closure, the tunnel handle |
208 | * @param size number of bytes available in buf | 272 | * @param size number of bytes available in buf |
209 | * @param buf where the callee should write the message | 273 | * @param buf where the callee should write the create tunnel message |
210 | * @return number of bytes written to buf | 274 | * @return number of bytes written to buf |
211 | */ | 275 | */ |
212 | static size_t | 276 | static size_t |
@@ -237,6 +301,7 @@ send_tunnel_create_packet (void *cls, size_t size, void *buf) | |||
237 | msg->header.type = htons(GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT); | 301 | msg->header.type = htons(GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT); |
238 | 302 | ||
239 | msg->header.size = htons(sizeof(struct GNUNET_MESH_TunnelMessage)); | 303 | msg->header.size = htons(sizeof(struct GNUNET_MESH_TunnelMessage)); |
304 | msg->tunnel_id = htonl(t->tid); | ||
240 | 305 | ||
241 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 306 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
242 | "Sent %lu bytes long message\n", | 307 | "Sent %lu bytes long message\n", |
@@ -246,21 +311,94 @@ send_tunnel_create_packet (void *cls, size_t size, void *buf) | |||
246 | } | 311 | } |
247 | 312 | ||
248 | 313 | ||
314 | /******************************************************************************/ | ||
315 | /*********************** RECEIVE HANDLERS ****************************/ | ||
316 | /******************************************************************************/ | ||
317 | |||
249 | /** | 318 | /** |
250 | * Type of a function to call when we receive a message | 319 | * Process the new tunnel notification and add it to the tunnels in the handle |
251 | * from the service. | 320 | * |
321 | * @param h The mesh handle | ||
322 | * @param msh A message with the details of the new incoming tunnel | ||
323 | */ | ||
324 | static void | ||
325 | process_tunnel_create(struct GNUNET_MESH_Handle *h, | ||
326 | const struct GNUNET_MESH_TunnelMessage *msg) | ||
327 | { | ||
328 | struct GNUNET_MESH_Tunnel *t; | ||
329 | MESH_TunnelID tid; | ||
330 | |||
331 | tid = ntohl(msg->tunnel_id); | ||
332 | if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_MARK) { | ||
333 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
334 | "MESH: received an incoming tunnel with tid in local range (%X)\n", | ||
335 | tid); | ||
336 | return; //FIXME abort? reconnect? | ||
337 | } | ||
338 | t = GNUNET_malloc(sizeof(struct GNUNET_MESH_Tunnel)); | ||
339 | t->cls = h->cls; | ||
340 | t->connect_handler = NULL; | ||
341 | t->disconnect_handler = NULL; | ||
342 | t->mesh = h; | ||
343 | t->tid = tid; | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Process the incoming data packets | ||
350 | * | ||
351 | * @param h The mesh handle | ||
352 | * @param msh A message encapsulating the data | ||
353 | */ | ||
354 | static void | ||
355 | process_incoming_data(struct GNUNET_MESH_Handle *h, | ||
356 | const struct GNUNET_MESH_Data *msg) | ||
357 | { | ||
358 | const struct GNUNET_MESH_Data *payload; | ||
359 | const struct GNUNET_MESH_MessageHandler *handler; | ||
360 | struct GNUNET_MESH_Tunnel *t; | ||
361 | uint16_t type; | ||
362 | int i; | ||
363 | |||
364 | t = retrieve_tunnel(h, ntohl(msg->tunnel_id)); | ||
365 | |||
366 | payload = (struct GNUNET_MESH_Data *) &msg[1]; | ||
367 | type = ntohs(payload->header.type); | ||
368 | for (i = 0; i < h->n_handlers; i++) { | ||
369 | handler = &h->message_handlers[i]; | ||
370 | if (handler->type == type) { | ||
371 | /* FIXME */ | ||
372 | if (GNUNET_OK == handler->callback (h->cls, | ||
373 | t, | ||
374 | NULL, | ||
375 | NULL, | ||
376 | NULL, | ||
377 | NULL)) | ||
378 | { | ||
379 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
380 | "MESH: callback completed successfully\n"); | ||
381 | } else { | ||
382 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
383 | "MESH: callback caused disconnection\n"); | ||
384 | GNUNET_MESH_disconnect(h); | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Function to process all messages received from the service | ||
252 | * | 394 | * |
253 | * @param cls closure | 395 | * @param cls closure |
254 | * @param msg message received, NULL on timeout or fatal error | 396 | * @param msg message received, NULL on timeout or fatal error |
255 | */ | 397 | */ |
256 | void | 398 | static void |
257 | msg_received (void *cls, const struct GNUNET_MessageHeader * msg) | 399 | msg_received (void *cls, const struct GNUNET_MessageHeader * msg) |
258 | { | 400 | { |
259 | struct GNUNET_MESH_Handle *h = cls; | 401 | struct GNUNET_MESH_Handle *h = cls; |
260 | const struct GNUNET_MessageHeader *payload; | ||
261 | const struct GNUNET_MESH_MessageHandler *handler; | ||
262 | uint16_t type; | ||
263 | int i; | ||
264 | 402 | ||
265 | if (msg == NULL) { | 403 | if (msg == NULL) { |
266 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 404 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
@@ -271,7 +409,7 @@ msg_received (void *cls, const struct GNUNET_MessageHeader * msg) | |||
271 | switch (ntohs(msg->type)) { | 409 | switch (ntohs(msg->type)) { |
272 | /* Notify of a new incoming tunnel */ | 410 | /* Notify of a new incoming tunnel */ |
273 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE: | 411 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE: |
274 | /* */ | 412 | process_tunnel_create(h, (struct GNUNET_MESH_TunnelMessage *)msg); |
275 | break; | 413 | break; |
276 | /* Notify of a new peer in the tunnel */ | 414 | /* Notify of a new peer in the tunnel */ |
277 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_CONNECTED: | 415 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_CONNECTED: |
@@ -281,27 +419,7 @@ msg_received (void *cls, const struct GNUNET_MessageHeader * msg) | |||
281 | break; | 419 | break; |
282 | /* Notify of a new data packet in the tunnel */ | 420 | /* Notify of a new data packet in the tunnel */ |
283 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA: | 421 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA: |
284 | payload = &msg[1]; | 422 | process_incoming_data(h, (struct GNUNET_MESH_Data *)msg); |
285 | for (i = 0, type = ntohs(payload->type); i < h->n_handlers; i++) { | ||
286 | handler = &h->message_handlers[i]; | ||
287 | if (handler->type == type) { | ||
288 | /* FIXME */ | ||
289 | if (GNUNET_OK == handler->callback (h->cls, | ||
290 | NULL, | ||
291 | NULL, | ||
292 | NULL, | ||
293 | NULL, | ||
294 | NULL)) | ||
295 | { | ||
296 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
297 | "MESH: callback completed successfully\n"); | ||
298 | } else { | ||
299 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
300 | "MESH: callback caused disconnection\n"); | ||
301 | GNUNET_MESH_disconnect(h); | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | break; | 423 | break; |
306 | /* We shouldn't get any other packages, log and ignore */ | 424 | /* We shouldn't get any other packages, log and ignore */ |
307 | default: | 425 | default: |
@@ -319,6 +437,9 @@ msg_received (void *cls, const struct GNUNET_MessageHeader * msg) | |||
319 | return; | 437 | return; |
320 | } | 438 | } |
321 | 439 | ||
440 | /******************************************************************************/ | ||
441 | /********************** API CALL DEFINITIONS *************************/ | ||
442 | /******************************************************************************/ | ||
322 | 443 | ||
323 | /** | 444 | /** |
324 | * Connect to the mesh service. | 445 | * Connect to the mesh service. |
@@ -361,6 +482,7 @@ GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
361 | h->cls = cls; | 482 | h->cls = cls; |
362 | h->message_handlers = handlers; | 483 | h->message_handlers = handlers; |
363 | h->applications = stypes; | 484 | h->applications = stypes; |
485 | h->next_tid = 0x80000000; | ||
364 | 486 | ||
365 | for(h->n_handlers = 0; handlers[h->n_handlers].type; h->n_handlers++); | 487 | for(h->n_handlers = 0; handlers[h->n_handlers].type; h->n_handlers++); |
366 | for(h->n_applications = 0; stypes[h->n_applications]; h->n_applications++); | 488 | for(h->n_applications = 0; stypes[h->n_applications]; h->n_applications++); |
@@ -425,6 +547,8 @@ GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, | |||
425 | tunnel->disconnect_handler = disconnect_handler; | 547 | tunnel->disconnect_handler = disconnect_handler; |
426 | tunnel->cls = handler_cls; | 548 | tunnel->cls = handler_cls; |
427 | tunnel->mesh = h; | 549 | tunnel->mesh = h; |
550 | tunnel->tid = h->next_tid++; | ||
551 | h->next_tid |= GNUNET_MESH_LOCAL_TUNNEL_ID_MARK; // keep in range | ||
428 | 552 | ||
429 | h->th = GNUNET_CLIENT_notify_transmit_ready(h->client, | 553 | h->th = GNUNET_CLIENT_notify_transmit_ready(h->client, |
430 | sizeof(struct GNUNET_MESH_TunnelMessage), | 554 | sizeof(struct GNUNET_MESH_TunnelMessage), |