summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-08-02 17:17:34 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-08-02 17:17:34 -0400
commit80d8b7d0ae56f1dce8b5b25ab7930df436755daf (patch)
treedc3eecbc787610f216036ddf202d052a29d94ea2 /node
parentf823fd05acb2a786fc0de00f77c952b23ca3414d (diff)
downloadinfinitytier-80d8b7d0ae56f1dce8b5b25ab7930df436755daf.tar.gz
infinitytier-80d8b7d0ae56f1dce8b5b25ab7930df436755daf.zip
Netconf wired up, ready to test.
Diffstat (limited to 'node')
-rw-r--r--node/Node.cpp46
-rw-r--r--node/Packet.hpp13
-rw-r--r--node/PacketDecoder.cpp52
3 files changed, 111 insertions, 0 deletions
diff --git a/node/Node.cpp b/node/Node.cpp
index e67dd526..8079e801 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -50,6 +50,7 @@
#include "Node.hpp"
#include "Topology.hpp"
#include "Demarc.hpp"
+#include "Packet.hpp"
#include "Switch.hpp"
#include "Utils.hpp"
#include "EthernetTap.hpp"
@@ -192,9 +193,54 @@ struct _NodeImpl
}
};
+#ifndef __WINDOWS__
static void _netconfServiceMessageHandler(void *renv,Service &svc,const Dictionary &msg)
{
+ if (!renv)
+ return; // sanity check
+ const RuntimeEnvironment *_r = (const RuntimeEnvironment *)renv;
+
+ try {
+ const std::string &type = msg.get("type");
+ if (type == "netconf-response") {
+ uint64_t inRePacketId = strtoull(msg.get("requestId").c_str(),(char **)0,16);
+ SharedPtr<Network> network = _r->nc->network(strtoull(msg.get("nwid").c_str(),(char **)0,16));
+ Address peerAddress(msg.get("peer").c_str());
+
+ if ((network)&&(peerAddress)) {
+ if (msg.contains("error")) {
+ Packet::ErrorCode errCode = Packet::ERROR_INVALID_REQUEST;
+ const std::string &err = msg.get("error");
+ if (err == "NOT_FOUND")
+ errCode = Packet::ERROR_NOT_FOUND;
+
+ Packet outp(peerAddress,_r->identity.address(),Packet::VERB_ERROR);
+ outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
+ outp.append(inRePacketId);
+ outp.append((unsigned char)errCode);
+ outp.append(network->id());
+ _r->sw->send(outp,true);
+ } else if (msg.contains("netconf")) {
+ const std::string &netconf = msg.get("netconf");
+ if (netconf.length() < 2048) { // sanity check
+ Packet outp(peerAddress,_r->identity.address(),Packet::VERB_OK);
+ outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
+ outp.append(inRePacketId);
+ outp.append(network->id());
+ outp.append((uint16_t)netconf.length());
+ outp.append(netconf.data(),netconf.length());
+ _r->sw->send(outp,true);
+ }
+ }
+ }
+ }
+ } catch (std::exception &exc) {
+ LOG("unexpected exception parsing response from netconf service: %s",exc.what());
+ } catch ( ... ) {
+ LOG("unexpected exception parsing response from netconf service: unknown exception");
+ }
}
+#endif // !__WINDOWS__
Node::Node(const char *hp)
throw() :
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 1d63929b..0e7ccea3 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -132,27 +132,34 @@
#define ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES 64
// Field incides for parsing verbs
+
#define ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION + 1)
#define ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION + 1)
#define ZT_PROTO_VERB_HELLO_IDX_REVISION (ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION + 1)
#define ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP (ZT_PROTO_VERB_HELLO_IDX_REVISION + 2)
#define ZT_PROTO_VERB_HELLO_IDX_IDENTITY (ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP + 8)
+
#define ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID (ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB + 1)
#define ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE (ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID + 8)
#define ZT_PROTO_VERB_ERROR_IDX_PAYLOAD (ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE + 1)
+
#define ZT_PROTO_VERB_OK_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID (ZT_PROTO_VERB_OK_IDX_IN_RE_VERB + 1)
#define ZT_PROTO_VERB_OK_IDX_PAYLOAD (ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID + 8)
+
#define ZT_PROTO_VERB_WHOIS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD)
+
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT (ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS + 5)
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN (ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT + 2)
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN + 1)
+
#define ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE + 2)
+
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_ADDRESS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + 8)
@@ -166,6 +173,12 @@
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SIGNATURE_LENGTH (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD_LENGTH + 2)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SIGNATURE_LENGTH + 2)
+#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
+#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8)
+#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN + 2)
+
+#define ZT_PROTO_VERB_NETWORK_CONFIG_REFRESH_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
+
// Field indices for parsing OK and ERROR payloads of replies
#define ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP (ZT_PROTO_VERB_OK_IDX_PAYLOAD)
#define ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY (ZT_PROTO_VERB_OK_IDX_PAYLOAD)
diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp
index 0353625c..518ed9e7 100644
--- a/node/PacketDecoder.cpp
+++ b/node/PacketDecoder.cpp
@@ -25,6 +25,7 @@
* LLC. Start here: http://www.zerotier.com/
*/
+#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Topology.hpp"
#include "PacketDecoder.hpp"
@@ -32,6 +33,7 @@
#include "Peer.hpp"
#include "NodeConfig.hpp"
#include "Filter.hpp"
+#include "Service.hpp"
namespace ZeroTier {
@@ -546,14 +548,64 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
bool PacketDecoder::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
{
+ // TODO: not implemented yet, will be needed for private networks.
+
+ return true;
}
bool PacketDecoder::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
{
+ char tmp[128];
+ try {
+ uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID);
+#ifndef __WINDOWS__
+ if (_r->netconfService) {
+ unsigned int dictLen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN);
+ std::string dict((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,dictLen),dictLen);
+
+ Dictionary request;
+ request["type"] = "netconf-request";
+ request["peerId"] = peer->identity().toString(false);
+ sprintf(tmp,"%llx",(unsigned long long)nwid);
+ request["nwid"] = tmp;
+ sprintf(tmp,"%llx",(unsigned long long)packetId());
+ request["requestId"] = tmp;
+ _r->netconfService->send(request);
+ } else {
+#endif // !__WINDOWS__
+ Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR);
+ outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
+ outp.append(packetId());
+ outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
+ outp.append(nwid);
+ outp.encrypt(peer->cryptKey());
+ outp.hmacSet(peer->macKey());
+ _r->demarc->send(_localPort,_remoteAddress,outp.data(),outp.size(),-1);
+ TRACE("sent ERROR(NETWORK_CONFIG_REQUEST,UNSUPPORTED_OPERATION) to %s(%s)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
+#ifndef __WINDOWS__
+ }
+#endif // !__WINDOWS__
+ } catch (std::exception &exc) {
+ TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
+ } catch ( ... ) {
+ TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
+ }
+ return true;
}
bool PacketDecoder::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
{
+ try {
+ uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REFRESH_IDX_NETWORK_ID);
+ SharedPtr<Network> nw(_r->nc->network(nwid));
+ if ((nw)&&(source() == nw->controller())) // only respond to requests from controller
+ nw->requestConfiguration();
+ } catch (std::exception &exc) {
+ TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
+ } catch ( ... ) {
+ TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
+ }
+ return true;
}
} // namespace ZeroTier