Refactor iwp into multiple files

pull/467/head
Michael 5 years ago
parent 17b39b0ed4
commit 426a9b0df5
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -166,7 +166,8 @@ set(LIB_SRC
handlers/exit.cpp
handlers/null.cpp
handlers/tun.cpp
link/iwp_internal.cpp
link/iwp_linklayer.cpp
link/iwp_outermessage.cpp
link/iwp.cpp
link/server.cpp
link/session.cpp

@ -1,5 +1,5 @@
#include <link/iwp.hpp>
#include <link/iwp_internal.hpp>
#include <link/iwp_linklayer.hpp>
#include <router/abstractrouter.hpp>
namespace llarp

@ -0,0 +1,180 @@
#include <link/iwp_linklayer.hpp>
namespace llarp
{
namespace iwp
{
LinkLayer::LinkLayer(Crypto* c, const SecretKey& enckey, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler t, SessionClosedHandler closed)
: ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed), crypto(c)
{
m_FlowCookie.Randomize();
}
LinkLayer::~LinkLayer()
{
}
void
LinkLayer::Pump()
{
ILinkLayer::Pump();
}
const char*
LinkLayer::Name() const
{
return "iwp";
}
bool
LinkLayer::KeyGen(SecretKey& k)
{
k.Zero();
crypto->encryption_keygen(k);
return !k.IsZero();
}
uint16_t
LinkLayer::Rank() const
{
return 2;
}
bool
LinkLayer::Start(Logic* l)
{
if(!ILinkLayer::Start(l))
return false;
/// TODO: change me to true when done
return false;
}
void
LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz)
{
m_OuterMsg.Clear();
llarp_buffer_t sigbuf(pkt, sz);
llarp_buffer_t decodebuf(pkt, sz);
if(!m_OuterMsg.Decode(&decodebuf))
{
LogError("failed to decode outer message");
return;
}
NetID ourNetID;
switch(m_OuterMsg.command)
{
case eOCMD_ObtainFlowID:
sigbuf.sz -= m_OuterMsg.Zsig.size();
if(!crypto->verify(m_OuterMsg.pubkey, sigbuf, m_OuterMsg.Zsig))
{
LogError("failed to verify signature on '",
(char)m_OuterMsg.command, "' message from ", from);
return;
}
if(!ShouldSendFlowID(from))
{
SendReject(from, "no flo 4u :^)");
return;
}
if(m_OuterMsg.netid == ourNetID)
{
if(GenFlowIDFor(m_OuterMsg.pubkey, from, m_OuterMsg.flow))
SendFlowID(from, m_OuterMsg.flow);
else
SendReject(from, "genflow fail");
}
else
SendReject(from, "bad netid");
}
}
ILinkSession*
LinkLayer::NewOutboundSession(const RouterContact& rc,
const AddressInfo& ai)
{
(void)rc;
(void)ai;
// TODO: implement me
return nullptr;
}
void
LinkLayer::SendFlowID(const Addr& to, const FlowID_t& flow)
{
// TODO: implement me
(void)to;
(void)flow;
}
bool
LinkLayer::VerifyFlowID(const PubKey& pk, const Addr& from,
const FlowID_t& flow) const
{
FlowID_t expected;
if(!GenFlowIDFor(pk, from, expected))
return false;
return expected == flow;
}
bool
LinkLayer::GenFlowIDFor(const PubKey& pk, const Addr& from,
FlowID_t& flow) const
{
std::array< byte_t, 128 > tmp = {{0}};
if(inet_ntop(AF_INET6, from.addr6(), (char*)tmp.data(), tmp.size())
== nullptr)
return false;
std::copy_n(pk.begin(), pk.size(), tmp.begin() + 64);
std::copy_n(m_FlowCookie.begin(), m_FlowCookie.size(),
tmp.begin() + 64 + pk.size());
llarp_buffer_t buf(tmp);
ShortHash h;
if(!crypto->shorthash(h, buf))
return false;
std::copy_n(h.begin(), flow.size(), flow.begin());
return true;
}
bool
LinkLayer::ShouldSendFlowID(const Addr& to) const
{
(void)to;
// TODO: implement me
return false;
}
void
LinkLayer::SendReject(const Addr& to, const char* msg)
{
if(strlen(msg) > 14)
{
throw std::logic_error("reject message too big");
}
std::array< byte_t, 120 > pkt;
auto now = Now();
PubKey pk = GetOurRC().pubkey;
OuterMessage m;
m.CreateReject(msg, now, pk);
llarp_buffer_t encodebuf(pkt);
if(!m.Encode(&encodebuf))
{
LogError("failed to encode reject message to ", to);
return;
}
llarp_buffer_t signbuf(pkt.data(), pkt.size() - m.Zsig.size());
if(!Sign(m.Zsig, signbuf))
{
LogError("failed to sign reject messsage to ", to);
return;
}
std::copy_n(m.Zsig.begin(), m.Zsig.size(),
pkt.begin() + (pkt.size() - m.Zsig.size()));
llarp_buffer_t pktbuf(pkt);
SendTo_LL(to, pktbuf);
}
} // namespace iwp
} // namespace llarp

