aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_hello_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport_api_hello_get.c')
-rw-r--r--src/transport/transport_api_hello_get.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/transport/transport_api_hello_get.c b/src/transport/transport_api_hello_get.c
new file mode 100644
index 000000000..9d4209e04
--- /dev/null
+++ b/src/transport/transport_api_hello_get.c
@@ -0,0 +1,275 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file transport/transport_api_hello_get.c
23 * @brief library to obtain our HELLO from our transport service
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_arm_service.h"
30#include "gnunet_hello_lib.h"
31#include "gnunet_protocols.h"
32#include "gnunet_transport_hello_service.h"
33#include "transport.h"
34
35
36/**
37 * Functions to call with this peer's HELLO.
38 */
39struct GNUNET_TRANSPORT_HelloGetHandle
40{
41
42 /**
43 * Our configuration.
44 */
45 const struct GNUNET_CONFIGURATION_Handle *cfg;
46
47 /**
48 * Transport handle.
49 */
50 struct GNUNET_MQ_Handle *mq;
51
52 /**
53 * Callback to call once we got our HELLO.
54 */
55 GNUNET_TRANSPORT_HelloUpdateCallback rec;
56
57 /**
58 * Closure for @e rec.
59 */
60 void *rec_cls;
61
62 /**
63 * Task for calling the HelloUpdateCallback when we already have a HELLO
64 */
65 struct GNUNET_SCHEDULER_Task *notify_task;
66
67 /**
68 * ID of the task trying to reconnect to the service.
69 */
70 struct GNUNET_SCHEDULER_Task *reconnect_task;
71
72 /**
73 * Delay until we try to reconnect.
74 */
75 struct GNUNET_TIME_Relative reconnect_delay;
76
77 /**
78 * Type of HELLOs client cares about.
79 */
80 enum GNUNET_ATS_Network_Type nt;
81};
82
83
84/**
85 * Function we use for checking incoming HELLO messages.
86 *
87 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
88 * @param msg message received
89 * @return #GNUNET_OK if message is well-formed
90 */
91static int
92check_hello (void *cls,
93 const struct GNUNET_MessageHeader *msg)
94{
95 struct GNUNET_PeerIdentity me;
96
97 if (GNUNET_OK !=
98 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg,
99 &me))
100 {
101 GNUNET_break (0);
102 return GNUNET_SYSERR;
103 }
104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
105 "Receiving (my own) HELLO message (%u bytes), I am `%s'.\n",
106 (unsigned int) ntohs (msg->size),
107 GNUNET_i2s (&me));
108 return GNUNET_OK;
109}
110
111
112/**
113 * Function we use for handling incoming HELLO messages.
114 *
115 * @param cls closure, a `struct GNUNET_TRANSPORT_HelloGetHandle *`
116 * @param msg message received
117 */
118static void
119handle_hello (void *cls,
120 const struct GNUNET_MessageHeader *msg)
121{
122 struct GNUNET_TRANSPORT_HelloGetHandle *ghh = cls;
123
124 ghh->rec (ghh->rec_cls,
125 msg);
126}
127
128
129/**
130 * Function that will schedule the job that will try
131 * to connect us again to the client.
132 *
133 * @param ghh transport service to reconnect
134 */
135static void
136schedule_reconnect (struct GNUNET_TRANSPORT_HelloGetHandle *ghh);
137
138
139/**
140 * Generic error handler, called with the appropriate
141 * error code and the same closure specified at the creation of
142 * the message queue.
143 * Not every message queue implementation supports an error handler.
144 *
145 * @param cls closure with the `struct GNUNET_TRANSPORT_Handle *`
146 * @param error error code
147 */
148static void
149mq_error_handler (void *cls,
150 enum GNUNET_MQ_Error error)
151{
152 struct GNUNET_TRANSPORT_HelloGetHandle *ghh = cls;
153
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
155 "Error receiving from transport service, disconnecting temporarily.\n");
156 GNUNET_MQ_destroy (ghh->mq);
157 ghh->mq = NULL;
158 schedule_reconnect (ghh);
159}
160
161
162/**
163 * Try again to connect to transport service.
164 *
165 * @param cls the handle to the transport service
166 */
167static void
168reconnect (void *cls)
169{
170 GNUNET_MQ_hd_var_size (hello,
171 GNUNET_MESSAGE_TYPE_HELLO,
172 struct GNUNET_MessageHeader);
173 struct GNUNET_TRANSPORT_HelloGetHandle *ghh = cls;
174 struct GNUNET_MQ_MessageHandler handlers[] = {
175 make_hello_handler (ghh),
176 GNUNET_MQ_handler_end ()
177 };
178 struct GNUNET_MQ_Envelope *env;
179 struct StartMessage *s;
180
181 ghh->reconnect_task = NULL;
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
183 "Connecting to transport service.\n");
184 GNUNET_assert (NULL == ghh->mq);
185 ghh->mq = GNUNET_CLIENT_connecT (ghh->cfg,
186 "transport",
187 handlers,
188 &mq_error_handler,
189 ghh);
190 if (NULL == ghh->mq)
191 return;
192 env = GNUNET_MQ_msg (s,
193 GNUNET_MESSAGE_TYPE_TRANSPORT_START);
194 s->options = htonl (0);
195 GNUNET_MQ_send (ghh->mq,
196 env);
197}
198
199
200/**
201 * Function that will schedule the job that will try
202 * to connect us again to the client.
203 *
204 * @param ghh transport service to reconnect
205 */
206static void
207schedule_reconnect (struct GNUNET_TRANSPORT_HelloGetHandle *ghh)
208{
209 ghh->reconnect_task =
210 GNUNET_SCHEDULER_add_delayed (ghh->reconnect_delay,
211 &reconnect,
212 ghh);
213 ghh->reconnect_delay = GNUNET_TIME_STD_BACKOFF (ghh->reconnect_delay);
214}
215
216
217/**
218 * Obtain the HELLO message for this peer. The callback given in this function
219 * is never called synchronously.
220 *
221 * @param cfg configuration
222 * @param nt which network type should the addresses from the HELLO belong to?
223 * @param rec function to call with the HELLO, sender will be our peer
224 * identity; message and sender will be NULL on timeout
225 * (handshake with transport service pending/failed).
226 * cost estimate will be 0.
227 * @param rec_cls closure for @a rec
228 * @return handle to cancel the operation
229 */
230struct GNUNET_TRANSPORT_HelloGetHandle *
231GNUNET_TRANSPORT_hello_get (const struct GNUNET_CONFIGURATION_Handle *cfg,
232 enum GNUNET_ATS_Network_Type nt,
233 GNUNET_TRANSPORT_HelloUpdateCallback rec,
234 void *rec_cls)
235{
236 struct GNUNET_TRANSPORT_HelloGetHandle *ghh;
237
238 ghh = GNUNET_new (struct GNUNET_TRANSPORT_HelloGetHandle);
239 ghh->rec = rec;
240 ghh->rec_cls = rec_cls;
241 ghh->cfg = cfg;
242 ghh->nt = nt;
243 reconnect (ghh);
244 if (NULL == ghh->mq)
245 {
246 GNUNET_free (ghh);
247 return NULL;
248 }
249 return ghh;
250}
251
252
253/**
254 * Stop receiving updates about changes to our HELLO message.
255 *
256 * @param ghh handle to cancel
257 */
258void
259GNUNET_TRANSPORT_hello_get_cancel (struct GNUNET_TRANSPORT_HelloGetHandle *ghh)
260{
261 if (NULL != ghh->reconnect_task)
262 {
263 GNUNET_SCHEDULER_cancel (ghh->reconnect_task);
264 ghh->reconnect_task = NULL;
265 }
266 if (NULL != ghh->mq)
267 {
268 GNUNET_MQ_destroy (ghh->mq);
269 ghh->mq = NULL;
270 }
271 GNUNET_free (ghh);
272}
273
274
275/* end of transport_api_hello_get.c */