]> git.meshlink.io Git - meshlink-tiny/blob - src/meshlink-tiny++.h
b7893955d82723a5c39f06c6818a1afd7caab31d
[meshlink-tiny] / src / meshlink-tiny++.h
1 #ifndef MESHLINKPP_H
2 #define MESHLINKPP_H
3
4 /*
5     meshlink-tiny++.h -- MeshLink C++ API
6     Copyright (C) 2014, 2017 Guus Sliepen <guus@meshlink.io>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include <meshlink-tiny.h>
24 #include <new> // for 'placement new'
25
26 namespace meshlink {
27 class mesh;
28 class node;
29 class channel;
30
31 /// Severity of log messages generated by MeshLink.
32 typedef meshlink_log_level_t log_level_t;
33
34 /// Code of most recent error encountered.
35 typedef meshlink_errno_t errno_t;
36
37 /// A callback for receiving data from the mesh.
38 /** @param mesh      A handle which represents an instance of MeshLink.
39  *  @param source    A pointer to a meshlink::node describing the source of the data.
40  *  @param data      A pointer to a buffer containing the data sent by the source.
41  *  @param len       The length of the received data.
42  */
43 typedef void (*receive_cb_t)(mesh *mesh, node *source, const void *data, size_t len);
44
45 /// A callback reporting the meta-connection attempt made by the host node to an another node.
46 /** @param mesh      A handle which represents an instance of MeshLink.
47  *  @param node      A pointer to a meshlink_node_t describing the node to whom meta-connection is being tried.
48  *                   This pointer is valid until meshlink_close() is called.
49  */
50 typedef void (*connection_try_cb_t)(mesh *mesh, node *node);
51
52 /// A callback reporting node status changes.
53 /** @param mesh       A handle which represents an instance of MeshLink.
54  *  @param node       A pointer to a meshlink::node describing the node whose status changed.
55  *  @param reachable  True if the node is reachable, false otherwise.
56  */
57 typedef void (*node_status_cb_t)(mesh *mesh, node *node, bool reachable);
58
59 /// A callback reporting node path MTU changes.
60 /** @param mesh       A handle which represents an instance of MeshLink.
61  *  @param node       A pointer to a meshlink_node_t describing the node whose status changed.
62  *                    This pointer is valid until meshlink_close() is called.
63  *  @param pmtu       The current path MTU to the node, or 0 if UDP communication is not (yet) possible.
64  */
65 typedef void (*node_pmtu_cb_t)(mesh *mesh, node *node, uint16_t pmtu);
66
67 /// A callback reporting duplicate node detection.
68 /** @param mesh       A handle which represents an instance of MeshLink.
69  *  @param node       A pointer to a meshlink_node_t describing the node which is duplicate.
70  *                    This pointer is valid until meshlink_close() is called.
71  */
72 typedef void (*duplicate_cb_t)(mesh *mesh, node *node);
73
74 /// A callback for receiving log messages generated by MeshLink.
75 /** @param mesh      A handle which represents an instance of MeshLink.
76  *  @param level     An enum describing the severity level of the message.
77  *  @param text      A pointer to a string containing the textual log message.
78  */
79 typedef void (*log_cb_t)(mesh *mesh, log_level_t level, const char *text);
80
81 /// A callback for listening for incoming channels.
82 /** @param mesh         A handle which represents an instance of MeshLink.
83  *  @param node         A handle for the node that wants to open a channel.
84  *  @param port         The port number the peer wishes to connect to.
85  *
86  *  @return             This function should return true if the application listens for the incoming channel, false otherwise.
87  */
88 typedef bool (*meshlink_channel_listen_cb_t)(struct meshlink_handle *mesh, struct meshlink_node *node, uint16_t port);
89
90 /// A callback for accepting incoming channels.
91 /** @param mesh         A handle which represents an instance of MeshLink.
92  *  @param channel      A handle for the incoming channel.
93  *  @param port         The port number the peer wishes to connect to.
94  *  @param data         A pointer to a buffer containing data already received. (Not yet used.)
95  *  @param len          The length of the data. (Not yet used.)
96  *
97  *  @return             This function should return true if the application accepts the incoming channel, false otherwise.
98  *                      If returning false, the channel is invalid and may not be used anymore.
99  */
100 typedef bool (*channel_accept_cb_t)(mesh *mesh, channel *channel, uint16_t port, const void *data, size_t len);
101
102 /// A callback for receiving data from a channel.
103 /** @param mesh         A handle which represents an instance of MeshLink.
104  *  @param channel      A handle for the channel.
105  *  @param data         A pointer to a buffer containing data sent by the source.
106  *  @param len          The length of the data.
107  */
108 typedef void (*channel_receive_cb_t)(mesh *mesh, channel *channel, const void *data, size_t len);
109
110 /// A callback that is called when data can be send on a channel.
111 /** @param mesh         A handle which represents an instance of MeshLink.
112  *  @param channel      A handle for the channel.
113  *  @param len          The maximum length of data that is guaranteed to be accepted by a call to channel_send().
114  */
115 typedef void (*channel_poll_cb_t)(mesh *mesh, channel *channel, size_t len);
116
117 /// A callback for cleaning up buffers submitted for asynchronous I/O.
118 /** This callbacks signals that MeshLink has finished using this buffer.
119  *  The ownership of the buffer is now back into the application's hands.
120  *
121  *  @param mesh      A handle which represents an instance of MeshLink.
122  *  @param channel   A handle for the channel which used this buffer.
123  *  @param data      A pointer to a buffer containing the enqueued data.
124  *  @param len       The length of the buffer.
125  *  @param priv      A private pointer which was set by the application when submitting the buffer.
126  */
127 typedef void (*aio_cb_t)(mesh *mesh, channel *channel, const void *data, size_t len, void *priv);
128
129 /// A callback for asynchronous I/O to and from filedescriptors.
130 /** This callbacks signals that MeshLink has finished using this filedescriptor.
131  *
132  *  @param mesh      A handle which represents an instance of MeshLink.
133  *  @param channel   A handle for the channel which used this filedescriptor.
134  *  @param fd        The filedescriptor that was used.
135  *  @param len       The length of the data that was successfully sent or received.
136  *  @param priv      A private pointer which was set by the application when submitting the buffer.
137  */
138 typedef void (*aio_fd_cb_t)(mesh *mesh, channel *channel, int fd, size_t len, void *priv);
139
140 /// A class describing a MeshLink node.
141 class node: public meshlink_node_t {
142 };
143
144 /// A class describing a MeshLink channel.
145 class channel: public meshlink_channel_t {
146 public:
147         static const uint32_t RELIABLE = MESHLINK_CHANNEL_RELIABLE;
148         static const uint32_t ORDERED = MESHLINK_CHANNEL_ORDERED;
149         static const uint32_t FRAMED = MESHLINK_CHANNEL_FRAMED;
150         static const uint32_t DROP_LATE = MESHLINK_CHANNEL_DROP_LATE;
151         static const uint32_t NO_PARTIAL = MESHLINK_CHANNEL_NO_PARTIAL;
152         static const uint32_t TCP = MESHLINK_CHANNEL_TCP;
153         static const uint32_t UDP = MESHLINK_CHANNEL_UDP;
154 };
155
156 /// A class describing a MeshLink mesh.
157 class mesh {
158 public:
159         mesh() : handle(0) {}
160
161         virtual ~mesh() {
162                 this->close();
163         }
164
165         bool isOpen() const {
166                 return (handle != 0);
167         }
168
169 // TODO: please enable C++11 in autoconf to enable "move constructors":
170 //              mesh(mesh&& other)
171 //              : handle(other.handle)
172 //              {
173 //                      if(handle)
174 //                              handle->priv = this;
175 //                      other.handle = 0;
176 //              }
177
178         /// Initialize MeshLink's configuration directory.
179         /** This function causes MeshLink to initialize its configuration directory,
180          *  if it hasn't already been initialized.
181          *  It only has to be run the first time the application starts,
182          *  but it is not a problem if it is run more than once, as long as
183          *  the arguments given are the same.
184          *
185          *  This function does not start any network I/O yet. The application should
186          *  first set callbacks, and then call meshlink_start().
187          *
188          *  @param confbase The directory in which MeshLink will store its configuration files.
189          *  @param name     The name which this instance of the application will use in the mesh.
190          *  @param appname  The application name which will be used in the mesh.
191          *  @param devclass The device class which will be used in the mesh.
192          *
193          *  @return         This function will return a pointer to a meshlink::mesh if MeshLink has successfully set up its configuration files, NULL otherwise.
194          */
195         bool open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
196                 handle = meshlink_open(confbase, name, appname, devclass);
197
198                 if(handle) {
199                         handle->priv = this;
200                 }
201
202                 return isOpen();
203         }
204
205         mesh(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
206                 open(confbase, name, appname, devclass);
207         }
208
209         /// Close the MeshLink handle.
210         /** This function calls meshlink_stop() if necessary,
211          *  and frees all memory allocated by MeshLink.
212          *  Afterwards, the handle and any pointers to a struct meshlink_node are invalid.
213          */
214         void close() {
215                 if(handle) {
216                         handle->priv = 0;
217                         meshlink_close(handle);
218                 }
219
220                 handle = 0;
221         }
222
223         /** instead of registerin callbacks you derive your own class and overwrite the following abstract member functions.
224          *  These functions are run in MeshLink's own thread.
225          *  It is therefore important that these functions use apprioriate methods (queues, pipes, locking, etc.)
226          *  to hand the data over to the application's thread.
227          *  These functions should also not block itself and return as quickly as possible.
228          * The default member functions are no-ops, so you are not required to overwrite all these member functions
229          */
230
231         /// This function is called whenever another node sends data to the local node.
232         virtual void receive(node *source, const void *data, size_t length) {
233                 /* do nothing */
234                 (void)source;
235                 (void)data;
236                 (void) length;
237         }
238
239         /// This functions is called whenever another node's status changed.
240         virtual void node_status(node *peer, bool reachable) {
241                 /* do nothing */
242                 (void)peer;
243                 (void)reachable;
244         }
245
246         /// This functions is called whenever another node's path MTU changes.
247         virtual void node_pmtu(node *peer, uint16_t pmtu) {
248                 /* do nothing */
249                 (void)peer;
250                 (void)pmtu;
251         }
252
253         /// This functions is called whenever a duplicate node is detected.
254         virtual void node_duplicate(node *peer) {
255                 /* do nothing */
256                 (void)peer;
257         }
258
259         /// This functions is called whenever MeshLink has some information to log.
260         virtual void log(log_level_t level, const char *message) {
261                 /* do nothing */
262                 (void)level;
263                 (void)message;
264         }
265
266         /// This functions is called whenever MeshLink has encountered a serious error.
267         virtual void error(meshlink_errno_t meshlink_errno) {
268                 /* do nothing */
269                 (void)meshlink_errno;
270         }
271
272         /// This functions is called whenever MeshLink a meta-connection attempt is made.
273         virtual void connection_try(node *peer) {
274                 /* do nothing */
275                 (void)peer;
276         }
277
278         /// This functions is called to determine if we are listening for incoming channels.
279         /**
280          *  The function is run in MeshLink's own thread.
281          *  It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
282          *  to pass data to or from the application's thread.
283          *  The callback should also not block itself and return as quickly as possible.
284          *
285          *  @param node         A handle for the node that wants to open a channel.
286          *  @param port         The port number the peer wishes to connect to.
287          *
288          *  @return             This function should return true if the application accepts the incoming channel, false otherwise.
289          */
290         virtual bool channel_listen(node *node, uint16_t port) {
291                 /* by default accept all channels */
292                 (void)node;
293                 (void)port;
294                 return true;
295         }
296
297         /// This functions is called whenever another node attempts to open a channel to the local node.
298         /**
299          *  If the channel is accepted, the poll_callback will be set to channel_poll and can be
300          *  changed using set_channel_poll_cb(). Likewise, the receive callback is set to
301          *  channel_receive().
302          *
303          *  The function is run in MeshLink's own thread.
304          *  It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
305          *  to pass data to or from the application's thread.
306          *  The callback should also not block itself and return as quickly as possible.
307          *
308          *  @param channel      A handle for the incoming channel.
309          *  @param port         The port number the peer wishes to connect to.
310          *  @param data         A pointer to a buffer containing data already received. (Not yet used.)
311          *  @param len          The length of the data. (Not yet used.)
312          *
313          *  @return             This function should return true if the application accepts the incoming channel, false otherwise.
314          *                      If returning false, the channel is invalid and may not be used anymore.
315          */
316         virtual bool channel_accept(channel *channel, uint16_t port, const void *data, size_t len) {
317                 /* by default reject all channels */
318                 (void)channel;
319                 (void)port;
320                 (void)data;
321                 (void)len;
322                 return false;
323         }
324
325         /// This function is called by Meshlink for receiving data from a channel.
326         /**
327          *  The function is run in MeshLink's own thread.
328          *  It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
329          *  to pass data to or from the application's thread.
330          *  The callback should also not block itself and return as quickly as possible.
331          *
332          *  @param channel      A handle for the channel.
333          *  @param data         A pointer to a buffer containing data sent by the source.
334          *  @param len          The length of the data.
335          */
336         virtual void channel_receive(channel *channel, const void *data, size_t len) {
337                 /* do nothing */
338                 (void)channel;
339                 (void)data;
340                 (void)len;
341         }
342
343         /// This function is called by Meshlink when data can be send on a channel.
344         /**
345          *  The function is run in MeshLink's own thread.
346          *  It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
347          *  to pass data to or from the application's thread.
348          *
349          *  The callback should also not block itself and return as quickly as possible.
350          *  @param channel      A handle for the channel.
351          *  @param len          The maximum length of data that is guaranteed to be accepted by a call to channel_send().
352          */
353         virtual void channel_poll(channel *channel, size_t len) {
354                 /* do nothing */
355                 (void)channel;
356                 (void)len;
357         }
358
359         /// Start MeshLink.
360         /** This function causes MeshLink to open network sockets, make outgoing connections, and
361          *  create a new thread, which will handle all network I/O.
362          *
363          *  @return         This function will return true if MeshLink has successfully started its thread, false otherwise.
364          */
365         bool start() {
366                 meshlink_set_receive_cb(handle, &receive_trampoline);
367                 meshlink_set_node_status_cb(handle, &node_status_trampoline);
368                 meshlink_set_node_pmtu_cb(handle, &node_pmtu_trampoline);
369                 meshlink_set_node_duplicate_cb(handle, &node_duplicate_trampoline);
370                 meshlink_set_log_cb(handle, MESHLINK_DEBUG, &log_trampoline);
371                 meshlink_set_error_cb(handle, &error_trampoline);
372                 meshlink_set_channel_listen_cb(handle, &channel_listen_trampoline);
373                 meshlink_set_channel_accept_cb(handle, &channel_accept_trampoline);
374                 meshlink_set_connection_try_cb(handle, &connection_try_trampoline);
375                 return meshlink_start(handle);
376         }
377
378         /// Stop MeshLink.
379         /** This function causes MeshLink to disconnect from all other nodes,
380          *  close all sockets, and shut down its own thread.
381          */
382         void stop() {
383                 meshlink_stop(handle);
384         }
385
386         /// Send data to another node.
387         /** This functions sends one packet of data to another node in the mesh.
388          *  The packet is sent using UDP semantics, which means that
389          *  the packet is sent as one unit and is received as one unit,
390          *  and that there is no guarantee that the packet will arrive at the destination.
391          *  The application should take care of getting an acknowledgement and retransmission if necessary.
392          *
393          *  @param destination  A pointer to a meshlink::node describing the destination for the data.
394          *  @param data         A pointer to a buffer containing the data to be sent to the source.
395          *  @param len          The length of the data.
396          *  @return             This function will return true if MeshLink has queued the message for transmission, and false otherwise.
397          *                      A return value of true does not guarantee that the message will actually arrive at the destination.
398          */
399         bool send(node *destination, const void *data, unsigned int len) {
400                 return meshlink_send(handle, destination, data, len);
401         }
402
403         /// Get a handle for a specific node.
404         /** This function returns a handle for the node with the given name.
405          *
406          *  @param name         The name of the node for which a handle is requested.
407          *
408          *  @return             A pointer to a meshlink::node which represents the requested node,
409          *                      or NULL if the requested node does not exist.
410          */
411         node *get_node(const char *name) {
412                 return (node *)meshlink_get_node(handle, name);
413         }
414
415         /// Get a node's reachability status.
416         /** This function returns the current reachability of a given node, and the times of the last state changes.
417          *  If a given state change never happened, the time returned will be 0.
418          *
419          *  @param node              A pointer to a meshlink::node describing the node.
420          *  @param last_reachable    A pointer to a time_t variable that will be filled in with the last time the node became reachable.
421          *  @param last_unreachable  A pointer to a time_t variable that will be filled in with the last time the node became unreachable.
422          *
423          *  @return                  This function returns true if the node is currently reachable, false otherwise.
424          */
425         bool get_node_reachability(node *node, time_t *last_reachable = NULL, time_t *last_unreachable = NULL) {
426                 return meshlink_get_node_reachability(handle, node, last_reachable, last_unreachable);
427         }
428
429         /// Get a handle for our own node.
430         /** This function returns a handle for the local node.
431          *
432          *  @return             A pointer to a meshlink::node which represents the local node.
433          */
434         node *get_self() {
435                 return (node *)meshlink_get_self(handle);
436         }
437
438         /// Get a list of all nodes.
439         /** This function returns a list with handles for all known nodes.
440          *
441          *  @param nodes        A pointer to an array of pointers to meshlink::node, which should be allocated by the application.
442          *  @param nmemb        The maximum number of pointers that can be stored in the nodes array.
443          *
444          *  @return             The number of known nodes, or -1 in case of an error.
445          *                      This can be larger than nmemb, in which case not all nodes were stored in the nodes array.
446          */
447         node **get_all_nodes(node **nodes, size_t *nmemb) {
448                 return (node **)meshlink_get_all_nodes(handle, (meshlink_node_t **)nodes, nmemb);
449         }
450
451         /// Sign data using the local node's MeshLink key.
452         /** This function signs data using the local node's MeshLink key.
453          *  The generated signature can be securely verified by other nodes.
454          *
455          *  @param data         A pointer to a buffer containing the data to be signed.
456          *  @param len          The length of the data to be signed.
457          *  @param signature    A pointer to a buffer where the signature will be stored.
458          *  @param siglen       The size of the signature buffer. Will be changed after the call to match the size of the signature itself.
459          *
460          *  @return             This function returns true if the signature is valid, false otherwise.
461          */
462         bool sign(const void *data, size_t len, void *signature, size_t *siglen) {
463                 return meshlink_sign(handle, data, len, signature, siglen);
464         }
465
466         /// Verify the signature generated by another node of a piece of data.
467         /** This function verifies the signature that another node generated for a piece of data.
468          *
469          *  @param source       A pointer to a meshlink_node_t describing the source of the signature.
470          *  @param data         A pointer to a buffer containing the data to be verified.
471          *  @param len          The length of the data to be verified.
472          *  @param signature    A pointer to a string containing the signature.
473          *  @param siglen       The size of the signature.
474          *
475          *  @return             This function returns true if the signature is valid, false otherwise.
476          */
477         bool verify(node *source, const void *data, size_t len, const void *signature, size_t siglen) {
478                 return meshlink_verify(handle, source, data, len, signature, siglen);
479         }
480
481         /// Set the canonical Address for a node.
482         /** This function sets the canonical Address for a node.
483          *  This address is stored permanently until it is changed by another call to this function,
484          *  unlike other addresses associated with a node,
485          *  such as those added with meshlink_hint_address() or addresses discovered at runtime.
486          *
487          *  If a canonical Address is set for the local node,
488          *  it will be used for the hostname part of generated invitation URLs.
489          *
490          *  @param node         A pointer to a meshlink_node_t describing the node.
491          *  @param address      A nul-terminated C string containing the address, which can be either in numeric format or a hostname.
492          *  @param port         A nul-terminated C string containing the port, which can be either in numeric or symbolic format.
493          *                      If it is NULL, the listening port's number will be used.
494          *
495          *  @return             This function returns true if the address was added, false otherwise.
496          */
497         bool set_canonical_address(node *node, const char *address, const char *port = NULL) {
498                 return meshlink_set_canonical_address(handle, node, address, port);
499         }
500
501         /// Clear the canonical Address for a node.
502         /** This function clears the canonical Address for a node.
503          *
504          *  @param node         A pointer to a struct meshlink_node describing the node.
505          *
506          *  @return             This function returns true if the address was removed, false otherwise.
507          */
508         bool clear_canonical_address(node *node) {
509                 return meshlink_clear_canonical_address(handle, node);
510         }
511
512         /// Set the scheduling granularity of the application
513         /** This should be set to the effective scheduling granularity for the application.
514          *  This depends on the scheduling granularity of the operating system, the application's
515          *  process priority and whether it is running as realtime or not.
516          *  The default value is 10000 (10 milliseconds).
517          *
518          *  @param granularity  The scheduling granularity of the application in microseconds.
519          */
520         void set_granularity(long granularity) {
521                 meshlink_set_scheduling_granularity(handle, granularity);
522         }
523
524         /// Sets the storage policy used by MeshLink
525         /** This sets the policy MeshLink uses when it has new information about nodes.
526          *  By default, all udpates will be stored to disk (unless an ephemeral instance has been opened).
527          *  Setting the policy to MESHLINK_STORAGE_KEYS_ONLY, only updates that contain new keys for nodes
528          *  are stored.
529          *  By setting the policy to MESHLINK_STORAGE_DISABLED, no updates will be stored.
530          *
531          *  @param policy  The storage policy to use.
532          */
533         void set_storage_policy(meshlink_storage_policy_t policy) {
534                 meshlink_set_storage_policy(handle, policy);
535         }
536
537         /// Use an invitation to join a mesh.
538         /** This function allows the local node to join an existing mesh using an invitation URL generated by another node.
539          *  An invitation can only be used if the local node has never connected to other nodes before.
540          *  After a successfully accepted invitation, the name of the local node may have changed.
541          *
542          *  This function may only be called on a mesh that has not been started yet and which is not already part of an existing mesh.
543          *
544          *  This function is blocking. It can take several seconds before it returns.
545          *  There is no guarantee it will perform a successful join.
546          *  Failures might be caused by temporary network outages, or by the invitation having expired.
547          *
548          *  @param invitation   A string containing the invitation URL.
549          *
550          *  @return             This function returns true if the local node joined the mesh it was invited to, false otherwise.
551          */
552         bool join(const char *invitation) {
553                 return meshlink_join(handle, invitation);
554         }
555
556         /// Export the local node's key and addresses.
557         /** This function generates a string that contains the local node's public key and one or more IP addresses.
558          *  The application can pass it in some way to another node, which can then import it,
559          *  granting the local node access to the other node's mesh.
560          *
561          *  @return             This function returns a string that contains the exported key and addresses.
562          *                      The application should call free() after it has finished using this string.
563          */
564         char *export_key() {
565                 return meshlink_export(handle);
566         }
567
568         /// Import another node's key and addresses.
569         /** This function accepts a string containing the exported public key and addresses of another node.
570          *  By importing this data, the local node grants the other node access to its mesh.
571          *
572          *  @param data         A string containing the other node's exported key and addresses.
573          *
574          *  @return             This function returns true if the data was valid and the other node has been granted access to the mesh, false otherwise.
575          */
576         bool import_key(const char *data) {
577                 return meshlink_import(handle, data);
578         }
579
580         /// Forget any information about a node.
581         /** This function allows the local node to forget any information it has about a node,
582          *  and if possible will remove any data it has stored on disk about the node.
583          *
584          *  Any open channels to this node must be closed before calling this function.
585          *
586          *  After this call returns, the node handle is invalid and may no longer be used, regardless
587          *  of the return value of this call.
588          *
589          *  Note that this function does not prevent MeshLink from actually forgetting about a node,
590          *  or re-learning information about a node at a later point in time. It is merely a hint that
591          *  the application does not care about this node anymore and that any resources kept could be
592          *  cleaned up.
593          *
594          *  \memberof meshlink_node
595          *  @param node         A pointer to a struct meshlink_node describing the node to be forgotten.
596          *
597          *  @return             This function returns true if all currently known data about the node has been forgotten, false otherwise.
598          */
599         bool forget_node(node *node) {
600                 return meshlink_forget_node(handle, node);
601         }
602
603         /// Set the poll callback.
604         /** This functions sets the callback that is called whenever data can be sent to another node.
605          *  The callback is run in MeshLink's own thread.
606          *  It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
607          *  to pass data to or from the application's thread.
608          *  The callback should also not block itself and return as quickly as possible.
609          *
610          *  @param channel   A handle for the channel.
611          *  @param cb        A pointer to the function which will be called when data can be sent to another node.
612          *                   If a NULL pointer is given, the callback will be disabled.
613          */
614         void set_channel_poll_cb(channel *channel, channel_poll_cb_t cb) {
615                 meshlink_set_channel_poll_cb(handle, channel, (meshlink_channel_poll_cb_t)cb);
616         }
617
618         /// Set the send buffer size of a channel.
619         /** This function sets the desired size of the send buffer.
620          *  The default size is 128 kB.
621          *
622          *  @param channel   A handle for the channel.
623          *  @param size      The desired size for the send buffer.
624          *                   If a NULL pointer is given, the callback will be disabled.
625          */
626         void set_channel_sndbuf(channel *channel, size_t size) {
627                 meshlink_set_channel_sndbuf(handle, channel, size);
628         }
629
630         /// Set the receive buffer size of a channel.
631         /** This function sets the desired size of the receive buffer.
632          *  The default size is 128 kB.
633          *
634          *  @param channel   A handle for the channel.
635          *  @param size      The desired size for the send buffer.
636          *                   If a NULL pointer is given, the callback will be disabled.
637          */
638         void set_channel_rcvbuf(channel *channel, size_t size) {
639                 meshlink_set_channel_rcvbuf(handle, channel, size);
640         }
641
642         /// Set the flags of a channel.
643         /** This function allows changing some of the channel flags.
644          *  Currently only MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE are supported, other flags are ignored.
645          *  These flags only affect the local side of the channel with the peer.
646          *  The changes take effect immediately.
647          *
648          *  @param channel   A handle for the channel.
649          *  @param flags     A bitwise-or'd combination of flags that set the semantics for this channel.
650          */
651         void set_channel_flags(channel *channel, uint32_t flags) {
652                 meshlink_set_channel_flags(handle, channel, flags);
653         }
654
655         /// Set the send buffer storage of a channel.
656         /** This function provides MeshLink with a send buffer allocated by the application.
657         *
658         *  @param channel   A handle for the channel.
659         *  @param buf       A pointer to the start of the buffer.
660         *                   If a NULL pointer is given, MeshLink will use its own internal buffer again.
661         *  @param size      The size of the buffer.
662         */
663         void set_channel_sndbuf_storage(channel *channel, void *buf, size_t size) {
664                 meshlink_set_channel_sndbuf_storage(handle, channel, buf, size);
665         }
666
667         /// Set the receive buffer storage of a channel.
668         /** This function provides MeshLink with a receive buffer allocated by the application.
669         *
670         *  @param channel   A handle for the channel.
671         *  @param buf       A pointer to the start of the buffer.
672         *                   If a NULL pointer is given, MeshLink will use its own internal buffer again.
673         *  @param size      The size of the buffer.
674         */
675         void set_channel_rcvbuf_storage(channel *channel, void *buf, size_t size) {
676                 meshlink_set_channel_rcvbuf_storage(handle, channel, buf, size);
677         }
678
679         /// Set the connection timeout used for channels to the given node.
680         /** This sets the timeout after which unresponsive channels will be reported as closed.
681          *  The timeout is set for all current and future channels to the given node.
682          *
683          *  @param node         The node to set the channel timeout for.
684          *  @param timeout      The timeout in seconds after which unresponsive channels will be reported as closed.
685          *                      The default is 60 seconds.
686          */
687         void set_node_channel_timeout(node *node, int timeout) {
688                 meshlink_set_node_channel_timeout(handle, node, timeout);
689         }
690
691         /// Open a reliable stream channel to another node.
692         /** This function is called whenever a remote node wants to open a channel to the local node.
693          *  The application then has to decide whether to accept or reject this channel.
694          *
695          *  This function sets the channel poll callback to channel_poll_trampoline, which in turn
696          *  calls channel_poll. To set a different, channel-specific poll callback, use set_channel_poll_cb.
697          *
698          *  @param node         The node to which this channel is being initiated.
699          *  @param port         The port number the peer wishes to connect to.
700          *  @param cb           A pointer to the function which will be called when the remote node sends data to the local node.
701          *  @param data         A pointer to a buffer containing data to already queue for sending.
702          *  @param len          The length of the data.
703          *                      If len is 0, the data pointer is copied into the channel's priv member.
704          *  @param flags        A bitwise-or'd combination of flags that set the semantics for this channel.
705          *
706          *  @return             A handle for the channel, or NULL in case of an error.
707          */
708         channel *channel_open(node *node, uint16_t port, channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags = channel::TCP) {
709                 channel *ch = (channel *)meshlink_channel_open_ex(handle, node, port, (meshlink_channel_receive_cb_t)cb, data, len, flags);
710                 meshlink_set_channel_poll_cb(handle, ch, &channel_poll_trampoline);
711                 return ch;
712         }
713
714         /// Open a reliable stream channel to another node.
715         /** This function is called whenever a remote node wants to open a channel to the local node.
716          *  The application then has to decide whether to accept or reject this channel.
717          *
718          *  This function sets the channel receive callback to channel_receive_trampoline,
719          *  which in turn calls channel_receive.
720          *
721          *  This function sets the channel poll callback to channel_poll_trampoline, which in turn
722          *  calls channel_poll. To set a different, channel-specific poll callback, use set_channel_poll_cb.
723          *
724          *  @param node         The node to which this channel is being initiated.
725          *  @param port         The port number the peer wishes to connect to.
726          *  @param data         A pointer to a buffer containing data to already queue for sending.
727          *  @param len          The length of the data.
728          *                      If len is 0, the data pointer is copied into the channel's priv member.
729          *  @param flags        A bitwise-or'd combination of flags that set the semantics for this channel.
730          *
731          *  @return             A handle for the channel, or NULL in case of an error.
732          */
733         channel *channel_open(node *node, uint16_t port, const void *data, size_t len, uint32_t flags = channel::TCP) {
734                 channel *ch = (channel *)meshlink_channel_open_ex(handle, node, port, &channel_receive_trampoline, data, len, flags);
735                 meshlink_set_channel_poll_cb(handle, ch, &channel_poll_trampoline);
736                 return ch;
737         }
738
739         /// Partially close a reliable stream channel.
740         /** This shuts down the read or write side of a channel, or both, without closing the handle.
741          *  It can be used to inform the remote node that the local node has finished sending all data on the channel,
742          *  but still allows waiting for incoming data from the remote node.
743          *
744          *  @param channel      A handle for the channel.
745          *  @param direction    Must be one of SHUT_RD, SHUT_WR or SHUT_RDWR.
746          */
747         void channel_shutdown(channel *channel, int direction) {
748                 return meshlink_channel_shutdown(handle, channel, direction);
749         }
750
751         /// Close a reliable stream channel.
752         /** This informs the remote node that the local node has finished sending all data on the channel.
753          *  It also causes the local node to stop accepting incoming data from the remote node.
754          *  Afterwards, the channel handle is invalid and must not be used any more.
755          *
756          *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
757          *  If called with a valid handle, this function always succeeds, otherwise the result is undefined.
758          *
759          *  @param channel      A handle for the channel.
760          */
761         void channel_close(meshlink_channel_t *channel) {
762                 return meshlink_channel_close(handle, channel);
763         }
764
765         /// Abort a reliable stream channel.
766         /** This aborts a channel.
767          *  Data that was in the send and receive buffers is dropped, so potentially there is some data that
768          *  was sent on this channel that will not be received by the peer.
769          *  Afterwards, the channel handle is invalid and must not be used any more.
770          *
771          *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
772          *  If called with a valid handle, this function always succeeds, otherwise the result is undefined.
773          *
774          *  @param channel      A handle for the channel.
775          */
776         void channel_abort(meshlink_channel_t *channel) {
777                 return meshlink_channel_abort(handle, channel);
778         }
779
780         /// Transmit data on a channel
781         /** This queues data to send to the remote node.
782          *
783          *  @param channel      A handle for the channel.
784          *  @param data         A pointer to a buffer containing data sent by the source.
785          *  @param len          The length of the data.
786          *
787          *  @return             The amount of data that was queued, which can be less than len, or a negative value in case of an error.
788          *                      If MESHLINK_CHANNEL_NO_PARTIAL is set, then the result will either be len,
789          *                      0 if the buffer is currently too full, or -1 if len is too big even for an empty buffer.
790          */
791         ssize_t channel_send(channel *channel, void *data, size_t len) {
792                 return meshlink_channel_send(handle, channel, data, len);
793         }
794
795         /// Transmit data on a channel asynchronously
796         /** This registers a buffer that will be used to send data to the remote node.
797          *  Multiple buffers can be registered, in which case data will be sent in the order the buffers were registered.
798          *  While there are still buffers with unsent data, the poll callback will not be called.
799          *
800          *  @param channel      A handle for the channel.
801          *  @param data         A pointer to a buffer containing data sent by the source, or NULL if there is no data to send.
802          *                      After meshlink_channel_aio_send() returns, the buffer may not be modified or freed by the application
803          *                      until the callback routine is called.
804          *  @param len          The length of the data, or 0 if there is no data to send.
805          *  @param cb           A pointer to the function which will be called when MeshLink has finished using the buffer.
806          *  @param priv         A private pointer which was set by the application when submitting the buffer.
807          *
808          *  @return             True if the buffer was enqueued, false otherwise.
809          */
810         bool channel_aio_send(channel *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
811                 return meshlink_channel_aio_send(handle, channel, data, len, cb, priv);
812         }
813
814         /// Transmit data on a channel asynchronously from a filedescriptor
815         /** This will read up to the specified length number of bytes from the given filedescriptor, and send it over the channel.
816          *  The callback may be returned early if there is an error reading from the filedescriptor.
817          *  While there is still with unsent data, the poll callback will not be called.
818          *
819          *  @param channel      A handle for the channel.
820          *  @param fd           A file descriptor from which data will be read.
821          *  @param len          The length of the data, or 0 if there is no data to send.
822          *  @param cb           A pointer to the function which will be called when MeshLink has finished using the filedescriptor.
823          *  @param priv         A private pointer which was set by the application when submitting the buffer.
824          *
825          *  @return             True if the buffer was enqueued, false otherwise.
826          */
827         bool channel_aio_fd_send(channel *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
828                 return meshlink_channel_aio_fd_send(handle, channel, fd, len, cb, priv);
829         }
830
831         /// Receive data on a channel asynchronously
832         /** This registers a buffer that will be filled with incoming channel data.
833          *  Multiple buffers can be registered, in which case data will be received in the order the buffers were registered.
834          *  While there are still buffers that have not been filled, the receive callback will not be called.
835          *
836          *  @param channel      A handle for the channel.
837          *  @param data         A pointer to a buffer that will be filled with incoming data.
838          *                      After meshlink_channel_aio_receive() returns, the buffer may not be modified or freed by the application
839          *                      until the callback routine is called.
840          *  @param len          The length of the data.
841          *  @param cb           A pointer to the function which will be called when MeshLink has finished using the buffer.
842          *  @param priv         A private pointer which was set by the application when submitting the buffer.
843          *
844          *  @return             True if the buffer was enqueued, false otherwise.
845          */
846         bool channel_aio_receive(channel *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
847                 return meshlink_channel_aio_receive(handle, channel, data, len, cb, priv);
848         }
849
850         /// Receive data on a channel asynchronously and send it to a filedescriptor
851         /** This will read up to the specified length number of bytes from the channel, and send it to the filedescriptor.
852          *  The callback may be returned early if there is an error writing to the filedescriptor.
853          *  While there is still unread data, the receive callback will not be called.
854          *
855          *  @param channel      A handle for the channel.
856          *  @param fd           A file descriptor to which data will be written.
857          *  @param len          The length of the data.
858          *  @param cb           A pointer to the function which will be called when MeshLink has finished using the filedescriptor.
859          *  @param priv         A private pointer which was set by the application when submitting the buffer.
860          *
861          *  @return             True if the buffer was enqueued, false otherwise.
862          */
863         bool channel_aio_fd_receive(channel *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
864                 return meshlink_channel_aio_fd_receive(handle, channel, fd, len, cb, priv);
865         }
866
867         /// Get the amount of bytes in the send buffer.
868         /** This returns the amount of bytes in the send buffer.
869          *  These bytes have not been received by the peer yet.
870          *
871          *  @param channel      A handle for the channel.
872          *
873          *  @return             The amount of un-ACKed bytes in the send buffer.
874          */
875         size_t channel_get_sendq(channel *channel) {
876                 return meshlink_channel_get_sendq(handle, channel);
877         }
878
879         /// Get the amount of bytes in the receive buffer.
880         /** This returns the amount of bytes in the receive buffer.
881          *  These bytes have not been processed by the application yet.
882          *
883          *  @param channel      A handle for the channel.
884          *
885          *  @return             The amount of bytes in the receive buffer.
886          */
887         size_t channel_get_recvq(channel *channel) {
888                 return meshlink_channel_get_recvq(handle, channel);
889         }
890
891         /// Get the maximum segment size of a channel.
892         /** This returns the amount of bytes that can be sent at once for channels with UDP semantics.
893          *
894          *  @param channel      A handle for the channel.
895          *
896          *  @return             The amount of bytes in the receive buffer.
897          */
898         size_t channel_get_mss(channel *channel) {
899                 return meshlink_channel_get_mss(handle, channel);
900         };
901
902         /// Inform MeshLink that the local network configuration might have changed
903         /** This is intended to be used when there is no way for MeshLink to get notifications of local network changes.
904          *  It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses,
905          *  and will immediately check if all connections to other nodes are still alive.
906          */
907         void hint_network_change() {
908                 meshlink_hint_network_change(handle);
909         }
910
911         /// Set device class timeouts
912         /** This sets the ping interval and timeout for a given device class.
913          *
914          *  @param devclass      The device class to update
915          *  @param pinginterval  The interval between keepalive packets, in seconds. The default is 60.
916          *  @param pingtimeout   The required time within which a peer should respond, in seconds. The default is 5.
917          *                       The timeout must be smaller than the interval.
918          */
919         void set_dev_class_timeouts(dev_class_t devclass, int pinginterval, int pingtimeout) {
920                 meshlink_set_dev_class_timeouts(handle, devclass, pinginterval, pingtimeout);
921         }
922
923         /// Set device class fast retry period
924         /** This sets the fast retry period for a given device class.
925          *  During this period after the last time the mesh becomes unreachable, connections are tried once a second.
926          *
927          *  @param devclass           The device class to update
928          *  @param fast_retry_period  The period during which fast connection retries are done. The default is 0.
929          */
930         void set_dev_class_fast_retry_period(dev_class_t devclass, int fast_retry_period) {
931                 meshlink_set_dev_class_fast_retry_period(handle, devclass, fast_retry_period);
932         }
933
934         /// Set device class maximum timeout
935         /** This sets the maximum timeout for outgoing connection retries for a given device class.
936          *
937          *  @param devclass      The device class to update
938          *  @param maxtimeout    The maximum timeout between reconnection attempts, in seconds. The default is 900.
939          */
940         void set_dev_class_maxtimeout(dev_class_t devclass, int maxtimeout) {
941                 meshlink_set_dev_class_maxtimeout(handle, devclass, maxtimeout);
942         }
943
944         /// Set which order invitations are committed
945         /** This determines in which order configuration files are written to disk during an invitation.
946          *  By default, the invitee saves the configuration to disk first, then the inviter.
947          *  By calling this function with @a inviter_commits_first set to true, the order is reversed.
948          *
949          *  @param inviter_commits_first  If true, then the node that invited a peer will commit data to disk first.
950          */
951         void set_inviter_commits_first(bool inviter_commits_first) {
952                 meshlink_set_inviter_commits_first(handle, inviter_commits_first);
953         }
954
955 private:
956         // non-copyable:
957         mesh(const mesh &) /* TODO: C++11: = delete */;
958         void operator=(const mesh &) /* TODO: C++11: = delete */;
959
960         /// static callback trampolines:
961         static void receive_trampoline(meshlink_handle_t *handle, meshlink_node_t *source, const void *data, size_t length) {
962                 if(!(handle->priv)) {
963                         return;
964                 }
965
966                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
967                 that->receive(static_cast<node *>(source), data, length);
968         }
969
970         static void node_status_trampoline(meshlink_handle_t *handle, meshlink_node_t *peer, bool reachable) {
971                 if(!(handle->priv)) {
972                         return;
973                 }
974
975                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
976                 that->node_status(static_cast<node *>(peer), reachable);
977         }
978
979         static void node_pmtu_trampoline(meshlink_handle_t *handle, meshlink_node_t *peer, uint16_t pmtu) {
980                 if(!(handle->priv)) {
981                         return;
982                 }
983
984                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
985                 that->node_pmtu(static_cast<node *>(peer), pmtu);
986         }
987
988         static void node_duplicate_trampoline(meshlink_handle_t *handle, meshlink_node_t *peer) {
989                 if(!(handle->priv)) {
990                         return;
991                 }
992
993                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
994                 that->node_duplicate(static_cast<node *>(peer));
995         }
996
997         static void log_trampoline(meshlink_handle_t *handle, log_level_t level, const char *message) {
998                 if(!(handle->priv)) {
999                         return;
1000                 }
1001
1002                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1003                 that->log(level, message);
1004         }
1005
1006         static void error_trampoline(meshlink_handle_t *handle, meshlink_errno_t meshlink_errno) {
1007                 if(!(handle->priv)) {
1008                         return;
1009                 }
1010
1011                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1012                 that->error(meshlink_errno);
1013         }
1014
1015         static void connection_try_trampoline(meshlink_handle_t *handle, meshlink_node_t *peer) {
1016                 if(!(handle->priv)) {
1017                         return;
1018                 }
1019
1020                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1021                 that->connection_try(static_cast<node *>(peer));
1022         }
1023
1024         static bool channel_listen_trampoline(meshlink_handle_t *handle, meshlink_node_t *node, uint16_t port) {
1025                 if(!(handle->priv)) {
1026                         return false;
1027                 }
1028
1029                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1030                 return that->channel_listen(static_cast<meshlink::node *>(node), port);
1031         }
1032
1033         static bool channel_accept_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, uint16_t port, const void *data, size_t len) {
1034                 if(!(handle->priv)) {
1035                         return false;
1036                 }
1037
1038                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1039                 bool accepted = that->channel_accept(static_cast<meshlink::channel *>(channel), port, data, len);
1040
1041                 if(accepted) {
1042                         meshlink_set_channel_receive_cb(handle, channel, &channel_receive_trampoline);
1043                         meshlink_set_channel_poll_cb(handle, channel, &channel_poll_trampoline);
1044                 }
1045
1046                 return accepted;
1047         }
1048
1049         static void channel_receive_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, const void *data, size_t len) {
1050                 if(!(handle->priv)) {
1051                         return;
1052                 }
1053
1054                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1055                 that->channel_receive(static_cast<meshlink::channel *>(channel), data, len);
1056         }
1057
1058         static void channel_poll_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, size_t len) {
1059                 if(!(handle->priv)) {
1060                         return;
1061                 }
1062
1063                 meshlink::mesh *that = static_cast<mesh *>(handle->priv);
1064                 that->channel_poll(static_cast<meshlink::channel *>(channel), len);
1065         }
1066
1067         meshlink_handle_t *handle;
1068 };
1069
1070 static inline const char *strerror(errno_t err = meshlink_errno) {
1071         return meshlink_strerror(err);
1072 }
1073
1074 /// Destroy a MeshLink instance.
1075 /** This function remove all configuration files of a MeshLink instance. It should only be called when the application
1076  *  does not have an open handle to this instance. Afterwards, a call to meshlink_open() will create a completely
1077  *  new instance.
1078  *
1079  *  @param confbase The directory in which MeshLink stores its configuration files.
1080  *                  After the function returns, the application is free to overwrite or free @a confbase @a.
1081  *
1082  *  @return         This function will return true if the MeshLink instance was successfully destroyed, false otherwise.
1083  */
1084 static inline bool destroy(const char *confbase) {
1085         return meshlink_destroy(confbase);
1086 }
1087 }
1088
1089 #endif