2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2007, 2009 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file peerinfo/peerinfo_api.c
23 * @brief API to access peerinfo service
24 * @author Christian Grothoff
27 #include "gnunet_client_lib.h"
28 #include "gnunet_peerinfo_service.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_time_lib.h"
33 #define ADD_PEER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
38 struct GNUNET_CLIENT_Connection *client;
39 struct GNUNET_MessageHeader *msg;
44 copy_and_free (void *cls, size_t size, void *buf)
46 struct CAFContext *cc = cls;
47 struct GNUNET_MessageHeader *msg = cc->msg;
52 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
54 ("Failed to transmit message of type %u to `%s' service.\n"),
55 ntohs (msg->type), "peerinfo");
57 GNUNET_CLIENT_disconnect (cc->client);
61 msize = ntohs (msg->size);
62 GNUNET_assert (size >= msize);
63 memcpy (buf, msg, msize);
65 GNUNET_CLIENT_disconnect (cc->client);
73 * Add a host to the persistent list.
75 * @param cfg configuration to use
76 * @param sched scheduler to use
77 * @param peer identity of the peer
78 * @param hello the verified (!) HELLO message
79 * @param expiration when the HELLO will expire
82 GNUNET_PEERINFO_add_peer (struct GNUNET_CONFIGURATION_Handle *cfg,
83 struct GNUNET_SCHEDULER_Handle *sched,
84 const struct GNUNET_PeerIdentity *peer,
85 const struct GNUNET_HELLO_Message *hello)
87 struct GNUNET_CLIENT_Connection *client;
88 struct PeerAddMessage *pam;
90 struct CAFContext *cc;
92 client = GNUNET_CLIENT_connect (sched, "peerinfo", cfg);
95 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
96 _("Could not connect to `%s' service.\n"), "peerinfo");
99 hs = GNUNET_HELLO_size (hello);
100 pam = GNUNET_malloc (sizeof (struct PeerAddMessage) + hs);
101 pam->header.size = htons (hs + sizeof (struct PeerAddMessage));
102 pam->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_ADD);
103 memcpy (&pam->peer, peer, sizeof (struct GNUNET_PeerIdentity));
104 memcpy (&pam[1], hello, hs);
105 cc = GNUNET_malloc (sizeof (struct CAFContext));
107 cc->msg = &pam->header;
108 GNUNET_CLIENT_notify_transmit_ready (client,
109 ntohs (pam->header.size),
110 ADD_PEER_TIMEOUT, ©_and_free, cc);
115 * Context for the info handler.
121 * Our connection to the PEERINFO service.
123 struct GNUNET_CLIENT_Connection *client;
126 * Function to call with information.
128 GNUNET_PEERINFO_Processor callback;
131 * Closure for callback.
136 * When should we time out?
138 struct GNUNET_TIME_Absolute timeout;
144 * Type of a function to call when we receive a message
148 * @param msg message received, NULL on timeout or fatal error
151 info_handler (void *cls, const struct GNUNET_MessageHeader *msg)
153 struct InfoContext *ic = cls;
154 const struct InfoMessage *im;
155 const struct GNUNET_HELLO_Message *hello;
160 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
161 _("Failed to receive response from `%s' service.\n"),
163 ic->callback (ic->callback_cls, NULL, NULL, 1);
164 GNUNET_CLIENT_disconnect (ic->client);
168 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END)
170 ic->callback (ic->callback_cls, NULL, NULL, 0);
171 GNUNET_CLIENT_disconnect (ic->client);
175 ms = ntohs (msg->size);
176 if ((ms < sizeof (struct InfoMessage)) ||
177 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
180 ic->callback (ic->callback_cls, NULL, NULL, 2);
181 GNUNET_CLIENT_disconnect (ic->client);
185 im = (const struct InfoMessage *) msg;
187 if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader))
189 hello = (const struct GNUNET_HELLO_Message *) &im[1];
190 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
193 ic->callback (ic->callback_cls, NULL, NULL, 2);
194 GNUNET_CLIENT_disconnect (ic->client);
199 ic->callback (ic->callback_cls, &im->peer, hello, ntohl (im->trust));
200 GNUNET_CLIENT_receive (ic->client,
203 GNUNET_TIME_absolute_get_remaining (ic->timeout));
208 copy_then_receive (void *cls, size_t size, void *buf)
210 struct InfoContext *ic = cls;
211 const struct GNUNET_MessageHeader *msg =
212 (const struct GNUNET_MessageHeader *) &ic[1];
217 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
219 ("Failed to transmit message of type %u to `%s' service.\n"),
220 ntohs (msg->type), "peerinfo");
221 ic->callback (ic->callback_cls, NULL, NULL, 1);
222 GNUNET_CLIENT_disconnect (ic->client);
226 msize = ntohs (msg->size);
227 GNUNET_assert (size >= msize);
228 memcpy (buf, msg, msize);
229 GNUNET_CLIENT_receive (ic->client,
232 GNUNET_TIME_absolute_get_remaining (ic->timeout));
238 * Call a method for each known matching host and change
239 * its trust value. The method will be invoked once for
240 * each host and then finally once with a NULL pointer.
241 * Note that the last call can be triggered by timeout or
242 * by simply being done; however, the trust argument will
243 * be set to zero if we are done and to 1 if we timed out.
245 * @param cfg configuration to use
246 * @param sched scheduler to use
247 * @param peer restrict iteration to this peer only (can be NULL)
248 * @param trust_delta how much to change the trust in all matching peers
249 * @param timeout how long to wait until timing out
250 * @param callback the method to call for each peer
251 * @param callback_cls closure for callback
254 GNUNET_PEERINFO_for_all (struct GNUNET_CONFIGURATION_Handle *cfg,
255 struct GNUNET_SCHEDULER_Handle *sched,
256 const struct GNUNET_PeerIdentity *peer,
258 struct GNUNET_TIME_Relative timeout,
259 GNUNET_PEERINFO_Processor callback,
262 struct GNUNET_CLIENT_Connection *client;
263 struct ListAllPeersMessage *lapm;
264 struct ListPeerMessage *lpm;
266 struct InfoContext *ihc;
268 client = GNUNET_CLIENT_connect (sched, "peerinfo", cfg);
271 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
272 _("Could not connect to `%s' service.\n"), "peerinfo");
273 callback (callback_cls, NULL, NULL, 2);
276 ihc = GNUNET_malloc (sizeof (struct InfoContext) +
277 sizeof (struct ListPeerMessage));
278 ihc->client = client;
279 ihc->callback = callback;
280 ihc->callback_cls = callback_cls;
281 ihc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
285 lapm = (struct ListAllPeersMessage *) &ihc[1];
286 lapm->header.size = htons (hs = sizeof (struct ListAllPeersMessage));
287 lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
288 lapm->trust_change = htonl (trust_delta);
292 lpm = (struct ListPeerMessage *) &ihc[1];
293 lpm->header.size = htons (hs = sizeof (struct ListPeerMessage));
294 lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
295 lpm->trust_change = htonl (trust_delta);
296 memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
298 GNUNET_CLIENT_notify_transmit_ready (client,
299 hs, timeout, ©_then_receive, ihc);
302 /* end of peerinfo_api.c */