GNUnet  0.20.0
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 traversal 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 traversal 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.

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 }
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
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:646
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:674
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:366
Handle for active NAT registrations.
Definition: nat_api.c:72

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

Referenced by handle_test().

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.

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 }
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...
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
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:738
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:861
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:950
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Context information passed to each scheduler task.
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 ...
Closure for tcp_send.

References ctx, 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(), tc, and GNUNET_SCHEDULER_TaskContext::write_ready.

Referenced by try_send_tcp().

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.

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 }
uint32_t data
The data value.
static void tcp_send(void *cls)
Task called by the scheduler once we can do the TCP send (or once we failed to connect....
@ GNUNET_OK
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).
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum GNUNET_GenericReturnValue 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:602
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
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:1577
#define GNUNET_TIME_UNIT_SECONDS
One second.
handle to a socket
Definition: network.c:54
struct GNUNET_NETWORK_Handle * s
TCP socket.

References ctx, 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().

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.

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 }
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

References data, 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().

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)
tmmessage with details about what to test

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

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_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.
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.
static void try_anat(uint32_t dst_ipv4, uint16_t dport, int is_tcp)
Try contacting the peer using autonomous NAT traversal method.
@ GNUNET_YES
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2330
Information we track per client.
struct GNUNET_SERVICE_Client * client
Client handle.
uint32_t dst_ipv4
IPv4 target IP address.
Definition: nat-auto.h:48
uint16_t dport
Port to use, 0 to send dummy ICMP response.
Definition: nat-auto.h:53
int32_t is_tcp
GNUNET_YES for TCP, GNUNET_NO for UDP.
Definition: nat-auto.h:63
uint16_t data
Data to send OR advertised-port (in NBO) to use for dummy ICMP.
Definition: nat-auto.h:58

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().

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.

303 {
304  cfg = c;
305 }

References cfg.

◆ 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.

315 {
316  struct ClientData *cd = cls;
317 
318  cd->tt = NULL;
320 }
struct GNUNET_SCHEDULER_Task * tt
Timeout task.

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

Referenced by client_connect_cb().

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 332 of file gnunet-nat-server.c.

335 {
336  struct ClientData *cd;
337 
338  cd = GNUNET_new (struct ClientData);
339  cd->client = c;
341  &force_timeout,
342  cd);
343  return cd;
344 }
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:1272

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

Here is the call 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 355 of file gnunet-nat-server.c.

358 {
359  struct ClientData *cd = internal_cls;
360 
361  if (NULL != cd->tt)
363  GNUNET_free (cd);
364 }
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

References GNUNET_free, GNUNET_SCHEDULER_cancel(), and ClientData::tt.

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.

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

Referenced by run(), and try_anat().