/*
This file is part of GNUnet
- Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2010-2017 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
#include "gnunet_hello_lib.h"
#include "gnunet_util_lib.h"
#include "gnunet_fragmentation_lib.h"
-#include "gnunet_nat_lib.h"
+#include "gnunet_nat_service.h"
#include "gnunet_protocols.h"
#include "gnunet_resolver_service.h"
#include "gnunet_signatures.h"
*/
struct GNUNET_PeerIdentity target;
+ /**
+ * Tokenizer for inbound messages.
+ */
+ struct GNUNET_MessageStreamTokenizer *mst;
+
/**
* Plugin this session belongs to.
*/
GNUNET_free (s->frag_ctx);
s->frag_ctx = NULL;
}
+ if (NULL != s->mst)
+ {
+ GNUNET_MST_destroy (s->mst);
+ s->mst = NULL;
+ }
GNUNET_free (s);
}
#endif
a6.sin6_family = AF_INET6;
a6.sin6_port = u6->u6_port;
- memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr));
+ GNUNET_memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr));
sb = &a6;
sbs = sizeof(a6);
}
* Then reschedule this function to be called again once more is available.
*
* @param cls the plugin handle
- * @param tc the scheduling context (for rescheduling this function again)
*/
static void
-udp_plugin_select_v4 (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+udp_plugin_select_v4 (void *cls);
/**
* Then reschedule this function to be called again once more is available.
*
* @param cls the plugin handle
- * @param tc the scheduling context (for rescheduling this function again)
*/
static void
-udp_plugin_select_v6 (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+udp_plugin_select_v6 (void *cls);
/**
if (sizeof(struct IPv4UdpAddress) == addrlen)
{
+ struct sockaddr_in s4;
+
v4 = (const struct IPv4UdpAddress *) addr;
if (GNUNET_OK != check_port (plugin,
ntohs (v4->u4_port)))
return GNUNET_SYSERR;
+ memset (&s4, 0, sizeof (s4));
+ s4.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ s4.sin_len = sizeof (s4);
+#endif
+ s4.sin_port = v4->u4_port;
+ s4.sin_addr.s_addr = v4->ipv4_addr;
+
if (GNUNET_OK !=
- GNUNET_NAT_test_address (plugin->nat,
- &v4->ipv4_addr,
- sizeof (struct in_addr)))
+ GNUNET_NAT_test_address (plugin->nat,
+ &s4,
+ sizeof (struct sockaddr_in)))
return GNUNET_SYSERR;
}
else if (sizeof(struct IPv6UdpAddress) == addrlen)
{
+ struct sockaddr_in6 s6;
+
v6 = (const struct IPv6UdpAddress *) addr;
if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK != check_port (plugin,
- ntohs (v6->u6_port)))
- return GNUNET_SYSERR;
+ return GNUNET_OK; /* plausible, if unlikely... */
+ memset (&s6, 0, sizeof (s6));
+ s6.sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ s6.sin6_len = sizeof (s6);
+#endif
+ s6.sin6_port = v6->u6_port;
+ s6.sin6_addr = v6->ipv6_addr;
+
if (GNUNET_OK !=
- GNUNET_NAT_test_address (plugin->nat,
- &v6->ipv6_addr,
- sizeof (struct in6_addr)))
+ GNUNET_NAT_test_address (plugin->nat,
+ &s6,
+ sizeof(struct sockaddr_in6)))
return GNUNET_SYSERR;
}
else
* @param cls closure, the `struct Plugin`
* @param add_remove #GNUNET_YES to mean the new public IP address,
* #GNUNET_NO to mean the previous (now invalid) one
+ * @param ac address class the address belongs to
* @param addr either the previous or the new public IP address
* @param addrlen actual length of the @a addr
*/
static void
udp_nat_port_map_callback (void *cls,
int add_remove,
+ enum GNUNET_NAT_AddressClass ac,
const struct sockaddr *addr,
socklen_t addrlen)
{
GNUNET_assert (sizeof(struct sockaddr_in) == addrlen);
i4 = (const struct sockaddr_in *) addr;
if (0 == ntohs (i4->sin_port))
- {
- GNUNET_break (0);
- return;
- }
+ return; /* Port = 0 means unmapped, ignore these for UDP. */
memset (&u4,
0,
sizeof(u4));
GNUNET_assert (sizeof(struct sockaddr_in6) == addrlen);
i6 = (const struct sockaddr_in6 *) addr;
if (0 == ntohs (i6->sin6_port))
- {
- GNUNET_break (0);
- return;
- }
+ return; /* Port = 0 means unmapped, ignore these for UDP. */
memset (&u6,
0,
sizeof(u6));
return;
}
/* modify our published address list */
+ /* TODO: use 'ac' here in the future... */
address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
PLUGIN_NAME,
arg,
if (GNUNET_YES == session->in_destroy)
{
GNUNET_break (0);
+ GNUNET_free (udpw);
return;
}
- if (plugin->bytes_in_buffer + udpw->msg_size > INT64_MAX)
+ if (plugin->bytes_in_buffer > INT64_MAX - udpw->msg_size)
{
GNUNET_break (0);
}
udpw->frag_ctx = frag_ctx;
udpw->qc = &qc_fragment_sent;
udpw->qc_cls = plugin;
- memcpy (udpw->msg_buf,
- msg,
- msg_len);
+ GNUNET_memcpy (udpw->msg_buf,
+ msg,
+ msg_len);
enqueue (plugin,
udpw);
if (session->address->address_length == sizeof (struct IPv4UdpAddress))
if ( (sizeof(struct IPv4UdpAddress) == s->address->address_length) &&
(NULL == plugin->sockv4) )
return GNUNET_SYSERR;
- if (udpmlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ if (udpmlen >= GNUNET_MAX_MESSAGE_SIZE)
{
GNUNET_break (0);
return GNUNET_SYSERR;
udpw->frag_ctx = NULL;
udpw->qc = &qc_message_sent;
udpw->qc_cls = plugin;
- memcpy (udpw->msg_buf,
+ GNUNET_memcpy (udpw->msg_buf,
udp,
sizeof (struct UDPMessage));
- memcpy (&udpw->msg_buf[sizeof(struct UDPMessage)],
+ GNUNET_memcpy (&udpw->msg_buf[sizeof(struct UDPMessage)],
msgbuf,
msgbuf_size);
enqueue (plugin,
/* fragmented message */
if (NULL != s->frag_ctx)
return GNUNET_SYSERR;
- memcpy (&udp[1],
+ GNUNET_memcpy (&udp[1],
msgbuf,
msgbuf_size);
frag_ctx = GNUNET_new (struct UDP_FragmentationContext);
* Message tokenizer has broken up an incomming message. Pass it on
* to the service.
*
- * @param cls the `struct Plugin *`
- * @param client the `struct GNUNET_ATS_Session *`
+ * @param cls the `struct GNUNET_ATS_Session *`
* @param hdr the actual message
* @return #GNUNET_OK (always)
*/
static int
process_inbound_tokenized_messages (void *cls,
- void *client,
const struct GNUNET_MessageHeader *hdr)
{
- struct Plugin *plugin = cls;
- struct GNUNET_ATS_Session *session = client;
+ struct GNUNET_ATS_Session *session = cls;
+ struct Plugin *plugin = session->plugin;
if (GNUNET_YES == session->in_destroy)
return GNUNET_OK;
* Session was idle, so disconnect it.
*
* @param cls the `struct GNUNET_ATS_Session` to time out
- * @param tc scheduler context
*/
static void
-session_timeout (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+session_timeout (void *cls)
{
struct GNUNET_ATS_Session *s = cls;
struct Plugin *plugin = s->plugin;
struct GNUNET_ATS_Session *s;
s = GNUNET_new (struct GNUNET_ATS_Session);
+ s->mst = GNUNET_MST_create (&process_inbound_tokenized_messages,
+ s);
s->plugin = plugin;
s->address = GNUNET_HELLO_address_copy (address);
s->target = address->peer;
GNUNET_free (address);
s->rc++;
- GNUNET_SERVER_mst_receive (plugin->mst,
- s,
- (const char *) &msg[1],
- ntohs (msg->header.size) - sizeof(struct UDPMessage),
- GNUNET_YES,
- GNUNET_NO);
+ GNUNET_MST_from_buffer (s->mst,
+ (const char *) &msg[1],
+ ntohs (msg->header.size) - sizeof(struct UDPMessage),
+ GNUNET_YES,
+ GNUNET_NO);
s->rc--;
if ( (0 == s->rc) &&
(GNUNET_YES == s->in_destroy) )
udp_ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK);
udp_ack->delay = htonl (delay);
udp_ack->sender = *plugin->env->my_identity;
- memcpy (&udp_ack[1],
+ GNUNET_memcpy (&udp_ack[1],
msg,
ntohs (msg->size));
enqueue (plugin,
{
/* Create a new defragmentation context */
d_ctx = GNUNET_malloc (sizeof (struct DefragContext) + udp_addr_len);
- memcpy (&d_ctx[1],
+ GNUNET_memcpy (&d_ctx[1],
udp_addr,
udp_addr_len);
d_ctx->udp_addr = (const union UdpAddress *) &d_ctx[1];
msg))
{
/* keep this 'rc' from expiring */
- GNUNET_CONTAINER_heap_update_cost (plugin->defrag_ctxs,
- d_ctx->hnode,
+ GNUNET_CONTAINER_heap_update_cost (d_ctx->hnode,
(GNUNET_CONTAINER_HeapCostType) now.abs_value_us);
}
if (GNUNET_CONTAINER_heap_get_size (plugin->defrag_ctxs) >
sizeof(addr));
size = GNUNET_NETWORK_socket_recvfrom (rsock,
buf,
- sizeof(buf),
+ sizeof (buf),
(struct sockaddr *) &addr,
&fromlen);
sa = (const struct sockaddr *) &addr;
}
/* Check if this is a STUN packet */
- if (GNUNET_NAT_is_valid_stun_packet (plugin->nat,
- (uint8_t *)buf,
- size))
+ if (GNUNET_NO !=
+ GNUNET_NAT_stun_handle_packet (plugin->nat,
+ (const struct sockaddr *) &addr,
+ fromlen,
+ buf,
+ size))
return; /* was STUN, do not process further */
if (size < sizeof(struct GNUNET_MessageHeader))
if (size != ntohs (msg->size))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
- "UDP malformed message header from %s\n",
+ "UDP malformed message (size %u) header from %s\n",
(unsigned int) size,
GNUNET_a2s (sa,
fromlen));
* Then reschedule this function to be called again once more is available.
*
* @param cls the plugin handle
- * @param tc the scheduling context
*/
static void
-udp_plugin_select_v4 (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+udp_plugin_select_v4 (void *cls)
{
struct Plugin *plugin = cls;
+ const struct GNUNET_SCHEDULER_TaskContext *tc;
plugin->select_task_v4 = NULL;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
if (NULL == plugin->sockv4)
return;
+ tc = GNUNET_SCHEDULER_get_task_context ();
if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
(GNUNET_NETWORK_fdset_isset (tc->read_ready,
plugin->sockv4)))
* Then reschedule this function to be called again once more is available.
*
* @param cls the plugin handle
- * @param tc the scheduling context
*/
static void
-udp_plugin_select_v6 (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+udp_plugin_select_v6 (void *cls)
{
struct Plugin *plugin = cls;
+ const struct GNUNET_SCHEDULER_TaskContext *tc;
plugin->select_task_v6 = NULL;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
if (NULL == plugin->sockv6)
return;
+ tc = GNUNET_SCHEDULER_get_task_context ();
if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
(GNUNET_NETWORK_fdset_isset (tc->read_ready,
plugin->sockv6)) )
* @param bind_v4 IPv4 address to bind to (can be NULL, for 'any')
* @return number of sockets that were successfully bound
*/
-static int
+static unsigned int
setup_sockets (struct Plugin *plugin,
const struct sockaddr_in6 *bind_v6,
const struct sockaddr_in *bind_v4)
{
int tries;
- int sockets_created = 0;
+ unsigned int sockets_created = 0;
struct sockaddr_in6 server_addrv6;
struct sockaddr_in server_addrv4;
const struct sockaddr *server_addr;
schedule_select_v4 (plugin);
schedule_select_v6 (plugin);
plugin->nat = GNUNET_NAT_register (plugin->env->cfg,
- GNUNET_NO,
- plugin->port,
+ "transport-udp",
+ IPPROTO_UDP,
sockets_created,
addrs,
addrlens,
&udp_nat_port_map_callback,
NULL,
- plugin,
- plugin->sockv4);
+ plugin);
return sockets_created;
}
unsigned long long port;
unsigned long long aport;
unsigned long long udp_max_bps;
- unsigned long long enable_v6;
- unsigned long long enable_broadcasting;
- unsigned long long enable_broadcasting_recv;
+ int enable_v6;
+ int enable_broadcasting;
+ int enable_broadcasting_recv;
char *bind4_address;
char *bind6_address;
struct GNUNET_TIME_Relative interval;
struct sockaddr_in server_addrv4;
struct sockaddr_in6 server_addrv6;
- int res;
+ unsigned int res;
int have_bind4;
int have_bind6;
p->sessions = GNUNET_CONTAINER_multipeermap_create (16,
GNUNET_NO);
p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
- p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages,
- p);
GNUNET_BANDWIDTH_tracker_init (&p->tracker,
NULL,
NULL,
_("Failed to create UDP network sockets\n"));
GNUNET_CONTAINER_multipeermap_destroy (p->sessions);
GNUNET_CONTAINER_heap_destroy (p->defrag_ctxs);
- GNUNET_SERVER_mst_destroy (p->mst);
+ if (NULL != p->nat)
+ GNUNET_NAT_unregister (p->nat);
GNUNET_free (p);
return NULL;
}
GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs);
plugin->defrag_ctxs = NULL;
}
- if (NULL != plugin->mst)
- {
- GNUNET_SERVER_mst_destroy (plugin->mst);
- plugin->mst = NULL;
- }
while (NULL != (udpw = plugin->ipv4_queue_head))
{
dequeue (plugin,