From 707d7deed2d4f3d5446e78e4076cff8954f51903 Mon Sep 17 00:00:00 2001 From: Brenton Bostick Date: Mon, 21 Aug 2023 15:00:27 -0400 Subject: [PATCH] Fix problem of doing RX while inside of TX Part of fix for: https://github.com/zerotier/libzt/issues/211 --- node/Switch.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/node/Switch.cpp b/node/Switch.cpp index 5cbbeff85..5ea1653c2 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -509,7 +509,17 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const adv[42] = (checksum >> 8) & 0xff; adv[43] = checksum & 0xff; - RR->node->putFrame(tPtr,network->id(),network->userPtr(),peerMac,from,ZT_ETHERTYPE_IPV6,0,adv,72); + // + // call on separate background thread + // this prevents problems related to trying to do rx while inside of doing tx, such as acquiring same lock recursively + // + + std::thread([=]() { + + RR->node->putFrame(tPtr, network->id(), network->userPtr(), peerMac, from, ZT_ETHERTYPE_IPV6, 0, adv, 72); + + }).detach(); + return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query. } // else no NDP emulation } // else no NDP emulation @@ -546,8 +556,18 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const data, len); } else if (to == network->mac()) { + // Destination is this node, so just reinject it - RR->node->putFrame(tPtr,network->id(),network->userPtr(),from,to,etherType,vlanId,data,len); + + // + // same pattern as putFrame call above + // + std::thread([=]() { + + RR->node->putFrame(tPtr, network->id(), network->userPtr(), from, to, etherType, vlanId, data, len); + + }).detach(); + } else if (to[0] == MAC::firstOctetForNetwork(network->id())) { // Destination is another ZeroTier peer on the same network