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.
pull/15/head
Jeff Becker 6 years ago
parent 17c6780bcd
commit 4f691b8974
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -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 {

@ -3,6 +3,8 @@
#include <llarp/ip.hpp>
#include "llarp/buffer.hpp"
#include "mem.hpp"
#include <netinet/in.h>
#include <map>
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

@ -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());
}
}

@ -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;

Loading…
Cancel
Save