GNUnet  0.10.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 
41 
45  void *cb_cls;
46 
51 };
52 
53 
61 static int
62 check_reply(void *cls,
63  const struct AddressToStringResultMessage *atsm)
64 {
65  uint16_t size = ntohs(atsm->header.size) - sizeof(*atsm);
66  const char *address;
67  int result;
68  uint32_t addr_len;
69 
70  result = (int)ntohl(atsm->res);
71  addr_len = ntohl(atsm->addr_len);
72  if (GNUNET_SYSERR == result)
73  return GNUNET_OK;
74  if (0 == size)
75  {
76  if (GNUNET_OK != result)
77  {
78  GNUNET_break(0);
79  return GNUNET_SYSERR;
80  }
81  return GNUNET_OK;
82  }
83  address = (const char *)&atsm[1];
84  if ((addr_len > size) ||
85  (address[addr_len - 1] != '\0'))
86  {
87  /* invalid reply */
88  GNUNET_break(0);
89  return GNUNET_SYSERR;
90  }
91  return GNUNET_OK;
92 }
93 
94 
101 static void
102 handle_reply(void *cls,
103  const struct AddressToStringResultMessage *atsm)
104 {
105  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
106  uint16_t size = ntohs(atsm->header.size) - sizeof(*atsm);
107  const char *address;
108  int result;
109 
110  result = (int)ntohl(atsm->res);
111  if (GNUNET_SYSERR == result)
112  {
113  /* expect more replies; as this is not the last
114  call, we must pass the empty string for the address */
116  "Address resolution failed\n");
117  alucb->cb(alucb->cb_cls,
118  "",
119  GNUNET_NO);
120  return;
121  }
122  if (0 == size)
123  {
124  /* we are done (successfully, without communication errors) */
125  alucb->cb(alucb->cb_cls,
126  NULL,
127  GNUNET_OK);
129  return;
130  }
131  address = (const char *)&atsm[1];
132  /* return normal reply to caller, also expect more replies */
133  alucb->cb(alucb->cb_cls,
134  address,
135  GNUNET_OK);
136 }
137 
138 
148 static void
150  enum GNUNET_MQ_Error error)
151 {
152  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
153 
155  "Disconnected from transport, address resolution failed\n");
156  alucb->cb(alucb->cb_cls,
157  NULL,
158  GNUNET_SYSERR);
160 }
161 
162 
177  const struct GNUNET_HELLO_Address *address,
178  int numeric,
181  void *aluc_cls)
182 {
185  struct GNUNET_MQ_MessageHandler handlers[] = {
186  GNUNET_MQ_hd_var_size(reply,
189  alc),
191  };
192  size_t alen;
193  size_t slen;
194  struct AddressLookupMessage *msg;
195  struct GNUNET_MQ_Envelope *env;
196  char *addrbuf;
197 
198  alen = address->address_length;
199  slen = strlen(address->transport_name) + 1;
200  if ((alen + slen >= GNUNET_MAX_MESSAGE_SIZE
201  - sizeof(struct AddressLookupMessage)) ||
202  (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
203  (slen >= GNUNET_MAX_MESSAGE_SIZE))
204  {
205  GNUNET_break(0);
206  GNUNET_free(alc);
207  return NULL;
208  }
209  alc->cb = aluc;
210  alc->cb_cls = aluc_cls;
211  alc->mq = GNUNET_CLIENT_connect(cfg,
212  "transport",
213  handlers,
215  alc);
216  if (NULL == alc->mq)
217  {
218  GNUNET_break(0);
219  GNUNET_free(alc);
220  return NULL;
221  }
223  "Client tries to resolve for peer `%s' address plugin %s len %u\n",
224  GNUNET_i2s(&address->peer),
225  address->transport_name,
226  (unsigned int)address->address_length);
227  env = GNUNET_MQ_msg_extra(msg,
228  alen + slen,
230  msg->numeric_only = htons((int16_t)numeric);
231  msg->addrlen = htons((uint16_t)alen);
232  msg->timeout = GNUNET_TIME_relative_hton(timeout);
233  addrbuf = (char *)&msg[1];
234  GNUNET_memcpy(addrbuf,
235  address->address,
236  alen);
237  GNUNET_memcpy(&addrbuf[alen],
238  address->transport_name,
239  slen);
240  GNUNET_MQ_send(alc->mq,
241  env);
242  return alc;
243 }
244 
245 
251 void
253 {
254  GNUNET_MQ_destroy(alc->mq);
255  GNUNET_free(alc);
256 }
257 
258 
259 /* 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:315
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
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:330
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:900
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:325
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#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:349
Message handler for a specific message type.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#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:66
struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton(struct GNUNET_TIME_Relative a)
Convert relative time to network byte order.
Definition: time.c:623
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY.
Definition: transport.h:319
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:359
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:339
Handle to a message queue.
Definition: mq.c:84
GNUNET_TRANSPORT_AddressToStringCallback cb
Function to call with the human-readable address.
configuration data
Definition: configuration.c:83
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:821
uint16_t addrlen
Length of the (binary) address in bytes, in big-endian.
Definition: transport.h:354
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:351
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.