aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-10-11 16:48:57 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-10-11 16:48:57 +0000
commite447ff928a492524ff23007280ad81c2fc691d56 (patch)
treed37b539db1deb2072895b5e6f513c939c0dfa72f
parentc5d1714983fdbb5ca4defa5b18064c9ac35a1518 (diff)
downloadgnunet-e447ff928a492524ff23007280ad81c2fc691d56.tar.gz
gnunet-e447ff928a492524ff23007280ad81c2fc691d56.zip
safety check: session address comparison
-rw-r--r--src/transport/plugin_transport_udp.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index a74f25700..ec3e9fb10 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -424,7 +424,7 @@ udp_send (struct Plugin *plugin, const struct sockaddr *sa,
424 } 424 }
425 if (GNUNET_SYSERR == sent) 425 if (GNUNET_SYSERR == sent)
426 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); 426 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
427 LOG (GNUNET_ERROR_TYPE_ERROR, 427 LOG (GNUNET_ERROR_TYPE_DEBUG,
428 "UDP transmited %u-byte message to %s (%d: %s)\n", 428 "UDP transmited %u-byte message to %s (%d: %s)\n",
429 (unsigned int) ntohs (msg->size), GNUNET_a2s (sa, slen), 429 (unsigned int) ntohs (msg->size), GNUNET_a2s (sa, slen),
430 (int) sent, (sent < 0) ? STRERROR (errno) : "ok"); 430 (int) sent, (sent < 0) ? STRERROR (errno) : "ok");
@@ -553,6 +553,8 @@ udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
553 struct Plugin *plugin = cls; 553 struct Plugin *plugin = cls;
554 struct PeerSession *peer_session; 554 struct PeerSession *peer_session;
555 struct PeerSession *inbound_session; 555 struct PeerSession *inbound_session;
556 const struct IPv4UdpAddress *t4;
557 const struct IPv6UdpAddress *t6;
556 size_t mlen = msgbuf_size + sizeof (struct UDPMessage); 558 size_t mlen = msgbuf_size + sizeof (struct UDPMessage);
557 char mbuf[mlen]; 559 char mbuf[mlen];
558 struct UDPMessage *udp; 560 struct UDPMessage *udp;
@@ -563,17 +565,56 @@ udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
563 return GNUNET_SYSERR; 565 return GNUNET_SYSERR;
564 } 566 }
565 567
566 if (force_address == GNUNET_SYSERR)
567 return GNUNET_SYSERR;
568
569 LOG (GNUNET_ERROR_TYPE_DEBUG, 568 LOG (GNUNET_ERROR_TYPE_DEBUG,
570 "UDP transmits %u-byte message to `%s' using address `%s' session 0x%X\n", 569 "UDP transmits %u-byte message to `%s' using address `%s' session 0x%X mode %i\n",
571 msgbuf_size, GNUNET_i2s (target), udp_address_to_string (NULL, addr, addrlen), session); 570 msgbuf_size, GNUNET_i2s (target), udp_address_to_string (NULL, addr, addrlen), session, force_address);
572 571
573 if (session != NULL) 572 if ((force_address == GNUNET_SYSERR) && (session == NULL))
573 return GNUNET_SYSERR;
574
575 /* safety check: comparing address to address stored in session */
576 if ((session != NULL) && (addr != NULL) && (addrlen != 0))
574 { 577 {
575 inbound_session = (struct PeerSession *) session; 578 inbound_session = (struct PeerSession *) session;
576 GNUNET_assert (0 == memcmp (&inbound_session->target, target, sizeof (struct GNUNET_PeerIdentity))); 579 if (0 != memcmp (&inbound_session->target, target, sizeof (struct GNUNET_PeerIdentity)))
580 return GNUNET_SYSERR;
581 switch (addrlen)
582 {
583 case sizeof (struct IPv4UdpAddress):
584 if (NULL == plugin->sockv4)
585 {
586 if (cont != NULL)
587 cont (cont_cls, target, GNUNET_SYSERR);
588 return GNUNET_SYSERR;
589 }
590 t4 = addr;
591 if (inbound_session->addrlen != (sizeof (struct sockaddr_in)))
592 return GNUNET_SYSERR;
593 struct sockaddr_in *a4 = (struct sockaddr_in *) inbound_session->sock_addr;
594 GNUNET_assert (a4->sin_port == t4->u4_port);
595 GNUNET_assert (0 == memcmp(&a4->sin_addr, &t4->ipv4_addr, sizeof (struct in_addr)));
596 LOG (GNUNET_ERROR_TYPE_DEBUG,
597 "Session 0x%X successfully checked!\n", session);
598 break;
599 case sizeof (struct IPv6UdpAddress):
600 if (NULL == plugin->sockv6)
601 {
602 if (cont != NULL)
603 cont (cont_cls, target, GNUNET_SYSERR);
604 return GNUNET_SYSERR;
605 }
606 t6 = addr;
607 GNUNET_assert (inbound_session->addrlen == sizeof (struct sockaddr_in6));
608 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) inbound_session->sock_addr;
609 GNUNET_assert (a6->sin6_port == t6->u6_port);
610 GNUNET_assert (0 == memcmp(&a6->sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr)));
611 LOG (GNUNET_ERROR_TYPE_DEBUG,
612 "Session 0x%X successfully checked!\n", session);
613 break;
614 default:
615 /* Must have a valid address to send to */
616 GNUNET_break_op (0);
617 }
577 } 618 }
578 619
579 peer_session = create_session (plugin, target, addr, addrlen, cont, cont_cls); 620 peer_session = create_session (plugin, target, addr, addrlen, cont, cont_cls);