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;