aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat_stun.c
diff options
context:
space:
mode:
authorBruno Cabral <bcabral@uw.edu>2015-08-21 04:15:24 +0000
committerBruno Cabral <bcabral@uw.edu>2015-08-21 04:15:24 +0000
commitecc90530eb2b3f4d0d5037d8d8b69722dda2a2cb (patch)
treee43497b563f2d7ee7856fb8f2f57bb8f2598b371 /src/nat/nat_stun.c
parent946e39d3696847334b5316902c1eeb84d4c34cb0 (diff)
downloadgnunet-ecc90530eb2b3f4d0d5037d8d8b69722dda2a2cb.tar.gz
gnunet-ecc90530eb2b3f4d0d5037d8d8b69722dda2a2cb.zip
Fix crashes and memory leaks.
Diffstat (limited to 'src/nat/nat_stun.c')
-rw-r--r--src/nat/nat_stun.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/src/nat/nat_stun.c b/src/nat/nat_stun.c
index 5fff40656..4d1afb3bb 100644
--- a/src/nat/nat_stun.c
+++ b/src/nat/nat_stun.c
@@ -111,8 +111,10 @@ struct StunState {
111 * @param msg the received message 111 * @param msg the received message
112 * @return the converted StunClass 112 * @return the converted StunClass
113 */ 113 */
114static int decode_class(int msg) 114static int
115decode_class(int msg)
115{ 116{
117 /* Sorry for the magic, but this maps the class according to rfc5245 */
116 return ((msg & 0x0010) >> 4) | ((msg & 0x0100) >> 7); 118 return ((msg & 0x0010) >> 4) | ((msg & 0x0100) >> 7);
117} 119}
118 120
@@ -122,7 +124,8 @@ static int decode_class(int msg)
122 * @param msg the received message 124 * @param msg the received message
123 * @return the converted StunMethod 125 * @return the converted StunMethod
124 */ 126 */
125static int decode_method(int msg) 127static int
128decode_method(int msg)
126{ 129{
127 return (msg & 0x000f) | ((msg & 0x00e0) >> 1) | ((msg & 0x3e00) >> 2); 130 return (msg & 0x000f) | ((msg & 0x00e0) >> 1) | ((msg & 0x3e00) >> 2);
128} 131}
@@ -134,7 +137,8 @@ static int decode_method(int msg)
134 * @param method method to be converted 137 * @param method method to be converted
135 * @return message in a STUN compatible format 138 * @return message in a STUN compatible format
136 */ 139 */
137static int encode_message(StunClasses msg_class, StunMethods method) 140static int
141encode_message(StunClasses msg_class, StunMethods method)
138{ 142{
139 return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) | 143 return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) |
140 (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2); 144 (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2);
@@ -146,7 +150,8 @@ static int encode_message(StunClasses msg_class, StunMethods method)
146 * @param msg 150 * @param msg
147 * @return string with the message class and method 151 * @return string with the message class and method
148 */ 152 */
149static const char *stun_msg2str(int msg) 153static const char *
154stun_msg2str(int msg)
150{ 155{
151 156
152 const struct { enum StunClasses value; const char *name; } classes[] = { 157 const struct { enum StunClasses value; const char *name; } classes[] = {
@@ -180,7 +185,7 @@ static const char *stun_msg2str(int msg)
180 if (methods[i].value == value) 185 if (methods[i].value == value)
181 break; 186 break;
182 } 187 }
183 snprintf(result, sizeof(result), "%s %s", 188 GNUNET_snprintf(result, sizeof(result), "%s %s",
184 method ? : "Unknown Method", 189 method ? : "Unknown Method",
185 msg_class ? : "Unknown Class Message"); 190 msg_class ? : "Unknown Class Message");
186 return result; 191 return result;
@@ -192,7 +197,8 @@ static const char *stun_msg2str(int msg)
192 * @param msg with a attribute type 197 * @param msg with a attribute type
193 * @return string with the attribute name 198 * @return string with the attribute name
194 */ 199 */
195static const char *stun_attr2str(int msg) 200static const char *
201stun_attr2str(int msg)
196{ 202{
197 const struct { enum StunAttributes value; const char *name; } attrs[] = { 203 const struct { enum StunAttributes value; const char *name; } attrs[] = {
198 { STUN_MAPPED_ADDRESS, "Mapped Address" }, 204 { STUN_MAPPED_ADDRESS, "Mapped Address" },
@@ -234,7 +240,8 @@ static const char *stun_attr2str(int msg)
234 * 240 *
235 * @param req, stun header to be filled 241 * @param req, stun header to be filled
236 */ 242 */
237static int stun_process_attr(struct StunState *state, struct stun_attr *attr) 243static int
244stun_process_attr(struct StunState *state, struct stun_attr *attr)
238{ 245{
239 LOG (GNUNET_ERROR_TYPE_INFO, 246 LOG (GNUNET_ERROR_TYPE_INFO,
240 "Found STUN Attribute %s (%04x), length %d\n", 247 "Found STUN Attribute %s (%04x), length %d\n",
@@ -264,7 +271,7 @@ static int stun_process_attr(struct StunState *state, struct stun_attr *attr)
264static void 271static void
265generate_request_id(struct stun_header *req) 272generate_request_id(struct stun_header *req)
266{ 273{
267 int x; 274 unsigned int x;
268 req->magic = htonl(STUN_MAGIC_COOKIE); 275 req->magic = htonl(STUN_MAGIC_COOKIE);
269 for (x = 0; x < 3; x++) 276 for (x = 0; x < 3; x++)
270 req->id.id[x] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 277 req->id.id[x] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
@@ -282,7 +289,7 @@ generate_request_id(struct stun_header *req)
282 * @param arg , pointer to a sockaddr_in where we will set the reported IP and port 289 * @param arg , pointer to a sockaddr_in where we will set the reported IP and port
283 * @param magic , Magic cookie 290 * @param magic , Magic cookie
284 * 291 *
285 * @return 0 on sucess, other value otherwise 292 * @return 0 on success, other value otherwise
286 */ 293 */
287static int 294static int
288stun_get_mapped(struct StunState *st, struct stun_attr *attr,struct sockaddr_in *arg, unsigned int magic) 295stun_get_mapped(struct StunState *st, struct stun_attr *attr,struct sockaddr_in *arg, unsigned int magic)
@@ -312,7 +319,7 @@ stun_get_mapped(struct StunState *st, struct stun_attr *attr,struct sockaddr_in
312 } 319 }
313 320
314 st->attr = type; 321 st->attr = type;
315 /*TODO: Detect Family*/ 322
316 sa->sin_family = AF_INET; 323 sa->sin_family = AF_INET;
317 sa->sin_port = returned_addr->port ^ htons(ntohl(magic) >> 16); 324 sa->sin_port = returned_addr->port ^ htons(ntohl(magic) >> 16);
318 sa->sin_addr.s_addr = returned_addr->addr ^ magic; 325 sa->sin_addr.s_addr = returned_addr->addr ^ magic;
@@ -331,12 +338,12 @@ stun_get_mapped(struct StunState *st, struct stun_attr *attr,struct sockaddr_in
331 * @param len, the length of the packet 338 * @param len, the length of the packet
332 * @param arg, sockaddr_in where we will set our discovered packet 339 * @param arg, sockaddr_in where we will set our discovered packet
333 * 340 *
334 * @return, GNUNET_OK on OK, GNUNET_NO if the packet is invalid ( not a stun packet) 341 * @return, #GNUNET_OK on OK, #GNUNET_NO if the packet is invalid ( not a stun packet)
335 */ 342 */
336int 343int
337GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *arg) 344GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *arg)
338{ 345{
339 struct stun_header *hdr = (struct stun_header *)data; 346 const struct stun_header *hdr = (const struct stun_header *)data;
340 struct stun_attr *attr; 347 struct stun_attr *attr;
341 struct StunState st; 348 struct StunState st;
342 int ret = GNUNET_OK; 349 int ret = GNUNET_OK;
@@ -367,28 +374,29 @@ GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *
367 if(STUN_MAGIC_COOKIE != message_magic_cookie){ 374 if(STUN_MAGIC_COOKIE != message_magic_cookie){
368 LOG (GNUNET_ERROR_TYPE_INFO, 375 LOG (GNUNET_ERROR_TYPE_INFO,
369 "Invalid magic cookie \n"); 376 "Invalid magic cookie \n");
370 GNUNET_break_op (0);
371 return GNUNET_NO; 377 return GNUNET_NO;
372 } 378 }
373 379
374 380
375 LOG (GNUNET_ERROR_TYPE_INFO, "STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), advertised_message_size); 381 LOG (GNUNET_ERROR_TYPE_INFO, "STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)),
382 ntohs(hdr->msgtype),
383 advertised_message_size);
376 384
377 385
378 if (advertised_message_size > len) { 386 if (advertised_message_size > len) {
379 LOG (GNUNET_ERROR_TYPE_INFO, "Scrambled STUN packet length (got %d, expecting %d)\n", advertised_message_size, (int)len); 387 LOG (GNUNET_ERROR_TYPE_INFO, "Scrambled STUN packet length (got %d, expecting %d)\n", advertised_message_size,
380 GNUNET_break_op (0); 388 (int)len);
381 return GNUNET_NO; 389 return GNUNET_NO;
382 } else { 390 } else {
383 len = advertised_message_size; 391 len = advertised_message_size;
384 } 392 }
385 /* Zero the struct */ 393
386 memset(&st,0, sizeof(st)); 394 memset(&st,0, sizeof(st));
387 395
388 while (len > 0) { 396 while (len > 0) {
389 if (len < sizeof(struct stun_attr)) { 397 if (len < sizeof(struct stun_attr)) {
390 LOG (GNUNET_ERROR_TYPE_INFO, "Attribute too short (got %d, expecting %d)\n", (int)len, (int) sizeof(struct stun_attr)); 398 LOG (GNUNET_ERROR_TYPE_INFO, "Attribute too short (got %d, expecting %d)\n", (int)len,
391 GNUNET_break_op (0); 399 (int) sizeof(struct stun_attr));
392 break; 400 break;
393 } 401 }
394 attr = (struct stun_attr *)data; 402 attr = (struct stun_attr *)data;
@@ -398,8 +406,8 @@ GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *
398 406
399 /* Check if we still have space in our buffer */ 407 /* Check if we still have space in our buffer */
400 if (advertised_message_size > len ) { 408 if (advertised_message_size > len ) {
401 LOG (GNUNET_ERROR_TYPE_INFO, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", advertised_message_size, (int)len); 409 LOG (GNUNET_ERROR_TYPE_INFO, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", advertised_message_size,
402 GNUNET_break_op (0); 410 (int)len);
403 break; 411 break;
404 } 412 }
405 413
@@ -407,7 +415,8 @@ GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *
407 stun_get_mapped(&st, attr, arg, hdr->magic); 415 stun_get_mapped(&st, attr, arg, hdr->magic);
408 416
409 if (stun_process_attr(&st, attr)) { 417 if (stun_process_attr(&st, attr)) {
410 LOG (GNUNET_ERROR_TYPE_INFO, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr)); 418 LOG (GNUNET_ERROR_TYPE_INFO, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)),
419 ntohs(attr->attr));
411 break; 420 break;
412 } 421 }
413 /** Clear attribute id: in case previous entry was a string, 422 /** Clear attribute id: in case previous entry was a string,
@@ -429,7 +438,8 @@ GNUNET_NAT_stun_handle_packet(const void *data, size_t len, struct sockaddr_in *
429 * 438 *
430 * @param cls our `struct GNUNET_NAT_STUN_Handle *` 439 * @param cls our `struct GNUNET_NAT_STUN_Handle *`
431 */ 440 */
432void clean(struct GNUNET_NAT_STUN_Handle * handle) 441static void
442clean(struct GNUNET_NAT_STUN_Handle * handle)
433{ 443{
434 GNUNET_free(handle->stun_server); 444 GNUNET_free(handle->stun_server);
435 GNUNET_free(handle); 445 GNUNET_free(handle);
@@ -526,9 +536,9 @@ stun_dns_callback (void *cls,
526 * @param server, the address of the stun server 536 * @param server, the address of the stun server
527 * @param port, port of the stun server 537 * @param port, port of the stun server
528 * @param sock the socket used to send the request 538 * @param sock the socket used to send the request
529 * @return GNUNET_NAT_STUN_Handle on success, NULL on error. 539 * @return #GNUNET_OK success, #GNUNET_NO on error.
530 */ 540 */
531struct GNUNET_NAT_STUN_Handle * 541int
532GNUNET_NAT_stun_make_request(char * server, int port, 542GNUNET_NAT_stun_make_request(char * server, int port,
533 struct GNUNET_NETWORK_Handle * sock,GNUNET_NAT_stun_RequestCallback cb, 543 struct GNUNET_NETWORK_Handle * sock,GNUNET_NAT_stun_RequestCallback cb,
534 void *cb_cls) 544 void *cb_cls)
@@ -554,9 +564,10 @@ GNUNET_NAT_stun_make_request(char * server, int port,
554 if(rh->dns_active == NULL) 564 if(rh->dns_active == NULL)
555 { 565 {
556 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "Failed DNS"); 566 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "Failed DNS");
557 return NULL; 567 GNUNET_free(rh);
568 return GNUNET_NO;
558 } 569 }
559 570
560 571
561 return rh; 572 return GNUNET_OK;
562} 573}