GNUnet  0.10.x
Data Structures | Functions | Variables
gnunet-nat-server.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet_protocols.h"
#include "nat-auto.h"
Include dependency graph for gnunet-nat-server.c:

Go to the source code of this file.

Data Structures

struct  ClientData
 Information we track per client. More...
 
struct  TcpContext
 Closure for tcp_send. More...
 

Functions

static void try_anat (uint32_t dst_ipv4, uint16_t dport, int is_tcp)
 Try contacting the peer using autonomous NAT traveral method. More...
 
static void tcp_send (void *cls)
 Task called by the scheduler once we can do the TCP send (or once we failed to connect...). More...
 
static void try_send_tcp (uint32_t dst_ipv4, uint16_t dport, uint16_t data)
 Try to send data to the IP dst_ipv4' at port dport via TCP. More...
 
static void try_send_udp (uint32_t dst_ipv4, uint16_t dport, uint16_t data)
 Try to send data to the IP dst_ipv4 at port dport via UDP. More...
 
static void handle_test (void *cls, const struct GNUNET_NAT_AUTO_TestMessage *tm)
 We've received a request to probe a NAT traversal. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *srv)
 Main function that will be run. More...
 
static void force_timeout (void *cls)
 Forcefully drops client after 1s. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
 Callback called when a client disconnected from the service. More...
 
 GNUNET_SERVICE_MAIN ("nat-server", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(test, GNUNET_MESSAGE_TYPE_NAT_TEST, struct GNUNET_NAT_AUTO_TestMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration. More...
 

Function Documentation

◆ try_anat()

static void try_anat ( uint32_t  dst_ipv4,
uint16_t  dport,
int  is_tcp 
)
static

Try contacting the peer using autonomous NAT traveral method.

Parameters
dst_ipv4IPv4 address to send the fake ICMP message
dportdestination port to include in ICMP message
is_tcpmark for TCP (GNUNET_YES) or UDP (GNUNET_NO)

Definition at line 64 of file gnunet-nat-server.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NAT_register(), GNUNET_NAT_request_reversal(), GNUNET_NAT_unregister(), and h.

Referenced by handle_test().

67 {
68  struct GNUNET_NAT_Handle *h;
69  struct sockaddr_in lsa;
70  struct sockaddr_in rsa;
71  const struct sockaddr *sa;
72  socklen_t sa_len;
73 
75  "Asking for connection reversal with %x and code %u\n",
76  (unsigned int) dst_ipv4,
77  (unsigned int) dport);
78  memset (&lsa, 0, sizeof (lsa));
79  lsa.sin_family = AF_INET;
80 #if HAVE_SOCKADDR_IN_SIN_LEN
81  lsa.sin_len = sizeof (sa);
82 #endif
83  lsa.sin_addr.s_addr = 0;
84  lsa.sin_port = htons (dport);
85  memset (&rsa, 0, sizeof (rsa));
86  rsa.sin_family = AF_INET;
87 #if HAVE_SOCKADDR_IN_SIN_LEN
88  rsa.sin_len = sizeof (sa);
89 #endif
90  rsa.sin_addr.s_addr = dst_ipv4;
91  rsa.sin_port = htons (dport);
92  sa_len = sizeof (lsa);
93  sa = (const struct sockaddr *) &lsa;
95  "none",
96  is_tcp ? IPPROTO_TCP : IPPROTO_UDP,
97  1,
98  &sa,
99  &sa_len,
100  NULL, NULL, NULL);
102  &lsa,
103  &rsa);
105 }
Handle for active NAT registrations.
Definition: nat_api.c:72
int GNUNET_NAT_request_reversal(struct GNUNET_NAT_Handle *nh, const struct sockaddr_in *local_sa, const struct sockaddr_in *remote_sa)
We learned about a peer (possibly behind NAT) so run the gnunet-nat-client to send dummy ICMP respons...
Definition: nat_api.c:655
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:690
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:378
#define GNUNET_log(kind,...)
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_send()

static void tcp_send ( void *  cls)
static

Task called by the scheduler once we can do the TCP send (or once we failed to connect...).

Parameters
clsthe struct TcpContext

Definition at line 132 of file gnunet-nat-server.c.

