897b842749db3ca1b0a34db69fd5eceaa79c8fed
[oweals/gnunet.git] / src / include / gnunet_hello_lib.h
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011 Christian Grothoff (and other contributing authors)
4
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
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file include/gnunet_hello_lib.h
23  * @brief helper library for handling HELLOs
24  * @author Christian Grothoff
25  */
26
27 #ifndef GNUNET_HELLO_LIB_H
28 #define GNUNET_HELLO_LIB_H
29
30 #ifdef __cplusplus
31 extern "C"
32 {
33 #if 0                           /* keep Emacsens' auto-indent happy */
34 }
35 #endif
36 #endif
37
38 #include "gnunet_common.h"
39 #include "gnunet_crypto_lib.h"
40
41
42 /**
43  * Prefix that every HELLO URI must start with.
44  */
45 #define GNUNET_HELLO_URI_PREFIX "gnunet://hello/"
46
47 /**
48  * Prefix that every FRIEND HELLO URI must start with.
49  */
50 #define GNUNET_FRIEND_HELLO_URI_PREFIX "gnunet://friend-hello/"
51
52 /**
53  * An address for communicating with a peer.  We frequently
54  * need this tuple and the components cannot really be
55  * separated.  This is NOT the format that would be used
56  * on the wire.
57  */
58 struct GNUNET_HELLO_Address
59 {
60
61   /**
62    * For which peer is this an address?
63    */
64   struct GNUNET_PeerIdentity peer;
65
66   /**
67    * Name of the transport plugin enabling the communication using
68    * this address.
69    */
70   const char *transport_name;
71
72   /**
73    * Binary representation of the address (plugin-specific).
74    */
75   const void *address;
76
77   /**
78    * Number of bytes in 'address'.
79    */
80   size_t address_length;
81
82 };
83
84
85 /**
86  * Return HELLO type
87  *
88  * @param h HELLO Message to test
89  * @param GNUNET_MESSAGE_TYPE_HELLO or GNUNET_MESSAGE_TYPE_FRIEND_HELLO or 0 on error
90  */
91 uint16_t
92 GNUNET_HELLO_get_type (const struct GNUNET_MessageHeader *h);
93
94 /**
95  * Allocate an address struct.
96  *
97  * @param peer the peer
98  * @param transport_name plugin name
99  * @param address binary address
100  * @param address_length number of bytes in 'address'
101  * @return the address struct
102  */
103 struct GNUNET_HELLO_Address *
104 GNUNET_HELLO_address_allocate (const struct GNUNET_PeerIdentity *peer,
105                                const char *transport_name, const void *address,
106                                size_t address_length);
107
108
109 /**
110  * Copy an address struct.
111  *
112  * @param address address to copy
113  * @return a copy of the address struct
114  */
115 struct GNUNET_HELLO_Address *
116 GNUNET_HELLO_address_copy (const struct GNUNET_HELLO_Address *address);
117
118
119 /**
120  * Compare two addresses.  Does NOT compare the peer identity,
121  * that is assumed already to match!
122  *
123  * @param a1 first address
124  * @param a2 second address
125  * @return 0 if the addresses are equal, -1 if a1<a2, 1 if a1>a2.
126  */
127 int
128 GNUNET_HELLO_address_cmp (const struct GNUNET_HELLO_Address *a1,
129                           const struct GNUNET_HELLO_Address *a2);
130
131
132 /**
133  * Get the size of an address struct.
134  *
135  * @param address address
136  * @return the size
137  */
138 size_t
139 GNUNET_HELLO_address_get_size (const struct GNUNET_HELLO_Address *address);
140
141 /**
142  * Free an address.
143  *
144  * @param addr address to free
145  */
146 #define GNUNET_HELLO_address_free(addr) GNUNET_free(addr)
147
148
149 /**
150  * A HELLO message is used to exchange information about
151  * transports with other peers.  This struct is guaranteed
152  * to start with a "GNUNET_MessageHeader", everything else
153  * should be internal to the HELLO library.
154  */
155 struct GNUNET_HELLO_Message;
156
157
158 /**
159  * Copy the given address information into
160  * the given buffer using the format of HELLOs.
161  *
162  * @param address address to add
163  * @param expiration expiration for the address
164  * @param target where to copy the address
165  * @param max maximum number of bytes to copy to target
166  * @return number of bytes copied, 0 if
167  *         the target buffer was not big enough.
168  */
169 size_t
170 GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address,
171                           struct GNUNET_TIME_Absolute expiration, char *target,
172                           size_t max);
173
174
175 /**
176  * Callback function used to fill a buffer of max bytes with a list of
177  * addresses in the format used by HELLOs.  Should use
178  * "GNUNET_HELLO_add_address" as a helper function.
179  *
180  * @param cls closure
181  * @param max maximum number of bytes that can be written to buf
182  * @param buf where to write the address information
183  * @return number of bytes written, 0 to signal the
184  *         end of the iteration.
185  */
186 typedef size_t (*GNUNET_HELLO_GenerateAddressListCallback) (void *cls,
187                                                             size_t max,
188                                                             void *buf);
189
190
191 /**
192  * Construct a HELLO message given the public key,
193  * expiration time and an iterator that spews the
194  * transport addresses.
195  *
196  * If friend only is set to GNUNET_YES we create a FRIEND_HELLO which will
197  * not be gossiped to other peers
198  *
199  * @return the hello message
200  */
201 struct GNUNET_HELLO_Message *
202 GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded
203                      *publicKey,
204                      GNUNET_HELLO_GenerateAddressListCallback addrgen,
205                      void *addrgen_cls,
206                      int friend_only);
207
208
209 /**
210  * Return the size of the given HELLO message.
211  * @param hello to inspect
212  * @return the size, 0 if HELLO is invalid
213  */
214 uint16_t
215 GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello);
216
217
218 /**
219  * Construct a HELLO message by merging the
220  * addresses in two existing HELLOs (which
221  * must be for the same peer).
222  *
223  * @param h1 first HELLO message
224  * @param h2 the second HELLO message
225  * @return the combined hello message
226  */
227 struct GNUNET_HELLO_Message *
228 GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1,
229                     const struct GNUNET_HELLO_Message *h2);
230
231
232 /**
233  * Test if two HELLO messages contain the same addresses.
234  * If they only differ in expiration time, the lowest
235  * expiration time larger than 'now' where they differ
236  * is returned.
237  *
238  * @param h1 first HELLO message
239  * @param h2 the second HELLO message
240  * @param now time to use for deciding which addresses have
241  *            expired and should not be considered at all
242  * @return absolute time forever if the two HELLOs are
243  *         totally identical; smallest timestamp >= now if
244  *         they only differ in timestamps;
245  *         zero if the some addresses with expirations >= now
246  *         do not match at all
247  */
248 struct GNUNET_TIME_Absolute
249 GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
250                      const struct GNUNET_HELLO_Message *h2,
251                      struct GNUNET_TIME_Absolute now);
252
253
254 /**
255  * Iterator callback to go over all addresses.
256  *
257  * @param cls closure
258  * @param address the address
259  * @param expiration expiration time
260  * @return GNUNET_OK to keep the address,
261  *         GNUNET_NO to delete it from the HELLO
262  *         GNUNET_SYSERR to stop iterating (but keep current address)
263  */
264 typedef int (*GNUNET_HELLO_AddressIterator) (void *cls,
265                                              const struct GNUNET_HELLO_Address *
266                                              address,
267                                              struct GNUNET_TIME_Absolute
268                                              expiration);
269
270
271 /**
272  * When does the last address in the given HELLO expire?
273  *
274  * @param msg HELLO to inspect
275  * @return time the last address expires, 0 if there are no addresses in the HELLO
276  */
277 struct GNUNET_TIME_Absolute
278 GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg);
279
280
281 /**
282  * Iterate over all of the addresses in the HELLO.
283  *
284  * @param msg HELLO to iterate over; client does not need to
285  *        have verified that msg is well-formed (beyond starting
286  *        with a GNUNET_MessageHeader of the right type).
287  * @param return_modified if a modified copy should be returned,
288  *         otherwise NULL will be returned
289  * @param it iterator to call on each address
290  * @param it_cls closure for it
291  * @return the modified HELLO or NULL
292  */
293 struct GNUNET_HELLO_Message *
294 GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
295                                 int return_modified,
296                                 GNUNET_HELLO_AddressIterator it, void *it_cls);
297
298
299 /**
300  * Iterate over addresses in "new_hello" that
301  * are NOT already present in "old_hello".
302  *
303  * @param new_hello a HELLO message
304  * @param old_hello a HELLO message
305  * @param expiration_limit ignore addresses in old_hello
306  *        that expired before the given time stamp
307  * @param it iterator to call on each address
308  * @param it_cls closure for it
309  */
310 void
311 GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message
312                                     *new_hello,
313                                     const struct GNUNET_HELLO_Message
314                                     *old_hello,
315                                     struct GNUNET_TIME_Absolute
316                                     expiration_limit,
317                                     GNUNET_HELLO_AddressIterator it,
318                                     void *it_cls);
319
320
321 /**
322  * Get the public key from a HELLO message.
323  *
324  * @param hello the hello message
325  * @param publicKey where to copy the public key information, can be NULL
326  * @return GNUNET_SYSERR if the HELLO was malformed
327  */
328 int
329 GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
330                       struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded
331                       *publicKey);
332
333
334 /**
335  * Get the peer identity from a HELLO message.
336  *
337  * @param hello the hello message
338  * @param peer where to store the peer's identity
339  * @return GNUNET_SYSERR if the HELLO was malformed
340  */
341 int
342 GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello,
343                      struct GNUNET_PeerIdentity *peer);
344
345
346 /**
347  * Get the header from a HELLO message, used so other code
348  * can correctly send HELLO messages.
349  *
350  * @param hello the hello message
351  *
352  * @return header or NULL if the HELLO was malformed
353  */
354 struct GNUNET_MessageHeader *
355 GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello);
356
357
358 typedef struct GNUNET_TRANSPORT_PluginFunctions *
359 (*GNUNET_HELLO_TransportPluginsFind) (const char *name);
360
361
362 /**
363  * Compose a hello URI string from a hello message.
364  *
365  * @param hello Hello message
366  * @param plugins_find Function to find transport plugins by name
367  * @return Hello URI string
368  */
369 char *
370 GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
371                           GNUNET_HELLO_TransportPluginsFind plugins_find);
372
373 /**
374  * Parse a hello URI string to a hello message.
375  *
376  * @param uri URI string to parse
377  * @param pubkey Pointer to struct where public key is parsed
378  * @param hello Pointer to struct where hello message is parsed
379  * @param plugins_find Function to find transport plugins by name
380  * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
381  */
382 int
383 GNUNET_HELLO_parse_uri (const char *uri,
384                         struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pubkey,
385                         struct GNUNET_HELLO_Message **hello,
386                         GNUNET_HELLO_TransportPluginsFind plugins_find);
387
388 #if 0                           /* keep Emacsens' auto-indent happy */
389 {
390 #endif
391 #ifdef __cplusplus
392 }
393 #endif
394
395
396 /* ifndef GNUNET_HELLO_LIB_H */
397 #endif
398 /* end of gnunet_hello_lib.h */