summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-30 13:59:05 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-30 13:59:05 -0700
commit1a4f16e0ed1b62ebf3bdbb539858a3874c689fa4 (patch)
tree190b3fbf2f639471cac76322649e8ccd173e4e5f /node
parenta7bd1eaa409a5532c30ac5990a32289496d7ed3e (diff)
downloadinfinitytier-1a4f16e0ed1b62ebf3bdbb539858a3874c689fa4.tar.gz
infinitytier-1a4f16e0ed1b62ebf3bdbb539858a3874c689fa4.zip
More work on circuit testing...
Diffstat (limited to 'node')
-rw-r--r--node/IncomingPacket.cpp63
-rw-r--r--node/IncomingPacket.hpp4
-rw-r--r--node/Packet.hpp5
3 files changed, 70 insertions, 2 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index c94ffe2e..3866abf1 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -85,6 +85,8 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
case Packet::VERB_MULTICAST_GATHER: return _doMULTICAST_GATHER(RR,peer);
case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(RR,peer);
case Packet::VERB_PUSH_DIRECT_PATHS: return _doPUSH_DIRECT_PATHS(RR,peer);
+ case Packet::VERB_CIRCUIT_TEST: return _doCIRCUIT_TEST(RR,peer);
+ case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,peer);
}
} else {
RR->sw->requestWhois(source());
@@ -926,6 +928,67 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
return true;
}
+bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
+{
+ try {
+ const Address originatorAddress(field(ZT_PACKET_IDX_PAYLOAD,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
+ SharedPtr<Peer> originator(RR->topology->getPeer(originatorAddress));
+ if (!originator) {
+ RR->sw->requestWhois(originatorAddress);
+ return false;
+ }
+
+ const unsigned int flags = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 5);
+ const uint64_t timestamp = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 7);
+ const uint64_t testId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 15);
+
+ unsigned int vlf = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 23); // variable length field length
+ switch((*this)[ZT_PACKET_IDX_PAYLOAD + 25]) {
+ case 0x01: { // 64-bit network ID, originator must be controller
+ } break;
+ default: break;
+ }
+
+ vlf += at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 26 + vlf); // length of additional fields, currently unused
+
+ const unsigned int signatureLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 28 + vlf);
+ if (!originator->identity().verify(field(ZT_PACKET_IDX_PAYLOAD,28 + vlf),28 + vlf,field(30 + vlf,signatureLength),signatureLength)) {
+ TRACE("dropped CIRCUIT_TEST from %s(%s): signature by originator %s invalid",source().toString().c_str(),_remoteAddress.toString().c_str(),originatorAddress.toString().c_str());
+ return true;
+ }
+ vlf += signatureLength;
+
+ vlf += at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 30 + vlf);
+ switch((*this)[ZT_PACKET_IDX_PAYLOAD + 32 + vlf]) {
+ case 0x01: { // network certificate of membership for previous hop
+ } break;
+ default: break;
+ }
+
+ if ((ZT_PACKET_IDX_PAYLOAD + 33 + vlf) < size()) {
+ const unsigned int breadth = (*this)[ZT_PACKET_IDX_PAYLOAD + 33 + vlf];
+ Address nextHops[255];
+ SharedPtr<Peer> nextHopPeers[255];
+ unsigned int hptr = ZT_PACKET_IDX_PAYLOAD + 34 + vlf;
+ for(unsigned int h=0;((h<breadth)&&(h<255));++h) { // breadth can't actually be >256 but be safe anyway
+ nextHops[h].setTo(field(hptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
+ hptr += ZT_ADDRESS_LENGTH;
+ nextHopPeers[h] = RR->topology->getPeer(nextHops[h]);
+ }
+ }
+ } catch (std::exception &exc) {
+ TRACE("dropped CIRCUIT_TEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
+ } catch ( ... ) {
+ TRACE("dropped CIRCUIT_TEST from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
+ }
+ return true;
+}
+
+bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
+{
+ return true;
+}
+
void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,uint64_t nwid)
{
Packet outp(source(),RR->identity.address(),Packet::VERB_ERROR);
diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp
index d19eb5c6..06220c4b 100644
--- a/node/IncomingPacket.hpp
+++ b/node/IncomingPacket.hpp
@@ -124,8 +124,10 @@ private:
bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+ bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
- // Send an ERROR_NEED_MEMBERSHIP_CERTIFICATE to a peer indicating that an updated cert is needed to join
+ // Send an ERROR_NEED_MEMBERSHIP_CERTIFICATE to a peer indicating that an updated cert is needed to communicate
void _sendErrorNeedCertificate(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,uint64_t nwid);
uint64_t _receiveTime;
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 2d439b11..2a1a39af 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -911,12 +911,15 @@ public:
* <[2] 16-bit flags>
* <[8] 64-bit timestamp>
* <[8] 64-bit test ID (arbitrary, set by tester)>
+ * <[2] 16-bit originator credential length>
* <[1] originator credential type (for authorizing test)>
* <[...] credential>
* <[2] 16-bit length of additional fields>
* <[...] additional fields>
+ * [ ... end of signed portion of request ... ]
* <[2] 16-bit length of signature of request>
* <[...] signature of request by originator>
+ * <[2] 16-bit previous hop credential length>
* <[1] previous hop credential type>
* <[...] previous hop credential>
* <[...] next hop(s) in path>
@@ -939,7 +942,7 @@ public:
* <[...] one or more ZeroTier addresses of next hops>
*
* Path record flags (in each path record):
- * 0x80 - End of path (should be set on last entry)
+ * (unused, must be zero)
*
* The circuit test allows a device to send a message that will traverse
* the network along a specified path, with each hop optionally reporting