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; uint32_t usIP = m_OurIP;
auto buf = llarp::Buffer(msg->payload); auto buf = llarp::Buffer(msg->payload);
net::IPv4Packet pkt; 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.src(themIP);
pkt.dst(usIP); pkt.dst(usIP);
pkt.UpdateChecksum(); pkt.UpdateChecksum();
llarp::LogInfo(Name(), " handle data message ", msg->payload.size(), llarp::LogInfo(Name(), " handle data message ", msg->payload.size(),
" bytes from ", inet_ntoa({htonl(themIP)})); " bytes from ", inet_ntoa({htonl(themIP)}));
llarp_ev_tun_async_write(&tunif, pkt.buf, pkt.sz); llarp_ev_tun_async_write(&tunif, pkt.buf, pkt.sz);
/* /*
if(!m_NetworkToUserPktQueue.EmplaceIf( if(!m_NetworkToUserPktQueue.EmplaceIf(
[buf, themIP, usIP](net::IPv4Packet &pkt) -> bool { [buf, themIP, usIP](net::IPv4Packet &pkt) -> bool {

@ -3,6 +3,8 @@
#include <llarp/ip.hpp> #include <llarp/ip.hpp>
#include "llarp/buffer.hpp" #include "llarp/buffer.hpp"
#include "mem.hpp" #include "mem.hpp"
#include <netinet/in.h>
#include <map>
namespace llarp namespace llarp
{ {
@ -26,29 +28,44 @@ namespace llarp
return llarp::InitBuffer(buf, sz); return llarp::InitBuffer(buf, sz);
} }
void /// bytes offset to checksum relative to end of ip header for each protocol
IPv4Packet::UpdateChecksum() static std::map< byte_t, uint16_t > protoChecksumOffsets = {
{ {IPPROTO_TCP, 16}, {IPPROTO_ICMP, 2}, {IPPROTO_UDP, 6}};
auto hdr = Header();
hdr->check = 0;
size_t count = hdr->ihl; static uint16_t
ipchksum(const byte_t *buf, size_t sz)
{
uint32_t sum = 0; uint32_t sum = 0;
byte_t *addr = buf; while(sz > 1)
while(count > 1)
{ {
sum += *(uint16_t *)addr; sum += *(const uint16_t *)buf;
count -= sizeof(uint16_t); sz -= sizeof(uint16_t);
addr += sizeof(uint16_t); buf += sizeof(uint16_t);
} }
if(count > 0) if(sz > 0)
sum += *(byte_t *)addr; sum += *(const byte_t *)buf;
while(sum >> 16) while(sum >> 16)
sum = (sum & 0xffff) + (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 } // namespace net

@ -820,7 +820,7 @@ namespace llarp
Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr, Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr,
const IntroSet* i) const IntroSet* i)
{ {
if(i && addr == i->A.Addr() && currentIntroSet.OtherIsNewer(*i)) if(i)
{ {
currentIntroSet = *i; currentIntroSet = *i;
ShiftIntroduction(); ShiftIntroduction();
@ -837,8 +837,9 @@ namespace llarp
auto itr = m_AddressToService.find(remote); auto itr = m_AddressToService.find(remote);
if(itr != m_AddressToService.end()) if(itr != m_AddressToService.end())
{ {
ProtocolFrame f; routing::PathTransferMessage transfer;
path::Path* p = nullptr; ProtocolFrame& f = transfer.T;
path::Path* p = nullptr;
std::set< ConvoTag > tags; std::set< ConvoTag > tags;
if(!GetConvoTagsForService(itr->second, tags)) if(!GetConvoTagsForService(itr->second, tags))
{ {
@ -869,18 +870,20 @@ namespace llarp
return false; return false;
} }
ProtocolMessage m(f.T); ProtocolMessage m(f.T);
m.PutBuffer(data);
m.proto = t; m.proto = t;
m.introReply = p->intro; m.introReply = p->intro;
m.sender = m_Identity.pub; m.sender = m_Identity.pub;
m.PutBuffer(data);
f.N.Randomize(); f.N.Randomize();
f.S = GetSeqNoForConvo(f.T);
f.C.Zero(); f.C.Zero();
transfer.Y.Randomize();
transfer.P = intro.pathID;
if(!f.EncryptAndSign(&Router()->crypto, m, K, m_Identity)) if(!f.EncryptAndSign(&Router()->crypto, m, K, m_Identity))
{ {
llarp::LogError("failed to encrypt and sign"); llarp::LogError("failed to encrypt and sign");
return false; return false;
} }
routing::PathTransferMessage transfer(f, intro.pathID);
return p->SendRoutingMessage(&transfer, Router()); return p->SendRoutingMessage(&transfer, Router());
} }
} }

@ -248,7 +248,7 @@ namespace llarp
if(!self->frame->Verify(crypto, self->msg->sender)) if(!self->frame->Verify(crypto, self->msg->sender))
{ {
llarp::LogError("intro frame has invalid signature Z=", 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->msg;
delete self; delete self;
return; return;

Loading…
Cancel
Save