GNUnet  0.11.x
transport_api_address_to_string.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2014, 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  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_arm_service.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_protocols.h"
31 #include "transport.h"
32 
37 {
42 
46  void *cb_cls;
47 
52 };
53 
54 
62 static int
63 check_reply (void *cls,
64  const struct AddressToStringResultMessage *atsm)
65 {
66  uint16_t size = ntohs (atsm->header.size) - sizeof(*atsm);
67  const char *address;
68  int result;
69  uint32_t addr_len;
70 
71  result = (int) ntohl (atsm->res);
72  addr_len = ntohl (atsm->addr_len);
73  if (GNUNET_SYSERR == result)
74  return GNUNET_OK;
75  if (0 == size)
76  {
77  if (GNUNET_OK != result)
78  {
79  GNUNET_break (0);
80  return GNUNET_SYSERR;
81  }
82  return GNUNET_OK;
83  }
84  address = (const char *) &atsm[1];
85  if ((addr_len > size) ||
86  (address[addr_len - 1] != '\0'))
87  {
88  /* invalid reply */
89  GNUNET_break (0);
90  return GNUNET_SYSERR;
91  }
92  return GNUNET_OK;
93 }
94 
95 
102 static void
103 handle_reply (void *cls,
104  const struct AddressToStringResultMessage *atsm)
105 {
106  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
107  uint16_t size = ntohs (atsm->header.size) - sizeof(*atsm);
108  const char *address;
109  int result;
110 
111  result = (int) ntohl (atsm->res);
112  if (GNUNET_SYSERR == result)
113  {
114  /* expect more replies; as this is not the last
115  call, we must pass the empty string for the address */
117  "Address resolution failed\n");
118  alucb->cb (alucb->cb_cls,
119  "",
120  GNUNET_NO);
121  return;
122  }
123  if (0 == size)
124  {
125  /* we are done (successfully, without communication errors) */
126  alucb->cb (alucb->cb_cls,
127  NULL,
128  GNUNET_OK);
130  return;
131  }
132  address = (const char *) &atsm[1];
133  /* return normal reply to caller, also expect more replies */
134  alucb->cb (alucb->cb_cls,
135  address,
136  GNUNET_OK);
137 }
138 
139 
149 static void
150 mq_error_handler (void *cls,
151  enum GNUNET_MQ_Error error)
152 {
153  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
154 
156  "Disconnected from transport, address resolution failed\n");
157  alucb->cb (alucb->cb_cls,
158  NULL,
159  GNUNET_SYSERR);
161 }
162 
163 
179  const struct GNUNET_HELLO_Address *address,
180  int numeric,
183  aluc,
184  void *aluc_cls)
185 {
188  struct GNUNET_MQ_MessageHandler handlers[] = {
189  GNUNET_MQ_hd_var_size (reply,
192  alc),
194  };
195  size_t alen;
196  size_t slen;
197  struct AddressLookupMessage *msg;
198  struct GNUNET_MQ_Envelope *env;
199  char *addrbuf;
200 
201  alen = address->address_length;
202  slen = strlen (address->transport_name) + 1;
203  if ((alen + slen >= GNUNET_MAX_MESSAGE_SIZE
204  - sizeof(struct AddressLookupMessage)) ||
205  (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
206  (slen >= GNUNET_MAX_MESSAGE_SIZE))
207  {
208  GNUNET_break (0);
209  GNUNET_free (alc);
210  return NULL;
211  }
212  alc->cb = aluc;
213  alc->cb_cls = aluc_cls;
214  alc->mq = GNUNET_CLIENT_connect (cfg,
215  "transport",
216  handlers,
218  alc);
219  if (NULL == alc->mq)
220  {
221  GNUNET_break (0);
222  GNUNET_free (alc);
223  return NULL;
224  }
226  "Client tries to resolve for peer `%s' address plugin %s len %u\n",
227  GNUNET_i2s (&address->peer),
228  address->transport_name,
229  (unsigned int) address->address_length);
230  env = GNUNET_MQ_msg_extra (msg,
231  alen + slen,
233  msg->numeric_only = htons ((int16_t) numeric);
234  msg->addrlen = htons ((uint16_t) alen);
235  msg->timeout = GNUNET_TIME_relative_hton (timeout);
236  addrbuf = (char *) &msg[1];
237  GNUNET_memcpy (addrbuf,
238  address->address,
239  alen);
240  GNUNET_memcpy (&addrbuf[alen],
241  address->transport_name,
242  slen);
243  GNUNET_MQ_send (alc->mq,
244  env);
245  return alc;
246 }
247 
248 
254 void
257  *alc)
258 {
259  GNUNET_MQ_destroy (alc->mq);
260  GNUNET_free (alc);
261 }
262 
263 
264 /* end of transport_api_address_to_string.c */
size_t address_length
Number of bytes in address.
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...
Message used to notify the transport API about an address to string conversion.
Definition: transport.h:323
void(* GNUNET_TRANSPORT_AddressToStringCallback)(void *cls, const char *address, int res)
Function to call with a textual representation of an address.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
const void * address
Binary representation of the address (plugin-specific).
common internal definitions for transport service
uint32_t addr_len
Length of the following string, zero if is GNUNET_SYSERR.
Definition: transport.h:339
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
GNUNET_MQ_Error
Error codes for the queue.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
static int numeric
Option -n.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#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:52
uint32_t res
GNUNET_OK if the conversion succeeded, GNUNET_SYSERR if it failed
Definition: transport.h:334
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static int check_reply(void *cls, const struct AddressToStringResultMessage *atsm)
Function called with responses from the service.
void GNUNET_TRANSPORT_address_to_string_cancel(struct GNUNET_TRANSPORT_AddressToStringContext *alc)
Cancel request for address conversion.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY
Response to the address lookup request.
const char * transport_name
Name of the transport plugin enabling the communication using this address.
static int result
Global testing status.
int16_t numeric_only
Should the conversion use numeric IP addresses (otherwise a reverse DNS lookup is OK – if applicable...
Definition: transport.h:359
Message handler for a specific message type.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING
Request to look addresses of peers in server.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton(struct GNUNET_TIME_Relative a)
Convert relative time to network byte order.
Definition: time.c:625
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY.
Definition: transport.h:328
struct GNUNET_TRANSPORT_AddressToStringContext * GNUNET_TRANSPORT_address_to_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HELLO_Address *address, int numeric, struct GNUNET_TIME_Relative timeout, GNUNET_TRANSPORT_AddressToStringCallback aluc, void *aluc_cls)
Convert a binary address into a human readable address.
struct GNUNET_TIME_RelativeNBO timeout
timeout to give up (for DNS resolution timeout mostly)
Definition: transport.h:369
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_PeerIdentity peer
For which peer is this an address?
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Message from the library to the transport service asking for converting a transport address to a huma...
Definition: transport.h:348
Handle to a message queue.
Definition: mq.c:85
GNUNET_TRANSPORT_AddressToStringCallback cb
Function to call with the human-readable address.
configuration data
Definition: configuration.c:85
static void handle_reply(void *cls, const struct AddressToStringResultMessage *atsm)
Function called with responses from the service.
An address for communicating with a peer.
#define GNUNET_log(kind,...)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
uint16_t addrlen
Length of the (binary) address in bytes, in big-endian.
Definition: transport.h:364
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:353
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_MQ_Handle * mq
Connection to the service.