mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
temp workaround for oidc auth dropping issue
Add a method to "kick" the refresh thread and re-post the tokens in the case where the thread is somehow still running & controller pushes out an AUTH_REQUIRED. This situation happens in a corner case still under investigation where the controller pushes out many copies of the network config repeatedly
This commit is contained in:
parent
cdd25c389e
commit
d719137565
5 changed files with 47 additions and 4 deletions
|
@ -1058,9 +1058,11 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c
|
||||||
{
|
{
|
||||||
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
|
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
|
||||||
if (network) {
|
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);
|
const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD);
|
||||||
if (configUpdateId) {
|
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((uint8_t)Packet::VERB_ECHO);
|
||||||
outp.append((uint64_t)packetId());
|
outp.append((uint64_t)packetId());
|
||||||
outp.append((uint64_t)network->id());
|
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();
|
const int64_t now = RR->node->now();
|
||||||
outp.armor(peer->key(),true,peer->aesKeysIfSupported());
|
outp.armor(peer->key(),true,peer->aesKeysIfSupported());
|
||||||
peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -984,7 +984,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nc) {
|
if (nc) {
|
||||||
this->setConfiguration(tPtr,*nc,true);
|
fprintf(stderr, "Network::handleConfigChucnk->setConfiguration %.16llx\n", this->_id);
|
||||||
|
this->setConfiguration(tPtr, *nc, true);
|
||||||
delete nc;
|
delete nc;
|
||||||
return configUpdateId;
|
return configUpdateId;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -285,6 +285,11 @@ public:
|
||||||
const char* url = zeroidc::zeroidc_get_auth_url(_idc);
|
const char* url = zeroidc::zeroidc_get_auth_url(_idc);
|
||||||
memcpy(_config.authenticationURL, url, strlen(url));
|
memcpy(_config.authenticationURL, url, strlen(url));
|
||||||
_config.authenticationURL[strlen(url)] = 0;
|
_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
let s = CString::new(split[1]).unwrap();
|
||||||
return s.into_raw();
|
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();
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ struct Inner {
|
||||||
access_token: Option<AccessToken>,
|
access_token: Option<AccessToken>,
|
||||||
refresh_token: Option<RefreshToken>,
|
refresh_token: Option<RefreshToken>,
|
||||||
exp_time: u64,
|
exp_time: u64,
|
||||||
|
kick: bool,
|
||||||
|
|
||||||
url: Option<Url>,
|
url: Option<Url>,
|
||||||
csrf_token: Option<CsrfToken>,
|
csrf_token: Option<CsrfToken>,
|
||||||
|
@ -109,6 +110,7 @@ impl ZeroIDC {
|
||||||
access_token: None,
|
access_token: None,
|
||||||
refresh_token: None,
|
refresh_token: None,
|
||||||
exp_time: 0,
|
exp_time: 0,
|
||||||
|
kick: false,
|
||||||
|
|
||||||
url: None,
|
url: None,
|
||||||
csrf_token: None,
|
csrf_token: None,
|
||||||
|
@ -138,6 +140,11 @@ impl ZeroIDC {
|
||||||
Ok(idc)
|
Ok(idc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn kick_refresh_thread(&mut self) {
|
||||||
|
let local = Arc::clone(&self.inner);
|
||||||
|
(*local.lock().unwrap()).kick = true;
|
||||||
|
}
|
||||||
|
|
||||||
fn start(&mut self) {
|
fn start(&mut self) {
|
||||||
let local = Arc::clone(&self.inner);
|
let local = Arc::clone(&self.inner);
|
||||||
|
|
||||||
|
@ -160,7 +167,15 @@ impl ZeroIDC {
|
||||||
}
|
}
|
||||||
let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
|
let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
|
||||||
if let Some(refresh_token) = refresh_token {
|
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 token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
|
||||||
let res = c.exchange_refresh_token(&refresh_token)
|
let res = c.exchange_refresh_token(&refresh_token)
|
||||||
.request(http_client);
|
.request(http_client);
|
||||||
|
@ -356,6 +371,11 @@ impl ZeroIDC {
|
||||||
pub fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) {
|
pub fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) {
|
||||||
let local = Arc::clone(&self.inner);
|
let local = Arc::clone(&self.inner);
|
||||||
(*local.lock().expect("can't lock inner")).as_opt().map(|i| {
|
(*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 {
|
let need_verifier = match i.pkce_verifier {
|
||||||
None => true,
|
None => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
Loading…
Add table
Reference in a new issue