@ -0,0 +1,83 @@
#ifndef LLARP_LINK_IWP_LINKLAYER_HPP
#define LLARP_LINK_IWP_LINKLAYER_HPP
#include <constants/link_layer.hpp>
#include <crypto/crypto.hpp>
#include <crypto/encrypted.hpp>
#include <crypto/types.hpp>
#include <link/server.hpp>
#include <link/iwp_outermessage.hpp>
namespace llarp
{
namespace iwp
{
struct LinkLayer final : public ILinkLayer
{
LinkLayer(Crypto *crypto, const SecretKey &encryptionSecretKey,
GetRCFunc getrc, LinkMessageHandler h,
SessionEstablishedHandler established,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);
~LinkLayer();
Crypto *const crypto;
bool
Start(Logic *l) override;
ILinkSession *
NewOutboundSession(const RouterContact &rc,
const AddressInfo &ai) override;
void
Pump() override;
bool
KeyGen(SecretKey &k) override;
const char *
Name() const override;
uint16_t
Rank() const override;
/// verify that a new flow id matches addresses and pubkey
bool
VerifyFlowID(const PubKey &pk, const Addr &from,
const FlowID_t &flow) const;
void
RecvFrom(const Addr &from, const void *buf, size_t sz) override;
private:
bool
GenFlowIDFor(const PubKey &pk, const Addr &from, FlowID_t &flow) const;
bool
ShouldSendFlowID(const Addr &from) const;
void
SendReject(const Addr &to, const char *msg);
void
SendFlowID(const Addr &to, const FlowID_t &flow);
using ActiveFlows_t =
std::unordered_map< FlowID_t, RouterID, FlowID_t::Hash >;
ActiveFlows_t m_ActiveFlows;
using PendingFlows_t = std::unordered_map< Addr, FlowID_t, Addr::Hash >;
/// flows that are pending authentication
PendingFlows_t m_PendingFlows;
/// cookie used in flow id computation
AlignedBuffer< 32 > m_FlowCookie;
OuterMessage m_OuterMsg;
};
} // namespace iwp
} // namespace llarp
#endif

@ -1,4 +1,4 @@
#include <link/iwp_internal.hpp>
#include <link/iwp_outermessage.hpp>
namespace llarp
{
@ -151,178 +151,6 @@ namespace llarp
return false;
}
}
LinkLayer::LinkLayer(Crypto* c, const SecretKey& enckey, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler t, SessionClosedHandler closed)
: ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed), crypto(c)
{
m_FlowCookie.Randomize();
}
LinkLayer::~LinkLayer()
{
}
void
LinkLayer::Pump()
{
ILinkLayer::Pump();
}
const char*
LinkLayer::Name() const
{
return "iwp";
}
bool
LinkLayer::KeyGen(SecretKey& k)
{
k.Zero();
crypto->encryption_keygen(k);
return !k.IsZero();
}
uint16_t
LinkLayer::Rank() const
{
return 2;
}
bool
LinkLayer::Start(Logic* l)
{
if(!ILinkLayer::Start(l))
return false;
/// TODO: change me to true when done
return false;
}
void
LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz)
{
m_OuterMsg.Clear();
llarp_buffer_t sigbuf(pkt, sz);
llarp_buffer_t decodebuf(pkt, sz);
if(!m_OuterMsg.Decode(&decodebuf))
{
LogError("failed to decode outer message");
return;
}
NetID ourNetID;
switch(m_OuterMsg.command)
{
case eOCMD_ObtainFlowID:
sigbuf.sz -= m_OuterMsg.Zsig.size();
if(!crypto->verify(m_OuterMsg.pubkey, sigbuf, m_OuterMsg.Zsig))
{
LogError("failed to verify signature on '",
(char)m_OuterMsg.command, "' message from ", from);
return;
}
if(!ShouldSendFlowID(from))
{
SendReject(from, "no flo 4u :^)");
return;
}
if(m_OuterMsg.netid == ourNetID)
{
if(GenFlowIDFor(m_OuterMsg.pubkey, from, m_OuterMsg.flow))
SendFlowID(from, m_OuterMsg.flow);
else
SendReject(from, "genflow fail");
}
else
SendReject(from, "bad netid");
}
}
ILinkSession*
LinkLayer::NewOutboundSession(const RouterContact& rc,
const AddressInfo& ai)
{
(void)rc;
(void)ai;
// TODO: implement me
return nullptr;
}
void
LinkLayer::SendFlowID(const Addr& to, const FlowID_t& flow)
{
// TODO: implement me
(void)to;
(void)flow;
}
bool
LinkLayer::VerifyFlowID(const PubKey& pk, const Addr& from,
const FlowID_t& flow) const
{
FlowID_t expected;
if(!GenFlowIDFor(pk, from, expected))
return false;
return expected == flow;
}
bool
LinkLayer::GenFlowIDFor(const PubKey& pk, const Addr& from,
FlowID_t& flow) const
{
std::array< byte_t, 128 > tmp = {{0}};
if(inet_ntop(AF_INET6, from.addr6(), (char*)tmp.data(), tmp.size())
== nullptr)
return false;
std::copy_n(pk.begin(), pk.size(), tmp.begin() + 64);
std::copy_n(m_FlowCookie.begin(), m_FlowCookie.size(),
tmp.begin() + 64 + pk.size());
llarp_buffer_t buf(tmp);
ShortHash h;
if(!crypto->shorthash(h, buf))
return false;
std::copy_n(h.begin(), flow.size(), flow.begin());
return true;
}
bool
LinkLayer::ShouldSendFlowID(const Addr& to) const
{
(void)to;
// TODO: implement me
return false;
}
void
LinkLayer::SendReject(const Addr& to, const char* msg)
{
if(strlen(msg) > 14)
{
throw std::logic_error("reject message too big");
}
std::array< byte_t, 120 > pkt;
auto now = Now();
PubKey pk = GetOurRC().pubkey;
OuterMessage m;
m.CreateReject(msg, now, pk);
llarp_buffer_t encodebuf(pkt);
if(!m.Encode(&encodebuf))
{
LogError("failed to encode reject message to ", to);
return;
}
llarp_buffer_t signbuf(pkt.data(), pkt.size() - m.Zsig.size());
if(!Sign(m.Zsig, signbuf))
{
LogError("failed to sign reject messsage to ", to);
return;
}
std::copy_n(m.Zsig.begin(), m.Zsig.size(),
pkt.begin() + (pkt.size() - m.Zsig.size()));
llarp_buffer_t pktbuf(pkt);
SendTo_LL(to, pktbuf);
}
} // namespace iwp
} // namespace llarp

