aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_transport_service.h4
-rw-r--r--src/transport/transport_api_address_to_string.c196
2 files changed, 105 insertions, 95 deletions
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index 0ff6c185a..96182424e 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -399,10 +399,10 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
399/** 399/**
400 * Cancel request for address conversion. 400 * Cancel request for address conversion.
401 * 401 *
402 * @param pic the context handle 402 * @param alc the context handle
403 */ 403 */
404void 404void
405GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic); 405GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc);
406 406
407 407
408/* *********************** Monitoring ************************** */ 408/* *********************** Monitoring ************************** */
diff --git a/src/transport/transport_api_address_to_string.c b/src/transport/transport_api_address_to_string.c
index 2b8b426c7..53e4c832c 100644
--- a/src/transport/transport_api_address_to_string.c
+++ b/src/transport/transport_api_address_to_string.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2014 GNUnet e.V. 3 Copyright (C) 2009-2014, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -48,7 +48,7 @@ struct GNUNET_TRANSPORT_AddressToStringContext
48 /** 48 /**
49 * Connection to the service. 49 * Connection to the service.
50 */ 50 */
51 struct GNUNET_CLIENT_Connection *client; 51 struct GNUNET_MQ_Handle *mq;
52 52
53}; 53};
54 54
@@ -57,46 +57,59 @@ struct GNUNET_TRANSPORT_AddressToStringContext
57 * Function called with responses from the service. 57 * Function called with responses from the service.
58 * 58 *
59 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *` 59 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
60 * @param msg NULL on timeout or error, otherwise presumably a 60 * @param msg message with the human-readable address
61 * message with the human-readable address 61 * @return #GNUNET_OK if message is well-formed
62 */ 62 */
63static void 63static int
64address_response_processor (void *cls, 64check_reply (void *cls,
65 const struct GNUNET_MessageHeader *msg) 65 const struct AddressToStringResultMessage *atsm)
66{ 66{
67 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls; 67 uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
68 const struct AddressToStringResultMessage *atsm;
69 const char *address; 68 const char *address;
70 uint16_t size;
71 int result; 69 int result;
72 uint32_t addr_len; 70 uint32_t addr_len;
73 71
74 if (NULL == msg) 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)
75 { 77 {
76 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 78 if (GNUNET_OK != result)
77 "Disconnected from transport, address resolution failed\n"); 79 {
78 alucb->cb (alucb->cb_cls, 80 GNUNET_break (0);
79 NULL, 81 return GNUNET_SYSERR;
80 GNUNET_SYSERR); 82 }
81 GNUNET_TRANSPORT_address_to_string_cancel (alucb); 83 return GNUNET_OK;
82 return;
83 } 84 }
84 GNUNET_break (ntohs (msg->type) == 85 address = (const char *) &atsm[1];
85 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY); 86 if ( (addr_len > size) ||
86 87 (address[addr_len -1] != '\0') )
87 size = ntohs (msg->size);
88 if (size < sizeof (struct AddressToStringResultMessage))
89 { 88 {
89 /* invalid reply */
90 GNUNET_break (0); 90 GNUNET_break (0);
91 alucb->cb (alucb->cb_cls, 91 return GNUNET_SYSERR;
92 NULL,
93 GNUNET_SYSERR);
94 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
95 return;
96 } 92 }
97 atsm = (const struct AddressToStringResultMessage *) msg; 93 return GNUNET_OK;
94}
95
96
97/**
98 * Function called with responses from the service.
99 *
100 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
101 * @param msg message with the human-readable address
102 */
103static void
104handle_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
98 result = (int) ntohl (atsm->res); 112 result = (int) ntohl (atsm->res);
99 addr_len = ntohl (atsm->addr_len);
100 if (GNUNET_SYSERR == result) 113 if (GNUNET_SYSERR == result)
101 { 114 {
102 /* expect more replies; as this is not the last 115 /* expect more replies; as this is not the last
@@ -106,24 +119,10 @@ address_response_processor (void *cls,
106 alucb->cb (alucb->cb_cls, 119 alucb->cb (alucb->cb_cls,
107 "", 120 "",
108 GNUNET_NO); 121 GNUNET_NO);
109 GNUNET_CLIENT_receive (alucb->client,
110 &address_response_processor,
111 alucb,
112 GNUNET_TIME_UNIT_FOREVER_REL);
113 return; 122 return;
114 } 123 }
115 if (size == (sizeof (struct AddressToStringResultMessage))) 124 if (0 == size)
116 { 125 {
117 if (GNUNET_OK != result)
118 {
119 GNUNET_break (0);
120 alucb->cb (alucb->cb_cls,
121 NULL,
122 GNUNET_SYSERR);
123 GNUNET_CLIENT_disconnect (alucb->client);
124 GNUNET_free (alucb);
125 return;
126 }
127 /* we are done (successfully, without communication errors) */ 126 /* we are done (successfully, without communication errors) */
128 alucb->cb (alucb->cb_cls, 127 alucb->cb (alucb->cb_cls,
129 NULL, 128 NULL,
@@ -132,23 +131,7 @@ address_response_processor (void *cls,
132 return; 131 return;
133 } 132 }
134 address = (const char *) &atsm[1]; 133 address = (const char *) &atsm[1];
135 if ( (addr_len > (size - (sizeof (struct AddressToStringResultMessage)))) || 134 /* return normal reply to caller, also expect more replies */
136 (address[addr_len -1] != '\0') )
137 {
138 /* invalid reply */
139 GNUNET_break (0);
140 alucb->cb (alucb->cb_cls,
141 NULL,
142 GNUNET_SYSERR);
143 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
144 return;
145 }
146 /* expect more replies */
147 GNUNET_CLIENT_receive (alucb->client,
148 &address_response_processor,
149 alucb,
150 GNUNET_TIME_UNIT_FOREVER_REL);
151 /* return normal reply to caller */
152 alucb->cb (alucb->cb_cls, 135 alucb->cb (alucb->cb_cls,
153 address, 136 address,
154 GNUNET_OK); 137 GNUNET_OK);
@@ -156,6 +139,30 @@ address_response_processor (void *cls,
156 139
157 140
158/** 141/**
142 * Generic error handler, called with the appropriate
143 * error code and the same closure specified at the creation of
144 * the message queue.
145 * Not every message queue implementation supports an error handler.
146 *
147 * @param cls the `struct GNUNET_TRANSPORT_AddressToStringContext *`
148 * @param error error code
149 */
150static void
151mq_error_handler (void *cls,
152 enum GNUNET_MQ_Error error)
153{
154 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
155
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157 "Disconnected from transport, address resolution failed\n");
158 alucb->cb (alucb->cb_cls,
159 NULL,
160 GNUNET_SYSERR);
161 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
162}
163
164
165/**
159 * Convert a binary address into a human readable address. 166 * Convert a binary address into a human readable address.
160 * 167 *
161 * @param cfg configuration to use 168 * @param cfg configuration to use
@@ -175,39 +182,53 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
175 GNUNET_TRANSPORT_AddressToStringCallback aluc, 182 GNUNET_TRANSPORT_AddressToStringCallback aluc,
176 void *aluc_cls) 183 void *aluc_cls)
177{ 184{
178 size_t len; 185 GNUNET_MQ_hd_var_size (reply,
186 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY,
187 struct AddressToStringResultMessage);
188 struct GNUNET_TRANSPORT_AddressToStringContext *alc
189 = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
190 struct GNUNET_MQ_MessageHandler handlers[] = {
191 make_reply_handler (alc),
192 GNUNET_MQ_handler_end ()
193 };
179 size_t alen; 194 size_t alen;
180 size_t slen; 195 size_t slen;
181 struct AddressLookupMessage *msg; 196 struct AddressLookupMessage *msg;
182 struct GNUNET_TRANSPORT_AddressToStringContext *alc; 197 struct GNUNET_MQ_Envelope *env;
183 struct GNUNET_CLIENT_Connection *client;
184 char *addrbuf; 198 char *addrbuf;
185 199
186 GNUNET_assert (NULL != address);
187 alen = address->address_length; 200 alen = address->address_length;
188 slen = strlen (address->transport_name) + 1; 201 slen = strlen (address->transport_name) + 1;
189 len = sizeof (struct AddressLookupMessage) + alen + slen; 202 if ( (alen + slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE
190 if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 203 - sizeof (struct AddressLookupMessage)) ||
204 (alen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
205 (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) )
191 { 206 {
192 GNUNET_break (0); 207 GNUNET_break (0);
208 GNUNET_free (alc);
193 return NULL; 209 return NULL;
194 } 210 }
195 client = GNUNET_CLIENT_connect ("transport", cfg); 211 alc->cb = aluc;
196 if (NULL == client) 212 alc->cb_cls = aluc_cls;
213 alc->mq = GNUNET_CLIENT_connecT (cfg,
214 "transport",
215 handlers,
216 &mq_error_handler,
217 alc);
218 if (NULL == alc->mq)
197 { 219 {
198 GNUNET_break (0); 220 GNUNET_break (0);
221 GNUNET_free (alc);
199 return NULL; 222 return NULL;
200 } 223 }
201 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 224 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
202 "Client %p tries to resolve for peer `%s' address plugin %s len %u\n", 225 "Client tries to resolve for peer `%s' address plugin %s len %u\n",
203 client,
204 GNUNET_i2s (&address->peer), 226 GNUNET_i2s (&address->peer),
205 address->transport_name, 227 address->transport_name,
206 (unsigned int) address->address_length); 228 (unsigned int) address->address_length);
207 229 env = GNUNET_MQ_msg_extra (msg,
208 msg = GNUNET_malloc (len); 230 alen + slen,
209 msg->header.size = htons (len); 231 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
210 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
211 msg->numeric_only = htons ((int16_t) numeric); 232 msg->numeric_only = htons ((int16_t) numeric);
212 msg->addrlen = htons ((uint16_t) alen); 233 msg->addrlen = htons ((uint16_t) alen);
213 msg->timeout = GNUNET_TIME_relative_hton (timeout); 234 msg->timeout = GNUNET_TIME_relative_hton (timeout);
@@ -218,18 +239,8 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
218 memcpy (&addrbuf[alen], 239 memcpy (&addrbuf[alen],
219 address->transport_name, 240 address->transport_name,
220 slen); 241 slen);
221 alc = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext); 242 GNUNET_MQ_send (alc->mq,
222 alc->cb = aluc; 243 env);
223 alc->cb_cls = aluc_cls;
224 alc->client = client;
225 GNUNET_assert (GNUNET_OK ==
226 GNUNET_CLIENT_transmit_and_get_response (client,
227 &msg->header,
228 GNUNET_TIME_UNIT_FOREVER_REL,
229 GNUNET_YES,
230 &address_response_processor,
231 alc));
232 GNUNET_free (msg);
233 return alc; 244 return alc;
234} 245}
235 246
@@ -237,15 +248,14 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
237/** 248/**
238 * Cancel request for address conversion. 249 * Cancel request for address conversion.
239 * 250 *
240 * @param pic the context handle 251 * @param alc the context handle
241 */ 252 */
242void 253void
243GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic) 254GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc)
244{ 255{
245 GNUNET_CLIENT_disconnect (pic->client); 256 GNUNET_MQ_destroy (alc->mq);
246 GNUNET_free (pic); 257 GNUNET_free (alc);
247} 258}
248 259
249 260
250
251/* end of transport_api_address_to_string.c */ 261/* end of transport_api_address_to_string.c */