wire up exit traffic

This commit is contained in:
Jeff Becker 2018-11-14 14:34:17 -05:00
parent 5dbe41608f
commit 56676002aa
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
13 changed files with 214 additions and 26 deletions

View File

@ -492,7 +492,7 @@ main(int argc, char *argv[])
// llarp::LogInfo("Looking for string: ", rcfname); // llarp::LogInfo("Looking for string: ", rcfname);
llarp::PubKey binaryPK; llarp::PubKey binaryPK;
llarp::HexDecode(rcfname, binaryPK.data()); llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size());
llarp::LogInfo("Looking for binary: ", binaryPK); llarp::LogInfo("Looking for binary: ", binaryPK);
llarp::RouterContact *rc = llarp_main_getDatabase(ctx, binaryPK.data()); llarp::RouterContact *rc = llarp_main_getDatabase(ctx, binaryPK.data());
@ -513,7 +513,7 @@ main(int argc, char *argv[])
llarp_main_setup(ctx); llarp_main_setup(ctx);
llarp::PubKey binaryPK; llarp::PubKey binaryPK;
llarp::HexDecode(rcfname, binaryPK.data()); llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size());
llarp::LogInfo("Queueing job"); llarp::LogInfo("Queueing job");
llarp_router_lookup_job *job = new llarp_router_lookup_job; llarp_router_lookup_job *job = new llarp_router_lookup_job;
@ -584,7 +584,7 @@ main(int argc, char *argv[])
llarp::PubKey binaryPK; llarp::PubKey binaryPK;
// llarp::service::Address::FromString // llarp::service::Address::FromString
llarp::HexDecode(rcfname, binaryPK.data()); llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size());
char tmp[(1 + 32) * 2] = {0}; char tmp[(1 + 32) * 2] = {0};
std::string b32 = llarp::Base32Encode(binaryPK, tmp); std::string b32 = llarp::Base32Encode(binaryPK, tmp);
llarp::LogInfo("to base32 ", b32); llarp::LogInfo("to base32 ", b32);

View File

@ -133,8 +133,8 @@ namespace llarp
int int
char2int(char input); char2int(char input);
void bool
HexDecode(const char* src, uint8_t* target); HexDecode(const char* src, uint8_t* target, size_t sz);
} // namespace llarp } // namespace llarp
#endif #endif

View File

@ -1,6 +1,7 @@
#ifndef LLARP_EXIT_SESSION_HPP #ifndef LLARP_EXIT_SESSION_HPP
#define LLARP_EXIT_SESSION_HPP #define LLARP_EXIT_SESSION_HPP
#include <llarp/pathbuilder.hpp> #include <llarp/pathbuilder.hpp>
#include <llarp/ip.hpp>
namespace llarp namespace llarp
{ {
@ -9,8 +10,9 @@ namespace llarp
/// a persisiting exit session with an exit router /// a persisiting exit session with an exit router
struct BaseSession : public llarp::path::Builder struct BaseSession : public llarp::path::Builder
{ {
BaseSession(const llarp::RouterID& exitRouter, llarp_router* r, BaseSession(const llarp::RouterID& exitRouter,
size_t numpaths, size_t hoplen); std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen);
~BaseSession(); ~BaseSession();
@ -18,18 +20,28 @@ namespace llarp
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
size_t hop, llarp::path::PathRole roles) override; size_t hop, llarp::path::PathRole roles) override;
void
HandlePathBuilt(llarp::path::Path* p) override;
bool
SendUpstreamTraffic(llarp::net::IPv4Packet pkt);
protected: protected:
llarp::RouterID m_ExitRouter; llarp::RouterID m_ExitRouter;
}; std::function< bool(llarp_buffer_t) > m_WritePacket;
/// a N-hop exit sesssion form a client bool
struct ClientSesssion final : public BaseSession HandleTrafficDrop(llarp::path::Path* p, const llarp::PathID_t& path,
{ uint64_t s);
};
/// a "direct" session between service nodes bool
struct DirectSession final : public BaseSession HandleGotExit(llarp::path::Path* p, llarp_time_t b);
{
bool
HandleTraffic(llarp::path::Path* p, llarp_buffer_t buf);
private:
llarp::SecretKey m_ExitIdentity;
}; };
} // namespace exit } // namespace exit

View File

@ -2,7 +2,7 @@
#define LLARP_XI_HPP #define LLARP_XI_HPP
#include <llarp/bencode.hpp> #include <llarp/bencode.hpp>
#include <llarp/crypto.hpp> #include <llarp/crypto.hpp>
#include <llarp/net.h> #include <llarp/net.hpp>
#include <iostream> #include <iostream>
#include <llarp/bits.hpp> #include <llarp/bits.hpp>
@ -21,6 +21,16 @@ namespace llarp
struct in6_addr netmask; struct in6_addr netmask;
PubKey pubkey; PubKey pubkey;
ExitInfo(const PubKey &pk, const nuint32_t &ipv4_exit) : IBEncodeMessage()
{
pubkey = pk;
memset(address.s6_addr, 0, 16);
address.s6_addr[11] = 0xff;
address.s6_addr[10] = 0xff;
memcpy(address.s6_addr + 12, &ipv4_exit, 4);
memset(netmask.s6_addr, 0xff, 16);
}
ExitInfo() : IBEncodeMessage() ExitInfo() : IBEncodeMessage()
{ {
} }

View File

@ -152,6 +152,18 @@ namespace llarp
m_AddrToIP; m_AddrToIP;
private: private:
bool
QueueInboundPacketForExit(llarp_buffer_t buf)
{
return m_NetworkToUserPktQueue.EmplaceIf(
[&](llarp::net::IPv4Packet& pkt) -> bool {
if(!pkt.Load(buf))
return false;
pkt.UpdateIPv4PacketOnDst(pkt.src(), m_OurIP);
return true;
});
}
#ifndef WIN32 #ifndef WIN32
/// handles setup, given value true on success and false on failure to set /// handles setup, given value true on success and false on failure to set
/// up interface /// up interface

View File

@ -469,11 +469,15 @@ namespace llarp
std::string std::string
Name() const; Name() const;
/// ask endpoint for exit void
/// call handler with result when we get it AddObtainExitHandler(ObtainedExitHandler handler)
/// returns false if we failed to send the OXM {
m_ObtainedExitHooks.push_back(handler);
}
bool bool
ObtainExit(llarp_router* r, ObtainedExitHandler handler) const; SendExitRequest(const llarp::routing::ObtainExitMessage* msg,
llarp_router* r);
protected: protected:
llarp::routing::InboundMessageParser m_InboundMessageParser; llarp::routing::InboundMessageParser m_InboundMessageParser;

View File

@ -7,6 +7,8 @@
#include <llarp/service/protocol.hpp> #include <llarp/service/protocol.hpp>
#include <llarp/path.hpp> #include <llarp/path.hpp>
#include <llarp/ev.h> #include <llarp/ev.h>
#include <llarp/net.hpp>
#include <llarp/exit/session.hpp>
// minimum time between interoset shifts // minimum time between interoset shifts
#ifndef MIN_SHIFT_INTERVAL #ifndef MIN_SHIFT_INTERVAL
@ -414,6 +416,7 @@ namespace llarp
protected: protected:
IDataHandler* m_DataHandler = nullptr; IDataHandler* m_DataHandler = nullptr;
Identity m_Identity; Identity m_Identity;
std::unique_ptr< llarp::exit::BaseSession > m_Exit;
private: private:
llarp_router* m_Router; llarp_router* m_Router;

View File

@ -15,13 +15,15 @@ namespace llarp
return 0; return 0;
} }
void bool
HexDecode(const char* src, uint8_t* target) HexDecode(const char* src, uint8_t* target, size_t sz)
{ {
while(*src && src[1]) while(*src && src[1] && sz)
{ {
*(target++) = char2int(*src) * 16 + char2int(src[1]); *(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2; src += 2;
--sz;
} }
return sz == 0;
} }
} // namespace llarp } // namespace llarp

View File

@ -1,8 +1,105 @@
#include <llarp/exit/session.hpp> #include <llarp/exit/session.hpp>
#include "router.hpp"
namespace llarp namespace llarp
{ {
namespace exit namespace exit
{ {
} BaseSession::BaseSession(const llarp::RouterID& router,
std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen)
: llarp::path::Builder(r, r->dht, numpaths, hoplen)
, m_ExitRouter(router)
, m_WritePacket(writepkt)
{
r->crypto.identity_keygen(m_ExitIdentity);
}
BaseSession::~BaseSession()
{
}
bool
BaseSession::SelectHop(llarp_nodedb* db, const RouterContact& prev,
RouterContact& cur, size_t hop,
llarp::path::PathRole roles)
{
if(hop == numHops - 1)
return llarp_nodedb_get_rc(db, m_ExitRouter, cur);
else
return path::Builder::SelectHop(db, prev, cur, hop, roles);
}
void
BaseSession::HandlePathBuilt(llarp::path::Path* p)
{
p->SetDropHandler(std::bind(&BaseSession::HandleTrafficDrop, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
p->SetExitTrafficHandler(std::bind(&BaseSession::HandleTraffic, this,
std::placeholders::_1,
std::placeholders::_2));
p->AddObtainExitHandler(std::bind(&BaseSession::HandleGotExit, this,
std::placeholders::_1,
std::placeholders::_2));
llarp::routing::ObtainExitMessage obtain;
obtain.S = p->NextSeqNo();
obtain.T = llarp_randint();
obtain.X = 0;
if(!obtain.Sign(&router->crypto, m_ExitIdentity))
{
llarp::LogError("Failed to sign exit request");
return;
}
if(p->SendExitRequest(&obtain, router))
llarp::LogInfo("asking ", m_ExitRouter, " for exit");
else
llarp::LogError("faild to send exit request");
}
bool
BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b)
{
if(b == 0)
{
llarp::LogInfo("obtained an exit via ", p->Endpoint());
}
return true;
}
bool
BaseSession::HandleTraffic(llarp::path::Path* p, llarp_buffer_t pkt)
{
(void)p;
if(m_WritePacket)
return m_WritePacket(pkt);
return false;
}
bool
BaseSession::HandleTrafficDrop(llarp::path::Path* p, const PathID_t& path,
uint64_t s)
{
(void)p;
llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s,
" P=", path);
return true;
}
bool
BaseSession::SendUpstreamTraffic(llarp::net::IPv4Packet pkt)
{
auto path = PickRandomEstablishedPath(llarp::path::ePathRoleExit);
if(!path)
return false;
llarp::routing::TransferTrafficMessage transfer;
transfer.S = path->NextSeqNo();
transfer.X.resize(pkt.sz);
memcpy(transfer.X.data(), pkt.buf, pkt.sz);
if(!transfer.Sign(&router->crypto, m_ExitIdentity))
return false;
return path->SendRoutingMessage(&transfer, router);
}
} // namespace exit
} // namespace llarp } // namespace llarp

View File

@ -37,6 +37,21 @@ namespace llarp
bool bool
TunEndpoint::SetOption(const std::string &k, const std::string &v) TunEndpoint::SetOption(const std::string &k, const std::string &v)
{ {
if(k == "exit-node")
{
llarp::RouterID exitRouter;
if(!HexDecode(v.c_str(), exitRouter, exitRouter.size()))
{
llarp::LogError(Name(), " bad exit router key: ", v);
return false;
}
m_Exit.reset(new llarp::exit::BaseSession(
exitRouter,
std::bind(&TunEndpoint::QueueInboundPacketForExit, this,
std::placeholders::_1),
router, m_NumPaths, numHops));
llarp::LogInfo(Name(), " using exit at ", exitRouter);
}
if(k == "local-dns") if(k == "local-dns")
{ {
std::string resolverAddr = v; std::string resolverAddr = v;
@ -338,7 +353,13 @@ namespace llarp
auto itr = m_IPToAddr.find(pkt.dst()); auto itr = m_IPToAddr.find(pkt.dst());
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end())
{ {
llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst()); if(m_Exit)
{
pkt.UpdateIPv4PacketOnDst({0}, pkt.dst());
m_Exit->SendUpstreamTraffic(std::move(pkt));
}
else
llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst());
return true; return true;
} }

View File

@ -702,6 +702,14 @@ namespace llarp
return false; return false;
} }
bool
Path::SendExitRequest(const llarp::routing::ObtainExitMessage* msg,
llarp_router* r)
{
m_ExitObtainTX = msg->T;
return SendRoutingMessage(msg, r);
}
bool bool
Path::HandleObtainExitMessage(const llarp::routing::ObtainExitMessage* msg, Path::HandleObtainExitMessage(const llarp::routing::ObtainExitMessage* msg,
llarp_router* r) llarp_router* r)

View File

@ -751,7 +751,16 @@ llarp_router::Run()
// set public signing key // set public signing key
_rc.pubkey = llarp::seckey_topublic(identity); _rc.pubkey = llarp::seckey_topublic(identity);
llarp::LogInfo("Your Identity pubkey ", rc().pubkey); llarp::LogInfo("Your Identity pubkey ", rc().pubkey);
if(ExitEnabled())
{
llarp::nuint32_t a = publicAddr.xtonl();
// TODO: enable this once the network can serialize xi
//_rc.exits.emplace_back(_rc.pubkey, a);
llarp::LogInfo(
"Neato tehl33toh, You are a freaking exit relay. w00t!!!!! your exit "
"is advertised as exiting at ",
a);
}
llarp::LogInfo("Signing rc..."); llarp::LogInfo("Signing rc...");
if(!_rc.Sign(&crypto, identity)) if(!_rc.Sign(&crypto, identity))
{ {

View File

@ -25,6 +25,7 @@
#include "crypto.hpp" #include "crypto.hpp"
#include "fs.hpp" #include "fs.hpp"
#include "mem.hpp" #include "mem.hpp"
#include "str.hpp"
bool bool
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath, llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
@ -102,6 +103,15 @@ struct llarp_router
/// default exit config /// default exit config
llarp::exit::Context::Config_t exitConf; llarp::exit::Context::Config_t exitConf;
bool
ExitEnabled() const
{
auto itr = exitConf.find("exit");
if(itr == exitConf.end())
return false;
return llarp::IsTrueValue(itr->second.c_str());
}
bool bool
CreateDefaultHiddenService(); CreateDefaultHiddenService();