aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-02 11:10:12 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-02 11:10:12 +0000
commitb734ef1365245bbaf42fbdb1861baeaa95327f67 (patch)
tree6f65f4ce7e052244c5523bdcc89724820ca41d56 /src/core
parent45063a766d9a922d7f2b762ede305679e728cbfc (diff)
downloadgnunet-b734ef1365245bbaf42fbdb1861baeaa95327f67.tar.gz
gnunet-b734ef1365245bbaf42fbdb1861baeaa95327f67.zip
-fixing #2293
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am3
-rw-r--r--src/core/core_api_is_connected.c232
-rw-r--r--src/core/core_api_iterate_peers.c46
3 files changed, 235 insertions, 46 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index b79b6cc6a..e95cbcffd 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -20,7 +20,8 @@ lib_LTLIBRARIES = \
20 20
21libgnunetcore_la_SOURCES = \ 21libgnunetcore_la_SOURCES = \
22 core_api.c core.h \ 22 core_api.c core.h \
23 core_api_iterate_peers.c 23 core_api_iterate_peers.c \
24 core_api_is_connected.c
24libgnunetcore_la_LIBADD = \ 25libgnunetcore_la_LIBADD = \
25 $(top_builddir)/src/util/libgnunetutil.la \ 26 $(top_builddir)/src/util/libgnunetutil.la \
26 $(GN_LIBINTL) $(XLIB) 27 $(GN_LIBINTL) $(XLIB)
diff --git a/src/core/core_api_is_connected.c b/src/core/core_api_is_connected.c
new file mode 100644
index 000000000..2e56dffc8
--- /dev/null
+++ b/src/core/core_api_is_connected.c
@@ -0,0 +1,232 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010, 2012 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 core/core_api_is_connected.c
23 * @brief implementation of the 'GNUNET_CORE_is_peer_connected function
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 *
27 * TODO:
28 * - define nice structs for the IPC messages in core.h
29 * - consider NOT always sending the 'END' message -- it is redundant!
30 */
31#include "platform.h"
32#include "gnunet_core_service.h"
33#include "core.h"
34
35
36/**
37 * Closure for 'transmit_is_connected_request"
38 */
39struct GNUNET_CORE_ConnectTestHandle
40{
41
42 /**
43 * Our connection to the service.
44 */
45 struct GNUNET_CLIENT_Connection *client;
46
47 /**
48 * Handle for transmitting a request.
49 */
50 struct GNUNET_CLIENT_TransmitHandle *th;
51
52 /**
53 * Function called with the peer.
54 */
55 GNUNET_CORE_ConnectEventHandler peer_cb;
56
57 /**
58 * Peer to check for.
59 */
60 struct GNUNET_PeerIdentity peer;
61
62 /**
63 * Closure for peer_cb.
64 */
65 void *cb_cls;
66
67};
68
69
70/**
71 * Receive reply from core service with information about a peer.
72 *
73 * @param cls our 'struct GNUNET_CORE_RequestContext *'
74 * @param msg NULL on error or last entry
75 */
76static void
77receive_connect_info (void *cls, const struct GNUNET_MessageHeader *msg)
78{
79 struct GNUNET_CORE_ConnectTestHandle *cth = cls;
80 const struct ConnectNotifyMessage *connect_message;
81 uint32_t ats_count;
82 uint16_t msize;
83
84 if (NULL == msg)
85 {
86 /* core died, failure */
87 cth->peer_cb (cth->cb_cls, NULL, NULL, 0);
88 GNUNET_CORE_is_peer_connected_cancel (cth);
89 return;
90 }
91 if ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END) &&
92 (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader)))
93 {
94 /* end of transmissions */
95 cth->peer_cb (cth->cb_cls, NULL, NULL, 0);
96 GNUNET_CORE_is_peer_connected_cancel (cth);
97 return;
98 }
99 msize = ntohs (msg->size);
100 /* Handle incorrect message type or size, disconnect and clean up */
101 if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) ||
102 (msize < sizeof (struct ConnectNotifyMessage)))
103 {
104 GNUNET_break (0);
105 cth->peer_cb (cth->cb_cls, NULL, NULL, 0);
106 GNUNET_CORE_is_peer_connected_cancel (cth);
107 return;
108 }
109 connect_message = (const struct ConnectNotifyMessage *) msg;
110 ats_count = ntohl (connect_message->ats_count);
111 if (msize !=
112 sizeof (struct ConnectNotifyMessage) +
113 ats_count * sizeof (struct GNUNET_ATS_Information))
114 {
115 GNUNET_break (0);
116 cth->peer_cb (cth->cb_cls, NULL, NULL, 0);
117 GNUNET_CORE_is_peer_connected_cancel (cth);
118 return;
119 }
120 /* Normal case */
121 cth->peer_cb (cth->cb_cls, &connect_message->peer,
122 (const struct GNUNET_ATS_Information *)
123 &connect_message[1], ats_count);
124 GNUNET_CLIENT_receive (cth->client, &receive_connect_info,
125 cth, GNUNET_TIME_UNIT_FOREVER_REL);
126}
127
128
129/**
130 * Function called to notify a client about the socket
131 * begin ready to queue more data. "buf" will be
132 * NULL and "size" zero if the socket was closed for
133 * writing in the meantime.
134 *
135 * @param cls closure
136 * @param size number of bytes available in buf
137 * @param buf where the callee should write the message
138 * @return number of bytes written to buf
139 */
140static size_t
141transmit_is_connected_request (void *cls, size_t size, void *buf)
142{
143 struct GNUNET_CORE_ConnectTestHandle *cth = cls;
144 struct GNUNET_MessageHeader *msg;
145 unsigned int msize;
146
147 cth->th = NULL;
148 msize =
149 sizeof (struct GNUNET_MessageHeader) +
150 sizeof (struct GNUNET_PeerIdentity);
151 if ( (NULL == buf) || (0 == size) )
152 {
153 cth->peer_cb (cth->cb_cls,
154 NULL,
155 NULL, 0);
156 GNUNET_CLIENT_disconnect (cth->client);
157 GNUNET_free (cth);
158 return 0;
159 }
160 GNUNET_assert (size >= msize);
161 msg = (struct GNUNET_MessageHeader *) buf;
162 msg->size = htons (msize);
163 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED);
164 memcpy (&msg[1], &cth->peer, sizeof (struct GNUNET_PeerIdentity));
165 GNUNET_CLIENT_receive (cth->client, &receive_connect_info, cth,
166 GNUNET_TIME_UNIT_FOREVER_REL);
167 return msize;
168}
169
170
171/**
172 * Iterate over all currently connected peers.
173 * Calls peer_cb with each connected peer, and then
174 * once with NULL to indicate that all peers have
175 * been handled.
176 *
177 * @param cfg configuration to use
178 * @param peer the specific peer to check for
179 * @param peer_cb function to call with the peer information
180 * @param cb_cls closure for peer_cb
181 *
182 * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
183 */
184struct GNUNET_CORE_ConnectTestHandle *
185GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg,
186 const struct GNUNET_PeerIdentity *peer,
187 GNUNET_CORE_ConnectEventHandler peer_cb,
188 void *cb_cls)
189{
190 struct GNUNET_CORE_ConnectTestHandle *cth;
191 struct GNUNET_CLIENT_Connection *client;
192
193 GNUNET_assert (NULL != peer);
194 GNUNET_assert (NULL != peer_cb);
195 client = GNUNET_CLIENT_connect ("core", cfg);
196 if (NULL == client)
197 return NULL;
198 cth = GNUNET_malloc (sizeof (struct GNUNET_CORE_ConnectTestHandle));
199 cth->peer = *peer;
200 cth->client = client;
201 cth->peer_cb = peer_cb;
202 cth->cb_cls = cb_cls;
203 cth->th =
204 GNUNET_CLIENT_notify_transmit_ready (client,
205 sizeof (struct GNUNET_MessageHeader) +
206 sizeof (struct GNUNET_PeerIdentity),
207 GNUNET_TIME_relative_get_forever (),
208 GNUNET_YES, &transmit_is_connected_request, cth);
209 GNUNET_assert (NULL != cth->th);
210 return cth;
211}
212
213
214/**
215 * Abort 'is_connected' test operation.
216 *
217 * @param cth handle for operation to cancel
218 */
219void
220GNUNET_CORE_is_peer_connected_cancel (struct GNUNET_CORE_ConnectTestHandle *cth)
221{
222 if (NULL != cth->th)
223 {
224 GNUNET_CLIENT_notify_transmit_ready_cancel (cth->th);
225 cth->th = NULL;
226 }
227 GNUNET_CLIENT_disconnect (cth->client);
228 GNUNET_free (cth);
229}
230
231
232/* end of core_api_is_connected.c */
diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c
index 0ecd98ed7..8e6904480 100644
--- a/src/core/core_api_iterate_peers.c
+++ b/src/core/core_api_iterate_peers.c
@@ -119,6 +119,7 @@ receive_info (void *cls, const struct GNUNET_MessageHeader *msg)
119 request_context, GNUNET_TIME_UNIT_FOREVER_REL); 119 request_context, GNUNET_TIME_UNIT_FOREVER_REL);
120} 120}
121 121
122
122/** 123/**
123 * Function called to notify a client about the socket 124 * Function called to notify a client about the socket
124 * begin ready to queue more data. "buf" will be 125 * begin ready to queue more data. "buf" will be
@@ -143,10 +144,8 @@ transmit_request (void *cls, size_t size, void *buf)
143 msize = 144 msize =
144 sizeof (struct GNUNET_MessageHeader) + 145 sizeof (struct GNUNET_MessageHeader) +
145 sizeof (struct GNUNET_PeerIdentity); 146 sizeof (struct GNUNET_PeerIdentity);
146
147 if ((size < msize) || (buf == NULL)) 147 if ((size < msize) || (buf == NULL))
148 return 0; 148 return 0;
149
150 msg = (struct GNUNET_MessageHeader *) buf; 149 msg = (struct GNUNET_MessageHeader *) buf;
151 msg->size = htons (msize); 150 msg->size = htons (msize);
152 if (peer != NULL) 151 if (peer != NULL)
@@ -160,50 +159,7 @@ transmit_request (void *cls, size_t size, void *buf)
160 return msize; 159 return msize;
161} 160}
162 161
163/**
164 * Iterate over all currently connected peers.
165 * Calls peer_cb with each connected peer, and then
166 * once with NULL to indicate that all peers have
167 * been handled.
168 *
169 * @param cfg configuration to use
170 * @param peer the specific peer to check for
171 * @param peer_cb function to call with the peer information
172 * @param cb_cls closure for peer_cb
173 *
174 * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
175 */
176int
177GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg,
178 struct GNUNET_PeerIdentity *peer,
179 GNUNET_CORE_ConnectEventHandler peer_cb,
180 void *cb_cls)
181{
182 struct GNUNET_CORE_RequestContext *request_context;
183 struct GNUNET_CLIENT_Connection *client;
184
185 client = GNUNET_CLIENT_connect ("core", cfg);
186 if (client == NULL)
187 return GNUNET_SYSERR;
188 GNUNET_assert (peer != NULL);
189 request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext));
190 request_context->client = client;
191 request_context->peer_cb = peer_cb;
192 request_context->cb_cls = cb_cls;
193 request_context->peer = peer;
194 162
195 request_context->th =
196 GNUNET_CLIENT_notify_transmit_ready (client,
197 sizeof (struct GNUNET_MessageHeader)
198 +
199 sizeof (struct GNUNET_PeerIdentity),
200 GNUNET_TIME_relative_get_forever (),
201 GNUNET_YES, &transmit_request, peer);
202 GNUNET_assert (request_context->th != NULL);
203 GNUNET_CLIENT_receive (client, &receive_info, request_context,
204 GNUNET_TIME_relative_get_forever ());
205 return GNUNET_OK;
206}
207 163
208/** 164/**
209 * Iterate over all currently connected peers. 165 * Iterate over all currently connected peers.