1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

expire introsets correctly and allow multiple tun if

This commit is contained in:
Jeff Becker 2018-09-10 12:36:36 -04:00
parent b96887ddb2
commit c3a7f64344
No known key found for this signature in database
GPG key ID: F357B3B42F6F9B05
9 changed files with 229 additions and 187 deletions

View file

@ -28,6 +28,20 @@ namespace llarp
expiresAt = other.expiresAt;
}
bool
IsExpired(llarp_time_t now) const
{
return now <= expiresAt;
}
bool
ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 5000) const
{
if(dlt)
return now <= (expiresAt - (llarp_randint() % dlt));
return IsExpired(now);
}
~Introduction();
friend std::ostream&
@ -55,4 +69,4 @@ namespace llarp
} // namespace service
} // namespace llarp
#endif
#endif

View file

@ -102,20 +102,18 @@ namespace llarp
}
bool
IsNewerThan(const IntroSet& other) const
OtherIsNewerThan(const IntroSet& other) const
{
return GetNewestIntro().expiresAt > other.GetNewestIntro().expiresAt;
return GetNewestIntroExpiration() < other.GetNewestIntroExpiration();
}
Introduction
GetNewestIntro() const
llarp_time_t
GetNewestIntroExpiration() const
{
Introduction i;
i.expiresAt = 0;
llarp_time_t t = 0;
for(const auto& intro : I)
if(intro.expiresAt > i.expiresAt)
i = intro;
return i;
t = std::max(intro.expiresAt, t);
return t;
}
bool

View file

@ -188,7 +188,7 @@ namespace llarp
private:
bool
OnIntroSetUpdate(const IntroSet* i);
OnIntroSetUpdate(const Address& addr, const IntroSet* i);
void
EncryptAndSendTo(path::Path* p, llarp_buffer_t payload, ProtocolType t);
@ -275,7 +275,7 @@ namespace llarp
private:
bool
OnOutboundLookup(const IntroSet* i); /* */
OnOutboundLookup(const Address&, const IntroSet* i); /* */
static bool
SetupIsolatedNetwork(void* user, bool success);

View file

@ -123,7 +123,7 @@ namespace llarp
{
if(itr->second.introset.IsExpired(now))
{
llarp::LogInfo("introset expired ", itr->second.introset.A.Addr());
llarp::LogDebug("introset expired ", itr->second.introset.A.Addr());
itr = nodes.erase(itr);
}
else

View file

@ -238,7 +238,7 @@ namespace llarp
if(itr != m_AddrToIP.end())
{
// mark ip active
m_IPActivity[itr->second] = now;
m_IPActivity[itr->second] = std::max(now, m_IPActivity[itr->second]);
return itr->second;
}
}
@ -276,7 +276,7 @@ namespace llarp
}
// mark ip active
m_IPActivity[nextIP] = now;
m_IPActivity[nextIP] = std::max(m_IPActivity[nextIP], now);
return nextIP;
}
@ -290,7 +290,7 @@ namespace llarp
void
TunEndpoint::MarkIPActive(uint32_t ip)
{
m_IPActivity[ip] = llarp_time_now_ms();
m_IPActivity[ip] = std::max(llarp_time_now_ms(), m_IPActivity[ip]);
}
void

View file

@ -119,6 +119,7 @@ namespace llarp
{
return path->HandleDownstream(X.Buffer(), Y, r);
}
llarp::LogWarn("unhandled downstream message");
return false;
}
} // namespace llarp

View file

@ -105,7 +105,7 @@ namespace llarp
auto highest = now;
for(const auto& i : I)
highest = std::max(i.expiresAt, highest);
return highest == now;
return highest >= now;
}
Introduction::~Introduction()

View file

