From 4f691b8974c64bd8dca04772638a5ed2923f3988 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 16 Sep 2018 08:06:19 -0400 Subject: [PATCH] make tun write correct number of bytes try doing correct ip checksum and for upper layers that need it too supported right now are icmp, tcp, and udp. more will come later probably. --- llarp/handlers/tun.cpp | 5 ++-- llarp/ip.cpp | 47 ++++++++++++++++++++++++++------------ llarp/service/endpoint.cpp | 13 +++++++---- llarp/service/protocol.cpp | 2 +- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index ae6d57e6f..7d296d348 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -209,14 +209,15 @@ namespace llarp uint32_t usIP = m_OurIP; auto buf = llarp::Buffer(msg->payload); net::IPv4Packet pkt; - memcpy(pkt.buf, buf.base, std::min(buf.sz, sizeof(pkt.buf))); + pkt.sz = std::min(buf.sz, sizeof(pkt.buf)); + memcpy(pkt.buf, buf.base, pkt.sz); pkt.src(themIP); pkt.dst(usIP); pkt.UpdateChecksum(); llarp::LogInfo(Name(), " handle data message ", msg->payload.size(), " bytes from ", inet_ntoa({htonl(themIP)})); - llarp_ev_tun_async_write(&tunif, pkt.buf, pkt.sz); + /* if(!m_NetworkToUserPktQueue.EmplaceIf( [buf, themIP, usIP](net::IPv4Packet &pkt) -> bool { diff --git a/llarp/ip.cpp b/llarp/ip.cpp index b83e7b3a5..2ec9023f1 100644 --- a/llarp/ip.cpp +++ b/llarp/ip.cpp @@ -3,6 +3,8 @@ #include #include "llarp/buffer.hpp" #include "mem.hpp" +#include +#include namespace llarp { @@ -26,29 +28,44 @@ namespace llarp return llarp::InitBuffer(buf, sz); } - void - IPv4Packet::UpdateChecksum() - { - auto hdr = Header(); - hdr->check = 0; + /// bytes offset to checksum relative to end of ip header for each protocol + static std::map< byte_t, uint16_t > protoChecksumOffsets = { + {IPPROTO_TCP, 16}, {IPPROTO_ICMP, 2}, {IPPROTO_UDP, 6}}; - size_t count = hdr->ihl; + static uint16_t + ipchksum(const byte_t *buf, size_t sz) + { uint32_t sum = 0; - byte_t *addr = buf; - - while(count > 1) + while(sz > 1) { - sum += *(uint16_t *)addr; - count -= sizeof(uint16_t); - addr += sizeof(uint16_t); + sum += *(const uint16_t *)buf; + sz -= sizeof(uint16_t); + buf += sizeof(uint16_t); } - if(count > 0) - sum += *(byte_t *)addr; + if(sz > 0) + sum += *(const byte_t *)buf; while(sum >> 16) sum = (sum & 0xffff) + (sum >> 16); - hdr->check = ~sum; + return ~sum; + } + + void + IPv4Packet::UpdateChecksum() + { + auto hdr = Header(); + hdr->check = 0; + auto len = hdr->ihl * 4; + hdr->check = ipchksum(buf, len); + + auto itr = protoChecksumOffsets.find(hdr->protocol); + if(itr != protoChecksumOffsets.end()) + { + uint16_t *check = (uint16_t *)(buf + len + itr->second); + *check = 0; + *check = ipchksum(buf, sz); + } } } // namespace net diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 434fcb25a..88471e93f 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -820,7 +820,7 @@ namespace llarp Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr, const IntroSet* i) { - if(i && addr == i->A.Addr() && currentIntroSet.OtherIsNewer(*i)) + if(i) { currentIntroSet = *i; ShiftIntroduction(); @@ -837,8 +837,9 @@ namespace llarp auto itr = m_AddressToService.find(remote); if(itr != m_AddressToService.end()) { - ProtocolFrame f; - path::Path* p = nullptr; + routing::PathTransferMessage transfer; + ProtocolFrame& f = transfer.T; + path::Path* p = nullptr; std::set< ConvoTag > tags; if(!GetConvoTagsForService(itr->second, tags)) { @@ -869,18 +870,20 @@ namespace llarp return false; } ProtocolMessage m(f.T); - m.PutBuffer(data); m.proto = t; m.introReply = p->intro; m.sender = m_Identity.pub; + m.PutBuffer(data); f.N.Randomize(); + f.S = GetSeqNoForConvo(f.T); f.C.Zero(); + transfer.Y.Randomize(); + transfer.P = intro.pathID; if(!f.EncryptAndSign(&Router()->crypto, m, K, m_Identity)) { llarp::LogError("failed to encrypt and sign"); return false; } - routing::PathTransferMessage transfer(f, intro.pathID); return p->SendRoutingMessage(&transfer, Router()); } } diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index a4fb75434..dcf5fe1c4 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -248,7 +248,7 @@ namespace llarp if(!self->frame->Verify(crypto, self->msg->sender)) { llarp::LogError("intro frame has invalid signature Z=", - self->frame->Z, " from ", self->msg->sender); + self->frame->Z, " from ", self->msg->sender.Addr()); delete self->msg; delete self; return;