summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/IncomingPacket.cpp21
-rw-r--r--node/IncomingPacket.hpp1
-rw-r--r--node/Multicaster.hpp2
-rw-r--r--node/Node.cpp24
-rw-r--r--node/Node.hpp1
-rw-r--r--node/Packet.hpp4
-rw-r--r--node/Utils.hpp11
7 files changed, 58 insertions, 6 deletions
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/Multicaster.hpp b/node/Multicaster.hpp
index 5c94cd3a..32dec9cf 100644
--- a/node/Multicaster.hpp
+++ b/node/Multicaster.hpp
@@ -220,7 +220,7 @@ private:
{
_GatherAuthKey() : member(0),networkId(0) {}
_GatherAuthKey(const uint64_t nwid,const Address &a) : member(a.toInt()),networkId(nwid) {}
- inline unsigned long hashCode() const { return (member ^ networkId); }
+ inline unsigned long hashCode() const { return (unsigned long)(member ^ networkId); }
inline bool operator==(const _GatherAuthKey &k) const { return ((member == k.member)&&(networkId == k.networkId)); }
uint64_t member;
uint64_t networkId;
diff --git a/node/Node.cpp b/node/Node.cpp
index ed60817f..0d0750ca 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -473,6 +473,21 @@ void Node::clearLocalInterfaceAddresses()
_directPaths.clear();
}
+int Node::sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
+{
+ try {
+ if (RR->identity.address().toInt() != dest) {
+ 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 +1007,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
};
diff --git a/node/Utils.hpp b/node/Utils.hpp
index 48c43da3..48cf799e 100644
--- a/node/Utils.hpp
+++ b/node/Utils.hpp
@@ -335,8 +335,7 @@ public:
*
* @return -1, 0, or 1 based on whether first tuple is less than, equal to, or greater than second
*/
- static inline int compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1,unsigned int maj2,unsigned int min2,unsigned int rev2)
- throw()
+ static inline int compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1,unsigned int b1,unsigned int maj2,unsigned int min2,unsigned int rev2,unsigned int b2)
{
if (maj1 > maj2)
return 1;
@@ -352,7 +351,13 @@ public:
return 1;
else if (rev1 < rev2)
return -1;
- else return 0;
+ else {
+ if (b1 > b2)
+ return 1;
+ else if (b1 < b2)
+ return -1;
+ else return 0;
+ }
}
}
}