diff options
-rw-r--r-- | include/ZeroTierOne.h | 52 | ||||
-rw-r--r-- | node/IncomingPacket.cpp | 21 | ||||
-rw-r--r-- | node/IncomingPacket.hpp | 1 | ||||
-rw-r--r-- | node/Node.cpp | 23 | ||||
-rw-r--r-- | node/Node.hpp | 1 | ||||
-rw-r--r-- | node/Packet.hpp | 4 |
6 files changed, 99 insertions, 3 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 21544b96..8b1ee0ac 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -393,7 +393,17 @@ enum ZT_Event * * Meta-data: C string, TRACE message */ - ZT_EVENT_TRACE = 5 + ZT_EVENT_TRACE = 5, + + /** + * VERB_USER_MESSAGE received + * + * These are generated when a VERB_USER_MESSAGE packet is received via + * ZeroTier VL1. + * + * Meta-data: ZT_UserMessage structure + */ + ZT_EVENT_USER_MESSAGE = 6 }; /** @@ -407,6 +417,32 @@ enum ZT_RelayPolicy }; /** + * User message used with ZT_EVENT_USER_MESSAGE + */ +typedef struct +{ + /** + * ZeroTier address of sender (least significant 40 bits) + */ + uint64_t origin; + + /** + * User message type ID + */ + uint64_t typeId; + + /** + * User message data (not including type ID) + */ + const void *data; + + /** + * Length of data in bytes + */ + unsigned int length; +} ZT_UserMessage; + +/** * Current node status */ typedef struct @@ -1854,6 +1890,20 @@ int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node); /** + * Send a VERB_USER_MESSAGE to another ZeroTier node + * + * There is no delivery guarantee here. Failure can occur if the message is + * too large or if dest is not a valid ZeroTier address. + * + * @param dest Destination ZeroTier address + * @param typeId VERB_USER_MESSAGE type ID + * @param data Payload data to attach to user message + * @param len Length of data in bytes + * @return Boolean: non-zero on success, zero on failure + */ +int ZT_Node_sendUserMessage(ZT_Node *node,uint64_t dest,uint64_t typeId,const void *data,unsigned int len); + +/** * Set peer role * * Right now this can only be used to set a peer to either LEAF or diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 7b828f8b..562aee91 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -106,8 +106,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) 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); - case Packet::VERB_USER_MESSAGE: - return true; + case Packet::VERB_USER_MESSAGE: return _doUSER_MESSAGE(RR,peer); } } else { RR->sw->requestWhois(sourceAddress); @@ -1345,6 +1344,24 @@ bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const S return true; } +bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer) +{ + try { + if (size() >= (ZT_PACKET_IDX_PAYLOAD + 8)) { + ZT_UserMessage um; + um.origin = peer->address().toInt(); + um.typeId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD); + um.data = reinterpret_cast<const void *>(reinterpret_cast<const uint8_t *>(data()) + ZT_PACKET_IDX_PAYLOAD + 8); + um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8); + RR->node->postEvent(ZT_EVENT_USER_MESSAGE,reinterpret_cast<const void *>(&um)); + } + peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false); + } catch ( ... ) { + TRACE("dropped CIRCUIT_TEST_REPORT from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str()); + } + return true; +} + void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid) { const uint64_t now = RR->node->now(); diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp index 80244ea4..febff28a 100644 --- a/node/IncomingPacket.hpp +++ b/node/IncomingPacket.hpp @@ -131,6 +131,7 @@ private: 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); + bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer); void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid); diff --git a/node/Node.cpp b/node/Node.cpp index ed60817f..32d41305 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -473,6 +473,20 @@ void Node::clearLocalInterfaceAddresses() _directPaths.clear(); } +int Node::sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigned int len) +{ + try { + Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE); + outp.append(typeId); + outp.append(data,len); + outp.compress(); + RR->sw->send(outp,true); + return 1; + } catch ( ... ) { + return 0; + } +} + void Node::setRole(uint64_t ztAddress,ZT_PeerRole role) { RR->topology->setUpstream(Address(ztAddress),(role == ZT_PEER_ROLE_UPSTREAM)); @@ -992,6 +1006,15 @@ void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node) } catch ( ... ) {} } +int ZT_Node_sendUserMessage(ZT_Node *node,uint64_t dest,uint64_t typeId,const void *data,unsigned int len) +{ + try { + return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(dest,typeId,data,len); + } catch ( ... ) { + return 0; + } +} + void ZT_Node_setRole(ZT_Node *node,uint64_t ztAddress,ZT_PeerRole role) { try { diff --git a/node/Node.hpp b/node/Node.hpp index eb46527d..64c9fcb4 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -98,6 +98,7 @@ public: void freeQueryResult(void *qr); int addLocalInterfaceAddress(const struct sockaddr_storage *addr); void clearLocalInterfaceAddresses(); + int sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigned int len); void setRole(uint64_t ztAddress,ZT_PeerRole role); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); diff --git a/node/Packet.hpp b/node/Packet.hpp index 8ff817aa..5ecbecba 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -1048,6 +1048,10 @@ public: * This can be used to send arbitrary messages over VL1. It generates no * OK or ERROR and has no special semantics outside of whatever the user * (via the ZeroTier core API) chooses to give it. + * + * Message type IDs less than or equal to 65535 are reserved for use by + * ZeroTier, Inc. itself. We recommend making up random ones for your own + * implementations. */ VERB_USER_MESSAGE = 0x14 }; |