GNUnet 0.21.0
dns_api.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
26#include "platform.h"
27#include "gnunet_dns_service.h"
28#include "dns.h"
29
30
35{
40
44 uint64_t request_id;
45
49 uint32_t generation;
50};
51
52
57{
62
67
72
76 void *rh_cls;
77
82
86 uint32_t generation;
87
92
97 unsigned int pending_requests;
98};
99
100
106static void
107reconnect (void *cls);
108
109
115static void
117{
118 if (NULL != dh->mq)
119 {
120 GNUNET_MQ_destroy (dh->mq);
121 dh->mq = NULL;
122 }
123 dh->reconnect_task =
125 &reconnect,
126 dh);
127}
128
129
138static void
140 enum GNUNET_MQ_Error error)
141{
142 struct GNUNET_DNS_Handle *dh = cls;
143
144 force_reconnect (dh);
145}
146
147
155static int
156check_request (void *cls,
157 const struct GNUNET_DNS_Request *req)
158{
159 if (0 != ntohl (req->reserved))
160 {
161 GNUNET_break (0);
162 return GNUNET_SYSERR;
163 }
164 return GNUNET_OK;
165}
166
167
175static void
176handle_request (void *cls,
177 const struct GNUNET_DNS_Request *req)
178{
179 struct GNUNET_DNS_Handle *dh = cls;
180 size_t payload_length = ntohs (req->header.size) - sizeof(*req);
181 struct GNUNET_DNS_RequestHandle *rh;
182
184 rh->dh = dh;
185 rh->request_id = req->request_id;
186 rh->generation = dh->generation;
188 dh->rh (dh->rh_cls,
189 rh,
190 payload_length,
191 (const char *) &req[1]);
192}
193
194
195static void
196reconnect (void *cls)
197{
198 struct GNUNET_DNS_Handle *dh = cls;
202 struct GNUNET_DNS_Request,
203 dh),
205 };
206 struct GNUNET_MQ_Envelope *env;
207 struct GNUNET_DNS_Register *msg;
208
209 dh->reconnect_task = NULL;
210 dh->mq = GNUNET_CLIENT_connect (dh->cfg,
211 "dns",
212 handlers,
214 dh);
215 if (NULL == dh->mq)
216 return;
217 dh->generation++;
220 msg->flags = htonl (dh->flags);
221 GNUNET_MQ_send (dh->mq,
222 env);
223}
224
225
236void
238{
239 struct GNUNET_MQ_Envelope *env;
240 struct GNUNET_DNS_Response *resp;
241
242 GNUNET_assert (0 < rh->dh->pending_requests--);
243 if (rh->generation != rh->dh->generation)
244 {
245 GNUNET_free (rh);
246 return;
247 }
248 env = GNUNET_MQ_msg (resp,
250 resp->drop_flag = htonl (1);
251 resp->request_id = rh->request_id;
252 GNUNET_MQ_send (rh->dh->mq,
253 env);
254 GNUNET_free (rh);
255}
256
257
264void
266{
267 struct GNUNET_MQ_Envelope *env;
268 struct GNUNET_DNS_Response *resp;
269
270 GNUNET_assert (0 < rh->dh->pending_requests--);
271 if (rh->generation != rh->dh->generation)
272 {
273 GNUNET_free (rh);
274 return;
275 }
276 env = GNUNET_MQ_msg (resp,
278 resp->request_id = rh->request_id;
279 resp->drop_flag = htonl (0);
280 GNUNET_MQ_send (rh->dh->mq,
281 env);
282 GNUNET_free (rh);
283}
284
285
295void
297 uint16_t reply_length,
298 const char *reply)
299{
300 struct GNUNET_MQ_Envelope *env;
301 struct GNUNET_DNS_Response *resp;
302
303 GNUNET_assert (0 < rh->dh->pending_requests--);
304 if (rh->generation != rh->dh->generation)
305 {
306 GNUNET_free (rh);
307 return;
308 }
309 if (reply_length + sizeof(struct GNUNET_DNS_Response)
311 {
312 GNUNET_break (0);
313 GNUNET_free (rh);
314 return;
315 }
316 env = GNUNET_MQ_msg_extra (resp,
317 reply_length,
319 resp->drop_flag = htonl (2);
320 resp->request_id = rh->request_id;
321 GNUNET_memcpy (&resp[1],
322 reply,
323 reply_length);
324 GNUNET_MQ_send (rh->dh->mq,
325 env);
326 GNUNET_free (rh);
327}
328
329
339struct GNUNET_DNS_Handle *
343 void *rh_cls)
344{
345 struct GNUNET_DNS_Handle *dh;
346
347 dh = GNUNET_new (struct GNUNET_DNS_Handle);
348 dh->cfg = cfg;
349 dh->flags = flags;
350 dh->rh = rh;
351 dh->rh_cls = rh_cls;
353 return dh;
354}
355
356
362void
364{
365 if (NULL != dh->mq)
366 {
367 GNUNET_MQ_destroy (dh->mq);
368 dh->mq = NULL;
369 }
370 if (NULL != dh->reconnect_task)
371 {
373 dh->reconnect_task = NULL;
374 }
375 /* make sure client has no pending requests left over! */
377 GNUNET_free (dh);
378}
379
380
381/* end of dns_api.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
IPC messages between DNS API and DNS service.
static void force_reconnect(struct GNUNET_DNS_Handle *dh)
Drop the existing connection and reconnect to the DNS service.
Definition: dns_api.c:116
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: dns_api.c:139
static void reconnect(void *cls)
Reconnect to the DNS service.
Definition: dns_api.c:196
static int check_request(void *cls, const struct GNUNET_DNS_Request *req)
This receives packets from the DNS service and calls the application to check that the request is wel...
Definition: dns_api.c:156
static void handle_request(void *cls, const struct GNUNET_DNS_Request *req)
This receives packets from the DNS service and calls the application to handle it.
Definition: dns_api.c:176
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
API to access the DNS service.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
void(* GNUNET_DNS_RequestHandler)(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
Signature of a function that is called whenever the DNS service encounters a DNS request and needs to...
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:363
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is given to other clients or the glob...
Definition: dns_api.c:237
void GNUNET_DNS_request_answer(struct GNUNET_DNS_RequestHandle *rh, uint16_t reply_length, const char *reply)
If a GNUNET_DNS_RequestHandler calls this function, the request is supposed to be answered with the d...
Definition: dns_api.c:296
struct GNUNET_DNS_Handle * GNUNET_DNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_DNS_Flags flags, GNUNET_DNS_RequestHandler rh, void *rh_cls)
Connect to the service-dns.
Definition: dns_api.c:340
void GNUNET_DNS_request_drop(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is to be dropped and no response shou...
Definition: dns_api.c:265
GNUNET_DNS_Flags
Flags that specify when to call the client's handler.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST
Type of messages between the gnunet-helper-dns and the service.
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE
Type of messages between the gnunet-helper-dns and the service.
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT
Initial message from client to DNS service for registration.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
#define GNUNET_TIME_UNIT_SECONDS
One second.
DNS handle.
Definition: dns_api.c:57
struct GNUNET_SCHEDULER_Task * reconnect_task
Task to reconnect to the service.
Definition: dns_api.c:81
GNUNET_DNS_RequestHandler rh
Function to call to get replies.
Definition: dns_api.c:71
enum GNUNET_DNS_Flags flags
Flags for events we care about.
Definition: dns_api.c:91
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: dns_api.c:66
struct GNUNET_MQ_Handle * mq
Connection to DNS service, or NULL.
Definition: dns_api.c:61
uint32_t generation
Re-connect counter, to make sure we did not reconnect in the meantime.
Definition: dns_api.c:86
unsigned int pending_requests
Number of GNUNET_DNS_RequestHandles we have outstanding.
Definition: dns_api.c:97
void * rh_cls
Closure for rh.
Definition: dns_api.c:76
Message from client to DNS service to register itself.
Definition: dns.h:36
Handle to identify an individual DNS request.
Definition: dns_api.c:35
struct GNUNET_DNS_Handle * dh
Handle to DNS API.
Definition: dns_api.c:39
uint32_t generation
Re-connect counter, to make sure we did not reconnect in the meantime.
Definition: dns_api.c:49
uint64_t request_id
Stored in network byte order (as for us, it is just a random number).
Definition: dns_api.c:44
Message from DNS service to client: please handle a request.
Definition: dns.h:53
uint32_t reserved
Always zero.
Definition: dns.h:62
uint64_t request_id
Unique request ID.
Definition: dns.h:67
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST.
Definition: dns.h:57
Message from client to DNS service: here is my reply.
Definition: dns.h:77
uint32_t drop_flag
Zero to drop, 1 for no change (no payload), 2 for update (message has payload).
Definition: dns.h:86
uint64_t request_id
Unique request ID.
Definition: dns.h:91
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Entry in list of pending tasks.
Definition: scheduler.c:136