Don't add endpoint route if route is not in included_routes

This commit is contained in:
Ludvig Strigeus 2018-11-16 15:01:44 +01:00
parent 2a73a27e68
commit 3ae15bcff5
4 changed files with 24 additions and 20 deletions

View file

@ -1237,22 +1237,6 @@ bool TunWin32Adapter::OpenAdapter(TunsafeBackendWin32 *backend, DWORD open_flags
return (handle_ != NULL); return (handle_ != NULL);
} }
static inline bool CheckFirstNbitsEquals(const byte *a, const byte *b, size_t n) {
return memcmp(a, b, n >> 3) == 0 && ((n & 7) == 0 || !((a[n >> 3] ^ b[n >> 3]) & (0xff << (8 - (n & 7)))));
}
static bool IsWgCidrAddrSubsetOf(const WgCidrAddr &inner, const WgCidrAddr &outer) {
return inner.size == outer.size && inner.cidr >= outer.cidr &&
CheckFirstNbitsEquals(inner.addr, outer.addr, outer.cidr);
}
static bool IsWgCidrAddrSubsetOfAny(const WgCidrAddr &inner, const std::vector<WgCidrAddr> &addr) {
for (auto &a : addr)
if (IsWgCidrAddrSubsetOf(inner, a))
return true;
return false;
}
bool TunWin32Adapter::ConfigureAdapter(const TunInterface::TunConfig &&config, TunInterface::TunConfigOut *out) { bool TunWin32Adapter::ConfigureAdapter(const TunInterface::TunConfig &&config, TunInterface::TunConfigOut *out) {
DWORD len, err; DWORD len, err;

View file

@ -82,6 +82,22 @@ bool ParseCidrAddr(const char *s, WgCidrAddr *out) {
return false; return false;
} }
static inline bool CheckFirstNbitsEquals(const byte *a, const byte *b, size_t n) {
return memcmp(a, b, n >> 3) == 0 && ((n & 7) == 0 || !((a[n >> 3] ^ b[n >> 3]) & (0xff << (8 - (n & 7)))));
}
static bool IsWgCidrAddrSubsetOf(const WgCidrAddr &inner, const WgCidrAddr &outer) {
return inner.size == outer.size && inner.cidr >= outer.cidr &&
CheckFirstNbitsEquals(inner.addr, outer.addr, outer.cidr);
}
bool IsWgCidrAddrSubsetOfAny(const WgCidrAddr &inner, const std::vector<WgCidrAddr> &addr) {
for (auto &a : addr)
if (IsWgCidrAddrSubsetOf(inner, a))
return true;
return false;
}
static Mutex g_dns_mutex; static Mutex g_dns_mutex;
// This starts a background thread for running DNS resolving. // This starts a background thread for running DNS resolving.

View file

@ -2,7 +2,7 @@
#define TUNSAFE_IPADDR_H_ #define TUNSAFE_IPADDR_H_
#include "tunsafe_types.h" #include "tunsafe_types.h"
#include <vector>
#if !defined(OS_WIN) #if !defined(OS_WIN)
#include <sys/types.h> #include <sys/types.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -27,9 +27,10 @@ class DnsResolver;
const char *print_ip_prefix(char buf[kSizeOfAddress], int family, const void *ip, int prefixlen); const char *print_ip_prefix(char buf[kSizeOfAddress], int family, const void *ip, int prefixlen);
char *PrintIpAddr(const IpAddr &addr, char buf[kSizeOfAddress]); char *PrintIpAddr(const IpAddr &addr, char buf[kSizeOfAddress]);
char *PrintWgCidrAddr(const WgCidrAddr &addr, char buf[kSizeOfAddress]); char *PrintWgCidrAddr(const WgCidrAddr &addr, char buf[kSizeOfAddress]);
bool ParseCidrAddr(const char *s, WgCidrAddr *out); bool ParseCidrAddr(const char *s, WgCidrAddr *out);
bool IsWgCidrAddrSubsetOfAny(const WgCidrAddr &inner, const std::vector<WgCidrAddr> &addr);
enum { enum {
kParseSockaddrDontDoNAT64 = 1, kParseSockaddrDontDoNAT64 = 1,
}; };

View file

@ -190,9 +190,12 @@ bool WireguardProcessor::ConfigureTun() {
if (it->cidr == 0) if (it->cidr == 0)
peer->allow_endpoint_change_ = false; peer->allow_endpoint_change_ = false;
} }
// Add the peer's endpoint to the route exclusion list. }
for (WgPeer *peer = dev_.first_peer(); peer; peer = peer->next_peer_) {
// Add the peer's endpoint to the route exclusion list, but only
// if the endpoint is covered by one of the included_routes.
WgCidrAddr endpoint_addr = WgCidrAddrFromIpAddr(peer->endpoint_); WgCidrAddr endpoint_addr = WgCidrAddrFromIpAddr(peer->endpoint_);
if (endpoint_addr.size != 0) if (endpoint_addr.size != 0 && IsWgCidrAddrSubsetOfAny(endpoint_addr, config.included_routes))
config.excluded_routes.push_back(endpoint_addr); config.excluded_routes.push_back(endpoint_addr);
} }
} }