expire introsets correctly and allow multiple tun if

pull/15/head
Jeff Becker 6 years ago
parent b96887ddb2
commit c3a7f64344
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -28,6 +28,20 @@ namespace llarp
expiresAt = other.expiresAt; 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(); ~Introduction();
friend std::ostream& friend std::ostream&
@ -55,4 +69,4 @@ namespace llarp
} // namespace service } // namespace service
} // namespace llarp } // namespace llarp
#endif #endif

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

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

@ -123,7 +123,7 @@ namespace llarp
{ {
if(itr->second.introset.IsExpired(now)) 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); itr = nodes.erase(itr);
} }
else else

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

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

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

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

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

Loading…
Cancel
Save