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

66 {
67  struct GNUNET_NAT_Handle *h;
68  struct sockaddr_in lsa;
69  struct sockaddr_in rsa;
70  const struct sockaddr *sa;
71  socklen_t sa_len;
72 
74  "Asking for connection reversal with %x and code %u\n",
75  (unsigned int)dst_ipv4,
76  (unsigned int)dport);
77  memset(&lsa, 0, sizeof(lsa));
78  lsa.sin_family = AF_INET;
79 #if HAVE_SOCKADDR_IN_SIN_LEN
80  lsa.sin_len = sizeof(sa);
81 #endif
82  lsa.sin_addr.s_addr = 0;
83  lsa.sin_port = htons(dport);
84  memset(&rsa, 0, sizeof(rsa));
85  rsa.sin_family = AF_INET;
86 #if HAVE_SOCKADDR_IN_SIN_LEN
87  rsa.sin_len = sizeof(sa);
88 #endif
89  rsa.sin_addr.s_addr = dst_ipv4;
90  rsa.sin_port = htons(dport);
91  sa_len = sizeof(lsa);
92  sa = (const struct sockaddr *)&lsa;
94  "none",
95  is_tcp ? IPPROTO_TCP : IPPROTO_UDP,
96  1,
97  &sa,
98  &sa_len,
99  NULL, NULL, NULL);
101  &lsa,
102  &rsa);
104 }
Handle for active NAT registrations.
Definition: nat_api.c:70
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:376
#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 130 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().

131 {
132  struct TcpContext *ctx = cls;
133  const struct GNUNET_SCHEDULER_TaskContext *tc;
134 
136  if ((NULL != tc->write_ready) &&
138  {
139  if (-1 ==
140  GNUNET_NETWORK_socket_send(ctx->s, &ctx->data, sizeof(ctx->data)))
141  {
143  }
144  GNUNET_NETWORK_socket_shutdown(ctx->s, SHUT_RDWR);
145  }
147  GNUNET_free(ctx);
148 }
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:737
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:804
Context information passed to each scheduler task.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:410
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:928
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:1017
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
#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 160 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().

163 {
164  struct GNUNET_NETWORK_Handle *s;
165  struct sockaddr_in sa;
166  struct TcpContext *ctx;
167 
168  s = GNUNET_NETWORK_socket_create(AF_INET,
169  SOCK_STREAM,
170  0);
171  if (NULL == s)
172  {
174  "socket");
175  return;
176  }
177  memset(&sa, 0, sizeof(sa));
178  sa.sin_family = AF_INET;
179 #if HAVE_SOCKADDR_IN_SIN_LEN
180  sa.sin_len = sizeof(sa);
181 #endif
182  sa.sin_addr.s_addr = dst_ipv4;
183  sa.sin_port = htons(dport);
185  "Sending TCP message to `%s'\n",
186  GNUNET_a2s((struct sockaddr *)&sa,
187  sizeof(sa)));
188  if ((GNUNET_OK !=
190  (const struct sockaddr *)&sa,
191  sizeof(sa))) &&
192  (errno != EINPROGRESS))
193  {
195  "connect");
197  return;
198  }
199  ctx = GNUNET_new(struct TcpContext);
200  ctx->s = s;
201  ctx->data = data;
203  s,
204  &tcp_send,
205  ctx);
206 }
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:1537
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:646
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:548
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
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 218 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().

221 {
222  struct GNUNET_NETWORK_Handle *s;
223  struct sockaddr_in sa;
224 
225  s = GNUNET_NETWORK_socket_create(AF_INET,
226  SOCK_DGRAM,
227  0);
228  if (NULL == s)
229  {
231  "socket");
232  return;
233  }
234  memset(&sa, 0, sizeof(sa));
235  sa.sin_family = AF_INET;
236 #if HAVE_SOCKADDR_IN_SIN_LEN
237  sa.sin_len = sizeof(sa);
238 #endif
239  sa.sin_addr.s_addr = dst_ipv4;
240  sa.sin_port = htons(dport);
242  "Sending UDP packet to `%s'\n",
243  GNUNET_a2s((struct sockaddr *)&sa,
244  sizeof(sa)));
245  if (-1 ==
247  &data,
248  sizeof(data),
249  (const struct sockaddr *)&sa,
250  sizeof(sa)))
252  "sendto");
254 }
#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:838
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:548
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
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 265 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().

267 {
268  struct ClientData *cd = cls;
269  uint16_t dport;
270 
272  "Received test request\n");
273  dport = ntohs(tm->dport);
274  if (0 == dport)
275  try_anat(tm->dst_ipv4,
276  ntohs(tm->data),
277  (int)ntohl(tm->is_tcp));
278  else if (GNUNET_YES == ntohl(tm->is_tcp))
280  dport,
281  tm->data);
282  else
284  dport,
285  tm->data);
287 }
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:63
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2315
struct GNUNET_SERVICE_Client * client
Client handle.
uint32_t dst_ipv4
IPv4 target IP address.
Definition: nat-auto.h:48
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:53
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:77
uint16_t data
Data to send OR advertised-port (in NBO) to use for dummy ICMP.
Definition: nat-auto.h:58
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 298 of file gnunet-nat-server.c.

Referenced by client_disconnect_cb().

301 {
302  cfg = c;
303 }
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 312 of file gnunet-nat-server.c.

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

Referenced by client_connect_cb().

313 {
314  struct ClientData *cd = cls;
315 
316  cd->tt = NULL;
318 }
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2315
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 331 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().

334 {
335  struct ClientData *cd;
336 
337  cd = GNUNET_new(struct ClientData);
338  cd->client = c;
340  &force_timeout,
341  cd);
342  return cd;
343 }
#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:1237
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 354 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.

357 {
358  struct ClientData *cd = internal_cls;
359 
360  if (NULL != cd->tt)
362  GNUNET_free(cd);
363 }
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:956
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 52 of file gnunet-nat-server.c.