GNUnet 0.21.1
gnunet-nat-server.c File Reference
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 65 of file gnunet-nat-server.c.

68{
69 struct GNUNET_NAT_Handle *h;
70 struct sockaddr_in lsa;
71 struct sockaddr_in rsa;
72 const struct sockaddr *sa;
73 socklen_t sa_len;
74
76 "Asking for connection reversal with %x and code %u\n",
77 (unsigned int) dst_ipv4,
78 (unsigned int) dport);
79 memset (&lsa, 0, sizeof(lsa));
80 lsa.sin_family = AF_INET;
81#if HAVE_SOCKADDR_IN_SIN_LEN
82 lsa.sin_len = sizeof(sa);
83#endif
84 lsa.sin_addr.s_addr = 0;
85 lsa.sin_port = htons (dport);
86 memset (&rsa, 0, sizeof(rsa));
87 rsa.sin_family = AF_INET;
88#if HAVE_SOCKADDR_IN_SIN_LEN
89 rsa.sin_len = sizeof(sa);
90#endif
91 rsa.sin_addr.s_addr = dst_ipv4;
92 rsa.sin_port = htons (dport);
93 sa_len = sizeof(lsa);
94 sa = (const struct sockaddr *) &lsa;
96 "none",
97 is_tcp ? IPPROTO_TCP : IPPROTO_UDP,
98 1,
99 &sa,
100 &sa_len,
101 NULL, NULL, NULL);
103 &lsa,
104 &rsa);
106}
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:699
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
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:727
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 133 of file gnunet-nat-server.c.

134{
135 struct TcpContext *ctx = cls;
136 const struct GNUNET_SCHEDULER_TaskContext *tc;
137
139 if ((NULL != tc->write_ready) &&
141 {
142 if (-1 ==
143 GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof(ctx->data)))
144 {
146 }
147 GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
148 }
151}
static struct GNUNET_FS_Handle * ctx
#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:508
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:737
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:860
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:949
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:758
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 163 of file gnunet-nat-server.c.

166{
167 struct GNUNET_NETWORK_Handle *s;
168 struct sockaddr_in sa;
169 struct TcpContext *ctx;
170
172 SOCK_STREAM,
173 0);
174 if (NULL == s)
175 {
177 "socket");
178 return;
179 }
180 memset (&sa, 0, sizeof(sa));
181 sa.sin_family = AF_INET;
182#if HAVE_SOCKADDR_IN_SIN_LEN
183 sa.sin_len = sizeof(sa);
184#endif
185 sa.sin_addr.s_addr = dst_ipv4;
186 sa.sin_port = htons (dport);
188 "Sending TCP message to `%s'\n",
189 GNUNET_a2s ((struct sockaddr *) &sa,
190 sizeof(sa)));
191 if ((GNUNET_OK !=
193 (const struct sockaddr *) &sa,
194 sizeof(sa))) &&
195 (errno != EINPROGRESS))
196 {
198 "connect");
200 return;
201 }
202 ctx = GNUNET_new (struct TcpContext);
203 ctx->s = s;
204 ctx->data = data;
206 s,
207 &tcp_send,
208 ctx);
209}
static char * data
The data to insert into the dht.
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.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
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:601
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:1583
#define GNUNET_TIME_UNIT_SECONDS
One second.
handle to a socket
Definition: network.c:53
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 221 of file gnunet-nat-server.c.

224{
225 struct GNUNET_NETWORK_Handle *s;
226 struct sockaddr_in sa;
227
228 s = GNUNET_NETWORK_socket_create (AF_INET,
229 SOCK_DGRAM,
230 0);
231 if (NULL == s)
232 {
234 "socket");
235 return;
236 }
237 memset (&sa, 0, sizeof(sa));
238 sa.sin_family = AF_INET;
239#if HAVE_SOCKADDR_IN_SIN_LEN
240 sa.sin_len = sizeof(sa);
241#endif
242 sa.sin_addr.s_addr = dst_ipv4;
243 sa.sin_port = htons (dport);
245 "Sending UDP packet to `%s'\n",
246 GNUNET_a2s ((struct sockaddr *) &sa,
247 sizeof(sa)));
248 if (-1 ==
250 &data,
251 sizeof(data),
252 (const struct sockaddr *) &sa,
253 sizeof(sa)))
255 "sendto");
257}
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:771

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

270{
271 struct ClientData *cd = cls;
272 uint16_t dport;
273
275 "Received test request\n");
276 dport = ntohs (tm->dport);
277 if (0 == dport)
278 try_anat (tm->dst_ipv4,
279 ntohs (tm->data),
280 (int) ntohl (tm->is_tcp));
281 else if (GNUNET_YES == ntohl (tm->is_tcp))
283 dport,
284 tm->data);
285 else
287 dport,
288 tm->data);
290}
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:2489
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 301 of file gnunet-nat-server.c.

304{
305 cfg = c;
306}

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

316{
317 struct ClientData *cd = cls;
318
319 cd->tt = NULL;
321}
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 333 of file gnunet-nat-server.c.

336{
337 struct ClientData *cd;
338
339 cd = GNUNET_new (struct ClientData);
340 cd->client = c;
343 cd);
344 return cd;
345}
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:1278

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

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

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

Referenced by run(), and try_anat().