You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @return the network type
*/
static enum GNUNET_ATS_Network_Type
-udp_get_network (void *cls,
- struct Session *session)
+udp_plugin_get_network (void *cls,
+ struct Session *session)
{
return session->scope;
}
+/**
+ * Function obtain the network type for an address.
+ *
+ * @param cls closure (`struct Plugin *`)
+ * @param address the address
+ * @return the network type
+ */
+static enum GNUNET_ATS_Network_Type
+udp_plugin_get_network_for_address (void *cls,
+ const struct GNUNET_HELLO_Address *address)
+{
+ struct Plugin *plugin = cls;
+ size_t addrlen;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4UdpAddress *u4;
+ const struct IPv6UdpAddress *u6;
+ const void *sb;
+ size_t sbs;
+
+ addrlen = address->address_length;
+ if (addrlen == sizeof(struct IPv6UdpAddress))
+ {
+ GNUNET_assert (NULL != address->address); /* make static analysis happy */
+ u6 = address->address;
+ memset (&a6, 0, sizeof(a6));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ a6.sin6_len = sizeof (a6);
+#endif
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = u6->u6_port;
+ memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr));
+ sb = &a6;
+ sbs = sizeof(a6);
+ }
+ else if (addrlen == sizeof(struct IPv4UdpAddress))
+ {
+ GNUNET_assert (NULL != address->address); /* make static analysis happy */
+ u4 = address->address;
+ memset (&a4, 0, sizeof(a4));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ a4.sin_len = sizeof (a4);
+#endif
+ a4.sin_family = AF_INET;
+ a4.sin_port = u4->u4_port;
+ a4.sin_addr.s_addr = u4->ipv4_addr;
+ sb = &a4;
+ sbs = sizeof(a4);
+ }
+ else
+ {
+ GNUNET_break (0);
+ return GNUNET_ATS_NET_UNSPECIFIED;
+ }
+ return plugin->env->get_address_type (plugin->env->cls,
+ sb,
+ sbs);
+}
+
+
/* ******************* Event loop ******************** */
/**
{
struct Session *session = udpw->session;
+ if (GNUNET_YES == session->in_destroy)
+ {
+ GNUNET_break (0);
+ return;
+ }
if (plugin->bytes_in_buffer + udpw->msg_size > INT64_MAX)
{
GNUNET_break (0);
GNUNET_NO);
GNUNET_STATISTICS_update (plugin->env->stats,
"# UDP, unfragmented bytes payload queued total",
- udpw->payload_size,
+ msgbuf_size,
GNUNET_NO);
}
else
return;
}
udp_ack = (const struct UDP_ACK_Message *) msg;
+ ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
+ if (ntohs (ack->size) != ntohs (msg->size) - sizeof(struct UDP_ACK_Message))
+ {
+ GNUNET_break_op(0);
+ return;
+ }
address = GNUNET_HELLO_address_allocate (&udp_ack->sender,
PLUGIN_NAME,
udp_addr,
}
if (NULL == s->frag_ctx)
{
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Fragmentation context of address %s for ACK not found\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+ "Fragmentation context of address %s for ACK (%s) not found\n",
udp_address_to_string (plugin,
address->address,
- address->address_length));
+ address->address_length),
+ GNUNET_FRAGMENT_print_ack (ack));
GNUNET_HELLO_address_free (address);
return;
}
GNUNET_i2s (&udp_ack->sender));
s->flow_delay_from_other_peer = GNUNET_TIME_relative_to_absolute (flow_delay);
- ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
- if (ntohs (ack->size) != ntohs (msg->size) - sizeof(struct UDP_ACK_Message))
- {
- GNUNET_break_op(0);
- return;
- }
if (GNUNET_OK !=
GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag,
fragmented_message_done (s->frag_ctx,
GNUNET_SYSERR);
}
-
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multipeermap_remove (plugin->sessions,
+ &s->target,
+ s));
frc.rc = NULL;
frc.udp_addr = s->address->address;
frc.udp_addr_len = s->address->address_length;
GNUNET_free (d_ctx);
}
}
+ s->in_destroy = GNUNET_YES;
next = plugin->ipv4_queue_head;
while (NULL != (udpw = next))
{
GNUNET_free (udpw);
}
}
- notify_session_monitor (s->plugin,
- s,
- GNUNET_TRANSPORT_SS_DONE);
- plugin->env->session_end (plugin->env->cls,
- s->address,
- s);
-
if ( (NULL != s->frag_ctx) &&
(NULL != s->frag_ctx->cont) )
{
s->frag_ctx->payload_size,
s->frag_ctx->on_wire_size);
}
-
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multipeermap_remove (plugin->sessions,
- &s->target,
- s));
+ notify_session_monitor (s->plugin,
+ s,
+ GNUNET_TRANSPORT_SS_DONE);
+ plugin->env->session_end (plugin->env->cls,
+ s->address,
+ s);
GNUNET_STATISTICS_set (plugin->env->stats,
"# UDP sessions active",
GNUNET_CONTAINER_multipeermap_size (plugin->sessions),
GNUNET_NO);
- if (s->rc > 0)
- {
- s->in_destroy = GNUNET_YES;
- }
- else
- {
+ if (0 == s->rc)
free_session (s);
- }
return GNUNET_OK;
}
{
struct Plugin *plugin = cls;
struct Session *s;
- enum GNUNET_ATS_Network_Type network_type;
+ enum GNUNET_ATS_Network_Type network_type = GNUNET_ATS_NET_UNSPECIFIED;
const struct IPv4UdpAddress *udp_v4;
const struct IPv6UdpAddress *udp_v6;
if (GNUNET_NO == rc->have_sender)
{
/* tried to defragment but never succeeded, hence will not ACK */
- GNUNET_break_op (0);
+ /* This can happen if we just lost msgs */
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ "# UDP, fragments discarded without ACK",
+ 1,
+ GNUNET_NO);
return;
}
address = GNUNET_HELLO_address_allocate (&rc->sender,
delay = s->flow_delay_for_other_peer.rel_value_us;
else
delay = UINT32_MAX;
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Sending ACK to `%s' including delay of %s\n",
udp_address_to_string (plugin,
/* Connection failure or something. Not a protocol violation. */
return;
}
+
+ /* Check if this is a STUN packet */
+ if (GNUNET_NAT_is_valid_stun_packet (plugin->nat,
+ (uint8_t *)buf,
+ size))
+ return; /* was STUN, do not process further */
+
if (size < sizeof(struct GNUNET_MessageHeader))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
GNUNET_break_op (0);
return;
}
+
+
+
+
msg = (const struct GNUNET_MessageHeader *) buf;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"UDP received %u-byte message from `%s' type %u\n",
if (GNUNET_TIME_UNIT_ZERO.rel_value_us == remaining.rel_value_us)
{
/* Message timed out */
- udpw->qc (udpw->qc_cls,
- udpw,
- GNUNET_SYSERR);
- /* Remove message */
removed = GNUNET_YES;
dequeue (plugin,
udpw);
+ udpw->qc (udpw->qc_cls,
+ udpw,
+ GNUNET_SYSERR);
GNUNET_free (udpw);
if (sock == plugin->sockv4)
else
{
GNUNET_break (0);
+ dequeue (plugin,
+ udpw);
udpw->qc (udpw->qc_cls,
udpw,
GNUNET_SYSERR);
- dequeue (plugin,
- udpw);
notify_session_monitor (plugin,
udpw->session,
GNUNET_TRANSPORT_SS_UPDATE);
udpw->msg_size,
a,
slen);
+ dequeue (plugin,
+ udpw);
if (GNUNET_SYSERR == sent)
{
/* Failure */
udpw,
GNUNET_OK);
}
- dequeue (plugin,
- udpw);
notify_session_monitor (plugin,
udpw->session,
GNUNET_TRANSPORT_SS_UPDATE);
plugin->select_task_v4 = NULL;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
+ if (NULL == plugin->sockv4)
+ return;
if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
- (NULL != plugin->sockv4) &&
(GNUNET_NETWORK_fdset_isset (tc->read_ready,
plugin->sockv4)))
udp_select_read (plugin,
plugin->select_task_v6 = NULL;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
+ if (NULL == plugin->sockv6)
+ return;
if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
- (NULL != plugin->sockv6) &&
(GNUNET_NETWORK_fdset_isset (tc->read_ready,
plugin->sockv6)) )
udp_select_read (plugin,
plugin->sockv6);
+
udp_select_send (plugin,
plugin->sockv6);
schedule_select_v6 (plugin);
addrlens,
&udp_nat_port_map_callback,
NULL,
- plugin);
+ plugin,
+ plugin->sockv4);
return sockets_created;
}
api->check_address = &udp_plugin_check_address;
api->get_session = &udp_plugin_get_session;
api->send = &udp_plugin_send;
- api->get_network = &udp_get_network;
+ api->get_network = &udp_plugin_get_network;
+ api->get_network_for_address = &udp_plugin_get_network_for_address;
api->update_session_timeout = &udp_plugin_update_session_timeout;
api->setup_monitor = &udp_plugin_setup_monitor;
return api;
plugin->ppc_dll_tail,
cur);
GNUNET_RESOLVER_request_cancel (cur->resolver_handle);
+ if (NULL != cur->timeout_task)
+ {
+ GNUNET_SCHEDULER_cancel (cur->timeout_task);
+ cur->timeout_task = NULL;
+ }
GNUNET_free (cur);
}
GNUNET_free (plugin);