References ctx, TcpContext::data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log_strerror, GNUNET_NETWORK_fdset_isset(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_send(), GNUNET_NETWORK_socket_shutdown(), GNUNET_SCHEDULER_get_task_context(), TcpContext::s, tc, and GNUNET_SCHEDULER_TaskContext::write_ready.

Referenced by try_send_tcp().

133 {
134  struct TcpContext *ctx = cls;
135  const struct GNUNET_SCHEDULER_TaskContext *tc;
136 
138  if ((NULL != tc->write_ready) &&
140  {
141  if (-1 ==
142  GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data)))
143  {
145  }
146  GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
147  }
149  GNUNET_free (ctx);
150 }
struct GNUNET_NETWORK_Handle * s
TCP socket.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:746
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:927
Context information passed to each scheduler task.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
const struct GNUNET_NETWORK_FDSet * write_ready
Set of file descriptors ready for writing; note that additional bits may be set that were not in the ...
int GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:1065
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#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...
Closure for tcp_send.
uint16_t data
Data to transmit.
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:1181
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_send_tcp()

static void try_send_tcp ( uint32_t  dst_ipv4,
uint16_t  dport,
uint16_t  data 
)
static

Try to send data to the IP dst_ipv4' at port dport via TCP.

Parameters
dst_ipv4target IP
dporttarget port
datadata to send

Definition at line 162 of file gnunet-nat-server.c.

References ctx, data, TcpContext::data, GNUNET_a2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_SECONDS, TcpContext::s, and tcp_send().

Referenced by handle_test().

165 {
166  struct GNUNET_NETWORK_Handle *s;
167  struct sockaddr_in sa;
168  struct TcpContext *ctx;
169 
170  s = GNUNET_NETWORK_socket_create (AF_INET,
171  SOCK_STREAM,
172  0);
173  if (NULL == s)
174  {
176  "socket");
177  return;
178  }
179  memset (&sa, 0, sizeof (sa));
180  sa.sin_family = AF_INET;
181 #if HAVE_SOCKADDR_IN_SIN_LEN
182  sa.sin_len = sizeof (sa);
183 #endif
184  sa.sin_addr.s_addr = dst_ipv4;
185  sa.sin_port = htons (dport);
187  "Sending TCP message to `%s'\n",
188  GNUNET_a2s ((struct sockaddr *) &sa,
189  sizeof (sa)));
190  if ( (GNUNET_OK !=
192  (const struct sockaddr *) &sa,
193  sizeof (sa))) &&
194  (errno != EINPROGRESS) )
195  {
197  "connect");
199  return;
200  }
201  ctx = GNUNET_new (struct TcpContext);
202  ctx->s = s;
203  ctx->data = data;
205  s,
206  &tcp_send,
207  ctx);
208 }
struct GNUNET_NETWORK_Handle * s
TCP socket.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1548
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#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...
int GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:731
Closure for tcp_send.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
static void tcp_send(void *cls)
Task called by the scheduler once we can do the TCP send (or once we failed to connect...).
uint16_t data
Data to transmit.
#define GNUNET_log(kind,...)
handle to a socket
Definition: network.c:46
uint32_t data
The data value.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_send_udp()

static void try_send_udp ( uint32_t  dst_ipv4,
uint16_t  dport,
uint16_t  data 
)
static

Try to send data to the IP dst_ipv4 at port dport via UDP.

Parameters
dst_ipv4target IP
dporttarget port
datadata to send

Definition at line 220 of file gnunet-nat-server.c.

References GNUNET_a2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), and GNUNET_NETWORK_socket_sendto().

Referenced by handle_test().

223 {
224  struct GNUNET_NETWORK_Handle *s;
225  struct sockaddr_in sa;
226 
227  s = GNUNET_NETWORK_socket_create (AF_INET,
228  SOCK_DGRAM,
229  0);
230  if (NULL == s)
231  {
233  "socket");
234  return;
235  }
236  memset (&sa, 0, sizeof (sa));
237  sa.sin_family = AF_INET;
238 #if HAVE_SOCKADDR_IN_SIN_LEN
239  sa.sin_len = sizeof (sa);
240 #endif
241  sa.sin_addr.s_addr = dst_ipv4;
242  sa.sin_port = htons (dport);
244  "Sending UDP packet to `%s'\n",
245  GNUNET_a2s ((struct sockaddr *) &sa,
246  sizeof (sa)));
247  if (-1 ==
249  &data,
250  sizeof (data),
251  (const struct sockaddr *) &sa,
252  sizeof (sa)))
254  "sendto");
256 }
#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...
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:968
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
#define GNUNET_log(kind,...)
handle to a socket
Definition: network.c:46
uint32_t data
The data value.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_test()

static void handle_test ( void *  cls,
const struct GNUNET_NAT_AUTO_TestMessage tm 
)
static

We've received a request to probe a NAT traversal.

Do it.

Parameters
clshandle to client (we always close)
msgmessage with details about what to test

Definition at line 267 of file gnunet-nat-server.c.

