aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_unix.c')
-rw-r--r--src/transport/plugin_transport_unix.c363
1 files changed, 206 insertions, 157 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 03c38f4e1..881a4b9ff 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2010, 2013 Christian Grothoff (and other contributing authors) 3 (C) 2010-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -62,11 +62,22 @@ enum UNIX_ADDRESS_OPTIONS
62 62
63GNUNET_NETWORK_STRUCT_BEGIN 63GNUNET_NETWORK_STRUCT_BEGIN
64 64
65/**
66 * Binary format for an UNIX Domain Socket address in GNUnet.
67 */
65struct UnixAddress 68struct UnixAddress
66{ 69{
70 /**
71 * Options to use for the address, in NBO
72 */
67 uint32_t options GNUNET_PACKED; 73 uint32_t options GNUNET_PACKED;
68 74
75 /**
76 * Length of the address (path length), in NBO
77 */
69 uint32_t addrlen GNUNET_PACKED; 78 uint32_t addrlen GNUNET_PACKED;
79
80 /* followed by actual path */
70}; 81};
71 82
72 83
@@ -88,15 +99,28 @@ struct UNIXMessage
88}; 99};
89 100
90GNUNET_NETWORK_STRUCT_END 101GNUNET_NETWORK_STRUCT_END
102
91/** 103/**
92 * Handle for a session. 104 * Handle for a session.
93 */ 105 */
94struct Session 106struct Session
95{ 107{
108 /**
109 * To whom are we talking to (set to our identity
110 * if we are still waiting for the welcome message).
111 *
112 * FIXME: information duplicated with 'peer' in address!
113 */
96 struct GNUNET_PeerIdentity target; 114 struct GNUNET_PeerIdentity target;
97 115
98 struct Plugin * plugin; 116 /**
117 * Pointer to the global plugin struct.
118 */
119 struct Plugin *plugin;
99 120
121 /**
122 * Address of the other peer.
123 */
100 struct GNUNET_HELLO_Address *address; 124 struct GNUNET_HELLO_Address *address;
101 125
102 /** 126 /**
@@ -106,6 +130,9 @@ struct Session
106}; 130};
107 131
108 132
133/**
134 *
135 */
109struct UNIXMessageWrapper 136struct UNIXMessageWrapper
110{ 137{
111 /** 138 /**
@@ -121,7 +148,7 @@ struct UNIXMessageWrapper
121 /** 148 /**
122 * The actual payload (allocated separately right now). 149 * The actual payload (allocated separately right now).
123 */ 150 */
124 struct UNIXMessage * msg; 151 struct UNIXMessage *msg;
125 152
126 /** 153 /**
127 * Session this message belongs to. 154 * Session this message belongs to.
@@ -134,7 +161,7 @@ struct UNIXMessageWrapper
134 GNUNET_TRANSPORT_TransmitContinuation cont; 161 GNUNET_TRANSPORT_TransmitContinuation cont;
135 162
136 /** 163 /**
137 * Closure for 'cont'. 164 * Closure for @e cont.
138 */ 165 */
139 void *cont_cls; 166 void *cont_cls;
140 167
@@ -144,12 +171,12 @@ struct UNIXMessageWrapper
144 struct GNUNET_TIME_Absolute timeout; 171 struct GNUNET_TIME_Absolute timeout;
145 172
146 /** 173 /**
147 * Number of bytes in 'msg'. 174 * Number of bytes in @e msg.
148 */ 175 */
149 size_t msgsize; 176 size_t msgsize;
150 177
151 /** 178 /**
152 * Number of bytes of payload encapsulated in 'msg'. 179 * Number of bytes of payload encapsulated in @e msg.
153 */ 180 */
154 size_t payload; 181 size_t payload;
155 182
@@ -167,58 +194,6 @@ struct Plugin;
167 194
168 195
169/** 196/**
170 * UNIX "Session"
171 */
172struct PeerSession
173{
174
175 /**
176 * Stored in a linked list.
177 */
178 struct PeerSession *next;
179
180 /**
181 * Pointer to the global plugin struct.
182 */
183 struct Plugin *plugin;
184
185 /**
186 * To whom are we talking to (set to our identity
187 * if we are still waiting for the welcome message)
188 */
189 struct GNUNET_PeerIdentity target;
190
191 /**
192 * Address of the other peer (either based on our 'connect'
193 * call or on our 'accept' call).
194 */
195 void *connect_addr;
196
197 /**
198 * Length of connect_addr.
199 */
200 size_t connect_alen;
201
202 /**
203 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
204 */
205 int expecting_welcome;
206
207 /**
208 * From which socket do we need to send to this peer?
209 */
210 struct GNUNET_NETWORK_Handle *sock;
211
212 /*
213 * Queue of messages for this peer, in the case that
214 * we have to await a connection...
215 */
216 struct MessageQueue *messages;
217
218};
219
220
221/**
222 * Information we keep for each of our listen sockets. 197 * Information we keep for each of our listen sockets.
223 */ 198 */
224struct UNIX_Sock_Info 199struct UNIX_Sock_Info
@@ -264,7 +239,7 @@ struct Plugin
264 struct GNUNET_TRANSPORT_PluginEnvironment *env; 239 struct GNUNET_TRANSPORT_PluginEnvironment *env;
265 240
266 /** 241 /**
267 * Sessions 242 * Sessions (map from peer identity to `struct Session`)
268 */ 243 */
269 struct GNUNET_CONTAINER_MultiPeerMap *session_map; 244 struct GNUNET_CONTAINER_MultiPeerMap *session_map;
270 245
@@ -294,6 +269,16 @@ struct Plugin
294 struct UNIXMessageWrapper *msg_tail; 269 struct UNIXMessageWrapper *msg_tail;
295 270
296 /** 271 /**
272 * Function to call about session status changes.
273 */
274 GNUNET_TRANSPORT_SessionInfoCallback sic;
275
276 /**
277 * Closure for @e sic.
278 */
279 void *sic_cls;
280
281 /**
297 * socket that we transmit all data with 282 * socket that we transmit all data with
298 */ 283 */
299 struct UNIX_Sock_Info unix_sock; 284 struct UNIX_Sock_Info unix_sock;
@@ -303,20 +288,23 @@ struct Plugin
303 */ 288 */
304 uint32_t myoptions; 289 uint32_t myoptions;
305 290
306
307 /** 291 /**
308 * ATS network 292 * ATS network
309 */ 293 */
310 struct GNUNET_ATS_Information ats_network; 294 struct GNUNET_ATS_Information ats_network;
311 295
312 /** 296 /**
313 * Is the write set in the current 'select' task? GNUNET_NO if the 297 * Is the write set in the current 'select' task? #GNUNET_NO if the
314 * write queue was empty when the main task was scheduled, 298 * write queue was empty when the main task was scheduled,
315 * GNUNET_YES if we're already waiting for being allowed to write. 299 * #GNUNET_YES if we're already waiting for being allowed to write.
316 */ 300 */
317 int with_ws; 301 int with_ws;
318 302
303 /**
304 * Are we using an abstract UNIX domain socket?
305 */
319 int abstract; 306 int abstract;
307
320}; 308};
321 309
322 310
@@ -338,9 +326,17 @@ reschedule_session_timeout (struct Session *s);
338 * @param tc the scheduling context (for rescheduling this function again) 326 * @param tc the scheduling context (for rescheduling this function again)
339 */ 327 */
340static void 328static void
341unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 329unix_plugin_select (void *cls,
330 const struct GNUNET_SCHEDULER_TaskContext *tc);
342 331
343 332
333/**
334 * Convert unix path to a `struct sockaddr_un`
335 *
336 * @param unixpath path to convert
337 * @param sock_len[out] set to the length of the address
338 * @return converted unix path
339 */
344static struct sockaddr_un * 340static struct sockaddr_un *
345unix_address_to_sockaddr (const char *unixpath, 341unix_address_to_sockaddr (const char *unixpath,
346 socklen_t *sock_len) 342 socklen_t *sock_len)
@@ -400,7 +396,6 @@ unix_address_to_string (void *cls,
400 GNUNET_break(0); 396 GNUNET_break(0);
401 return NULL; 397 return NULL;
402 } 398 }
403
404 if ('\0' != addrstr[addr_str_len - 1]) 399 if ('\0' != addrstr[addr_str_len - 1])
405 { 400 {
406 GNUNET_break(0); 401 GNUNET_break(0);
@@ -429,13 +424,13 @@ unix_address_to_string (void *cls,
429 424
430 425
431/** 426/**
432 * Re-schedule the main 'select' callback (unix_plugin_select) 427 * Re-schedule the main 'select' callback (#unix_plugin_select())
433 * for this plugin. 428 * for this plugin.
434 * 429 *
435 * @param plugin the plugin context 430 * @param plugin the plugin context
436 */ 431 */
437static void 432static void
438reschedule_select (struct Plugin * plugin) 433reschedule_select (struct Plugin *plugin)
439{ 434{
440 if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) 435 if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
441 { 436 {
@@ -466,7 +461,7 @@ reschedule_select (struct Plugin * plugin)
466 461
467 462
468/** 463/**
469 * Closure to #lookup_session_it. 464 * Closure to #lookup_session_it().
470 */ 465 */
471struct LookupCtx 466struct LookupCtx
472{ 467{
@@ -475,14 +470,17 @@ struct LookupCtx
475 */ 470 */
476 struct Session *res; 471 struct Session *res;
477 472
478 struct GNUNET_HELLO_Address *address; 473 /**
474 * Address we are looking for.
475 */
476 const struct GNUNET_HELLO_Address *address;
479}; 477};
480 478
481 479
482/** 480/**
483 * Function called to find a session by address. 481 * Function called to find a session by address.
484 * 482 *
485 * @param cls the 'struct LookupCtx' 483 * @param cls the `struct LookupCtx *`
486 * @param key peer we are looking for (unused) 484 * @param key peer we are looking for (unused)
487 * @param value a session 485 * @param value a session
488 * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success 486 * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success
@@ -513,7 +511,7 @@ lookup_session_it (void *cls,
513 */ 511 */
514static struct Session * 512static struct Session *
515lookup_session (struct Plugin *plugin, 513lookup_session (struct Plugin *plugin,
516 struct GNUNET_HELLO_Address *address) 514 const struct GNUNET_HELLO_Address *address)
517{ 515{
518 struct LookupCtx lctx; 516 struct LookupCtx lctx;
519 517
@@ -559,7 +557,9 @@ unix_session_disconnect (void *cls,
559 next = msgw->next; 557 next = msgw->next;
560 if (msgw->session != s) 558 if (msgw->session != s)
561 continue; 559 continue;
562 GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw); 560 GNUNET_CONTAINER_DLL_remove (plugin->msg_head,
561 plugin->msg_tail,
562 msgw);
563 if (NULL != msgw->cont) 563 if (NULL != msgw->cont)
564 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, 564 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR,
565 msgw->payload, 0); 565 msgw->payload, 0);
@@ -590,7 +590,7 @@ unix_session_disconnect (void *cls,
590 590
591/** 591/**
592 * Function that is called to get the keepalive factor. 592 * Function that is called to get the keepalive factor.
593 * GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to 593 * #GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to
594 * calculate the interval between keepalive packets. 594 * calculate the interval between keepalive packets.
595 * 595 *
596 * @param cls closure with the `struct Plugin` 596 * @param cls closure with the `struct Plugin`
@@ -627,8 +627,10 @@ unix_query_keepalive_factor (void *cls)
627static ssize_t 627static ssize_t
628unix_real_send (void *cls, 628unix_real_send (void *cls,
629 struct GNUNET_NETWORK_Handle *send_handle, 629 struct GNUNET_NETWORK_Handle *send_handle,
630 const struct GNUNET_PeerIdentity *target, const char *msgbuf, 630 const struct GNUNET_PeerIdentity *target,
631 size_t msgbuf_size, unsigned int priority, 631 const char *msgbuf,
632 size_t msgbuf_size,
633 unsigned int priority,
632 struct GNUNET_TIME_Absolute timeout, 634 struct GNUNET_TIME_Absolute timeout,
633 const struct UnixAddress *addr, 635 const struct UnixAddress *addr,
634 size_t addrlen, 636 size_t addrlen,
@@ -729,48 +731,6 @@ resend:
729 731
730 732
731/** 733/**
732 * Closure for 'get_session_it'.
733 */
734struct GetSessionIteratorContext
735{
736 /**
737 * Location to store the session, if found.
738 */
739 struct Session *res;
740
741 /**
742 * Address information.
743 */
744 const struct GNUNET_HELLO_Address *address;
745};
746
747
748/**
749 * Function called to find a session by address.
750 *
751 * @param cls the 'struct LookupCtx'
752 * @param key peer we are looking for (unused)
753 * @param value a session
754 * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success
755 */
756static int
757get_session_it (void *cls,
758 const struct GNUNET_PeerIdentity *key,
759 void *value)
760{
761 struct GetSessionIteratorContext *gsi = cls;
762 struct Session *s = value;
763
764 if (0 == GNUNET_HELLO_address_cmp(s->address, gsi->address))
765 {
766 gsi->res = s;
767 return GNUNET_NO;
768 }
769 return GNUNET_YES;
770}
771
772
773/**
774 * Session was idle for too long, so disconnect it 734 * Session was idle for too long, so disconnect it
775 * 735 *
776 * @param cls the 'struct Session' to disconnect 736 * @param cls the 'struct Session' to disconnect
@@ -822,7 +782,6 @@ unix_plugin_get_session (void *cls,
822{ 782{
823 struct Plugin *plugin = cls; 783 struct Plugin *plugin = cls;
824 struct Session *s; 784 struct Session *s;
825 struct GetSessionIteratorContext gsi;
826 struct UnixAddress *ua; 785 struct UnixAddress *ua;
827 char * addrstr; 786 char * addrstr;
828 uint32_t addr_str_len; 787 uint32_t addr_str_len;
@@ -864,19 +823,17 @@ unix_plugin_get_session (void *cls,
864 return NULL; 823 return NULL;
865 } 824 }
866 825
867 /* Check if already existing */ 826 /* Check if a session for this address already exists */
868 gsi.address = address; 827 if (NULL != (s = lookup_session (plugin,
869 gsi.res = NULL; 828 address)))
870 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->session_map,
871 &address->peer,
872 &get_session_it, &gsi);
873 if (NULL != gsi.res)
874 { 829 {
875 LOG (GNUNET_ERROR_TYPE_DEBUG, 830 LOG (GNUNET_ERROR_TYPE_DEBUG,
876 "Found existing session %p for address `%s'\n", 831 "Found existing session %p for address `%s'\n",
877 gsi.res, 832 s,
878 unix_address_to_string (NULL, address->address, address->address_length)); 833 unix_address_to_string (NULL,
879 return gsi.res; 834 address->address,
835 address->address_length));
836 return s;
880 } 837 }
881 838
882 /* create a new session */ 839 /* create a new session */
@@ -904,10 +861,20 @@ unix_plugin_get_session (void *cls,
904 return s; 861 return s;
905} 862}
906 863
864
865/**
866 * Function that will be called whenever the transport service wants
867 * to notify the plugin that a session is still active and in use and
868 * therefore the session timeout for this session has to be updated
869 *
870 * @param cls closure with the `struct Plugin *`
871 * @param peer which peer was the session for
872 * @param session which session is being updated
873 */
907static void 874static void
908unix_plugin_update_session_timeout (void *cls, 875unix_plugin_update_session_timeout (void *cls,
909 const struct GNUNET_PeerIdentity *peer, 876 const struct GNUNET_PeerIdentity *peer,
910 struct Session *session) 877 struct Session *session)
911{ 878{
912 struct Plugin *plugin = cls; 879 struct Plugin *plugin = cls;
913 880
@@ -919,6 +886,7 @@ unix_plugin_update_session_timeout (void *cls,
919 reschedule_session_timeout (session); 886 reschedule_session_timeout (session);
920} 887}
921 888
889
922/** 890/**
923 * Function that can be used by the transport service to transmit 891 * Function that can be used by the transport service to transmit
924 * a message using the plugin. Note that in the case of a 892 * a message using the plugin. Note that in the case of a
@@ -949,7 +917,8 @@ unix_plugin_update_session_timeout (void *cls,
949static ssize_t 917static ssize_t
950unix_plugin_send (void *cls, 918unix_plugin_send (void *cls,
951 struct Session *session, 919 struct Session *session,
952 const char *msgbuf, size_t msgbuf_size, 920 const char *msgbuf,
921 size_t msgbuf_size,
953 unsigned int priority, 922 unsigned int priority,
954 struct GNUNET_TIME_Relative to, 923 struct GNUNET_TIME_Relative to,
955 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) 924 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
@@ -987,13 +956,13 @@ unix_plugin_send (void *cls,
987 memcpy (&message->sender, plugin->env->my_identity, 956 memcpy (&message->sender, plugin->env->my_identity,
988 sizeof (struct GNUNET_PeerIdentity)); 957 sizeof (struct GNUNET_PeerIdentity));
989 memcpy (&message[1], msgbuf, msgbuf_size); 958 memcpy (&message[1], msgbuf, msgbuf_size);
990
991 wrapper = GNUNET_new (struct UNIXMessageWrapper); 959 wrapper = GNUNET_new (struct UNIXMessageWrapper);
992 wrapper->msg = message; 960 wrapper->msg = message;
993 wrapper->msgsize = ssize; 961 wrapper->msgsize = ssize;
994 wrapper->payload = msgbuf_size; 962 wrapper->payload = msgbuf_size;
995 wrapper->priority = priority; 963 wrapper->priority = priority;
996 wrapper->timeout = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), to); 964 wrapper->timeout = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
965 to);
997 wrapper->cont = cont; 966 wrapper->cont = cont;
998 wrapper->cont_cls = cont_cls; 967 wrapper->cont_cls = cont_cls;
999 wrapper->session = session; 968 wrapper->session = session;
@@ -1368,26 +1337,30 @@ unix_transport_server_start (void *cls)
1368 * 1337 *
1369 * @param cls closure, should be our handle to the Plugin 1338 * @param cls closure, should be our handle to the Plugin
1370 * @param addr pointer to the address 1339 * @param addr pointer to the address
1371 * @param addrlen length of addr 1340 * @param addrlen length of @a addr
1372 * @return GNUNET_OK if this is a plausible address for this peer 1341 * @return #GNUNET_OK if this is a plausible address for this peer
1373 * and transport, GNUNET_SYSERR if not 1342 * and transport, #GNUNET_SYSERR if not
1374 * 1343 *
1375 */ 1344 */
1376static int 1345static int
1377unix_check_address (void *cls, const void *addr, size_t addrlen) 1346unix_check_address (void *cls,
1347 const void *addr,
1348 size_t addrlen)
1378{ 1349{
1379 struct Plugin* plugin = cls; 1350 struct Plugin* plugin = cls;
1380 struct UnixAddress *ua = (struct UnixAddress *) addr; 1351 const struct UnixAddress *ua = addr;
1381 char *addrstr; 1352 char *addrstr;
1382 size_t addr_str_len; 1353 size_t addr_str_len;
1383 1354
1384 if ((NULL == addr) || (0 == addrlen) || (sizeof (struct UnixAddress) > addrlen)) 1355 if ( (NULL == addr) ||
1356 (0 == addrlen) ||
1357 (sizeof (struct UnixAddress) > addrlen) )
1385 { 1358 {
1386 GNUNET_break (0); 1359 GNUNET_break (0);
1387 return GNUNET_SYSERR; 1360 return GNUNET_SYSERR;
1388 } 1361 }
1389 addrstr = (char *) &ua[1]; 1362 addrstr = (char *) &ua[1];
1390 addr_str_len = ntohl (ua->addrlen); 1363 addr_str_len = ntohl (ua->addrlen);
1391 if ('\0' != addrstr[addr_str_len - 1]) 1364 if ('\0' != addrstr[addr_str_len - 1])
1392 { 1365 {
1393 GNUNET_break (0); 1366 GNUNET_break (0);
@@ -1421,7 +1394,8 @@ unix_check_address (void *cls, const void *addr, size_t addrlen)
1421 */ 1394 */
1422static void 1395static void
1423unix_plugin_address_pretty_printer (void *cls, const char *type, 1396unix_plugin_address_pretty_printer (void *cls, const char *type,
1424 const void *addr, size_t addrlen, 1397 const void *addr,
1398 size_t addrlen,
1425 int numeric, 1399 int numeric,
1426 struct GNUNET_TIME_Relative timeout, 1400 struct GNUNET_TIME_Relative timeout,
1427 GNUNET_TRANSPORT_AddressStringCallback asc, 1401 GNUNET_TRANSPORT_AddressStringCallback asc,
@@ -1551,9 +1525,13 @@ address_notification (void *cls,
1551 1525
1552 plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK; 1526 plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
1553 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity, 1527 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
1554 PLUGIN_NAME, ua, len, GNUNET_HELLO_ADDRESS_INFO_NONE); 1528 PLUGIN_NAME,
1555 1529 ua,
1556 plugin->env->notify_address (plugin->env->cls, GNUNET_YES, address); 1530 len,
1531 GNUNET_HELLO_ADDRESS_INFO_NONE);
1532 plugin->env->notify_address (plugin->env->cls,
1533 GNUNET_YES,
1534 address);
1557 GNUNET_free (ua); 1535 GNUNET_free (ua);
1558 GNUNET_free (address); 1536 GNUNET_free (address);
1559} 1537}
@@ -1570,9 +1548,9 @@ reschedule_session_timeout (struct Session *s)
1570 GNUNET_assert (NULL != s); 1548 GNUNET_assert (NULL != s);
1571 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); 1549 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task);
1572 GNUNET_SCHEDULER_cancel (s->timeout_task); 1550 GNUNET_SCHEDULER_cancel (s->timeout_task);
1573 s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1551 s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1574 &session_timeout, 1552 &session_timeout,
1575 s); 1553 s);
1576 LOG (GNUNET_ERROR_TYPE_DEBUG, 1554 LOG (GNUNET_ERROR_TYPE_DEBUG,
1577 "Timeout rescheduled for session %p set to %s\n", 1555 "Timeout rescheduled for session %p set to %s\n",
1578 s, 1556 s,
@@ -1615,7 +1593,7 @@ unix_peer_disconnect (void *cls,
1615{ 1593{
1616 struct Plugin *plugin = cls; 1594 struct Plugin *plugin = cls;
1617 1595
1618 GNUNET_assert (plugin != NULL); 1596 GNUNET_assert (NULL != plugin);
1619 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->session_map, 1597 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->session_map,
1620 target, 1598 target,
1621 &get_session_delete_it, plugin); 1599 &get_session_delete_it, plugin);
@@ -1623,6 +1601,67 @@ unix_peer_disconnect (void *cls,
1623 1601
1624 1602
1625/** 1603/**
1604 * Return information about the given session to the
1605 * monitor callback.
1606 *
1607 * @param cls the `struct Plugin` with the monitor callback (`sic`)
1608 * @param peer peer we send information about
1609 * @param value our `struct Session` to send information about
1610 * @return #GNUNET_OK (continue to iterate)
1611 */
1612static int
1613send_session_info_iter (void *cls,
1614 const struct GNUNET_PeerIdentity *peer,
1615 void *value)
1616{
1617 struct Plugin *plugin = cls;
1618 struct Session *session = value;
1619 struct GNUNET_TRANSPORT_SessionInfo info;
1620
1621 memset (&info, 0, sizeof (info));
1622 info.state = GNUNET_TRANSPORT_SS_UP; /* ??? */
1623 // FIXME: info->is_inbound = ?
1624 // FIXME: info->num_msg_pending = ?
1625 // FIXME: info->num_bytes_pending = ?
1626 // FIXME: info->receive_delay = ?
1627 // FIXME: info->session_timeout = ?
1628 info.address = session->address;
1629 plugin->sic (plugin->sic_cls,
1630 session,
1631 &info);
1632 return GNUNET_OK;
1633}
1634
1635
1636/**
1637 * Begin monitoring sessions of a plugin. There can only
1638 * be one active monitor per plugin (i.e. if there are
1639 * multiple monitors, the transport service needs to
1640 * multiplex the generated events over all of them).
1641 *
1642 * @param cls closure of the plugin
1643 * @param sic callback to invoke, NULL to disable monitor;
1644 * plugin will being by iterating over all active
1645 * sessions immediately and then enter monitor mode
1646 * @param sic_cls closure for @a sic
1647 */
1648static void
1649unix_setup_monitor (void *cls,
1650 GNUNET_TRANSPORT_SessionInfoCallback sic,
1651 void *sic_cls)
1652{
1653 struct Plugin *plugin = cls;
1654
1655 plugin->sic = sic;
1656 plugin->sic_cls = sic_cls;
1657 if (NULL != sic)
1658 GNUNET_CONTAINER_multipeermap_iterate (plugin->session_map,
1659 &send_session_info_iter,
1660 plugin);
1661}
1662
1663
1664/**
1626 * The exported method. Initializes the plugin and returns a 1665 * The exported method. Initializes the plugin and returns a
1627 * struct with the callbacks. 1666 * struct with the callbacks.
1628 * 1667 *
@@ -1675,7 +1714,6 @@ libgnunet_plugin_transport_unix_init (void *cls)
1675 1714
1676 api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions); 1715 api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
1677 api->cls = plugin; 1716 api->cls = plugin;
1678
1679 api->get_session = &unix_plugin_get_session; 1717 api->get_session = &unix_plugin_get_session;
1680 api->send = &unix_plugin_send; 1718 api->send = &unix_plugin_send;
1681 api->disconnect_peer = &unix_peer_disconnect; 1719 api->disconnect_peer = &unix_peer_disconnect;
@@ -1687,6 +1725,7 @@ libgnunet_plugin_transport_unix_init (void *cls)
1687 api->string_to_address = &unix_string_to_address; 1725 api->string_to_address = &unix_string_to_address;
1688 api->get_network = &unix_get_network; 1726 api->get_network = &unix_get_network;
1689 api->update_session_timeout = &unix_plugin_update_session_timeout; 1727 api->update_session_timeout = &unix_plugin_update_session_timeout;
1728 api->setup_monitor = &unix_setup_monitor;
1690 sockets_created = unix_transport_server_start (plugin); 1729 sockets_created = unix_transport_server_start (plugin);
1691 if ((0 == sockets_created) || (GNUNET_SYSERR == sockets_created)) 1730 if ((0 == sockets_created) || (GNUNET_SYSERR == sockets_created))
1692 { 1731 {
@@ -1698,7 +1737,8 @@ libgnunet_plugin_transport_unix_init (void *cls)
1698 return NULL; 1737 return NULL;
1699 } 1738 }
1700 plugin->session_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); 1739 plugin->session_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
1701 plugin->address_update_task = GNUNET_SCHEDULER_add_now (&address_notification, plugin); 1740 plugin->address_update_task = GNUNET_SCHEDULER_add_now (&address_notification,
1741 plugin);
1702 return api; 1742 return api;
1703} 1743}
1704 1744
@@ -1724,24 +1764,33 @@ libgnunet_plugin_transport_unix_done (void *cls)
1724 GNUNET_free (api); 1764 GNUNET_free (api);
1725 return NULL; 1765 return NULL;
1726 } 1766 }
1727
1728 len = sizeof (struct UnixAddress) + strlen (plugin->unix_socket_path) + 1; 1767 len = sizeof (struct UnixAddress) + strlen (plugin->unix_socket_path) + 1;
1729 ua = GNUNET_malloc (len); 1768 ua = GNUNET_malloc (len);
1730 ua->options = htonl (plugin->myoptions); 1769 ua->options = htonl (plugin->myoptions);
1731 ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1); 1770 ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1);
1732 memcpy (&ua[1], plugin->unix_socket_path, strlen (plugin->unix_socket_path) + 1); 1771 memcpy (&ua[1],
1772 plugin->unix_socket_path,
1773 strlen (plugin->unix_socket_path) + 1);
1733 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity, 1774 address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
1734 PLUGIN_NAME, ua, len, GNUNET_HELLO_ADDRESS_INFO_NONE); 1775 PLUGIN_NAME,
1735 plugin->env->notify_address (plugin->env->cls, GNUNET_NO, address); 1776 ua, len,
1777 GNUNET_HELLO_ADDRESS_INFO_NONE);
1778 plugin->env->notify_address (plugin->env->cls,
1779 GNUNET_NO,
1780 address);
1736 1781
1737 GNUNET_free (address); 1782 GNUNET_free (address);
1738 GNUNET_free (ua); 1783 GNUNET_free (ua);
1739 1784
1740 while (NULL != (msgw = plugin->msg_head)) 1785 while (NULL != (msgw = plugin->msg_head))
1741 { 1786 {
1742 GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw); 1787 GNUNET_CONTAINER_DLL_remove (plugin->msg_head,
1743 if (msgw->cont != NULL) 1788 plugin->msg_tail,
1744 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, 1789 msgw);
1790 if (NULL != msgw->cont)
1791 msgw->cont (msgw->cont_cls,
1792 &msgw->session->target,
1793 GNUNET_SYSERR,
1745 msgw->payload, 0); 1794 msgw->payload, 0);
1746 GNUNET_free (msgw->msg); 1795 GNUNET_free (msgw->msg);
1747 GNUNET_free (msgw); 1796 GNUNET_free (msgw);