From 0c1e22650eae6a7a4742b3a8de1e10afcb493fdb Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 18 Sep 2018 07:08:47 -0400 Subject: [PATCH] try calcuating tcp checksums right try tracking convo tags correctly --- include/llarp/handlers/tun.hpp | 4 +-- include/llarp/service/endpoint.hpp | 7 ++---- include/llarp/service/handler.hpp | 2 +- llarp/handlers/tun.cpp | 11 ++++----- llarp/ip.cpp | 39 ++++++++++++++++++------------ llarp/service/endpoint.cpp | 12 +++++++++ 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/include/llarp/handlers/tun.hpp b/include/llarp/handlers/tun.hpp index 22e12c1d2..b02bbec6e 100644 --- a/include/llarp/handlers/tun.hpp +++ b/include/llarp/handlers/tun.hpp @@ -43,9 +43,9 @@ namespace llarp bool SetupNetworking(); - /// overrides Endpoint + /// extends Endpoint /// handle inbound traffic - void + bool HandleDataMessage(const PathID_t& src, service::ProtocolMessage* msg); #ifndef _MINGW32_NO_THREADS diff --git a/include/llarp/service/endpoint.hpp b/include/llarp/service/endpoint.hpp index ffdf9f067..a8febc928 100644 --- a/include/llarp/service/endpoint.hpp +++ b/include/llarp/service/endpoint.hpp @@ -105,11 +105,8 @@ namespace llarp bool ForgetPathToService(const Address& remote); - virtual void - HandleDataMessage(const PathID_t&, ProtocolMessage* msg) - { - // override me in subclass - } + virtual bool + HandleDataMessage(const PathID_t&, ProtocolMessage* msg); /// ensure that we know a router, looks up if it doesn't void diff --git a/include/llarp/service/handler.hpp b/include/llarp/service/handler.hpp index 0f8f07bf6..5c17ffe08 100644 --- a/include/llarp/service/handler.hpp +++ b/include/llarp/service/handler.hpp @@ -14,7 +14,7 @@ namespace llarp struct ProtocolMessage; struct IDataHandler { - virtual void + virtual bool HandleDataMessage(const PathID_t&, ProtocolMessage* msg) = 0; virtual bool diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 58394ff7d..dac1db265 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -196,15 +196,13 @@ namespace llarp }); } - void + bool TunEndpoint::HandleDataMessage(const PathID_t &src, service::ProtocolMessage *msg) { - PutIntroFor(msg->tag, msg->introReply); - EnsureReplyPath(msg->sender); - service::Address addr; - msg->sender.CalculateAddress(addr.data()); - uint32_t themIP = ObtainIPForAddr(addr); + if(!Endpoint::HandleDataMessage(src, msg)) + return false; + uint32_t themIP = ObtainIPForAddr(msg->sender.Addr()); uint32_t usIP = m_OurIP; auto buf = llarp::Buffer(msg->payload); if(m_NetworkToUserPktQueue.EmplaceIf( @@ -223,6 +221,7 @@ namespace llarp " bytes from ", inet_ntoa({htonl(themIP)})); else llarp::LogWarn(Name(), " dropped packet"); + return true; } uint32_t diff --git a/llarp/ip.cpp b/llarp/ip.cpp index e16d6207a..886559066 100644 --- a/llarp/ip.cpp +++ b/llarp/ip.cpp @@ -4,6 +4,7 @@ #include "llarp/buffer.hpp" #include "mem.hpp" #include +#include #include namespace llarp @@ -28,17 +29,9 @@ namespace llarp return llarp::InitBuffer(buf, sz); } - /// first map entry is bytes offset to checksum relative to end of ip header - /// second map entry is offset from beginning of packet for checksum - static std::map< byte_t, std::pair< uint16_t, uint16_t > > - protoChecksumOffsets = {{IPPROTO_TCP, {16, 12}}, - {IPPROTO_ICMP, {2, 0}}, - {IPPROTO_UDP, {6, 0}}}; - static uint16_t - ipchksum(const byte_t *buf, size_t sz) + ipchksum(const byte_t *buf, size_t sz, uint32_t sum = 0) { - uint32_t sum = 0; while(sz > 1) { sum += *(const uint16_t *)buf; @@ -54,6 +47,24 @@ namespace llarp return ~sum; } + static std::map< + byte_t, std::function< void(const ip_header *, byte_t *, size_t) > > + protoCheckSummer = { + {IPPROTO_ICMP, + [](const ip_header *hdr, byte_t *buf, size_t sz) { + auto len = hdr->ihl * 4; + uint16_t *check = (uint16_t *)buf + len + 2; + *check = 0; + *check = ipchksum(buf, sz); + }}, + {IPPROTO_TCP, [](const ip_header *hdr, byte_t *pkt, size_t sz) { + auto len = hdr->ihl * 4; + uint16_t *check = (uint16_t *)pkt + 28 + len; + *check = 0; + *check = + ipchksum(pkt, sz - len, + hdr->saddr + hdr->daddr + IPPROTO_TCP + (sz - len)); + }}}; void IPv4Packet::UpdateChecksum() { @@ -62,15 +73,11 @@ namespace llarp auto len = hdr->ihl * 4; hdr->check = ipchksum(buf, len); auto proto = hdr->protocol; - auto itr = protoChecksumOffsets.find(proto); - if(itr != protoChecksumOffsets.end()) + auto itr = protoCheckSummer.find(proto); + if(itr != protoCheckSummer.end()) { - auto offset = itr->second.second; - uint16_t *check = (uint16_t *)(buf + len + itr->second.first); - *check = 0; - *check = ipchksum(buf + offset, sz - offset); + itr->second(hdr, buf, sz); } } - } // namespace net } // namespace llarp diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 642cb80dc..1c781acc0 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -698,6 +698,18 @@ namespace llarp return true; } + bool + Endpoint::HandleDataMessage(const PathID_t& src, ProtocolMessage* msg) + { + msg->sender.UpdateAddr(); + auto path = GetPathByID(src); + if(!path) + return false; + PutIntroFor(msg->tag, path->intro); + EnsureReplyPath(msg->sender); + return true; + } + bool Endpoint::HandleHiddenServiceFrame(const ProtocolFrame* frame) {