2 This file is part of GNUnet.
3 Copyright (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 GNUnet e.V.
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.
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.
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file peerinfo/peerinfo_api_notify.c
23 * @brief notify API to access peerinfo service
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_peerinfo_service.h"
29 #include "gnunet_protocols.h"
32 #define LOG(kind,...) GNUNET_log_from (kind, "peerinfo-api",__VA_ARGS__)
35 * Context for the info handler.
37 struct GNUNET_PEERINFO_NotifyContext
41 * Our connection to the PEERINFO service.
43 struct GNUNET_MQ_Handle *mq;
46 * Function to call with information.
48 GNUNET_PEERINFO_Processor callback;
51 * Closure for @e callback.
58 const struct GNUNET_CONFIGURATION_Handle *cfg;
61 * Tasked used for delayed re-connection attempt.
63 struct GNUNET_SCHEDULER_Task *task;
66 * Include friend only HELLOs in callbacks
68 int include_friend_only;
73 * Task to re-try connecting to peerinfo.
75 * @param cls the `struct GNUNET_PEERINFO_NotifyContext *`
78 reconnect (void *cls);
82 * We encountered an error, reconnect to the service.
84 * @param nc context to reconnect
87 do_reconnect (struct GNUNET_PEERINFO_NotifyContext *nc)
89 GNUNET_MQ_destroy (nc->mq);
91 nc->task = GNUNET_SCHEDULER_add_now (&reconnect,
97 * We got a disconnect after asking regex to do the announcement.
100 * @param cls the `struct GNUNET_PEERINFO_NotifyContext` to retry
101 * @param error error code
104 mq_error_handler (void *cls,
105 enum GNUNET_MQ_Error error)
107 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
114 * Check that a peerinfo information message is well-formed.
117 * @param im message received
118 * @return #GNUNET_OK if the message is well-formed
121 check_notification (void *cls,
122 const struct InfoMessage *im)
124 uint16_t ms = ntohs (im->header.size) - sizeof (*im);
126 if (ms >= sizeof (struct GNUNET_MessageHeader))
128 const struct GNUNET_HELLO_Message *hello;
130 hello = (const struct GNUNET_HELLO_Message *) &im[1];
131 if (ms != GNUNET_HELLO_size (hello))
134 return GNUNET_SYSERR;
141 return GNUNET_SYSERR;
143 return GNUNET_OK; /* odd... */
148 * Receive a peerinfo information message, process it.
151 * @param im message received
154 handle_notification (void *cls,
155 const struct InfoMessage *im)
157 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
158 const struct GNUNET_HELLO_Message *hello;
159 uint16_t ms = ntohs (im->header.size) - sizeof (struct InfoMessage);
163 hello = (const struct GNUNET_HELLO_Message *) &im[1];
164 LOG (GNUNET_ERROR_TYPE_DEBUG,
165 "Received information about peer `%s' from peerinfo database\n",
166 GNUNET_i2s (&im->peer));
167 nc->callback (nc->callback_cls,
175 * Task to re-try connecting to peerinfo.
177 * @param cls the `struct GNUNET_PEERINFO_NotifyContext *`
180 reconnect (void *cls)
182 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
183 struct GNUNET_MQ_MessageHandler handlers[] = {
184 GNUNET_MQ_hd_var_size (notification,
185 GNUNET_MESSAGE_TYPE_PEERINFO_INFO,
188 GNUNET_MQ_handler_end ()
190 struct GNUNET_MQ_Envelope *env;
191 struct NotifyMessage *nm;
194 nc->mq = GNUNET_CLIENT_connecT (nc->cfg,
201 env = GNUNET_MQ_msg (nm,
202 GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY);
203 nm->include_friend_only = htonl (nc->include_friend_only);
204 GNUNET_MQ_send (nc->mq,
210 * Call a method whenever our known information about peers
211 * changes. Initially calls the given function for all known
212 * peers and then only signals changes.
214 * If @a include_friend_only is set to #GNUNET_YES peerinfo will include HELLO
215 * messages which are intended for friend to friend mode and which do not
216 * have to be gossiped. Otherwise these messages are skipped.
218 * @param cfg configuration to use
219 * @param include_friend_only include HELLO messages for friends only
220 * @param callback the method to call for each peer
221 * @param callback_cls closure for @a callback
222 * @return NULL on error
224 struct GNUNET_PEERINFO_NotifyContext *
225 GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg,
226 int include_friend_only,
227 GNUNET_PEERINFO_Processor callback,
230 struct GNUNET_PEERINFO_NotifyContext *nc;
232 nc = GNUNET_new (struct GNUNET_PEERINFO_NotifyContext);
234 nc->callback = callback;
235 nc->callback_cls = callback_cls;
236 nc->include_friend_only = include_friend_only;
240 LOG (GNUNET_ERROR_TYPE_WARNING,
241 "Could not connect to PEERINFO service.\n");
250 * Stop notifying about changes.
252 * @param nc context to stop notifying
255 GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc)
259 GNUNET_MQ_destroy (nc->mq);
262 if (NULL != nc->task)
264 GNUNET_SCHEDULER_cancel (nc->task);
270 /* end of peerinfo_api_notify.c */