/*
This file is part of GNUnet.
- Copyright (C) 2009, 2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2009, 2015 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
static const char *
stun_msg2str(int msg)
{
- static const struct { enum StunClasses value; const char *name; } classes[] = {
+ static const struct {
+ enum StunClasses value;
+ const char *name;
+ } classes[] = {
{ STUN_REQUEST, "Request" },
{ STUN_INDICATION, "Indication" },
{ STUN_RESPONSE, "Response" },
{ STUN_ERROR_RESPONSE, "Error Response" },
{ 0, NULL }
};
- static const struct { enum StunMethods value; const char *name; } methods[] = {
+ static const struct {
+ enum StunMethods value;
+ const char *name;
+ } methods[] = {
{ STUN_BINDING, "Binding" },
{ 0, NULL }
};
* @return string with the attribute name
*/
static const char *
-stun_attr2str(int msg)
+stun_attr2str (int msg)
{
- const struct { enum StunAttributes value; const char *name; } attrs[] = {
+ static const struct {
+ enum StunAttributes value;
+ const char *name;
+ } attrs[] = {
{ STUN_MAPPED_ADDRESS, "Mapped Address" },
{ STUN_RESPONSE_ADDRESS, "Response Address" },
{ STUN_CHANGE_ADDRESS, "Change Address" },
* @param req, stun header to be filled
*/
static void
-generate_request_id(struct stun_header *req)
+generate_request_id (struct stun_header *req)
{
unsigned int x;
default:
return 1;
}
- if (ntohs(attr->len) < 8 && returned_addr->family != 1)
+ if ( (ntohs(attr->len) < 8) &&
+ (returned_addr->family != 1) )
{
return 1;
}
* If a callback is specified, invoke it with the attribute.
*
* @param data the packet
- * @param len the length of the packet
- * @param arg sockaddr_in where we will set our discovered packet
+ * @param len the length of the packet in @a data
+ * @param[out] arg sockaddr_in where we will set our discovered address
*
* @return, #GNUNET_OK on OK, #GNUNET_NO if the packet is invalid (not a stun packet)
*/
message_magic_cookie = ntohl(hdr->magic);
/* Compare if the cookie match */
- if(STUN_MAGIC_COOKIE != message_magic_cookie)
+ if (STUN_MAGIC_COOKIE != message_magic_cookie)
{
LOG (GNUNET_ERROR_TYPE_INFO,
"Invalid magic cookie \n");
(int)len);
return GNUNET_NO;
}
- else
- {
- len = advertised_message_size;
- }
- memset (&st,0, sizeof(st));
+ len = advertised_message_size;
+ memset (&st, 0, sizeof(st));
while (len > 0)
{
(int)len);
break;
}
- stun_get_mapped (&st, attr, arg, hdr->magic);
+ stun_get_mapped (&st,
+ attr,
+ arg,
+ hdr->magic);
/* Clear attribute id: in case previous entry was a string,
* this will act as the terminator for the string.
*/
/**
- * Clean-up used memory
+ * Cancel active STUN request. Frees associated resources
+ * and ensures that the callback is no longer invoked.
*
- * @param handle handle to release memory for
+ * @param rh request to cancel
*/
-static void
-clean (struct GNUNET_NAT_STUN_Handle *handle)
+void
+GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh)
{
- GNUNET_free (handle->stun_server);
- GNUNET_free (handle);
+ if (NULL != rh->dns_active)
+ {
+ GNUNET_RESOLVER_request_cancel (rh->dns_active);
+ rh->dns_active = NULL;
+ }
+ GNUNET_free (rh->stun_server);
+ GNUNET_free (rh);
}
const struct sockaddr *addr,
socklen_t addrlen)
{
- struct GNUNET_NAT_STUN_Handle *request = cls;
+ struct GNUNET_NAT_STUN_Handle *rh = cls;
struct stun_header *req;
uint8_t reqdata[1024];
int reqlen;
struct sockaddr_in server;
- if (NULL == request)
- {
- if (GNUNET_NO == request->dns_success)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Empty request\n");
- request->cb (request->cb_cls,
- GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
- clean (request);
- }
- return;
- }
+ rh->dns_active = NULL;
if (NULL == addr)
{
- request->dns_active = NULL;
- if (GNUNET_NO == request->dns_success)
+ if (GNUNET_NO == rh->dns_success)
{
LOG (GNUNET_ERROR_TYPE_INFO,
"Error resolving host %s\n",
- request->stun_server);
- request->cb (request->cb_cls,
- GNUNET_NAT_ERROR_NOT_ONLINE);
- clean (request);
+ rh->stun_server);
+ rh->cb (rh->cb_cls,
+ GNUNET_NAT_ERROR_NOT_ONLINE);
+ GNUNET_NAT_stun_make_request_cancel (rh);
}
return;
}
- request->dns_success= GNUNET_YES;
- memset(&server,0, sizeof(server));
+ rh->dns_success = GNUNET_YES;
+ memset (&server,0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr;
- server.sin_port = htons(request->stun_port);
+ server.sin_port = htons(rh->stun_port);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ server.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
/*Craft the simplest possible STUN packet. A request binding*/
req = (struct stun_header *)reqdata;
req->msgtype = htons(encode_message(STUN_REQUEST, STUN_BINDING));
/* Send the packet */
- if (-1 == GNUNET_NETWORK_socket_sendto (request->sock,
+ if (-1 == GNUNET_NETWORK_socket_sendto (rh->sock,
req,
ntohs(req->msglen) + sizeof(*req),
(const struct sockaddr *) &server,
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"Fail to sendto");
- request->cb (request->cb_cls,
- GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
- clean (request);
+ rh->cb (rh->cb_cls,
+ GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
+ GNUNET_NAT_stun_make_request_cancel (rh);
return;
}
+ /* sending STUN request done, let's wait for replies... */
+ rh->cb (rh->cb_cls,
+ GNUNET_NAT_ERROR_SUCCESS);
+ GNUNET_NAT_stun_make_request_cancel (rh);
}
* @param sock the socket used to send the request
* @param cb callback in case of error
* @param cb_cls closure for @a cb
- * @return #GNUNET_OK success, #GNUNET_NO on error.
+ * @return NULL on error
*/
-int
+struct GNUNET_NAT_STUN_Handle *
GNUNET_NAT_stun_make_request (const char *server,
uint16_t port,
struct GNUNET_NETWORK_Handle *sock,
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"Failed DNS");
- clean (rh);
- return GNUNET_NO;
+ GNUNET_NAT_stun_make_request_cancel (rh);
+ return NULL;
}
- return GNUNET_OK;
+ return rh;
}
+
+/* end of nat_stun.c */