mirror of https://github.com/oxen-io/lokinet
Refactor iwp into multiple files
parent
17b39b0ed4
commit
426a9b0df5
@ -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
|
Loading…
Reference in New Issue