diff --git a/ext/installfiles/linux/zerotier-containerized/Dockerfile b/ext/installfiles/linux/zerotier-containerized/Dockerfile index f0386c800..b6d122a0e 100644 --- a/ext/installfiles/linux/zerotier-containerized/Dockerfile +++ b/ext/installfiles/linux/zerotier-containerized/Dockerfile @@ -5,7 +5,7 @@ FROM debian:buster-slim as builder ## Supports x86_64, x86, arm, and arm64 RUN apt-get update && apt-get install -y curl gnupg -RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 0x1657198823e52a61 && \ +RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 0x1657198823e52a61 && \ echo "deb http://download.zerotier.com/debian/buster buster main" > /etc/apt/sources.list.d/zerotier.list RUN apt-get update && apt-get install -y zerotier-one=1.8.4 COPY ext/installfiles/linux/zerotier-containerized/main.sh /var/lib/zerotier-one/main.sh diff --git a/ext/libnatpmp/getgateway.c b/ext/libnatpmp/getgateway.c index f743a0894..0f06e1dc2 100644 --- a/ext/libnatpmp/getgateway.c +++ b/ext/libnatpmp/getgateway.c @@ -271,7 +271,9 @@ int getdefaultgateway(in_addr_t *addr) rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; + so_dst.sa_len = sizeof(struct sockaddr); so_mask.sa_family = AF_INET; + so_mask.sa_len = sizeof(struct sockaddr); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); diff --git a/make-bsd.mk b/make-bsd.mk index 06c188090..637f80d68 100644 --- a/make-bsd.mk +++ b/make-bsd.mk @@ -7,6 +7,29 @@ LIBS= include objects.mk ONE_OBJS+=osdep/BSDEthernetTap.o ext/http-parser/http_parser.o +ifeq ($(OSTYPE),FreeBSD) + # Auto-detect miniupnpc and nat-pmp as well and use ports libs if present, + # otherwise build into binary as done on Mac and Windows. + INCLUDES+=-I/usr/local/include + LIBS+=-L/usr/local/lib + ONE_OBJS+=osdep/PortMapper.o + override DEFS+=-DZT_USE_MINIUPNPC + MINIUPNPC_IS_NEW_ENOUGH=$(shell grep -sqr '.*define.*MINIUPNPC_VERSION.*"2..*"' /usr/local/include/miniupnpc/miniupnpc.h && echo 1) + ifeq ($(MINIUPNPC_IS_NEW_ENOUGH),1) + LIBS+=-lminiupnpc + override DEFS+=-DZT_USE_SYSTEM_MINIUPNPC + else + override DEFS+=-DMINIUPNP_STATICLIB -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -D_BSD_SOURCE -D_DEFAULT_SOURCE -DOS_STRING=\"FreeBSD/$(shell uname -r)\" -DMINIUPNPC_VERSION_STRING=\"2.0\" -DUPNP_VERSION_STRING=\"UPnP/1.1\" -DENABLE_STRNATPMPERR + ONE_OBJS+=ext/miniupnpc/connecthostport.o ext/miniupnpc/igd_desc_parse.o ext/miniupnpc/minisoap.o ext/miniupnpc/minissdpc.o ext/miniupnpc/miniupnpc.o ext/miniupnpc/miniwget.o ext/miniupnpc/minixml.o ext/miniupnpc/portlistingparse.o ext/miniupnpc/receivedata.o ext/miniupnpc/upnpcommands.o ext/miniupnpc/upnpdev.o ext/miniupnpc/upnperrors.o ext/miniupnpc/upnpreplyparse.o + endif + ifeq ($(wildcard /usr/local/include/natpmp.h),) + ONE_OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o + else + LIBS+=-lnatpmp + override DEFS+=-DZT_USE_SYSTEM_NATPMP + endif +endif + # Build with address sanitization library for advanced debugging (clang) ifeq ($(ZT_SANITIZE),1) SANFLAGS+=-fsanitize=address -DASAN_OPTIONS=symbolize=1 diff --git a/make-mac.mk b/make-mac.mk index 4655c8618..ca1fed6aa 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -75,7 +75,6 @@ ifeq ($(ZT_DEBUG),1) ARCH_FLAGS= CFLAGS+=-Wall -g $(INCLUDES) $(DEFS) $(ARCH_FLAGS) STRIP=echo - RUSTFLAGS= RUST_VARIANT=debug # The following line enables optimization for the crypto code, since # C25519 in particular is almost UNUSABLE in heavy testing without it. @@ -84,7 +83,6 @@ else CFLAGS?=-Ofast -fstack-protector-strong CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=$(MACOS_VERSION_MIN) -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) STRIP=strip - RUSTFLAGS=--release RUST_VARIANT=release endif @@ -121,8 +119,8 @@ zerotier-one: one zeroidc: zeroidc/target/libzeroidc.a zeroidc/target/libzeroidc.a: FORCE - cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=x86_64-apple-darwin $(RUSTFLAGS) - cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=aarch64-apple-darwin $(RUSTFLAGS) + cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=x86_64-apple-darwin --$(RUST_VARIANT) + cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=aarch64-apple-darwin --$(RUST_VARIANT) cd zeroidc && lipo -create target/x86_64-apple-darwin/$(RUST_VARIANT)/libzeroidc.a target/aarch64-apple-darwin/$(RUST_VARIANT)/libzeroidc.a -output target/libzeroidc.a central-controller: diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 5fc38be02..e4e184241 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -1058,9 +1058,11 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c { const SharedPtr network(RR->node->network(at(ZT_PACKET_IDX_PAYLOAD))); if (network) { + fprintf(stderr, "IncomingPacket::_doNETWORK_CONFIG %.16llx\n", network->id()); const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD); if (configUpdateId) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + fprintf(stderr, "Have config update ID: %llu\n", configUpdateId); + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((uint8_t)Packet::VERB_ECHO); outp.append((uint64_t)packetId()); outp.append((uint64_t)network->id()); @@ -1068,7 +1070,9 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c const int64_t now = RR->node->now(); outp.armor(peer->key(),true,peer->aesKeysIfSupported()); peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + if (!_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now())) { + fprintf(stderr, "Error sending VERB_OK after NETWORK_CONFIG packet for %.16llx\n", network->id()); + } } } diff --git a/node/Network.cpp b/node/Network.cpp index c77f94a6d..8a6d40686 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -984,7 +984,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add } if (nc) { - this->setConfiguration(tPtr,*nc,true); + fprintf(stderr, "Network::handleConfigChucnk->setConfiguration %.16llx\n", this->_id); + this->setConfiguration(tPtr, *nc, true); delete nc; return configUpdateId; } else { diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index 421da1f63..6f07963eb 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -25,6 +25,7 @@ #ifndef IFNAMSIZ #define IFNAMSIZ 16 #endif +const int ZT_RTE_METRIC = 5000; namespace ZeroTier { @@ -731,6 +732,23 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c rtl += rtap->rta_len; if(via) { + /* + * Setting a metric keeps zerotier routes from taking priority over physical + * At best the computer would use zerotier through the router instead of the LAN. + * At worst it stops working at all. + * + * default via 192.168.82.1 dev eth0 proto dhcp src 192.168.82.169 metric 202 + * 10.147.17.0/24 dev zt5u4uptmb proto kernel scope link src 10.147.17.94 + * 192.168.82.0/24 dev eth0 proto dhcp scope link src 192.168.82.169 metric 202 + * 192.168.82.0/24 via 10.147.17.1 dev zt5u4uptmb proto static metric 5000 + * + */ + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); + rtap->rta_type = RTA_PRIORITY; + rtap->rta_len = RTA_LENGTH(sizeof(ZT_RTE_METRIC)); + memcpy(RTA_DATA(rtap), &ZT_RTE_METRIC, sizeof(ZT_RTE_METRIC)); + rtl += rtap->rta_len; + rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); rtap->rta_type = RTA_GATEWAY; if(via.isV4()) { diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 746808112..325f4c803 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -526,14 +526,13 @@ bool ManagedRoute::sync() #ifdef __LINUX__ // ---------------------------------------------------------- - const char *const devptr = (_via) ? (const char *)0 : _device; - if ((leftt)&&(!LinuxNetLink::getInstance().routeIsSet(leftt,_via,_src,devptr))) { + if ((leftt)&&(!LinuxNetLink::getInstance().routeIsSet(leftt,_via,_src,_device))) { _applied[leftt] = false; // boolean unused - LinuxNetLink::getInstance().addRoute(leftt, _via, _src, devptr); + LinuxNetLink::getInstance().addRoute(leftt, _via, _src, _device); } - if ((rightt)&&(!LinuxNetLink::getInstance().routeIsSet(rightt,_via,_src,devptr))) { + if ((rightt)&&(!LinuxNetLink::getInstance().routeIsSet(rightt,_via,_src,_device))) { _applied[rightt] = false; // boolean unused - LinuxNetLink::getInstance().addRoute(rightt, _via, _src, devptr); + LinuxNetLink::getInstance().addRoute(rightt, _via, _src, _device); } #endif // __LINUX__ ---------------------------------------------------------- diff --git a/service/OneService.cpp b/service/OneService.cpp index 6c4be6b54..191103209 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -285,6 +285,11 @@ public: const char* url = zeroidc::zeroidc_get_auth_url(_idc); memcpy(_config.authenticationURL, url, strlen(url)); _config.authenticationURL[strlen(url)] = 0; + + if (zeroidc::zeroidc_is_running(_idc) && nwc->status == ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED) { + // TODO: kick the refresh thread + zeroidc::zeroidc_kick_refresh_thread(_idc); + } } } diff --git a/zeroidc/src/ext.rs b/zeroidc/src/ext.rs index 9bf0181bc..361e7ab6e 100644 --- a/zeroidc/src/ext.rs +++ b/zeroidc/src/ext.rs @@ -218,3 +218,16 @@ pub extern "C" fn zeroidc_network_id_from_state(state: *const c_char) -> *const let s = CString::new(split[1]).unwrap(); return s.into_raw(); } + +#[no_mangle] +pub extern "C" fn zeroidc_kick_refresh_thread(idc: *mut ZeroIDC) { + if idc.is_null() { + println!("idc is null"); + return; + } + let idc = unsafe { + &mut *idc + }; + + idc.kick_refresh_thread(); +} \ No newline at end of file diff --git a/zeroidc/src/lib.rs b/zeroidc/src/lib.rs index 0bca86890..579dad7d9 100644 --- a/zeroidc/src/lib.rs +++ b/zeroidc/src/lib.rs @@ -48,6 +48,7 @@ struct Inner { access_token: Option, refresh_token: Option, exp_time: u64, + kick: bool, url: Option, csrf_token: Option, @@ -109,6 +110,7 @@ impl ZeroIDC { access_token: None, refresh_token: None, exp_time: 0, + kick: false, url: None, csrf_token: None, @@ -138,6 +140,11 @@ impl ZeroIDC { Ok(idc) } + fn kick_refresh_thread(&mut self) { + let local = Arc::clone(&self.inner); + (*local.lock().unwrap()).kick = true; + } + fn start(&mut self) { let local = Arc::clone(&self.inner); @@ -160,7 +167,15 @@ impl ZeroIDC { } let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone(); if let Some(refresh_token) = refresh_token { - if now >= (exp - Duration::from_secs(30)) { + let should_kick = (*inner_local.lock().unwrap()).kick; + if now >= (exp - Duration::from_secs(30)) || should_kick { + if should_kick { + #[cfg(debug_assertions)] { + println!("refresh thread kicked"); + } + (*inner_local.lock().unwrap()).kick = false; + } + let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| { let res = c.exchange_refresh_token(&refresh_token) .request(http_client); @@ -356,6 +371,11 @@ impl ZeroIDC { pub fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) { let local = Arc::clone(&self.inner); (*local.lock().expect("can't lock inner")).as_opt().map(|i| { + if i.running { + println!("refresh thread running. not setting new nonce or csrf"); + return + } + let need_verifier = match i.pkce_verifier { None => true, _ => false,