diff options
-rw-r--r-- | src/include/gnunet_transport_service.h | 4 | ||||
-rw-r--r-- | src/transport/transport_api_address_to_string.c | 196 |
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 | */ |
404 | void | 404 | void |
405 | GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic); | 405 | GNUNET_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 | */ |
63 | static void | 63 | static int |
64 | address_response_processor (void *cls, | 64 | check_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 | */ | ||
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 | |||
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 | */ | ||
150 | static void | ||
151 | mq_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 | */ |
242 | void | 253 | void |
243 | GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic) | 254 | GNUNET_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 */ |