aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/mesh_api_new.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-05-16 13:15:30 +0000
committerBart Polot <bart@net.in.tum.de>2011-05-16 13:15:30 +0000
commitf1d701c55b497773d7abda7b75c97012c0abab28 (patch)
tree4b8ae8f43d9e8826267b0293ba1bd2fe11ae03d5 /src/mesh/mesh_api_new.c
parent480f5966b1e07e53fc07bdc2adc556352b82eec9 (diff)
downloadgnunet-f1d701c55b497773d7abda7b75c97012c0abab28.tar.gz
gnunet-f1d701c55b497773d7abda7b75c97012c0abab28.zip
WiP
Diffstat (limited to 'src/mesh/mesh_api_new.c')
-rw-r--r--src/mesh/mesh_api_new.c204
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 */
93struct GNUNET_MESH_Tunnel { 115struct 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 */
173static struct GNUNET_MESH_Tunnel *
174retrieve_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 */
140static size_t 203static 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 */
212static size_t 276static 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 */
324static void
325process_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 */
354static void
355process_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 */
256void 398static void
257msg_received (void *cls, const struct GNUNET_MessageHeader * msg) 399msg_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),