summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ZeroTierOne.h52
-rw-r--r--node/IncomingPacket.cpp21
-rw-r--r--node/IncomingPacket.hpp1
-rw-r--r--node/Node.cpp23
-rw-r--r--node/Node.hpp1
-rw-r--r--node/Packet.hpp4
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
};