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 
37 {
42 
46  void *cb_cls;
47 
52 
53 };
54 
55 
63 static int
64 check_reply (void *cls,
65  const struct AddressToStringResultMessage *atsm)
66 {
67  uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
68  const char *address;
69  int result;
70  uint32_t addr_len;
71 
72  result = (int) ntohl (atsm->res);
73  addr_len = ntohl (atsm->addr_len);
74  if (GNUNET_SYSERR == result)
75  return GNUNET_OK;
76  if (0 == size)
77  {
78  if (GNUNET_OK != result)
79  {
80  GNUNET_break (0);
81  return GNUNET_SYSERR;
82  }
83  return GNUNET_OK;
84  }
85  address = (const char *) &atsm[1];
86  if ( (addr_len > size) ||
87  (address[addr_len -1] != '\0') )
88  {
89  /* invalid reply */
90  GNUNET_break (0);
91  return GNUNET_SYSERR;
92  }
93  return GNUNET_OK;
94 }
95 
96 
103 static void
104 handle_reply (void *cls,
105  const struct AddressToStringResultMessage *atsm)
106 {
107  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
108  uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
109  const char *address;
110  int result;
111 
112  result = (int) ntohl (atsm->res);
113  if (GNUNET_SYSERR == result)
114  {
115  /* expect more replies; as this is not the last
116  call, we must pass the empty string for the address */
118  "Address resolution failed\n");
119  alucb->cb (alucb->cb_cls,
120  "",
121  GNUNET_NO);
122  return;
123  }
124  if (0 == size)
125  {
126  /* we are done (successfully, without communication errors) */
127  alucb->cb (alucb->cb_cls,
128  NULL,
129  GNUNET_OK);
131  return;
132  }
133  address = (const char *) &atsm[1];
134  /* return normal reply to caller, also expect more replies */
135  alucb->cb (alucb->cb_cls,
136  address,
137  GNUNET_OK);
138 }
139 
140 
150 static void
151 mq_error_handler (void *cls,
152  enum GNUNET_MQ_Error error)
153 {
154  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
155 
157  "Disconnected from transport, address resolution failed\n");
158  alucb->cb (alucb->cb_cls,
159  NULL,
160  GNUNET_SYSERR);
162 }
163 
164 
179  const struct GNUNET_HELLO_Address *address,
180  int numeric,
183  void *aluc_cls)
184 {
187  struct GNUNET_MQ_MessageHandler handlers[] = {
188  GNUNET_MQ_hd_var_size (reply,
191  alc),
193  };
194  size_t alen;
195  size_t slen;
196  struct AddressLookupMessage *msg;
197  struct GNUNET_MQ_Envelope *env;
198  char *addrbuf;
199 
200  alen = address->address_length;
201  slen = strlen (address->transport_name) + 1;
202  if ( (alen + slen >= GNUNET_MAX_MESSAGE_SIZE
203  - sizeof (struct AddressLookupMessage)) ||
204  (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
205  (slen >= GNUNET_MAX_MESSAGE_SIZE) )
206  {
207  GNUNET_break (0);
208  GNUNET_free (alc);
209  return NULL;
210  }
211  alc->cb = aluc;
212  alc->cb_cls = aluc_cls;
213  alc->mq = GNUNET_CLIENT_connect (cfg,
214  "transport",
215  handlers,
217  alc);
218  if (NULL == alc->mq)
219  {
220  GNUNET_break (0);
221  GNUNET_free (alc);
222  return NULL;
223  }
225  "Client tries to resolve for peer `%s' address plugin %s len %u\n",
226  GNUNET_i2s (&address->peer),
227  address->transport_name,
228  (unsigned int) address->address_length);
229  env = GNUNET_MQ_msg_extra (msg,
230  alen + slen,
232  msg->numeric_only = htons ((int16_t) numeric);
233  msg->addrlen = htons ((uint16_t) alen);
234  msg->timeout = GNUNET_TIME_relative_hton (timeout);
235  addrbuf = (char *) &msg[1];
236  GNUNET_memcpy (addrbuf,
237  address->address,
238  alen);
239  GNUNET_memcpy (&addrbuf[alen],
240  address->transport_name,
241  slen);
242  GNUNET_MQ_send (alc->mq,
243  env);
244  return alc;
245 }
246 
247 
253 void
255 {
256  GNUNET_MQ_destroy (alc->mq);
257  GNUNET_free (alc);
258 }
259 
260 
261 /* 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:336
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:353
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:901
GNUNET_MQ_Error
Error codes for the queue.
#define GNUNET_NO
Definition: gnunet_common.h:81
static int numeric
Option -n.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:348
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
#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:374
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:79
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:622
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY.
Definition: transport.h:342
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:384
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:362
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:379
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.