diff options
Diffstat (limited to 'src/transport/plugin_transport_unix.c')
-rw-r--r-- | src/transport/plugin_transport_unix.c | 363 |
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 | ||
63 | GNUNET_NETWORK_STRUCT_BEGIN | 63 | GNUNET_NETWORK_STRUCT_BEGIN |
64 | 64 | ||
65 | /** | ||
66 | * Binary format for an UNIX Domain Socket address in GNUnet. | ||
67 | */ | ||
65 | struct UnixAddress | 68 | struct 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 | ||
90 | GNUNET_NETWORK_STRUCT_END | 101 | GNUNET_NETWORK_STRUCT_END |
102 | |||
91 | /** | 103 | /** |
92 | * Handle for a session. | 104 | * Handle for a session. |
93 | */ | 105 | */ |
94 | struct Session | 106 | struct 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 | */ | ||
109 | struct UNIXMessageWrapper | 136 | struct 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 | */ | ||
172 | struct 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 | */ |
224 | struct UNIX_Sock_Info | 199 | struct 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 | */ |
340 | static void | 328 | static void |
341 | unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 329 | unix_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 | */ | ||
344 | static struct sockaddr_un * | 340 | static struct sockaddr_un * |
345 | unix_address_to_sockaddr (const char *unixpath, | 341 | unix_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 | */ |
437 | static void | 432 | static void |
438 | reschedule_select (struct Plugin * plugin) | 433 | reschedule_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 | */ |
471 | struct LookupCtx | 466 | struct 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 | */ |
514 | static struct Session * | 512 | static struct Session * |
515 | lookup_session (struct Plugin *plugin, | 513 | lookup_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) | |||
627 | static ssize_t | 627 | static ssize_t |
628 | unix_real_send (void *cls, | 628 | unix_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 | */ | ||
734 | struct 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 | */ | ||
756 | static int | ||
757 | get_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 | */ | ||
907 | static void | 874 | static void |
908 | unix_plugin_update_session_timeout (void *cls, | 875 | unix_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, | |||
949 | static ssize_t | 917 | static ssize_t |
950 | unix_plugin_send (void *cls, | 918 | unix_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 | */ |
1376 | static int | 1345 | static int |
1377 | unix_check_address (void *cls, const void *addr, size_t addrlen) | 1346 | unix_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 | */ |
1422 | static void | 1395 | static void |
1423 | unix_plugin_address_pretty_printer (void *cls, const char *type, | 1396 | unix_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 | */ | ||
1612 | static int | ||
1613 | send_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 | */ | ||
1648 | static void | ||
1649 | unix_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); |