remove gversion.
[oweals/gnunet.git] / src / include / gnunet_transport_plugin.h
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2009-2014 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @author Christian Grothoff
23  *
24  * @file
25  * Transport service plugin API
26  *
27  * @defgroup transport-plugin  Transport Service plugin API
28  *
29  * Specifies the struct that is given to the plugin's entry method and the other
30  * struct that must be returned.  Note that the destructors of transport plugins
31  * will be given the value returned by the constructor and is expected to return
32  * a NULL pointer.
33  *
34  * @{
35  */
36 #ifndef PLUGIN_TRANSPORT_H
37 #define PLUGIN_TRANSPORT_H
38
39 #include "gnunet_configuration_lib.h"
40 #include "gnunet_scheduler_lib.h"
41 #include "gnunet_statistics_service.h"
42 #include "gnunet_transport_service.h"
43 #include "gnunet_ats_service.h"
44
45 #define TRANSPORT_SESSION_INBOUND_STRING "<inbound>"
46
47 /**
48  * Opaque pointer that plugins can use to distinguish specific
49  * connections to a given peer.  Typically used by stateful plugins to
50  * allow the service to refer to specific streams instead of a more
51  * general notion of "some connection" to the given peer.  This is
52  * useful since sometimes (i.e. for inbound TCP connections) a
53  * connection may not have an address that can be used for meaningful
54  * distinction between sessions to the same peer.
55  *
56  * Each 'struct GNUNET_ATS_Session' MUST start with the 'struct GNUNET_PeerIdentity'
57  * of the peer the session is for (which will be used for some error
58  * checking by the ATS code).
59  */
60 struct GNUNET_ATS_Session;
61
62
63 /**
64  * Function that will be called whenever the plugin internally
65  * cleans up a session pointer and hence the service needs to
66  * discard all of those sessions as well.  Plugins that do not
67  * use sessions can simply omit calling this function and always
68  * use NULL wherever a session pointer is needed.  This function
69  * should be called BEFORE a potential "TransmitContinuation"
70  * from the "TransmitFunction".
71  *
72  * @param cls closure
73  * @param peer which peer was the session for
74  * @param session which session is being destroyed
75  */
76 typedef void
77 (*GNUNET_TRANSPORT_SessionEnd) (void *cls,
78                                 const struct GNUNET_HELLO_Address *address,
79                                 struct GNUNET_ATS_Session *session);
80
81
82 /**
83  * Plugin tells transport service about a new inbound session
84  *
85  * @param cls unused
86  * @param address the address
87  * @param session the new session
88  * @param net network information
89  */
90 typedef void
91 (*GNUNET_TRANSPORT_SessionStart) (void *cls,
92                                   const struct GNUNET_HELLO_Address *address,
93                                   struct GNUNET_ATS_Session *session,
94                                   enum GNUNET_NetworkType net);
95
96
97 /**
98  * Function called by the transport for each received message.
99  * This function should also be called with "NULL" for the
100  * message to signal that the other peer disconnected.
101  *
102  * @param cls closure
103  * @param peer (claimed) identity of the other peer
104  * @param message the message, NULL if we only care about
105  *                learning about the delay until we should receive again
106  * @param session identifier used for this session (NULL for plugins
107  *                that do not offer bi-directional communication to the sender
108  *                using the same "connection")
109  * @param sender_address binary address of the sender (if we established the
110  *                connection or are otherwise sure of it; should be NULL
111  *                for inbound TCP/UDP connections since it it not clear
112  *                that we could establish ourselves a connection to that
113  *                IP address and get the same system)
114  * @param sender_address_len number of bytes in @a sender_address
115  * @return how long the plugin should wait until receiving more data;
116  *         returning #GNUNET_TIME_UNIT_FOREVER_REL means that the
117  *         connection should be closed
118  */
119 typedef struct GNUNET_TIME_Relative
120 (*GNUNET_TRANSPORT_PluginReceiveCallback) (void *cls,
121                                            const struct
122                                            GNUNET_HELLO_Address *address,
123                                            struct GNUNET_ATS_Session *session,
124                                            const struct
125                                            GNUNET_MessageHeader *message);
126
127
128 /**
129  * Function that can be called by plugins to figure if an address is
130  * an loopback, LAN or WAN address.   Ultimately invokes
131  * #GNUNET_ATS_address_get_type().
132  *
133  * @param cls closure
134  * @param addr binary address
135  * @param addrlen length of the @a addr
136  * @return type of the network the address belongs to
137  */
138 typedef enum GNUNET_NetworkType
139 (*GNUNET_TRANSPORT_AddressToType)(void *cls,
140                                   const struct sockaddr *addr,
141                                   size_t addrlen);
142
143
144 /**
145  * Function called when distance of an address changes.
146  *
147  * @param cls closure
148  * @param peer peer
149  * @param distance new distance
150  */
151 typedef void
152 (*GNUNET_TRANSPORT_UpdateAddressDistance) (void *cls,
153                                            const struct
154                                            GNUNET_HELLO_Address *address,
155                                            uint32_t distance);
156
157
158 /**
159  * Function that will be called for each address the transport
160  * is aware that it might be reachable under.
161  *
162  * @param cls closure
163  * @param add_remove should the address added (#GNUNET_YES) or removed (#GNUNET_NO) from the
164  *                   set of valid addresses?
165  * @param address the address to add or remove
166  */
167 typedef void
168 (*GNUNET_TRANSPORT_AddressNotification) (void *cls,
169                                          int add_remove,
170                                          const struct
171                                          GNUNET_HELLO_Address *address);
172
173
174 /**
175  * Function that will be called whenever the plugin receives data over
176  * the network and wants to determine how long it should wait until
177  * the next time it reads from the given peer.  Note that some plugins
178  * (such as UDP) may not be able to wait (for a particular peer), so
179  * the waiting part is optional.  Plugins that can wait should call
180  * this function, sleep the given amount of time, and call it again
181  * (with zero bytes read) UNTIL it returns zero and only then read.
182  *
183  * @param cls closure
184  * @param peer which peer did we read data from
185  * @param amount_recved number of bytes read (can be zero)
186  * @return how long to wait until reading more from this peer
187  *         (to enforce inbound quotas); returning #GNUNET_TIME_UNIT_FOREVER_REL
188  *         means that the connection should be closed
189  */
190 typedef struct GNUNET_TIME_Relative
191 (*GNUNET_TRANSPORT_TrafficReport) (void *cls,
192                                    const struct GNUNET_PeerIdentity *peer,
193                                    size_t amount_recved);
194
195
196 /**
197  * Function that returns a HELLO message.
198  *
199  * @return HELLO message (FIXME with what?)
200  */
201 typedef const struct GNUNET_MessageHeader *
202 (*GNUNET_TRANSPORT_GetHelloCallback) (void);
203
204
205 /**
206  * The transport service will pass a pointer to a struct
207  * of this type as the first and only argument to the
208  * entry point of each transport plugin.
209  */
210 struct GNUNET_TRANSPORT_PluginEnvironment
211 {
212   /**
213    * Configuration to use.
214    */
215   const struct GNUNET_CONFIGURATION_Handle *cfg;
216
217   /**
218    * Identity of this peer.
219    */
220   const struct GNUNET_PeerIdentity *my_identity;
221
222   /**
223    * Closure for the various callbacks.
224    */
225   void *cls;
226
227   /**
228    * Handle for reporting statistics.
229    */
230   struct GNUNET_STATISTICS_Handle *stats;
231
232   /**
233    * Function that should be called by the transport plugin
234    * whenever a message is received.  If this field is "NULL",
235    * the plugin should load in 'stub' mode and NOT fully
236    * initialize and instead only return an API with the
237    * @e address_pretty_printer, @e address_to_string and
238    * @e string_to_address functions.
239    */
240   GNUNET_TRANSPORT_PluginReceiveCallback receive;
241
242   /**
243    * Function that returns our HELLO.
244    */
245   GNUNET_TRANSPORT_GetHelloCallback get_our_hello;
246
247   /**
248    * Function that must be called by each plugin to notify the
249    * transport service about the addresses under which the transport
250    * provided by the plugin can be reached.
251    */
252   GNUNET_TRANSPORT_AddressNotification notify_address;
253
254   /**
255    * Function that must be called by the plugin when a non-NULL
256    * session handle stops being valid (is destroyed).
257    */
258   GNUNET_TRANSPORT_SessionEnd session_end;
259
260   /**
261    * Function called by the plugin when a new (incoming) session was created
262    * not explicitly created using the the get_session function
263    */
264   GNUNET_TRANSPORT_SessionStart session_start;
265
266   /**
267    * Function that will be called to figure if an address is an loopback,
268    * LAN, WAN etc. address
269    */
270   GNUNET_TRANSPORT_AddressToType get_address_type;
271
272   /**
273    * Function that will be called by DV to update distance for
274    * an address.
275    */
276   GNUNET_TRANSPORT_UpdateAddressDistance update_address_distance;
277
278   /**
279    * What is the maximum number of connections that this transport
280    * should allow?  Transports that do not have sessions (such as
281    * UDP) can ignore this value.
282    */
283   uint32_t max_connections;
284 };
285
286
287 /**
288  * Function called by the #GNUNET_TRANSPORT_TransmitFunction
289  * upon "completion".  In the case that a peer disconnects,
290  * this function must be called for each pending request
291  * (with a 'failure' indication) AFTER notifying the service
292  * about the disconnect event (so that the service won't try
293  * to transmit more messages, believing the connection still
294  * exists...).
295  *
296  * @param cls closure
297  * @param target who was the recipient of the message?
298  * @param result #GNUNET_OK on success
299  *               #GNUNET_SYSERR if the target disconnected;
300  *               disconnect will ALSO be signalled using
301  *               the ReceiveCallback.
302  * @param size_payload bytes of payload from transport service in message
303  * @param size_on_wire bytes required on wire for transmission,
304  *               0 if result == #GNUNET_SYSERR
305  */
306 typedef void
307 (*GNUNET_TRANSPORT_TransmitContinuation) (void *cls,
308                                           const struct
309                                           GNUNET_PeerIdentity *target,
310                                           int result,
311                                           size_t size_payload,
312                                           size_t size_on_wire);
313
314
315 /**
316  * The new send function with just the session and no address
317  *
318  * Function that can be used by the transport service to transmit
319  * a message using the plugin.   Note that in the case of a
320  * peer disconnecting, the continuation MUST be called
321  * prior to the disconnect notification itself.  This function
322  * will be called with this peer's HELLO message to initiate
323  * a fresh connection to another peer.
324  *
325  * @param cls closure
326  * @param session which session must be used
327  * @param msgbuf the message to transmit
328  * @param msgbuf_size number of bytes in @a msgbuf
329  * @param priority how important is the message (most plugins will
330  *                 ignore message priority and just FIFO)
331  * @param to how long to wait at most for the transmission (does not
332  *                require plugins to discard the message after the timeout,
333  *                just advisory for the desired delay; most plugins will ignore
334  *                this as well)
335  * @param cont continuation to call once the message has
336  *        been transmitted (or if the transport is ready
337  *        for the next transmission call; or if the
338  *        peer disconnected...); can be NULL
339  * @param cont_cls closure for @a cont
340  * @return number of bytes used (on the physical network, with overheads);
341  *         -1 on hard errors (i.e. address invalid); 0 is a legal value
342  *         and does NOT mean that the message was not transmitted (DV)
343  */
344 typedef ssize_t
345 (*GNUNET_TRANSPORT_TransmitFunction) (void *cls,
346                                       struct GNUNET_ATS_Session *session,
347                                       const char *msgbuf,
348                                       size_t msgbuf_size,
349                                       unsigned int priority,
350                                       struct GNUNET_TIME_Relative to,
351                                       GNUNET_TRANSPORT_TransmitContinuation cont,
352                                       void *cont_cls);
353
354
355 /**
356  * Function that can be called to force a disconnect from the
357  * specified neighbour for the given session only.  .  This should
358  * also cancel all previously scheduled transmissions for this
359  * session.  Obviously the transmission may have been partially
360  * completed already, which is OK.  The plugin is supposed to close
361  * the connection (if applicable).
362  *
363  * @param cls closure with the `struct Plugin`
364  * @param session session to destroy
365  * @return #GNUNET_OK on success
366  */
367 typedef int
368 (*GNUNET_TRANSPORT_DisconnectSessionFunction) (void *cls,
369                                                struct GNUNET_ATS_Session *
370                                                session);
371
372
373 /**
374  * Function that is called to get the keepalive factor.
375  * #GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to
376  * calculate the interval between keepalive packets.
377  *
378  * @param cls closure with the `struct Plugin`
379  * @return keepalive factor
380  */
381 typedef unsigned int
382 (*GNUNET_TRANSPORT_QueryKeepaliveFactorFunction) (void *cls);
383
384
385 /**
386  * Function that can be called to force a disconnect from the
387  * specified neighbour.  This should also cancel all previously
388  * scheduled transmissions.  Obviously the transmission may have been
389  * partially completed already, which is OK.  The plugin is supposed
390  * to close the connection (if applicable) and no longer call the
391  * transmit continuation(s).
392  *
393  * @param cls closure
394  * @param target peer for which the last transmission is
395  *        to be cancelled
396  */
397 typedef void
398 (*GNUNET_TRANSPORT_DisconnectPeerFunction) (void *cls,
399                                             const struct
400                                             GNUNET_PeerIdentity *target);
401
402
403 /**
404  * Function called by the pretty printer for the resolved address for
405  * each human-readable address obtained.  The callback can be called
406  * several times. The last invocation must be with a @a address of
407  * NULL and a @a res of #GNUNET_OK.  Thus, to indicate conversion
408  * errors, the callback might be called first with @a address NULL and
409  * @a res being #GNUNET_SYSERR.  In that case, there must still be a
410  * subsequent call later with @a address NULL and @a res #GNUNET_OK.
411  *
412  * @param cls closure
413  * @param address one of the names for the host, NULL on last callback
414  * @param res #GNUNET_OK if conversion was successful, #GNUNET_SYSERR on failure,
415  *      #GNUNET_OK on last callback
416  */
417 typedef void
418 (*GNUNET_TRANSPORT_AddressStringCallback) (void *cls,
419                                            const char *address,
420                                            int res);
421
422
423 /**
424  * Convert the transports address to a nice, human-readable
425  * format.
426  *
427  * @param cls closure
428  * @param type name of the transport that generated the address
429  * @param addr one of the addresses of the host, NULL for the last address
430  *        the specific address format depends on the transport
431  * @param addrlen length of the @a addr
432  * @param numeric should (IP) addresses be displayed in numeric form?
433  * @param timeout after how long should we give up?
434  * @param asc function to call on each string
435  * @param asc_cls closure for @a asc
436  */
437 typedef void
438 (*GNUNET_TRANSPORT_AddressPrettyPrinter) (void *cls,
439                                           const char *type,
440                                           const void *addr,
441                                           size_t addrlen,
442                                           int numeric,
443                                           struct GNUNET_TIME_Relative timeout,
444                                           GNUNET_TRANSPORT_AddressStringCallback
445                                           asc,
446                                           void *asc_cls);
447
448
449 /**
450  * Another peer has suggested an address for this peer and transport
451  * plugin.  Check that this could be a valid address.  This function
452  * is not expected to 'validate' the address in the sense of trying to
453  * connect to it but simply to see if the binary format is technically
454  * legal for establishing a connection to this peer (and make sure that
455  * the address really corresponds to our network connection/settings
456  * and not some potential man-in-the-middle).
457  *
458  * @param addr pointer to the address
459  * @param addrlen length of @a addr
460  * @return #GNUNET_OK if this is a plausible address for this peer
461  *         and transport, #GNUNET_SYSERR if not
462  */
463 typedef int
464 (*GNUNET_TRANSPORT_CheckAddress) (void *cls,
465                                   const void *addr,
466                                   size_t addrlen);
467
468
469 /**
470  * Create a new session to transmit data to the target
471  * This session will used to send data to this peer and the plugin will
472  * notify us by calling the env->session_end function
473  *
474  * @param cls the plugin
475  * @param address the hello address
476  * @return the session if the address is valid, NULL otherwise
477  */
478 typedef struct GNUNET_ATS_Session *
479 (*GNUNET_TRANSPORT_CreateSession) (void *cls,
480                                    const struct GNUNET_HELLO_Address *address);
481
482
483 /**
484  * Function that will be called whenever the transport service wants to
485  * notify the plugin that a session is still active and in use and
486  * therefore the session timeout for this session has to be updated
487  *
488  * @param cls closure
489  * @param peer which peer was the session for
490  * @param session which session is being updated
491  */
492 typedef void
493 (*GNUNET_TRANSPORT_UpdateSessionTimeout) (void *cls,
494                                           const struct
495                                           GNUNET_PeerIdentity *peer,
496                                           struct GNUNET_ATS_Session *session);
497
498
499 /**
500  * Function that will be called whenever the transport service wants to
501  * notify the plugin that the inbound quota changed and that the plugin
502  * should update it's delay for the next receive value
503  *
504  * @param cls closure
505  * @param peer which peer was the session for
506  * @param session which session is being updated
507  * @param delay new delay to use for receiving
508  */
509 typedef void
510 (*GNUNET_TRANSPORT_UpdateInboundDelay) (void *cls,
511                                         const struct GNUNET_PeerIdentity *peer,
512                                         struct GNUNET_ATS_Session *session,
513                                         struct GNUNET_TIME_Relative delay);
514
515
516 /**
517  * Function called for a quick conversion of the binary address to
518  * a numeric address.  Note that the caller must not free the
519  * address and that the next call to this function is allowed
520  * to override the address again.
521  *
522  * @param cls closure
523  * @param addr binary address
524  * @param addr_len length of the @a addr
525  * @return string representing the same address
526  */
527 typedef const char *
528 (*GNUNET_TRANSPORT_AddressToString) (void *cls,
529                                      const void *addr,
530                                      size_t addrlen);
531
532
533 /**
534  * Function called to convert a string address to
535  * a binary address.
536  *
537  * @param cls closure (`struct Plugin*`)
538  * @param addr string address
539  * @param addrlen length of the @a addr including \0 termination
540  * @param buf location to store the buffer
541  *        If the function returns #GNUNET_SYSERR, its contents are undefined.
542  * @param added length of created address
543  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
544  */
545 typedef int
546 (*GNUNET_TRANSPORT_StringToAddress) (void *cls,
547                                      const char *addr,
548                                      uint16_t addrlen,
549                                      void **buf,
550                                      size_t *added);
551
552
553 /**
554  * Function to obtain the network type for a session
555  *
556  * @param cls closure (`struct Plugin *`)
557  * @param session the session
558  * @return the network type
559  */
560 typedef enum GNUNET_NetworkType
561 (*GNUNET_TRANSPORT_GetNetworkType)(void *cls,
562                                    struct GNUNET_ATS_Session *session);
563
564
565 /**
566  * Function to obtain the network type for an address.
567  *
568  * @param cls closure (`struct Plugin *`)
569  * @param address the address
570  * @return the network type
571  */
572 typedef enum GNUNET_NetworkType
573 (*GNUNET_TRANSPORT_GetNetworkTypeForAddress)(void *cls,
574                                              const struct
575                                              GNUNET_HELLO_Address *address);
576
577
578 /**
579  * Function called by the plugin with information about the
580  * current sessions managed by the plugin (for monitoring).
581  *
582  * @param cls closure
583  * @param session session handle this information is about,
584  *        NULL to indicate that we are "in sync" (initial
585  *        iteration complete)
586  * @param info information about the state of the session,
587  *        NULL if @a session is also NULL and we are
588  *        merely signalling that the initial iteration is over
589  */
590 typedef void
591 (*GNUNET_TRANSPORT_SessionInfoCallback) (void *cls,
592                                          struct GNUNET_ATS_Session *session,
593                                          const struct
594                                          GNUNET_TRANSPORT_SessionInfo *info);
595
596
597 /**
598  * Begin monitoring sessions of a plugin.  There can only
599  * be one active monitor per plugin (i.e. if there are
600  * multiple monitors, the transport service needs to
601  * multiplex the generated events over all of them).
602  *
603  * @param cls closure of the plugin
604  * @param sic callback to invoke, NULL to disable monitor;
605  *            plugin will being by iterating over all active
606  *            sessions immediately and then enter monitor mode
607  * @param sic_cls closure for @a sic
608  */
609 typedef void
610 (*GNUNET_TRANSPORT_SessionMonitorSetup) (void *cls,
611                                          GNUNET_TRANSPORT_SessionInfoCallback
612                                          sic,
613                                          void *sic_cls);
614
615
616 /**
617  * Each plugin is required to return a pointer to a struct of this
618  * type as the return value from its entry point.
619  */
620 struct GNUNET_TRANSPORT_PluginFunctions
621 {
622   /**
623    * Closure for all of the callbacks.
624    */
625   void *cls;
626
627   /**
628    * Function that the transport service will use to transmit data to
629    * another peer.  May be NULL for plugins that only support
630    * receiving data.  After this call, the plugin call the specified
631    * continuation with success or error before notifying us about the
632    * target having disconnected.
633    */
634   GNUNET_TRANSPORT_TransmitFunction send;
635
636   /**
637    * Function that can be used to force the plugin to disconnect from
638    * the given peer and cancel all previous transmissions (and their
639    * continuations).
640    */
641   GNUNET_TRANSPORT_DisconnectPeerFunction disconnect_peer;
642
643   /**
644    * Function that can be used to force the plugin to disconnect from
645    * the given peer and cancel all previous transmissions (and their
646    * continuations).
647    */
648   GNUNET_TRANSPORT_DisconnectSessionFunction disconnect_session;
649
650   /**
651    * Function that will be called whenever the transport service wants to
652    * notify the plugin that a session is still active and in use and
653    * therefore the session timeout for this session has to be updated
654    */
655   GNUNET_TRANSPORT_UpdateSessionTimeout update_session_timeout;
656
657   /**
658    * Function that will be called whenever the transport service wants to
659    * notify the plugin that the inbound quota changed and that the plugin
660    * should update it's delay for the next receive value
661    */
662   GNUNET_TRANSPORT_UpdateInboundDelay update_inbound_delay;
663
664   /**
665    * Function that is used to query keepalive factor.
666    * #GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to
667    * calculate the interval between keepalive packets.
668    */
669   GNUNET_TRANSPORT_QueryKeepaliveFactorFunction query_keepalive_factor;
670
671   /**
672    * Function to pretty-print addresses.
673    */
674   GNUNET_TRANSPORT_AddressPrettyPrinter address_pretty_printer;
675
676   /**
677    * Function that will be called to check if a binary address
678    * for this plugin is well-formed and corresponds to an
679    * address for THIS peer (as per our configuration).  Naturally,
680    * if absolutely necessary, plugins can be a bit conservative in
681    * their answer, but in general plugins should make sure that the
682    * address does not redirect traffic to a 3rd party that might
683    * try to man-in-the-middle our traffic.
684    */
685   GNUNET_TRANSPORT_CheckAddress check_address;
686
687   /**
688    * Function that will be called to convert a binary address
689    * to a string (numeric conversion only).
690    */
691   GNUNET_TRANSPORT_AddressToString address_to_string;
692
693   /**
694    * Function that will be called to convert a string address
695    * to binary (numeric conversion only).
696    */
697   GNUNET_TRANSPORT_StringToAddress string_to_address;
698
699   /**
700    * Function that will be called tell the plugin to create a session
701    * object.
702    */
703   GNUNET_TRANSPORT_CreateSession get_session;
704
705   /**
706    * Function to obtain the network type for a session
707    */
708   GNUNET_TRANSPORT_GetNetworkType get_network;
709
710   /**
711    * Function to obtain the network type for an address
712    */
713   GNUNET_TRANSPORT_GetNetworkTypeForAddress get_network_for_address;
714
715   /**
716    * Function to monitor the sessions managed by the plugin.
717    */
718   GNUNET_TRANSPORT_SessionMonitorSetup setup_monitor;
719 };
720
721
722 /*#ifndef PLUGIN_TRANSPORT_H*/
723 #endif
724
725 /** @} */  /* end of group */
726
727 /* end of gnunet_transport_plugin.h */