GNUnet  0.20.0
nat_api_stun.c File Reference

This code provides some support for doing STUN transactions. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_resolver_service.h"
#include "gnunet_nat_service.h"
#include "nat_stun.h"
Include dependency graph for nat_api_stun.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_NAT_STUN_Handle
 Handle to a request given to the resolver. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "stun", __VA_ARGS__)
 
#define TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
 

Functions

static int encode_message (enum StunClasses msg_class, enum StunMethods method)
 Encode a class and method to a compatible STUN format. More...
 
static void generate_request_id (struct stun_header *req)
 Fill the stun_header with a random request_id. More...
 
static void stun_dns_callback (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Try to establish a connection given the specified address. More...
 
struct GNUNET_NAT_STUN_HandleGNUNET_NAT_stun_make_request (const char *server, uint16_t port, struct GNUNET_NETWORK_Handle *sock, GNUNET_NAT_TestCallback cb, void *cb_cls)
 Make Generic STUN request. More...
 
void GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh)
 Cancel active STUN request. More...
 

Detailed Description

This code provides some support for doing STUN transactions.

We send simplest possible packet ia REQUEST with BIND to a STUN server.

All STUN packets start with a simple header made of a type, length (excluding the header) and a 16-byte random transaction id. Following the header we may have zero or more attributes, each structured as a type, length and a value (whose format depends on the type, but often contains addresses). Of course all fields are in network format.

This code was based on ministun.c.

Functions for STUN functionality

Author
Bruno Souza Cabral

Definition in file nat_api_stun.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "stun", __VA_ARGS__)

Definition at line 46 of file nat_api_stun.c.

◆ TIMEOUT

Definition at line 48 of file nat_api_stun.c.

Function Documentation

◆ encode_message()

static int encode_message ( enum StunClasses  msg_class,
enum StunMethods  method 
)
static

Encode a class and method to a compatible STUN format.

Parameters
msg_classclass to be converted
methodmethod to be converted
Returns
message in a STUN compatible format

Definition at line 103 of file nat_api_stun.c.

105 {
106  return ((msg_class & 1) << 4) | ((msg_class & 2) << 7)
107  | (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800)
108  << 2);
109 }

Referenced by stun_dns_callback().

Here is the caller graph for this function:

◆ generate_request_id()

static void generate_request_id ( struct stun_header req)
static

Fill the stun_header with a random request_id.

Parameters
reqstun header to be filled

Definition at line 118 of file nat_api_stun.c.

119 {
120  req->magic = htonl (STUN_MAGIC_COOKIE);
121  for (unsigned int x = 0; x < 3; x++)
123  UINT32_MAX);
124 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
#define STUN_MAGIC_COOKIE
Definition: nat_stun.h:34
uint32_t magic
Definition: nat_stun.h:46
stun_trans_id id
Definition: nat_stun.h:47
uint32_t id[3]
Definition: nat_stun.h:38

References GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), stun_trans_id::id, stun_header::id, stun_header::magic, and STUN_MAGIC_COOKIE.

Referenced by stun_dns_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stun_dns_callback()

static void stun_dns_callback ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Try to establish a connection given the specified address.

Parameters
clsour struct GNUNET_NAT_STUN_Handle *
addraddress to try, NULL for "last call"
addrlenlength of addr

Definition at line 135 of file nat_api_stun.c.

138 {
139  struct GNUNET_NAT_STUN_Handle *rh = cls;
140  struct stun_header req;
141  struct sockaddr_in server;
142 
143  if (NULL == addr)
144  {
145  rh->dns_active = NULL;
146  if (GNUNET_NO == rh->dns_success)
147  {
149  "Error resolving host %s\n",
150  rh->stun_server);
151  rh->cb (rh->cb_cls,
153  }
154  else if (GNUNET_SYSERR == rh->dns_success)
155  {
156  rh->cb (rh->cb_cls,
158  }
159  else
160  {
161  rh->cb (rh->cb_cls,
163  }
165  return;
166  }
167 
168  rh->dns_success = GNUNET_YES;
169  memset (&server, 0, sizeof(server));
170  server.sin_family = AF_INET;
171  server.sin_addr = ((struct sockaddr_in *) addr)->sin_addr;
172  server.sin_port = htons (rh->stun_port);
173 #if HAVE_SOCKADDR_IN_SIN_LEN
174  server.sin_len = (u_char) sizeof(struct sockaddr_in);
175 #endif
176 
177  /* Craft the simplest possible STUN packet. A request binding */
178  generate_request_id (&req);
179  req.msglen = htons (0);
180  req.msgtype = htons (encode_message (STUN_REQUEST,
181  STUN_BINDING));
182 
183  /* Send the packet */
184  if (-1 ==
186  &req,
187  sizeof(req),
188  (const struct sockaddr *) &server,
189  sizeof(server)))
190  {
192  "sendto");
194  return;
195  }
196 }
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
void GNUNET_NAT_stun_make_request_cancel(struct GNUNET_NAT_STUN_Handle *rh)
Cancel active STUN request.
Definition: nat_api_stun.c:247
@ GNUNET_NAT_ERROR_NOT_ONLINE
detected that we are offline
@ GNUNET_NAT_ERROR_SUCCESS
Just the default.
@ GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR
Failure in network subsystem, check permissions.
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
#define LOG(kind,...)
Definition: nat_api_stun.c:46
static int encode_message(enum StunClasses msg_class, enum StunMethods method)
Encode a class and method to a compatible STUN format.
Definition: nat_api_stun.c:103
static void generate_request_id(struct stun_header *req)
Fill the stun_header with a random request_id.
Definition: nat_api_stun.c:118
@ STUN_BINDING
Definition: nat_stun.h:97
@ STUN_REQUEST
Definition: nat_stun.h:88
Handle to a request given to the resolver.
Definition: nat_api_stun.c:57
int dns_success
Do we got a DNS resolution successfully?
Definition: nat_api_stun.c:86
GNUNET_NAT_TestCallback cb
Function to call when a error occurs.
Definition: nat_api_stun.c:76
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request.
Definition: nat_api_stun.c:61
void * cb_cls
Closure for cb.
Definition: nat_api_stun.c:81
char * stun_server
Stun server address.
Definition: nat_api_stun.c:71
uint16_t stun_port
STUN port.
Definition: nat_api_stun.c:91
struct GNUNET_NETWORK_Handle * sock
Handle to the listen socket.
Definition: nat_api_stun.c:66

References GNUNET_NAT_STUN_Handle::cb, GNUNET_NAT_STUN_Handle::cb_cls, GNUNET_NAT_STUN_Handle::dns_active, GNUNET_NAT_STUN_Handle::dns_success, encode_message(), generate_request_id(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log_strerror, GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR, GNUNET_NAT_ERROR_NOT_ONLINE, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_stun_make_request_cancel(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, LOG, stun_header::msglen, stun_header::msgtype, GNUNET_NAT_STUN_Handle::sock, STUN_BINDING, GNUNET_NAT_STUN_Handle::stun_port, STUN_REQUEST, and GNUNET_NAT_STUN_Handle::stun_server.

Referenced by GNUNET_NAT_stun_make_request().

Here is the call graph for this function:
Here is the caller graph for this function: