mirror of https://github.com/oxen-io/lokinet
more exit stuff
This commit is contained in:
parent
f9a4c57d66
commit
5dbe41608f
|
@ -553,7 +553,9 @@ ip address used for exit traffic.
|
|||
A: "G",
|
||||
S: uint64_sequence_number,
|
||||
T: transaction_id_uint64,
|
||||
V: 0
|
||||
Y: "<16 byte nonce>",
|
||||
V: 0,
|
||||
Z: "<64 bytes signature>"
|
||||
}
|
||||
|
||||
any TITM recieved on the same path will be forwarded out to the internet if
|
||||
|
@ -571,14 +573,16 @@ was denied.
|
|||
R: [list, of, rejected, traffic, policies],
|
||||
S: uint64_sequence_number,
|
||||
T: transaction_id_uint64,
|
||||
V: 0
|
||||
V: 0,
|
||||
Y: "<16 byte nonce>",
|
||||
Z: "<64 bytes signature>"
|
||||
}
|
||||
|
||||
|
||||
discarded data fragment message (DDFM)
|
||||
|
||||
sent in reply to TDFM when we don't have a path locally or are doing network
|
||||
congestion control. indcates a TDFM was discarded.
|
||||
congestion control from a TITM.
|
||||
|
||||
{
|
||||
A: "D",
|
||||
|
@ -732,24 +736,25 @@ transfer data on a session previously made
|
|||
|
||||
transfer ip traffic message (TITM)
|
||||
|
||||
transfer ip traffic for exit
|
||||
transfer ip traffic
|
||||
|
||||
{
|
||||
A: "I",
|
||||
S: uint64_sequence_number,
|
||||
V: 0,
|
||||
X: "<N bytes ip packet>",
|
||||
Y: "<16 bytes nonce>",
|
||||
Z: "<64 bytes signature using previously provided signing key>"
|
||||
}
|
||||
|
||||
X is parsed as an IP packet and the source addresss is extracted.
|
||||
Next we find the corrisponding signing key for a previously granted exit address
|
||||
Next we find the corrisponding signing key for a previously granted address
|
||||
and use it to validate the siganture of the entire message. If the signing key
|
||||
cannot be found or the signature is invalid this message is dropped, otherwise
|
||||
the X value is sent on the appropriate exit network interface.
|
||||
the X value is sent on the appropriate network interface.
|
||||
|
||||
When we recieve an ip packet from the internet to an exit address, we put it
|
||||
into a TITM, signed with the exit info's signing key and send it downstream the
|
||||
into a TITM, signed with the router's signing key and send it downstream the
|
||||
corrisponding path in an LRDM.
|
||||
|
||||
update exit path message (UXPM)
|
||||
|
@ -763,31 +768,35 @@ should use the new path that this message came from.
|
|||
S: uint64_sequence_number,
|
||||
T: uint64_txid,
|
||||
V: 0,
|
||||
Y: "<16 bytes nonce>",
|
||||
Z: "<64 bytes signature using previously provided signing key>"
|
||||
}
|
||||
|
||||
close exit path message (CXPM)
|
||||
|
||||
client sends a CXPM when the exit is no longer needed.
|
||||
client sends a CXPM when the exit is no longer needed or by the exit if the
|
||||
exit wants to close prematurely.
|
||||
also sent by exit in reply to a CXPM to confirm close.
|
||||
|
||||
{
|
||||
A: "C",
|
||||
S: uint64_sequence_number,
|
||||
T: transaction_id_uint64,
|
||||
V: 0,
|
||||
Z: "<64 bytes signagure using previously provided signing key>"
|
||||
Y: "<16 bytes nonce>",
|
||||
Z: "<64 bytes signature>"
|
||||
}
|
||||
|
||||
update exit verify message (EXVM)
|
||||
|
||||
sent in reply to a UXPM to verify that the path handover was accepted
|
||||
sent in reply to a CXPM to verify that the exit was closed
|
||||
|
||||
{
|
||||
A: "V",
|
||||
S: uint64_sequence_number,
|
||||
T: uint64_txid,
|
||||
V: 0
|
||||
V: 0,
|
||||
Y: "<16 bytes nonce>",
|
||||
Z: "<64 bytes signature>"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,14 @@ namespace llarp
|
|||
llarp::exit::Endpoint *
|
||||
FindEndpointForPath(const llarp::PathID_t &path) const;
|
||||
|
||||
/// calculate (pk, tx, rx) for all exit traffic
|
||||
using TrafficStats =
|
||||
std::unordered_map< PubKey, std::pair< uint64_t, uint64_t >,
|
||||
PubKey::Hash >;
|
||||
|
||||
void
|
||||
CalculateExitTraffic(TrafficStats &stats);
|
||||
|
||||
private:
|
||||
llarp_router *m_Router;
|
||||
std::unordered_map< std::string,
|
||||
|
|
|
@ -24,10 +24,21 @@ namespace llarp
|
|||
|
||||
~Endpoint();
|
||||
|
||||
/// close ourselves
|
||||
void
|
||||
Close();
|
||||
|
||||
/// return true if we are expired right now
|
||||
bool
|
||||
IsExpired(llarp_time_t now) const;
|
||||
|
||||
bool
|
||||
ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 5000) const;
|
||||
|
||||
/// tick ourself, reset tx/rx rates
|
||||
void
|
||||
Tick(llarp_time_t now);
|
||||
|
||||
/// handle traffic from service node / internet
|
||||
bool
|
||||
SendInboundTraffic(llarp_buffer_t buff);
|
||||
|
@ -57,11 +68,24 @@ namespace llarp
|
|||
return m_CurrentPath;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
TxRate() const
|
||||
{
|
||||
return m_TxRate;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RxRate() const
|
||||
{
|
||||
return m_RxRate;
|
||||
}
|
||||
|
||||
private:
|
||||
llarp::handlers::ExitEndpoint* m_Parent;
|
||||
llarp::PubKey m_remoteSignKey;
|
||||
llarp::PathID_t m_CurrentPath;
|
||||
llarp::huint32_t m_IP;
|
||||
uint64_t m_TxRate, m_RxRate;
|
||||
bool m_RewriteSource;
|
||||
};
|
||||
} // namespace exit
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop) override;
|
||||
size_t hop, llarp::path::PathRole roles) override;
|
||||
|
||||
protected:
|
||||
llarp::RouterID m_ExitRouter;
|
||||
|
|
|
@ -34,10 +34,28 @@ namespace llarp
|
|||
UpdateEndpointPath(const llarp::PubKey& remote,
|
||||
const llarp::PathID_t& next);
|
||||
|
||||
template < typename Stats >
|
||||
void
|
||||
CalculateTrafficStats(Stats& stats)
|
||||
{
|
||||
auto itr = m_ActiveExits.begin();
|
||||
while(itr != m_ActiveExits.end())
|
||||
{
|
||||
stats[itr->first].first += itr->second.TxRate();
|
||||
stats[itr->first].second += itr->second.RxRate();
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
/// DO NOT CALL ME IF YOU DONT KNOW WHAT THIS DOES
|
||||
void
|
||||
DelEndpointInfo(const llarp::PathID_t& path, const huint32_t& ip,
|
||||
const llarp::PubKey& pk);
|
||||
|
||||
/// DO NOT CALL ME IF YOU DONT KNOW WHAT THIS DOES
|
||||
void
|
||||
RemoveExit(const llarp::exit::Endpoint* ep);
|
||||
|
||||
protected:
|
||||
void
|
||||
FlushSend();
|
||||
|
|
|
@ -49,7 +49,10 @@ namespace llarp
|
|||
|
||||
struct GrantExitMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer< 16 >;
|
||||
uint64_t T;
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
GrantExitMessage() : IMessage()
|
||||
{
|
||||
}
|
||||
|
@ -58,9 +61,18 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
GrantExitMessage&
|
||||
operator=(const GrantExitMessage& other);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Sign(llarp_crypto* c, const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(llarp_crypto* c, const llarp::PubKey& pk) const;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) override;
|
||||
|
||||
|
@ -70,9 +82,12 @@ namespace llarp
|
|||
|
||||
struct RejectExitMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer< 16 >;
|
||||
uint64_t B;
|
||||
std::vector< llarp::exit::Policy > R;
|
||||
uint64_t T;
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
|
||||
RejectExitMessage() : IMessage()
|
||||
{
|
||||
|
@ -82,6 +97,15 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
RejectExitMessage&
|
||||
operator=(const RejectExitMessage& other);
|
||||
|
||||
bool
|
||||
Sign(llarp_crypto* c, const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(llarp_crypto* c, const llarp::PubKey& pk) const;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const override;
|
||||
|
||||
|
@ -94,7 +118,10 @@ namespace llarp
|
|||
|
||||
struct UpdateExitVerifyMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer< 16 >;
|
||||
uint64_t T;
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
|
||||
UpdateExitVerifyMessage() : IMessage()
|
||||
{
|
||||
|
@ -104,6 +131,15 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
UpdateExitVerifyMessage&
|
||||
operator=(const UpdateExitVerifyMessage& other);
|
||||
|
||||
bool
|
||||
Sign(llarp_crypto* c, const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(llarp_crypto* c, const llarp::PubKey& pk) const;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const override;
|
||||
|
||||
|
@ -116,8 +152,10 @@ namespace llarp
|
|||
|
||||
struct UpdateExitMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer< 16 >;
|
||||
llarp::PathID_t P;
|
||||
uint64_t T;
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
|
||||
UpdateExitMessage() : IMessage()
|
||||
|
@ -149,6 +187,11 @@ namespace llarp
|
|||
|
||||
struct CloseExitMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer< 16 >;
|
||||
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
|
||||
CloseExitMessage() : IMessage()
|
||||
{
|
||||
}
|
||||
|
@ -157,6 +200,9 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
CloseExitMessage&
|
||||
operator=(const CloseExitMessage& other);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const override;
|
||||
|
||||
|
@ -165,6 +211,12 @@ namespace llarp
|
|||
|
||||
bool
|
||||
HandleMessage(IMessageHandler* h, llarp_router* r) const override;
|
||||
|
||||
bool
|
||||
Sign(llarp_crypto* c, const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(llarp_crypto* c, const llarp::PubKey& pk) const;
|
||||
};
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -11,7 +11,10 @@ namespace llarp
|
|||
constexpr size_t MaxExitMTU = 1500;
|
||||
struct TransferTrafficMessage final : public IMessage
|
||||
{
|
||||
using Nonce_t = AlignedBuffer< 16 >;
|
||||
|
||||
std::vector< byte_t > X;
|
||||
Nonce_t Y;
|
||||
llarp::Signature Z;
|
||||
|
||||
TransferTrafficMessage&
|
||||
|
|
|
@ -144,6 +144,10 @@ struct llarp_async_load_rc
|
|||
void
|
||||
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job);
|
||||
|
||||
bool
|
||||
llarp_nodedb_select_random_exit(struct llarp_nodedb *n,
|
||||
llarp::RouterContact &rc);
|
||||
|
||||
bool
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n,
|
||||
const llarp::RouterContact &prev,
|
||||
|
|
|
@ -104,6 +104,9 @@ namespace llarp
|
|||
virtual bool
|
||||
Expired(llarp_time_t now) const = 0;
|
||||
|
||||
virtual bool
|
||||
ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const = 0;
|
||||
|
||||
/// send routing message and increment sequence number
|
||||
virtual bool
|
||||
SendRoutingMessage(const llarp::routing::IMessage* msg,
|
||||
|
@ -162,7 +165,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
Expired(llarp_time_t now) const;
|
||||
Expired(llarp_time_t now) const override;
|
||||
|
||||
bool
|
||||
ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const override
|
||||
{
|
||||
return now >= ExpireTime() - dlt;
|
||||
}
|
||||
|
||||
// send routing message when end of path
|
||||
bool
|
||||
|
@ -274,6 +283,10 @@ namespace llarp
|
|||
DataHandlerFunc;
|
||||
typedef std::function< bool(Path*) > ExitUpdatedFunc;
|
||||
typedef std::function< bool(Path*) > ExitClosedFunc;
|
||||
typedef std::function< bool(Path*, llarp_buffer_t) >
|
||||
ExitTrafficHandlerFunc;
|
||||
/// (path, backoff) backoff is 0 on success
|
||||
typedef std::function< bool(Path*, llarp_time_t) > ObtainedExitHandler;
|
||||
|
||||
HopList hops;
|
||||
|
||||
|
@ -282,13 +295,37 @@ namespace llarp
|
|||
llarp::service::Introduction intro;
|
||||
|
||||
llarp_time_t buildStarted;
|
||||
PathStatus _status;
|
||||
|
||||
Path(const std::vector< RouterContact >& routers, PathSet* parent);
|
||||
Path(const std::vector< RouterContact >& routers, PathSet* parent,
|
||||
PathRole startingRoles);
|
||||
|
||||
PathRole
|
||||
Role() const
|
||||
{
|
||||
return _role;
|
||||
}
|
||||
|
||||
bool
|
||||
SupportsRoles(PathRole roles) const
|
||||
{
|
||||
return (_role & roles) == roles;
|
||||
}
|
||||
|
||||
PathStatus
|
||||
Status() const
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
void
|
||||
SetBuildResultHook(BuildResultHookFunc func);
|
||||
|
||||
void
|
||||
SetExitTrafficHandler(ExitTrafficHandlerFunc handler)
|
||||
{
|
||||
m_ExitTrafficHandler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
SetCloseExitFunc(ExitClosedFunc handler)
|
||||
{
|
||||
|
@ -328,6 +365,12 @@ namespace llarp
|
|||
return buildStarted + hops[0].lifetime;
|
||||
}
|
||||
|
||||
bool
|
||||
ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 5000) const
|
||||
{
|
||||
return now >= (ExpireTime() - dlt);
|
||||
}
|
||||
|
||||
bool
|
||||
Expired(llarp_time_t now) const;
|
||||
|
||||
|
@ -426,21 +469,36 @@ namespace llarp
|
|||
std::string
|
||||
Name() const;
|
||||
|
||||
/// ask endpoint for exit
|
||||
/// call handler with result when we get it
|
||||
/// returns false if we failed to send the OXM
|
||||
bool
|
||||
ObtainExit(llarp_router* r, ObtainedExitHandler handler) const;
|
||||
|
||||
protected:
|
||||
llarp::routing::InboundMessageParser m_InboundMessageParser;
|
||||
|
||||
private:
|
||||
/// call obtained exit hooks
|
||||
bool
|
||||
InformExitResult(llarp_time_t b);
|
||||
|
||||
BuildResultHookFunc m_BuiltHook;
|
||||
DataHandlerFunc m_DataHandler;
|
||||
DropHandlerFunc m_DropHandler;
|
||||
CheckForDeadFunc m_CheckForDead;
|
||||
ExitUpdatedFunc m_ExitUpdated;
|
||||
ExitClosedFunc m_ExitClosed;
|
||||
ExitTrafficHandlerFunc m_ExitTrafficHandler;
|
||||
std::vector< ObtainedExitHandler > m_ObtainedExitHooks;
|
||||
llarp_time_t m_LastRecvMessage = 0;
|
||||
llarp_time_t m_LastLatencyTestTime = 0;
|
||||
uint64_t m_LastLatencyTestID = 0;
|
||||
uint64_t m_UpdateExitTX = 0;
|
||||
uint64_t m_CloseExitTX = 0;
|
||||
uint64_t m_ExitObtainTX = 0;
|
||||
PathStatus _status;
|
||||
PathRole _role;
|
||||
};
|
||||
|
||||
enum PathBuildStatus
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace llarp
|
|||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop);
|
||||
size_t hop, PathRole roles);
|
||||
|
||||
virtual bool
|
||||
ShouldBuildMore(llarp_time_t now) const;
|
||||
|
@ -35,16 +35,18 @@ namespace llarp
|
|||
Now() const;
|
||||
|
||||
void
|
||||
BuildOne();
|
||||
BuildOne(PathRole roles = ePathRoleAny);
|
||||
|
||||
void
|
||||
Build(const std::vector< RouterContact >& hops);
|
||||
Build(const std::vector< RouterContact >& hops,
|
||||
PathRole roles = ePathRoleAny);
|
||||
|
||||
bool
|
||||
SelectHops(llarp_nodedb* db, std::vector< RouterContact >& hops);
|
||||
SelectHops(llarp_nodedb* db, std::vector< RouterContact >& hops,
|
||||
PathRole roles = ePathRoleAny);
|
||||
|
||||
void
|
||||
ManualRebuild(size_t N);
|
||||
ManualRebuild(size_t N, PathRole roles = ePathRoleAny);
|
||||
|
||||
virtual const byte_t*
|
||||
GetTunnelEncryptionSecretKey() const;
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace llarp
|
|||
|
||||
namespace path
|
||||
{
|
||||
/// status of a path
|
||||
enum PathStatus
|
||||
{
|
||||
ePathBuilding,
|
||||
|
@ -28,6 +29,21 @@ namespace llarp
|
|||
ePathTimeout,
|
||||
ePathExpired
|
||||
};
|
||||
|
||||
/// the role of this path can fuffill
|
||||
using PathRole = int;
|
||||
|
||||
/// capable of any role
|
||||
constexpr PathRole ePathRoleAny = 0;
|
||||
/// outbound hs traffic capabale
|
||||
constexpr PathRole ePathRoleOutboundHS = (1 << 0);
|
||||
/// inbound hs traffic capable
|
||||
constexpr PathRole ePathRoleInboundHS = (1 << 1);
|
||||
/// exit traffic capable
|
||||
constexpr PathRole ePathRoleExit = (1 << 2);
|
||||
/// dht message capable
|
||||
constexpr PathRole ePathRoleDHT = (1 << 3);
|
||||
|
||||
// forward declare
|
||||
struct Path;
|
||||
|
||||
|
@ -63,9 +79,14 @@ namespace llarp
|
|||
void
|
||||
ExpirePaths(llarp_time_t now);
|
||||
|
||||
/// get the number of paths in this status
|
||||
size_t
|
||||
NumInStatus(PathStatus st) const;
|
||||
|
||||
/// get the number of paths that match the role that are available
|
||||
size_t
|
||||
AvailablePaths(PathRole role) const;
|
||||
|
||||
/// get time from event loop
|
||||
virtual llarp_time_t
|
||||
Now() const = 0;
|
||||
|
@ -74,6 +95,14 @@ namespace llarp
|
|||
virtual bool
|
||||
ShouldBuildMore(llarp_time_t now) const;
|
||||
|
||||
/// return true if we need another path with the given path roles
|
||||
virtual bool
|
||||
ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const;
|
||||
|
||||
/// return the minimum number of paths we want for given roles
|
||||
virtual size_t
|
||||
MinRequiredForRoles(PathRole roles) const;
|
||||
|
||||
/// return true if we should publish a new hidden service descriptor
|
||||
virtual bool
|
||||
ShouldPublishDescriptors(__attribute__((unused)) llarp_time_t now) const
|
||||
|
@ -104,16 +133,19 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
GetEstablishedPathClosestTo(const RouterID& router) const;
|
||||
GetEstablishedPathClosestTo(const RouterID& router,
|
||||
PathRole roles = ePathRoleAny) const;
|
||||
|
||||
Path*
|
||||
PickRandomEstablishedPath() const;
|
||||
PickRandomEstablishedPath(PathRole roles = ePathRoleAny) const;
|
||||
|
||||
Path*
|
||||
GetPathByRouter(const RouterID& router) const;
|
||||
GetPathByRouter(const RouterID& router,
|
||||
PathRole roles = ePathRoleAny) const;
|
||||
|
||||
Path*
|
||||
GetNewestPathByRouter(const RouterID& router) const;
|
||||
GetNewestPathByRouter(const RouterID& router,
|
||||
PathRole roles = ePathRoleAny) const;
|
||||
|
||||
Path*
|
||||
GetPathByID(const PathID_t& id) const;
|
||||
|
@ -136,7 +168,7 @@ namespace llarp
|
|||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop) = 0;
|
||||
size_t hop, PathRole roles) = 0;
|
||||
|
||||
protected:
|
||||
size_t m_NumPaths;
|
||||
|
|
|
@ -53,6 +53,12 @@ namespace llarp
|
|||
void
|
||||
Clear();
|
||||
|
||||
bool
|
||||
IsExit() const
|
||||
{
|
||||
return exits.size() > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t *buf) override
|
||||
{
|
||||
|
|
|
@ -330,14 +330,6 @@ namespace llarp
|
|||
EnsurePathToService(const Address& remote, PathEnsureHook h,
|
||||
uint64_t timeoutMS, bool lookupOnRandomPath = false);
|
||||
|
||||
virtual bool
|
||||
HandleAuthenticatedDataFrom(__attribute__((unused)) const Address& remote,
|
||||
__attribute__((unused)) llarp_buffer_t data)
|
||||
{
|
||||
/// TODO: imlement me
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info);
|
||||
|
||||
|
|
|
@ -8,18 +8,71 @@ namespace llarp
|
|||
bool
|
||||
CloseExitMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
(void)buf;
|
||||
// TODO: implement me
|
||||
return false;
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "A", "C"))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("S", S, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("V", version, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Y", Y, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Z", Z, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf)
|
||||
{
|
||||
(void)k;
|
||||
(void)buf;
|
||||
// TODO: implement me
|
||||
return false;
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictInt("S", S, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("V", version, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Y", Y, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Z", Z, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::Verify(llarp_crypto* c, const llarp::PubKey& pk) const
|
||||
{
|
||||
byte_t tmp[128] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
CloseExitMessage copy;
|
||||
copy = *this;
|
||||
copy.Z.Zero();
|
||||
if(!copy.BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->verify(pk, buf, Z);
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::Sign(llarp_crypto* c, const llarp::SecretKey& sk)
|
||||
{
|
||||
byte_t tmp[128] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
Z.Zero();
|
||||
Y.Randomize();
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->sign(Z, sk, buf);
|
||||
}
|
||||
|
||||
CloseExitMessage&
|
||||
CloseExitMessage::operator=(const CloseExitMessage& other)
|
||||
{
|
||||
S = other.S;
|
||||
version = other.version;
|
||||
Y = other.Y;
|
||||
Z = other.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -22,6 +22,17 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::CalculateExitTraffic(TrafficStats& stats)
|
||||
{
|
||||
auto itr = m_Exits.begin();
|
||||
while(itr != m_Exits.end())
|
||||
{
|
||||
itr->second->CalculateTrafficStats(stats);
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
llarp::exit::Endpoint*
|
||||
Context::FindEndpointForPath(const llarp::PathID_t& path) const
|
||||
{
|
||||
|
|
|
@ -21,6 +21,12 @@ namespace llarp
|
|||
m_Parent->DelEndpointInfo(m_CurrentPath, m_IP, m_remoteSignKey);
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::Close()
|
||||
{
|
||||
m_Parent->RemoveExit(this);
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::UpdateLocalPath(const llarp::PathID_t& nextPath)
|
||||
{
|
||||
|
@ -30,6 +36,14 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::Tick(llarp_time_t now)
|
||||
{
|
||||
(void)now;
|
||||
m_RxRate = 0;
|
||||
m_TxRate = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::IsExpired(llarp_time_t now) const
|
||||
{
|
||||
|
@ -42,6 +56,15 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const
|
||||
{
|
||||
auto path = GetCurrentPath();
|
||||
if(path)
|
||||
return path->ExpiresSoon(now, dlt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::SendOutboundTraffic(llarp_buffer_t buf)
|
||||
{
|
||||
|
@ -54,7 +77,10 @@ namespace llarp
|
|||
else
|
||||
dst = pkt.dst();
|
||||
pkt.UpdateIPv4PacketOnDst(m_IP, dst);
|
||||
return m_Parent->QueueOutboundTraffic(std::move(pkt));
|
||||
if(!m_Parent->QueueOutboundTraffic(std::move(pkt)))
|
||||
return false;
|
||||
m_TxRate += buf.sz;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -69,7 +95,10 @@ namespace llarp
|
|||
msg.S = path->NextSeqNo();
|
||||
if(!msg.Sign(m_Parent->Crypto(), m_Parent->Router()->identity))
|
||||
return false;
|
||||
return path->SendRoutingMessage(&msg, m_Parent->Router());
|
||||
if(!path->SendRoutingMessage(&msg, m_Parent->Router()))
|
||||
return false;
|
||||
m_RxRate += buf.sz;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ namespace llarp
|
|||
return false;
|
||||
if(!BEncodeWriteDictInt("V", version, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Y", Y, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Z", Z, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
|
@ -31,9 +35,51 @@ namespace llarp
|
|||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("V", version, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Y", Y, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Z", Z, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::Verify(llarp_crypto* c, const llarp::PubKey& pk) const
|
||||
{
|
||||
byte_t tmp[128] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
GrantExitMessage copy;
|
||||
copy = *this;
|
||||
copy.Z.Zero();
|
||||
if(!copy.BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->verify(pk, buf, Z);
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::Sign(llarp_crypto* c, const llarp::SecretKey& sk)
|
||||
{
|
||||
byte_t tmp[128] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
Z.Zero();
|
||||
Y.Randomize();
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->sign(Z, sk, buf);
|
||||
}
|
||||
|
||||
GrantExitMessage&
|
||||
GrantExitMessage::operator=(const GrantExitMessage& other)
|
||||
{
|
||||
S = other.S;
|
||||
T = other.T;
|
||||
version = other.version;
|
||||
Y = other.Y;
|
||||
Z = other.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::HandleMessage(IMessageHandler* h, llarp_router* r) const
|
||||
{
|
||||
|
|
|
@ -8,19 +8,86 @@ namespace llarp
|
|||
bool
|
||||
RejectExitMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
(void)buf;
|
||||
|
||||
// TODO: implement me
|
||||
return false;
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "A", "J"))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("B", B, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictList("R", R, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("S", S, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("T", T, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("V", version, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Y", Y, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Z", Z, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf)
|
||||
{
|
||||
(void)k;
|
||||
(void)buf;
|
||||
// TODO: implement me
|
||||
return false;
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictInt("B", B, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictList("R", R, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("S", S, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("T", T, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("V", version, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Y", Y, read, k, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Z", Z, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
RejectExitMessage&
|
||||
RejectExitMessage::operator=(const RejectExitMessage& other)
|
||||
{
|
||||
B = other.B;
|
||||
R = other.R;
|
||||
S = other.S;
|
||||
T = other.T;
|
||||
version = other.version;
|
||||
Y = other.Y;
|
||||
Z = other.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::Sign(llarp_crypto* c, const llarp::SecretKey& sk)
|
||||
{
|
||||
byte_t tmp[512] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
Z.Zero();
|
||||
Y.Randomize();
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->sign(Z, sk, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::Verify(llarp_crypto* c, const llarp::PubKey& pk) const
|
||||
{
|
||||
byte_t tmp[512] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
RejectExitMessage copy;
|
||||
copy = *this;
|
||||
copy.Z.Zero();
|
||||
if(!copy.BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
return c->verify(pk, buf, Z);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -10,23 +10,22 @@ namespace llarp
|
|||
{
|
||||
byte_t tmp[MaxExitMTU + 512] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
llarp::Signature sig;
|
||||
// zero out sig
|
||||
Z.Zero();
|
||||
// randomize nonce
|
||||
Y.Randomize();
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
// rewind buffer
|
||||
buf.sz = buf.cur - buf.base;
|
||||
if(!c->sign(sig, k, buf))
|
||||
return false;
|
||||
Z = sig;
|
||||
return true;
|
||||
return c->sign(Z, k, buf);
|
||||
}
|
||||
|
||||
TransferTrafficMessage&
|
||||
TransferTrafficMessage::operator=(const TransferTrafficMessage& other)
|
||||
{
|
||||
Z = other.Z;
|
||||
Y = other.Y;
|
||||
S = other.S;
|
||||
version = other.version;
|
||||
X = other.X;
|
||||
|
@ -39,7 +38,6 @@ namespace llarp
|
|||
{
|
||||
byte_t tmp[MaxExitMTU + 512] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
llarp::Signature sig;
|
||||
// make copy
|
||||
TransferTrafficMessage copy;
|
||||
copy = *this;
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace llarp
|
|||
S = other.S;
|
||||
T = other.T;
|
||||
version = other.version;
|
||||
Y = other.Y;
|
||||
Z = other.Z;
|
||||
return *this;
|
||||
}
|
||||
|
@ -73,6 +74,7 @@ namespace llarp
|
|||
{
|
||||
byte_t tmp[128] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
Y.Randomize();
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
|
|
|
@ -85,6 +85,7 @@ namespace llarp
|
|||
void
|
||||
ExitEndpoint::FlushSend()
|
||||
{
|
||||
auto now = Now();
|
||||
m_UserToNetworkPktQueue.Process([&](net::IPv4Packet &pkt) {
|
||||
// find pubkey for addr
|
||||
if(!HasLocalIP(pkt.dst()))
|
||||
|
@ -94,16 +95,24 @@ namespace llarp
|
|||
}
|
||||
llarp::PubKey pk = ObtainAddrForIP< llarp::PubKey >(pkt.dst());
|
||||
pkt.UpdateIPv4PacketOnDst(pkt.src(), {0});
|
||||
auto range = m_ActiveExits.equal_range(pk);
|
||||
auto exit_itr = range.first;
|
||||
while(exit_itr != range.second)
|
||||
llarp::exit::Endpoint *ep = nullptr;
|
||||
auto range = m_ActiveExits.equal_range(pk);
|
||||
auto itr = range.first;
|
||||
uint64_t min = std::numeric_limits< uint64_t >::max();
|
||||
/// pick path with lowest rx rate
|
||||
while(itr != range.second)
|
||||
{
|
||||
if(exit_itr->second.SendInboundTraffic(pkt.Buffer()))
|
||||
return true;
|
||||
++exit_itr;
|
||||
if(ep == nullptr)
|
||||
ep = &itr->second;
|
||||
else if(itr->second.RxRate() < min && !itr->second.ExpiresSoon(now))
|
||||
{
|
||||
min = ep->RxRate();
|
||||
ep = &itr->second;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
// dropped
|
||||
llarp::LogWarn(Name(), " dropped traffic to ", pk);
|
||||
if(!ep->SendInboundTraffic(pkt.Buffer()))
|
||||
llarp::LogWarn(Name(), " dropped traffic to ", pk);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -123,6 +132,23 @@ namespace llarp
|
|||
m_AddrToIP.erase(pk);
|
||||
}
|
||||
|
||||
void
|
||||
ExitEndpoint::RemoveExit(const llarp::exit::Endpoint *ep)
|
||||
{
|
||||
auto range = m_ActiveExits.equal_range(ep->PubKey());
|
||||
auto itr = range.first;
|
||||
while(itr != range.second)
|
||||
{
|
||||
if(itr->second.LocalPath() == ep->LocalPath())
|
||||
{
|
||||
itr = m_ActiveExits.erase(itr);
|
||||
// now ep is gone af
|
||||
return;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExitEndpoint::Tick(llarp_time_t now)
|
||||
{
|
||||
|
@ -134,7 +160,10 @@ namespace llarp
|
|||
itr = m_ActiveExits.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
itr->second.Tick(now);
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
// call parent
|
||||
TunEndpoint::Tick(now);
|
||||
|
|
|
@ -411,6 +411,40 @@ llarp_nodedb_del_rc(struct llarp_nodedb *n, const llarp::RouterID &pk)
|
|||
return n->Remove(pk);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_nodedb_select_random_exit(struct llarp_nodedb *n,
|
||||
llarp::RouterContact &result)
|
||||
{
|
||||
const auto sz = n->entries.size();
|
||||
auto itr = n->entries.begin();
|
||||
if(sz < 3)
|
||||
return false;
|
||||
auto idx = llarp_randint() % sz;
|
||||
if(idx)
|
||||
std::advance(itr, idx - 1);
|
||||
while(itr != n->entries.end())
|
||||
{
|
||||
if(itr->second.IsExit())
|
||||
{
|
||||
result = itr->second;
|
||||
return true;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
// wrap arround
|
||||
itr = n->entries.begin();
|
||||
while(idx--)
|
||||
{
|
||||
if(itr->second.IsExit())
|
||||
{
|
||||
result = itr->second;
|
||||
return true;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n,
|
||||
const llarp::RouterContact &prev,
|
||||
|
|
|
@ -263,7 +263,11 @@ namespace llarp
|
|||
{
|
||||
if(builder->ShouldBuildMore(now))
|
||||
{
|
||||
builder->BuildOne();
|
||||
builder->BuildOne(ePathRoleAny);
|
||||
}
|
||||
if(builder->ShouldBuildMoreForRoles(now, ePathRoleExit))
|
||||
{
|
||||
builder->BuildOne(ePathRoleExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,8 +340,9 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
Path::Path(const std::vector< RouterContact >& h, PathSet* parent)
|
||||
: m_PathSet(parent)
|
||||
Path::Path(const std::vector< RouterContact >& h, PathSet* parent,
|
||||
PathRole startingRoles)
|
||||
: m_PathSet(parent), _role(startingRoles)
|
||||
{
|
||||
hops.resize(h.size());
|
||||
size_t hsz = h.size();
|
||||
|
@ -649,13 +654,13 @@ namespace llarp
|
|||
const llarp::routing::PathLatencyMessage* msg, llarp_router* r)
|
||||
{
|
||||
auto now = r->Now();
|
||||
// TODO: reanimate dead paths if they get this message
|
||||
if(msg->L == m_LastLatencyTestID && _status == ePathEstablished)
|
||||
if(msg->L == m_LastLatencyTestID)
|
||||
{
|
||||
intro.latency = now - m_LastLatencyTestTime;
|
||||
llarp::LogDebug("path latency is ", intro.latency,
|
||||
" ms for tx=", TXID(), " rx=", RXID());
|
||||
m_LastLatencyTestID = 0;
|
||||
_status = ePathEstablished;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -680,9 +685,20 @@ namespace llarp
|
|||
Path::HandleCloseExitMessage(const llarp::routing::CloseExitMessage* msg,
|
||||
llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
/// allows exits to close from their end
|
||||
if(SupportsRoles(ePathRoleExit))
|
||||
{
|
||||
if(msg->Verify(&r->crypto, Endpoint()))
|
||||
{
|
||||
llarp::LogInfo(Name(), " had its exit closed");
|
||||
_role &= ~ePathRoleExit;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
llarp::LogError(Name(), " CXM from exit with bad signature");
|
||||
}
|
||||
else
|
||||
llarp::LogError(Name(), " unwarrented CXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -690,9 +706,9 @@ namespace llarp
|
|||
Path::HandleObtainExitMessage(const llarp::routing::ObtainExitMessage* msg,
|
||||
llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
llarp::LogError(Name(), " got unwarrented OXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -700,9 +716,9 @@ namespace llarp
|
|||
Path::HandleUpdateExitMessage(const llarp::routing::UpdateExitMessage* msg,
|
||||
llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
llarp::LogError(Name(), " got unwarrented UXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -710,9 +726,16 @@ namespace llarp
|
|||
Path::HandleRejectExitMessage(const llarp::routing::RejectExitMessage* msg,
|
||||
llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
if(m_ExitObtainTX && msg->T == m_ExitObtainTX)
|
||||
{
|
||||
if(!msg->Verify(&r->crypto, Endpoint()))
|
||||
{
|
||||
llarp::LogError(Name(), "RXM invalid signature");
|
||||
return false;
|
||||
}
|
||||
return InformExitResult(msg->B);
|
||||
}
|
||||
llarp::LogError(Name(), " got unwarrented RXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -720,19 +743,48 @@ namespace llarp
|
|||
Path::HandleGrantExitMessage(const llarp::routing::GrantExitMessage* msg,
|
||||
llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
if(m_ExitObtainTX && msg->T == m_ExitObtainTX)
|
||||
{
|
||||
if(!msg->Verify(&r->crypto, Endpoint()))
|
||||
{
|
||||
llarp::LogError(Name(), " GXM signature failed");
|
||||
return false;
|
||||
}
|
||||
// we now can send exit traffic
|
||||
_role |= ePathRoleExit;
|
||||
return InformExitResult(0);
|
||||
}
|
||||
llarp::LogError(Name(), " got unwarrented GXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::InformExitResult(llarp_time_t B)
|
||||
{
|
||||
bool result = true;
|
||||
for(const auto& hook : m_ObtainedExitHooks)
|
||||
result &= hook(this, B);
|
||||
m_ObtainedExitHooks.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::HandleTransferTrafficMessage(
|
||||
const llarp::routing::TransferTrafficMessage* msg, llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
// check if we can handle exit data
|
||||
if(!SupportsRoles(ePathRoleExit))
|
||||
return false;
|
||||
// verify sig
|
||||
if(!msg->Verify(&r->crypto, Endpoint()))
|
||||
{
|
||||
llarp::LogError(Name(), " bad signature on inbound traffic");
|
||||
return false;
|
||||
}
|
||||
// handle traffic if we have a handler
|
||||
if(m_ExitTrafficHandler)
|
||||
return m_ExitTrafficHandler(this, llarp::ConstBuffer(msg->X));
|
||||
// fail if no handler
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
Builder::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
RouterContact& cur, size_t hop)
|
||||
RouterContact& cur, size_t hop, PathRole roles)
|
||||
{
|
||||
if(hop == 0 && router->NumberOfConnectedRouters())
|
||||
return router->GetRandomConnectedRouter(cur);
|
||||
|
@ -185,7 +185,10 @@ namespace llarp
|
|||
do
|
||||
{
|
||||
--tries;
|
||||
llarp_nodedb_select_random_hop(db, prev, cur, hop);
|
||||
if(hop == numHops - 1 && roles & ePathRoleExit)
|
||||
llarp_nodedb_select_random_exit(db, cur);
|
||||
else
|
||||
llarp_nodedb_select_random_hop(db, prev, cur, hop);
|
||||
} while(router->routerProfiling.IsBad(cur.pubkey) && tries > 0);
|
||||
return !router->routerProfiling.IsBad(cur.pubkey);
|
||||
}
|
||||
|
@ -204,16 +207,16 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
Builder::BuildOne()
|
||||
Builder::BuildOne(PathRole roles)
|
||||
{
|
||||
std::vector< RouterContact > hops;
|
||||
if(SelectHops(router->nodedb, hops))
|
||||
Build(hops);
|
||||
if(SelectHops(router->nodedb, hops, roles))
|
||||
Build(hops, roles);
|
||||
}
|
||||
|
||||
bool
|
||||
Builder::SelectHops(llarp_nodedb* nodedb,
|
||||
std::vector< RouterContact >& hops)
|
||||
std::vector< RouterContact >& hops, PathRole roles)
|
||||
{
|
||||
hops.resize(numHops);
|
||||
size_t idx = 0;
|
||||
|
@ -221,7 +224,7 @@ namespace llarp
|
|||
{
|
||||
if(idx == 0)
|
||||
{
|
||||
if(!SelectHop(nodedb, hops[0], hops[0], 0))
|
||||
if(!SelectHop(nodedb, hops[0], hops[0], 0, roles))
|
||||
{
|
||||
llarp::LogError("failed to select first hop");
|
||||
return false;
|
||||
|
@ -229,7 +232,7 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!SelectHop(nodedb, hops[idx - 1], hops[idx], idx))
|
||||
if(!SelectHop(nodedb, hops[idx - 1], hops[idx], idx, roles))
|
||||
{
|
||||
/// TODO: handle this failure properly
|
||||
llarp::LogWarn("Failed to select hop ", idx);
|
||||
|
@ -248,14 +251,14 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
Builder::Build(const std::vector< RouterContact >& hops)
|
||||
Builder::Build(const std::vector< RouterContact >& hops, PathRole roles)
|
||||
{
|
||||
lastBuild = Now();
|
||||
// async generate keys
|
||||
AsyncPathKeyExchangeContext< Builder >* ctx =
|
||||
new AsyncPathKeyExchangeContext< Builder >(&router->crypto);
|
||||
ctx->pathset = this;
|
||||
auto path = new llarp::path::Path(hops, this);
|
||||
auto path = new llarp::path::Path(hops, this, roles);
|
||||
path->SetBuildResultHook(std::bind(&llarp::path::Builder::HandlePathBuilt,
|
||||
this, std::placeholders::_1));
|
||||
ctx->AsyncGenerateKeys(path, router->logic, router->tp, this,
|
||||
|
@ -278,11 +281,11 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
Builder::ManualRebuild(size_t num)
|
||||
Builder::ManualRebuild(size_t num, PathRole roles)
|
||||
{
|
||||
llarp::LogDebug("manual rebuild ", num);
|
||||
while(num--)
|
||||
BuildOne();
|
||||
BuildOne(roles);
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
|
|
|
@ -18,6 +18,31 @@ namespace llarp
|
|||
return m_Paths.size() < m_NumPaths;
|
||||
}
|
||||
|
||||
bool
|
||||
PathSet::ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const
|
||||
{
|
||||
const size_t required = MinRequiredForRoles(roles);
|
||||
size_t has = 0;
|
||||
for(const auto& item : m_Paths)
|
||||
{
|
||||
if(item.second->SupportsRoles(roles))
|
||||
{
|
||||
if(!item.second->ExpiresSoon(now))
|
||||
++has;
|
||||
}
|
||||
}
|
||||
return has < required;
|
||||
}
|
||||
|
||||
size_t
|
||||
PathSet::MinRequiredForRoles(PathRole roles) const
|
||||
{
|
||||
size_t require = m_NumPaths > 1 ? m_NumPaths / 2 : m_NumPaths;
|
||||
if(roles & ePathRoleInboundHS || roles & ePathRoleOutboundHS)
|
||||
require += 2;
|
||||
return require;
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::Tick(llarp_time_t now, llarp_router* r)
|
||||
{
|
||||
|
@ -46,7 +71,8 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetEstablishedPathClosestTo(const AlignedBuffer< 32 >& id) const
|
||||
PathSet::GetEstablishedPathClosestTo(const AlignedBuffer< 32 >& id,
|
||||
PathRole roles) const
|
||||
{
|
||||
Path* path = nullptr;
|
||||
AlignedBuffer< 32 > dist;
|
||||
|
@ -55,6 +81,8 @@ namespace llarp
|
|||
{
|
||||
if(!item.second->IsReady())
|
||||
continue;
|
||||
if(!item.second->SupportsRoles(roles))
|
||||
continue;
|
||||
AlignedBuffer< 32 > localDist = item.second->Endpoint() ^ id;
|
||||
if(localDist < dist)
|
||||
{
|
||||
|
@ -66,13 +94,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetNewestPathByRouter(const RouterID& id) const
|
||||
PathSet::GetNewestPathByRouter(const RouterID& id, PathRole roles) const
|
||||
{
|
||||
Path* chosen = nullptr;
|
||||
auto itr = m_Paths.begin();
|
||||
while(itr != m_Paths.end())
|
||||
{
|
||||
if(itr->second->IsReady())
|
||||
if(itr->second->IsReady() && itr->second->SupportsRoles(roles))
|
||||
{
|
||||
if(itr->second->Endpoint() == id)
|
||||
{
|
||||
|
@ -88,13 +116,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetPathByRouter(const RouterID& id) const
|
||||
PathSet::GetPathByRouter(const RouterID& id, PathRole roles) const
|
||||
{
|
||||
Path* chosen = nullptr;
|
||||
auto itr = m_Paths.begin();
|
||||
while(itr != m_Paths.end())
|
||||
{
|
||||
if(itr->second->IsReady())
|
||||
if(itr->second->IsReady() && itr->second->SupportsRoles(roles))
|
||||
{
|
||||
if(itr->second->Endpoint() == id)
|
||||
{
|
||||
|
@ -129,7 +157,7 @@ namespace llarp
|
|||
auto itr = m_Paths.begin();
|
||||
while(itr != m_Paths.end())
|
||||
{
|
||||
if(itr->second->_status == st)
|
||||
if(itr->second->Status() == st)
|
||||
++count;
|
||||
++itr;
|
||||
}
|
||||
|
@ -232,13 +260,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::PickRandomEstablishedPath() const
|
||||
PathSet::PickRandomEstablishedPath(PathRole roles) const
|
||||
{
|
||||
std::vector< Path* > established;
|
||||
auto itr = m_Paths.begin();
|
||||
while(itr != m_Paths.end())
|
||||
{
|
||||
if(itr->second->IsReady())
|
||||
if(itr->second->IsReady() && itr->second->SupportsRoles(roles))
|
||||
established.push_back(itr->second);
|
||||
++itr;
|
||||
}
|
||||
|
|
|
@ -1197,7 +1197,13 @@ namespace llarp
|
|||
{
|
||||
self->defaultIfName = val;
|
||||
}
|
||||
if(!StrEq(key, "profiles"))
|
||||
if(StrEq(key, "profiles"))
|
||||
{
|
||||
self->routerProfilesFile = val;
|
||||
self->routerProfiling.Load(val);
|
||||
llarp::LogInfo("setting profiles to ", self->routerProfilesFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->exitConf.insert(std::make_pair(key, val));
|
||||
}
|
||||
|
@ -1245,23 +1251,6 @@ namespace llarp
|
|||
{
|
||||
self->connect[key] = val;
|
||||
}
|
||||
else if(StrEq(section, "network"))
|
||||
{
|
||||
if(StrEq(key, "profiles"))
|
||||
{
|
||||
self->routerProfilesFile = val;
|
||||
self->routerProfiling.Load(val);
|
||||
llarp::LogInfo("setting profiles to ", self->routerProfilesFile);
|
||||
}
|
||||
if(StrEq(key, "min-connected"))
|
||||
{
|
||||
self->minConnectedRouters = std::max(atoi(val), 0);
|
||||
}
|
||||
if(StrEq(key, "max-connected"))
|
||||
{
|
||||
self->maxConnectedRouters = std::max(atoi(val), 1);
|
||||
}
|
||||
}
|
||||
else if(StrEq(section, "router"))
|
||||
{
|
||||
if(StrEq(key, "nickname"))
|
||||
|
@ -1313,5 +1302,5 @@ namespace llarp
|
|||
self->publicOverride = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
} // namespace llarp
|
||||
|
|
|
@ -88,11 +88,7 @@ namespace llarp
|
|||
AsyncVerifyRouter(llarp::PubKey pk,
|
||||
std::function< void(llarp::PubKey, bool) > handler)
|
||||
{
|
||||
abyss::json::Value params;
|
||||
params.SetObject();
|
||||
QueueRPC("get_service_node", std::move(params),
|
||||
std::bind(&CallerImpl::NewConn, this, pk, handler,
|
||||
std::placeholders::_1));
|
||||
handler(pk, true);
|
||||
}
|
||||
|
||||
~CallerImpl()
|
||||
|
@ -112,6 +108,30 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ListExitLevels(Response& resp) const
|
||||
{
|
||||
llarp::exit::Context::TrafficStats stats;
|
||||
router->exitContext.CalculateExitTraffic(stats);
|
||||
auto& alloc = resp.GetAllocator();
|
||||
abyss::json::Value exits;
|
||||
exits.SetArray();
|
||||
auto itr = stats.begin();
|
||||
while(itr != stats.end())
|
||||
{
|
||||
abyss::json::Value info, ident;
|
||||
info.SetObject();
|
||||
ident.SetString(itr->first.ToHex().c_str(), alloc);
|
||||
info.AddMember("ident", ident, alloc);
|
||||
info.AddMember("tx", abyss::json::Value(itr->second.first), alloc);
|
||||
info.AddMember("rx", abyss::json::Value(itr->second.second), alloc);
|
||||
exits.PushBack(info, alloc);
|
||||
++itr;
|
||||
}
|
||||
resp.AddMember("result", exits, alloc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ListNeighboors(Response& resp) const
|
||||
{
|
||||
|
@ -148,6 +168,10 @@ namespace llarp
|
|||
{
|
||||
return ListNeighboors(response);
|
||||
}
|
||||
else if(method == "llarp.admin.exit.list")
|
||||
{
|
||||
return ListExitLevels(response);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1536,7 +1536,8 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return path::Builder::SelectHop(db, prev, cur, hop);
|
||||
return path::Builder::SelectHop(db, prev, cur, hop,
|
||||
llarp::path::ePathRoleOutboundHS);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
@ -1553,7 +1554,8 @@ namespace llarp
|
|||
{
|
||||
if(markedBad)
|
||||
return false;
|
||||
bool should = path::Builder::ShouldBuildMore(now);
|
||||
bool should = path::Builder::ShouldBuildMoreForRoles(
|
||||
now, llarp::path::ePathRoleOutboundHS);
|
||||
// determinte newest intro
|
||||
Introduction intro;
|
||||
if(!GetNewestIntro(intro))
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace llarp
|
|||
bool
|
||||
TransitHop::Expired(llarp_time_t now) const
|
||||
{
|
||||
return now > ExpireTime();
|
||||
return now >= ExpireTime();
|
||||
}
|
||||
|
||||
llarp_time_t
|
||||
|
@ -159,6 +159,8 @@ namespace llarp
|
|||
llarp::routing::GrantExitMessage grant;
|
||||
grant.S = NextSeqNo();
|
||||
grant.T = msg->T;
|
||||
if(!grant.Sign(&r->crypto, r->identity))
|
||||
return false;
|
||||
return SendRoutingMessage(&grant, r);
|
||||
}
|
||||
// TODO: exponential backoff
|
||||
|
@ -166,6 +168,8 @@ namespace llarp
|
|||
llarp::routing::RejectExitMessage reject;
|
||||
reject.S = NextSeqNo();
|
||||
reject.T = msg->T;
|
||||
if(!reject.Sign(&r->crypto, r->identity))
|
||||
return false;
|
||||
return SendRoutingMessage(&reject, r);
|
||||
}
|
||||
|
||||
|
@ -173,10 +177,18 @@ namespace llarp
|
|||
TransitHop::HandleCloseExitMessage(
|
||||
const llarp::routing::CloseExitMessage* msg, llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
return false;
|
||||
llarp::routing::DataDiscardMessage discard(info.txID, msg->S);
|
||||
auto ep = r->exitContext.FindEndpointForPath(info.txID);
|
||||
if(ep && msg->Verify(&r->crypto, ep->PubKey()))
|
||||
{
|
||||
ep->Close();
|
||||
// ep is now gone af
|
||||
llarp::routing::CloseExitMessage reply;
|
||||
reply.S = NextSeqNo();
|
||||
if(reply.Sign(&r->crypto, r->identity))
|
||||
return SendRoutingMessage(&reply, r);
|
||||
}
|
||||
return SendRoutingMessage(&discard, r);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -196,15 +208,15 @@ namespace llarp
|
|||
auto ep = r->exitContext.FindEndpointForPath(msg->P);
|
||||
if(ep)
|
||||
{
|
||||
if(msg->Verify(&r->crypto, ep->PubKey()))
|
||||
if(!msg->Verify(&r->crypto, ep->PubKey()))
|
||||
return false;
|
||||
|
||||
if(ep->UpdateLocalPath(info.txID))
|
||||
{
|
||||
if(ep->UpdateLocalPath(info.txID))
|
||||
{
|
||||
llarp::routing::UpdateExitVerifyMessage reply;
|
||||
reply.T = msg->T;
|
||||
reply.S = NextSeqNo();
|
||||
return SendRoutingMessage(&reply, r);
|
||||
}
|
||||
llarp::routing::UpdateExitVerifyMessage reply;
|
||||
reply.T = msg->T;
|
||||
reply.S = NextSeqNo();
|
||||
return SendRoutingMessage(&reply, r);
|
||||
}
|
||||
}
|
||||
// on fail tell message was discarded
|
||||
|
@ -216,9 +228,9 @@ namespace llarp
|
|||
TransitHop::HandleRejectExitMessage(
|
||||
const llarp::routing::RejectExitMessage* msg, llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
llarp::LogError(info, " got unwarrented RXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -226,9 +238,9 @@ namespace llarp
|
|||
TransitHop::HandleGrantExitMessage(
|
||||
const llarp::routing::GrantExitMessage* msg, llarp_router* r)
|
||||
{
|
||||
// TODO: implement me
|
||||
(void)msg;
|
||||
(void)r;
|
||||
llarp::LogError(info, " got unwarrented GXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -237,11 +249,14 @@ namespace llarp
|
|||
const llarp::routing::TransferTrafficMessage* msg, llarp_router* r)
|
||||
{
|
||||
auto endpoint = r->exitContext.FindEndpointForPath(info.txID);
|
||||
if(endpoint == nullptr)
|
||||
return false;
|
||||
if(!msg->Verify(&r->crypto, endpoint->PubKey()))
|
||||
return false;
|
||||
return endpoint->SendOutboundTraffic(llarp::ConstBuffer(msg->X));
|
||||
if(endpoint && msg->Verify(&r->crypto, endpoint->PubKey()))
|
||||
{
|
||||
if(endpoint->SendOutboundTraffic(llarp::ConstBuffer(msg->X)))
|
||||
return true;
|
||||
}
|
||||
// discarded
|
||||
llarp::routing::DataDiscardMessage discard(info.txID, msg->S);
|
||||
return SendRoutingMessage(&discard, r);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -249,25 +264,26 @@ namespace llarp
|
|||
const llarp::routing::PathTransferMessage* msg, llarp_router* r)
|
||||
{
|
||||
auto path = r->paths.GetPathForTransfer(msg->P);
|
||||
llarp::routing::DataDiscardMessage discarded(msg->P, msg->S);
|
||||
if(!path)
|
||||
{
|
||||
llarp::routing::DataDiscardMessage discarded(msg->P, msg->S);
|
||||
path = r->paths.GetPathForTransfer(msg->from);
|
||||
return path && path->SendRoutingMessage(&discarded, r);
|
||||
return SendRoutingMessage(&discarded, r);
|
||||
}
|
||||
|
||||
byte_t tmp[service::MAX_PROTOCOL_MESSAGE_SIZE];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(!msg->T.BEncode(&buf))
|
||||
{
|
||||
llarp::LogWarn("failed to transfer data message, encode failed");
|
||||
return false;
|
||||
llarp::LogWarn(info, " failed to transfer data message, encode failed");
|
||||
return SendRoutingMessage(&discarded, r);
|
||||
}
|
||||
// rewind0
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// send
|
||||
return path->HandleDownstream(buf, msg->Y, r);
|
||||
if(path->HandleDownstream(buf, msg->Y, r))
|
||||
return true;
|
||||
return SendRoutingMessage(&discarded, r);
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
|
|
Loading…
Reference in New Issue