@ -1,20 +1,14 @@
#ifndef LLARP_LINK_IWP_INTERNAL_HPP
#define LLARP_LINK_IWP_INTERNAL_HPP
#ifndef LLARP_LINK_IWP_OUTERMESSAGE_HPP
#define LLARP_LINK_IWP_OUTERMESSAGE_HPP
#include <constants/link_layer.hpp>
#include <crypto/crypto.hpp>
#include <crypto/encrypted.hpp>
#include <crypto/types.hpp>
#include <link/server.hpp>
#include <link/session.hpp>
#include <router_contact.hpp>
#include <util/aligned.hpp>
#include <array>
#include <bitset>
#include <deque>
namespace llarp
{
struct Crypto;
namespace iwp
{
using FlowID_t = AlignedBuffer< 32 >;
@ -87,73 +81,6 @@ namespace llarp
void
Clear();
};
struct LinkLayer final : public ILinkLayer
{
LinkLayer(Crypto *crypto, const SecretKey &encryptionSecretKey,
GetRCFunc getrc, LinkMessageHandler h,
SessionEstablishedHandler established,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);
~LinkLayer();
Crypto *const crypto;
bool
Start(Logic *l) override;
ILinkSession *
NewOutboundSession(const RouterContact &rc,
const AddressInfo &ai) override;
void
Pump() override;
bool
KeyGen(SecretKey &k) override;
const char *
Name() const override;
uint16_t
Rank() const override;
/// verify that a new flow id matches addresses and pubkey
bool
VerifyFlowID(const PubKey &pk, const Addr &from,
const FlowID_t &flow) const;
void
RecvFrom(const Addr &from, const void *buf, size_t sz) override;
private:
bool
GenFlowIDFor(const PubKey &pk, const Addr &from, FlowID_t &flow) const;
bool
ShouldSendFlowID(const Addr &from) const;
void
SendReject(const Addr &to, const char *msg);
void
SendFlowID(const Addr &to, const FlowID_t &flow);
using ActiveFlows_t =
std::unordered_map< FlowID_t, RouterID, FlowID_t::Hash >;
ActiveFlows_t m_ActiveFlows;
using PendingFlows_t = std::unordered_map< Addr, FlowID_t, Addr::Hash >;
/// flows that are pending authentication
PendingFlows_t m_PendingFlows;
/// cookie used in flow id computation
AlignedBuffer< 32 > m_FlowCookie;
OuterMessage m_OuterMsg;
};
} // namespace iwp
} // namespace llarp
#endif
Loading…
Cancel
Save