@ -477,8 +477,7 @@ namespace llarp
Endpoint::ShouldPublishDescriptors(llarp_time_t now) const
{
if(m_IntroSet.HasExpiredIntros(now))
return m_CurrentPublishTX == 0
&& now - m_LastPublishAttempt >= INTROSET_PUBLISH_RETRY_INTERVAL;
return now - m_LastPublishAttempt >= INTROSET_PUBLISH_RETRY_INTERVAL;
return m_CurrentPublishTX == 0
&& now - m_LastPublish >= INTROSET_PUBLISH_INTERVAL;
}
@ -498,7 +497,8 @@ namespace llarp
}
Address remote;
typedef std::function< bool(const IntroSet*) > HandlerFunc;
typedef std::function< bool(const Address&, const IntroSet*) >
HandlerFunc;
HandlerFunc handle;
HiddenServiceAddressLookup(Endpoint* p, HandlerFunc h,
@ -511,19 +511,11 @@ namespace llarp
HandleResponse(const std::set< IntroSet >& results)
{
llarp::LogInfo("found ", results.size(), " for ", remote.ToString());
if(results.size() == 1)
if(results.size() > 0)
{
llarp::LogInfo("hidden service lookup for ", remote.ToString(),
" success");
handle(&*results.begin());
return handle(remote, &*results.begin());
}
else
{
llarp::LogInfo("no response in hidden service lookup for ",
remote.ToString());
handle(nullptr);
}
return false;
return handle(remote, nullptr);
}
llarp::routing::IMessage*
@ -661,10 +653,17 @@ namespace llarp
}
bool
Endpoint::OnOutboundLookup(const IntroSet* introset)
Endpoint::OnOutboundLookup(const Address& addr, const IntroSet* introset)
{
if(!introset)
{
auto itr = m_PendingServiceLookups.find(addr);
if(itr != m_PendingServiceLookups.end())
{
itr->second(addr, nullptr);
}
return false;
}
PutNewOutboundContext(*introset);
return true;
}
@ -701,7 +700,8 @@ namespace llarp
HiddenServiceAddressLookup* job = new HiddenServiceAddressLookup(
this,
std::bind(&Endpoint::OnOutboundLookup, this, std::placeholders::_1),
std::bind(&Endpoint::OnOutboundLookup, this, std::placeholders::_1,
std::placeholders::_2),
remote, GenTXID());
if(job->SendRequestViaPath(path, Router()))
@ -726,9 +726,10 @@ namespace llarp
}
bool
Endpoint::OutboundContext::OnIntroSetUpdate(const IntroSet* i)
Endpoint::OutboundContext::OnIntroSetUpdate(const Address& addr,
const IntroSet* i)
{
if(i && i->IsNewerThan(currentIntroSet))
if(i && addr == i->A.Addr() && currentIntroSet.OtherIsNewerThan(*i))
{
currentIntroSet = *i;
}
@ -784,7 +785,7 @@ namespace llarp
selectedIntro = intro;
}
}
ManualRebuild(2);
ManualRebuild(1);
}
void
@ -911,7 +912,7 @@ namespace llarp
{
UpdateIntroSet();
}
if(selectedIntro.expiresAt <= now || now - selectedIntro.expiresAt > 1000)
if(selectedIntro.ExpiresSoon(now, 10000))
{
ShiftIntroduction();
}
@ -921,7 +922,7 @@ namespace llarp
if(path)
{
routing::PathTransferMessage transfer(msg, selectedIntro.pathID);
llarp::LogInfo("sending frame via ", path->Upstream(), " to ",
llarp::LogInfo("sending frame via ", selectedIntro.pathID, " to ",
path->Endpoint(), " for ", Name());
if(!path->SendRoutingMessage(&transfer, m_Parent->Router()))
llarp::LogError("Failed to send frame on path");
@ -943,13 +944,13 @@ namespace llarp
Endpoint::OutboundContext::UpdateIntroSet()
{
auto addr = currentIntroSet.A.Addr();
auto path = m_Parent->GetEstablishedPathClosestTo(addr.ToRouter());
auto path = m_Parent->PickRandomEstablishedPath();
if(path)
{
HiddenServiceAddressLookup* job = new HiddenServiceAddressLookup(
m_Parent,
std::bind(&Endpoint::OutboundContext::OnIntroSetUpdate, this,
std::placeholders::_1),
std::placeholders::_1, std::placeholders::_2),
addr, m_Parent->GenTXID());
if(!job->SendRequestViaPath(path, m_Parent->Router()))

View file

@ -35,187 +35,215 @@
#include "tuntap.h"
int
tuntap_sys_start(struct device *dev, int mode, int tun) {
int fd;
int persist;
char *ifname;
struct ifreq ifr;
tuntap_sys_start(struct device *dev, int mode, int tun)
{
int fd;
int persist;
char *ifname;
struct ifreq ifr;
/* Get the persistence bit */
if (mode & TUNTAP_MODE_PERSIST) {
mode &= ~TUNTAP_MODE_PERSIST;
persist = 1;
} else {
persist = 0;
}
/* Get the persistence bit */
if(mode & TUNTAP_MODE_PERSIST)
{
mode &= ~TUNTAP_MODE_PERSIST;
persist = 1;
}
else
{
persist = 0;
}
/* Set the mode: tun or tap */
(void)memset(&ifr, '\0', sizeof ifr);
if (mode == TUNTAP_MODE_ETHERNET) {
ifr.ifr_flags = IFF_TAP;
ifname = "tap%i";
} else if (mode == TUNTAP_MODE_TUNNEL) {
ifr.ifr_flags = IFF_TUN;
ifname = "tun%i";
} else {
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'");
return -1;
}
ifr.ifr_flags |= IFF_NO_PI;
/* Set the mode: tun or tap */
(void)memset(&ifr, '\0', sizeof ifr);
if(mode == TUNTAP_MODE_ETHERNET)
{
ifr.ifr_flags = IFF_TAP;
ifname = "tap%i";
}
else if(mode == TUNTAP_MODE_TUNNEL)
{
ifr.ifr_flags = IFF_TUN;
if(dev->if_name[0])
strncpy(ifr.ifr_name, dev->if_name, sizeof(ifr.ifr_name));
else
ifname = "tun%i";
}
else
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'mode'");
return -1;
}
ifr.ifr_flags |= IFF_NO_PI;
if (tun < 0) {
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'tun'");
return -1;
if(tun < 0)
{
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'tun'");
return -1;
}
/* Open the clonable interface */
fd = -1;
if((fd = open("/dev/net/tun", O_RDWR)) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't open /dev/net/tun");
return -1;
}
/* Set the interface name, if any */
if(fd > TUNTAP_ID_MAX)
{
return -1;
}
if(ifr.ifr_name[0] == 0 && tun)
(void)snprintf(ifr.ifr_name, sizeof ifr.ifr_name, ifname, tun);
/* Save interface name *after* SIOCGIFFLAGS */
/* Configure the interface */
if(ioctl(fd, TUNSETIFF, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;
}
/* Set it persistent if needed */
if(persist == 1)
{
if(ioctl(fd, TUNSETPERSIST, 1) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set persistent");
return -1;
}
}
/* Open the clonable interface */
fd = -1;
if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't open /dev/net/tun");
return -1;
}
/* Get the interface default values */
if(ioctl(dev->ctrl_sock, SIOCGIFFLAGS, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't get interface values");
return -1;
}
/* Set the interface name, if any */
if (tun != TUNTAP_ID_ANY) {
if (fd > TUNTAP_ID_MAX) {
return -1;
}
(void)snprintf(ifr.ifr_name, sizeof ifr.ifr_name,
ifname, tun);
/* Save interface name *after* SIOCGIFFLAGS */
}
/* Save flags for tuntap_{up, down} */
dev->flags = ifr.ifr_flags;
/* Configure the interface */
if (ioctl(fd, TUNSETIFF, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;
}
/* Save interface name */
(void)memcpy(dev->if_name, ifr.ifr_name, sizeof ifr.ifr_name);
/* Set it persistent if needed */
if (persist == 1) {
if (ioctl(fd, TUNSETPERSIST, 1) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set persistent");
return -1;
}
}
/* Save pre-existing MAC address */
if(mode == TUNTAP_MODE_ETHERNET)
{
struct ifreq ifr_hw;
/* Get the interface default values */
if (ioctl(dev->ctrl_sock, SIOCGIFFLAGS, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't get interface values");
return -1;
}
/* Save flags for tuntap_{up, down} */
dev->flags = ifr.ifr_flags;
/* Save interface name */
(void)memcpy(dev->if_name, ifr.ifr_name, sizeof ifr.ifr_name);
/* Save pre-existing MAC address */
if (mode == TUNTAP_MODE_ETHERNET) {
struct ifreq ifr_hw;
(void)memcpy(ifr_hw.ifr_name, dev->if_name,
sizeof(dev->if_name));
if (ioctl(fd, SIOCGIFHWADDR, &ifr_hw) == -1) {
tuntap_log(TUNTAP_LOG_WARN,
"Can't get link-layer address");
return fd;
}
(void)memcpy(dev->hwaddr, ifr_hw.ifr_hwaddr.sa_data, ETH_ALEN);
}
return fd;
(void)memcpy(ifr_hw.ifr_name, dev->if_name, sizeof(dev->if_name));
if(ioctl(fd, SIOCGIFHWADDR, &ifr_hw) == -1)
{
tuntap_log(TUNTAP_LOG_WARN, "Can't get link-layer address");
return fd;
}
(void)memcpy(dev->hwaddr, ifr_hw.ifr_hwaddr.sa_data, ETH_ALEN);
}
return fd;
}
void
tuntap_sys_destroy(struct device *dev) {
if (ioctl(dev->tun_fd, TUNSETPERSIST, 0) == -1) {
tuntap_log(TUNTAP_LOG_WARN, "Can't destroy the interface");
}
tuntap_sys_destroy(struct device *dev)
{
if(ioctl(dev->tun_fd, TUNSETPERSIST, 0) == -1)
{
tuntap_log(TUNTAP_LOG_WARN, "Can't destroy the interface");
}
}
int
tuntap_sys_set_hwaddr(struct device *dev, struct ether_addr *eth_addr) {
struct ifreq ifr;
tuntap_sys_set_hwaddr(struct device *dev, struct ether_addr *eth_addr)
{
struct ifreq ifr;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
(void)memcpy(ifr.ifr_hwaddr.sa_data, eth_addr->ether_addr_octet, 6);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
(void)memcpy(ifr.ifr_hwaddr.sa_data, eth_addr->ether_addr_octet, 6);
/* Linux has a special flag for setting the MAC address */
if (ioctl(dev->ctrl_sock, SIOCSIFHWADDR, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set link-layer address");
return -1;
}
return 0;
/* Linux has a special flag for setting the MAC address */
if(ioctl(dev->ctrl_sock, SIOCSIFHWADDR, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set link-layer address");
return -1;
}
return 0;
}
int
tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s4, uint32_t bits) {
struct ifreq ifr;
struct sockaddr_in mask;
tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s4, uint32_t bits)
{
struct ifreq ifr;
struct sockaddr_in mask;
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
(void)memset(&ifr, '\0', sizeof ifr);
(void)memcpy(ifr.ifr_name, dev->if_name, sizeof dev->if_name);
/* Set the IP address first */
(void)memcpy(&(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),
s4, sizeof(struct in_addr));
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(dev->ctrl_sock, SIOCSIFADDR, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set IP address");
return -1;
}
/* Reinit the struct ifr */
(void)memset(&ifr.ifr_addr, '\0', sizeof ifr.ifr_addr);
/* Set the IP address first */
(void)memcpy(&(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr), s4,
sizeof(struct in_addr));
ifr.ifr_addr.sa_family = AF_INET;
if(ioctl(dev->ctrl_sock, SIOCSIFADDR, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set IP address");
return -1;
}
/* Then set the netmask */
(void)memset(&mask, '\0', sizeof mask);
mask.sin_family = AF_INET;
mask.sin_addr.s_addr = bits;
(void)memcpy(&ifr.ifr_netmask, &mask, sizeof ifr.ifr_netmask);
if (ioctl(dev->ctrl_sock, SIOCSIFNETMASK, &ifr) == -1) {
tuntap_log(TUNTAP_LOG_ERR, "Can't set netmask");
return -1;
}
/* Reinit the struct ifr */
(void)memset(&ifr.ifr_addr, '\0', sizeof ifr.ifr_addr);
return 0;
/* Then set the netmask */
(void)memset(&mask, '\0', sizeof mask);
mask.sin_family = AF_INET;
mask.sin_addr.s_addr = bits;
(void)memcpy(&ifr.ifr_netmask, &mask, sizeof ifr.ifr_netmask);
if(ioctl(dev->ctrl_sock, SIOCSIFNETMASK, &ifr) == -1)
{
tuntap_log(TUNTAP_LOG_ERR, "Can't set netmask");
return -1;
}
return 0;
}
int
tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s6, uint32_t bits) {
(void)dev;
(void)s6;
(void)bits;
tuntap_log(TUNTAP_LOG_NOTICE, "IPv6 is not implemented on your system");
return -1;
tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s6, uint32_t bits)
{
(void)dev;
(void)s6;
(void)bits;
tuntap_log(TUNTAP_LOG_NOTICE, "IPv6 is not implemented on your system");
return -1;
}
int
tuntap_sys_set_ifname(struct device *dev, const char *ifname, size_t len) {
struct ifreq ifr;
tuntap_sys_set_ifname(struct device *dev, const char *ifname, size_t len)
{
struct ifreq ifr;
(void)strncpy(ifr.ifr_name, dev->if_name, IF_NAMESIZE);
(void)strncpy(ifr.ifr_newname, ifname, len);
(void)strncpy(ifr.ifr_name, dev->if_name, IF_NAMESIZE);
(void)strncpy(ifr.ifr_newname, ifname, len);
if (ioctl(dev->ctrl_sock, SIOCSIFNAME, &ifr) == -1) {
perror(NULL);
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;
}
return 0;
if(ioctl(dev->ctrl_sock, SIOCSIFNAME, &ifr) == -1)
{
perror(NULL);
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;
}
return 0;
}
int
tuntap_sys_set_descr(struct device *dev, const char *descr, size_t len) {
(void)dev;
(void)descr;
(void)len;
tuntap_log(TUNTAP_LOG_NOTICE,
"Your system does not support tuntap_set_descr()");
return -1;
tuntap_sys_set_descr(struct device *dev, const char *descr, size_t len)
{
(void)dev;
(void)descr;
(void)len;
tuntap_log(TUNTAP_LOG_NOTICE,
"Your system does not support tuntap_set_descr()");
return -1;
}