References ClientData::client, GNUNET_NAT_AUTO_TestMessage::data, GNUNET_NAT_AUTO_TestMessage::dport, GNUNET_NAT_AUTO_TestMessage::dst_ipv4, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SERVICE_client_drop(), GNUNET_YES, GNUNET_NAT_AUTO_TestMessage::is_tcp, try_anat(), try_send_tcp(), and try_send_udp().

269 {
270  struct ClientData *cd = cls;
271  uint16_t dport;
272 
274  "Received test request\n");
275  dport = ntohs (tm->dport);
276  if (0 == dport)
277  try_anat (tm->dst_ipv4,
278  ntohs (tm->data),
279  (int) ntohl (tm->is_tcp));
280  else if (GNUNET_YES == ntohl (tm->is_tcp))
281  try_send_tcp (tm->dst_ipv4,
282  dport,
283  tm->data);
284  else
285  try_send_udp (tm->dst_ipv4,
286  dport,
287  tm->data);
289 }
static void try_anat(uint32_t dst_ipv4, uint16_t dport, int is_tcp)
Try contacting the peer using autonomous NAT traveral method.
static void try_send_tcp(uint32_t dst_ipv4, uint16_t dport, uint16_t data)
Try to send data to the IP dst_ipv4' at port dport via TCP.
int32_t is_tcp
GNUNET_YES for TCP, GNUNET_NO for UDP.
Definition: nat-auto.h:64
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
struct GNUNET_SERVICE_Client * client
Client handle.
uint32_t dst_ipv4
IPv4 target IP address.
Definition: nat-auto.h:49
Information we track per client.
#define GNUNET_log(kind,...)
uint16_t dport
Port to use, 0 to send dummy ICMP response.
Definition: nat-auto.h:54
static void try_send_udp(uint32_t dst_ipv4, uint16_t dport, uint16_t data)
Try to send data to the IP dst_ipv4 at port dport via UDP.
#define GNUNET_YES
Definition: gnunet_common.h:80
uint16_t data
Data to send OR advertised-port (in NBO) to use for dummy ICMP.
Definition: nat-auto.h:59
Here is the call graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle srv 
)
static

Main function that will be run.

Parameters
clsclosure
cconfiguration
srvservice handle

Definition at line 300 of file gnunet-nat-server.c.

Referenced by client_disconnect_cb().

303 {
304  cfg = c;
305 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Here is the caller graph for this function:

◆ force_timeout()

static void force_timeout ( void *  cls)
static

Forcefully drops client after 1s.

Parameters
clsour struct ClientData of a client to drop

Definition at line 314 of file gnunet-nat-server.c.

References ClientData::client, GNUNET_SERVICE_client_drop(), and ClientData::tt.

Referenced by client_connect_cb().

315 {
316  struct ClientData *cd = cls;
317 
318  cd->tt = NULL;
320 }
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
struct GNUNET_SERVICE_Client * client
Client handle.
Information we track per client.
struct GNUNET_SCHEDULER_Task * tt
Timeout task.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
our struct ClientData

Definition at line 333 of file gnunet-nat-server.c.

References ClientData::client, force_timeout(), GNUNET_new, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_UNIT_SECONDS, and ClientData::tt.

Referenced by client_disconnect_cb().

336 {
337  struct ClientData *cd;
338 
339  cd = GNUNET_new (struct ClientData);
340  cd->client = c;
342  &force_timeout,
343  cd);
344  return cd;
345 }
#define GNUNET_TIME_UNIT_SECONDS
One second.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void force_timeout(void *cls)
Forcefully drops client after 1s.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
struct GNUNET_SERVICE_Client * client
Client handle.
Information we track per client.
struct GNUNET_SCHEDULER_Task * tt
Timeout task.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
void *  internal_cls 
)
static

Callback called when a client disconnected from the service.

Parameters
clsclosure for the service
cthe client that disconnected
internal_clsour struct ClientData

Definition at line 356 of file gnunet-nat-server.c.

References __attribute__, client_connect_cb(), GNUNET_free, GNUNET_MESSAGE_TYPE_NAT_TEST, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, run(), and ClientData::tt.

359 {
360  struct ClientData *cd = internal_cls;
361 
362  if (NULL != cd->tt)
364  GNUNET_free (cd);
365 }
Information we track per client.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_SCHEDULER_Task * tt
Timeout task.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( "nat-server"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_fixed_size(test, GNUNET_MESSAGE_TYPE_NAT_TEST, struct GNUNET_NAT_AUTO_TestMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Referenced by client_disconnect_cb().

Here is the caller graph for this function:

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 53 of file gnunet-nat-server.c.