Parcourir la source

Implement relay policy, and setting multicast limit to 0 now disables multicast on the network as would be expected.

Adam Ierymenko il y a 9 ans
Parent
commit
5b6d27e659
12 fichiers modifiés avec 159 ajouts et 83 suppressions
  1. 30 8
      include/ZeroTierOne.h
  2. 7 2
      node/Constants.hpp
  3. 14 2
      node/IncomingPacket.cpp
  4. 21 1
      node/Node.cpp
  5. 3 0
      node/Node.hpp
  6. 13 0
      node/Path.hpp
  7. 6 0
      node/Peer.cpp
  8. 12 6
      node/Peer.hpp
  9. 29 2
      node/Switch.cpp
  10. 21 59
      osdep/ManagedRoute.cpp
  11. 2 2
      osdep/ManagedRoute.hpp
  12. 1 1
      service/ControlPlane.cpp

+ 30 - 8
include/ZeroTierOne.h

@@ -870,19 +870,28 @@ enum ZT_VirtualNetworkConfigOperation
 	ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4
 };
 
+enum ZT_RelayPolicy
+{
+	ZT_RELAY_POLICY_NEVER = 0,
+	ZT_RELAY_POLICY_TRUSTED = 1,
+	ZT_RELAY_POLICY_ALWAYS = 2
+};
+
 /**
  * What trust hierarchy role does this peer have?
  */
-enum ZT_PeerRole {
+enum ZT_PeerRole
+{
 	ZT_PEER_ROLE_LEAF = 0,     // ordinary node
-	ZT_PEER_ROLE_RELAY = 1,    // relay node
-	ZT_PEER_ROLE_ROOT = 2      // root server
+	ZT_PEER_ROLE_UPSTREAM = 1, // upstream node
+	ZT_PEER_ROLE_ROOT = 2      // global root
 };
 
 /**
  * Vendor ID
  */
-enum ZT_Vendor {
+enum ZT_Vendor
+{
 	ZT_VENDOR_UNSPECIFIED = 0,
 	ZT_VENDOR_ZEROTIER = 1
 };
@@ -890,7 +899,8 @@ enum ZT_Vendor {
 /**
  * Platform type
  */
-enum ZT_Platform {
+enum ZT_Platform
+{
 	ZT_PLATFORM_UNSPECIFIED = 0,
 	ZT_PLATFORM_LINUX = 1,
 	ZT_PLATFORM_WINDOWS = 2,
@@ -905,13 +915,15 @@ enum ZT_Platform {
 	ZT_PLATFORM_VXWORKS = 11,
 	ZT_PLATFORM_FREERTOS = 12,
 	ZT_PLATFORM_SYSBIOS = 13,
-	ZT_PLATFORM_HURD = 14
+	ZT_PLATFORM_HURD = 14,
+	ZT_PLATFORM_WEB = 15
 };
 
 /**
  * Architecture type
  */
-enum ZT_Architecture {
+enum ZT_Architecture
+{
 	ZT_ARCHITECTURE_UNSPECIFIED = 0,
 	ZT_ARCHITECTURE_X86 = 1,
 	ZT_ARCHITECTURE_X64 = 2,
@@ -926,7 +938,8 @@ enum ZT_Architecture {
 	ZT_ARCHITECTURE_SPARC32 = 11,
 	ZT_ARCHITECTURE_SPARC64 = 12,
 	ZT_ARCHITECTURE_DOTNET_CLR = 13,
-	ZT_ARCHITECTURE_JAVA_JVM = 14
+	ZT_ARCHITECTURE_JAVA_JVM = 14,
+	ZT_ARCHITECTURE_WEB = 15
 };
 
 /**
@@ -1681,6 +1694,15 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
  */
 enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
 
+/**
+ * Set node's relay policy
+ *
+ * @param node Node instance
+ * @param rp New relay policy
+ * @return OK(0) or error code
+ */
+enum ZT_ResultCode ZT_Node_setRelayPolicy(ZT_Node *node,enum ZT_RelayPolicy rp);
+
 /**
  * Join a network
  *

+ 7 - 2
node/Constants.hpp

@@ -350,6 +350,11 @@
  */
 #define ZT_PUSH_DIRECT_PATHS_CUTOFF_LIMIT 5
 
+/**
+ * Maximum number of paths per IP scope (e.g. global, link-local) and family (e.g. v4/v6)
+ */
+#define ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY 4
+
 /**
  * Time horizon for VERB_NETWORK_CREDENTIALS cutoff
  */
@@ -366,9 +371,9 @@
 #define ZT_PEER_GENERAL_RATE_LIMIT 1000
 
 /**
- * Maximum number of paths per IP scope (e.g. global, link-local) and family (e.g. v4/v6)
+ * How long is a path or peer considered to have a trust relationship with us (for e.g. relay policy) since last trusted established packet?
  */
-#define ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY 4
+#define ZT_TRUST_EXPIRATION 600000
 
 /**
  * Enable support for older network configurations from older (pre-1.1.6) controllers

+ 14 - 2
node/IncomingPacket.cpp

@@ -670,8 +670,14 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
 								peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
 								return true;
 							}
-						} else if ( (to != network->mac()) && (!to.isMulticast()) ) {
-							if (!network->config().permitsBridging(RR->identity.address())) {
+						} else if (to != network->mac()) {
+							if (to.isMulticast()) {
+								if (network->config().multicastLimit == 0) {
+									TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: network %.16llx does not allow multicast",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
+									peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
+									return true;
+								}
+							} else if (!network->config().permitsBridging(RR->identity.address())) {
 								TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: I cannot bridge to %.16llx or bridging disabled on network",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
 								peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
 								return true;
@@ -1038,6 +1044,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
 				return true;
 			}
 
+			if (network->config().multicastLimit == 0) {
+				TRACE("dropped MULTICAST_FRAME from %s(%s): network %.16llx does not allow multicast",peer->address().toString().c_str(),_path->address().toString().c_str(),(unsigned long long)network->id());
+				peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
+				return true;
+			}
+
 			unsigned int gatherLimit = 0;
 			if ((flags & 0x02) != 0) {
 				gatherLimit = at<uint32_t>(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GATHER_LIMIT);

+ 21 - 1
node/Node.cpp

@@ -71,7 +71,8 @@ Node::Node(
 	_prngStreamPtr(0),
 	_now(now),
 	_lastPingCheck(0),
-	_lastHousekeepingRun(0)
+	_lastHousekeepingRun(0),
+	_relayPolicy(ZT_RELAY_POLICY_TRUSTED)
 {
 	_online = false;
 
@@ -118,6 +119,9 @@ Node::Node(
 		throw;
 	}
 
+	if (RR->topology->amRoot())
+		_relayPolicy = ZT_RELAY_POLICY_ALWAYS;
+
 	postEvent(ZT_EVENT_UP);
 }
 
@@ -131,6 +135,7 @@ Node::~Node()
 	delete RR->topology;
 	delete RR->mc;
 	delete RR->sw;
+
 #ifdef ZT_ENABLE_CLUSTER
 	delete RR->cluster;
 #endif
@@ -319,6 +324,12 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
 	return ZT_RESULT_OK;
 }
 
+ZT_ResultCode Node::setRelayPolicy(enum ZT_RelayPolicy rp)
+{
+	_relayPolicy = rp;
+	return ZT_RESULT_OK;
+}
+
 ZT_ResultCode Node::join(uint64_t nwid,void *uptr)
 {
 	Mutex::Lock _l(_networks_m);
@@ -824,6 +835,15 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol
 	}
 }
 
+enum ZT_ResultCode ZT_Node_setRelayPolicy(ZT_Node *node,enum ZT_RelayPolicy rp)
+{
+	try {
+		return reinterpret_cast<ZeroTier::Node *>(node)->setRelayPolicy(rp);
+	} catch ( ... ) {
+		return ZT_RESULT_FATAL_ERROR_INTERNAL;
+	}
+}
+
 enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr)
 {
 	try {

+ 3 - 0
node/Node.hpp

@@ -91,6 +91,7 @@ public:
 		unsigned int frameLength,
 		volatile uint64_t *nextBackgroundTaskDeadline);
 	ZT_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
+	ZT_ResultCode setRelayPolicy(enum ZT_RelayPolicy rp);
 	ZT_ResultCode join(uint64_t nwid,void *uptr);
 	ZT_ResultCode leave(uint64_t nwid,void **uptr);
 	ZT_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
@@ -245,6 +246,7 @@ public:
 	inline int configureVirtualNetworkPort(uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,nwid,nuptr,op,nc); }
 
 	inline bool online() const throw() { return _online; }
+	inline ZT_RelayPolicy relayPolicy() const { return _relayPolicy; }
 
 #ifdef ZT_TRACE
 	void postTrace(const char *module,unsigned int line,const char *fmt,...);
@@ -326,6 +328,7 @@ private:
 	uint64_t _now;
 	uint64_t _lastPingCheck;
 	uint64_t _lastHousekeepingRun;
+	ZT_RelayPolicy _relayPolicy;
 	bool _online;
 };
 

+ 13 - 0
node/Path.hpp

@@ -104,6 +104,7 @@ public:
 	Path() :
 		_lastOut(0),
 		_lastIn(0),
+		_lastTrustEstablishedPacketReceived(0),
 		_addr(),
 		_localAddress(),
 		_ipScope(InetAddress::IP_SCOPE_NONE)
@@ -113,6 +114,7 @@ public:
 	Path(const InetAddress &localAddress,const InetAddress &addr) :
 		_lastOut(0),
 		_lastIn(0),
+		_lastTrustEstablishedPacketReceived(0),
 		_addr(addr),
 		_localAddress(localAddress),
 		_ipScope(addr.ipScope())
@@ -126,6 +128,11 @@ public:
 	 */
 	inline void received(const uint64_t t) { _lastIn = t; }
 
+	/**
+	 * Set time last trusted packet was received (done in Peer::received())
+	 */
+	inline void trustedPacketReceived(const uint64_t t) { _lastTrustEstablishedPacketReceived = t; }
+
 	/**
 	 * Send a packet via this path (last out time is also updated)
 	 *
@@ -159,6 +166,11 @@ public:
 	 */
 	inline InetAddress::IpScope ipScope() const { return _ipScope; }
 
+	/**
+	 * @return True if path has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms
+	 */
+	inline bool trustEstablished(const uint64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); }
+
 	/**
 	 * @return Preference rank, higher == better
 	 */
@@ -232,6 +244,7 @@ public:
 private:
 	uint64_t _lastOut;
 	uint64_t _lastIn;
+	uint64_t _lastTrustEstablishedPacketReceived;
 	InetAddress _addr;
 	InetAddress _localAddress;
 	InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often

+ 6 - 0
node/Peer.cpp

@@ -52,6 +52,7 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
 	_lastEchoRequestReceived(0),
 	_lastComRequestReceived(0),
 	_lastCredentialsReceived(0),
+	_lastTrustEstablishedPacketReceived(0),
 	RR(renv),
 	_remoteClusterOptimal4(0),
 	_vProto(0),
@@ -132,6 +133,11 @@ void Peer::received(
 	else if (verb == Packet::VERB_MULTICAST_FRAME)
 		_lastMulticastFrame = now;
 
+	if (trustEstablished) {
+		_lastTrustEstablishedPacketReceived = now;
+		path->trustedPacketReceived(now);
+	}
+
 	if (hops == 0) {
 		bool pathIsConfirmed = false;
 		{

+ 12 - 6
node/Peer.hpp

@@ -312,7 +312,7 @@ public:
 	/**
 	 * @return 256-bit secret symmetric encryption key
 	 */
-	inline const unsigned char *key() const throw() { return _key; }
+	inline const unsigned char *key() const { return _key; }
 
 	/**
 	 * Set the currently known remote version of this peer's client
@@ -330,12 +330,17 @@ public:
 		_vRevision = (uint16_t)vrev;
 	}
 
-	inline unsigned int remoteVersionProtocol() const throw() { return _vProto; }
-	inline unsigned int remoteVersionMajor() const throw() { return _vMajor; }
-	inline unsigned int remoteVersionMinor() const throw() { return _vMinor; }
-	inline unsigned int remoteVersionRevision() const throw() { return _vRevision; }
+	inline unsigned int remoteVersionProtocol() const { return _vProto; }
+	inline unsigned int remoteVersionMajor() const { return _vMajor; }
+	inline unsigned int remoteVersionMinor() const { return _vMinor; }
+	inline unsigned int remoteVersionRevision() const { return _vRevision; }
 
-	inline bool remoteVersionKnown() const throw() { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
+	inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
+
+	/**
+	 * @return True if peer has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms
+	 */
+	inline bool trustEstablished(const uint64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); }
 
 	/**
 	 * Rate limit gate for VERB_PUSH_DIRECT_PATHS
@@ -470,6 +475,7 @@ private:
 	uint64_t _lastEchoRequestReceived;
 	uint64_t _lastComRequestReceived;
 	uint64_t _lastCredentialsReceived;
+	uint64_t _lastTrustEstablishedPacketReceived;
 	const RuntimeEnvironment *RR;
 	uint32_t _remoteClusterOptimal4;
 	uint16_t _vProto;

+ 29 - 2
node/Switch.cpp

@@ -105,7 +105,18 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
 				const Address destination(fragment.destination());
 
 				if (destination != RR->identity.address()) {
-					// Fragment is not for us, so try to relay it
+					switch(RR->node->relayPolicy()) {
+						case ZT_RELAY_POLICY_ALWAYS:
+							break;
+						case ZT_RELAY_POLICY_TRUSTED:
+							if (!path->trustEstablished(now))
+								return;
+							break;
+						// case ZT_RELAY_POLICY_NEVER:
+						default:
+							return;
+					}
+
 					if (fragment.hops() < ZT_RELAY_MAX_HOPS) {
 						fragment.incrementHops();
 
@@ -203,9 +214,20 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
 				//TRACE("<< %.16llx %s -> %s (size: %u)",(unsigned long long)packet->packetId(),source.toString().c_str(),destination.toString().c_str(),packet->size());
 
 				if (destination != RR->identity.address()) {
+					switch(RR->node->relayPolicy()) {
+						case ZT_RELAY_POLICY_ALWAYS:
+							break;
+						case ZT_RELAY_POLICY_TRUSTED:
+							if (!path->trustEstablished(now))
+								return;
+							break;
+						// case ZT_RELAY_POLICY_NEVER:
+						default:
+							return;
+					}
+
 					Packet packet(data,len);
 
-					// Packet is not for us, so try to relay it
 					if (packet.hops() < ZT_RELAY_MAX_HOPS) {
 						packet.incrementHops();
 
@@ -327,6 +349,11 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
 	}
 
 	if (to.isMulticast()) {
+		if (network->config().multicastLimit == 0) {
+			TRACE("%.16llx: dropped multicast: not allowed on network",network->id());
+			return;
+		}
+
 		// Destination is a multicast address (including broadcast)
 		MulticastGroup mg(to,0);
 

+ 21 - 59
osdep/ManagedRoute.cpp

@@ -436,12 +436,12 @@ bool ManagedRoute::sync()
 	}
 
 	if (!_applied.count(leftt)) {
-		_applied.insert(leftt);
+		_applied[rightt] = false; // not ifscoped
 		_routeCmd("add",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
 		_routeCmd("change",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
 	}
 	if ((rightt)&&(!_applied.count(rightt))) {
-		_applied.insert(rightt);
+		_applied[rightt] = false; // not ifscoped
 		_routeCmd("add",rightt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
 		_routeCmd("change",rightt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
 	}
@@ -457,7 +457,7 @@ bool ManagedRoute::sync()
 			}
 		} else {
 			if (!_applied.count(_target)) {
-				_applied.insert(_target);
+				_applied[_target] = true; // ifscoped
 				_routeCmd("add",_target,_via,_device,(_via) ? (const char *)0 : _device);
 				_routeCmd("change",_target,_via,_device,(_via) ? (const char *)0 : _device);
 			}
@@ -468,65 +468,27 @@ bool ManagedRoute::sync()
 
 #ifdef __LINUX__ // ----------------------------------------------------------
 
-	//if (needBifurcation) {
-		if (!_applied.count(leftt)) {
-			_applied.insert(leftt);
-			_routeCmd("replace",leftt,_via,(_via) ? (const char *)0 : _device);
-		}
-		if ((rightt)&&(!_applied.count(rightt))) {
-			_applied.insert(rightt);
-			_routeCmd("replace",rightt,_via,(_via) ? (const char *)0 : _device);
-		}
-		/*if (_applied.count(_target)) {
-			_applied.erase(_target);
-			_routeCmd("del",_target,_via,(_via) ? (const char *)0 : _device);
-		}*/
-	/*} else {
-		if (_applied.count(leftt)) {
-			_applied.erase(leftt);
-			_routeCmd("del",leftt,_via,(_via) ? (const char *)0 : _device);
-		}
-		if ((rightt)&&(_applied.count(rightt))) {
-			_applied.erase(rightt);
-			_routeCmd("del",rightt,_via,(_via) ? (const char *)0 : _device);
-		}
-		if (!_applied.count(_target)) {
-			_applied.insert(_target);
-			_routeCmd("replace",_target,_via,(_via) ? (const char *)0 : _device);
-		}
-	}*/
+	if (!_applied.count(leftt)) {
+		_applied[leftt] = false; // boolean unused
+		_routeCmd("replace",leftt,_via,(_via) ? (const char *)0 : _device);
+	}
+	if ((rightt)&&(!_applied.count(rightt))) {
+		_applied[rightt] = false; // boolean unused
+		_routeCmd("replace",rightt,_via,(_via) ? (const char *)0 : _device);
+	}
 
 #endif // __LINUX__ ----------------------------------------------------------
 
 #ifdef __WINDOWS__ // --------------------------------------------------------
 
-	//if (needBifurcation) {
-		if (!_applied.count(leftt)) {
-			_applied.insert(leftt);
-			_winRoute(false,interfaceLuid,interfaceIndex,leftt,_via);
-		}
-		if ((rightt)&&(!_applied.count(rightt))) {
-			_applied.insert(rightt);
-			_winRoute(false,interfaceLuid,interfaceIndex,rightt,_via);
-		}
-		/*if (_applied.count(_target)) {
-			_applied.erase(_target);
-			_winRoute(true,interfaceLuid,interfaceIndex,_target,_via);
-		}*/
-	/*} else {
-		if (_applied.count(leftt)) {
-			_applied.erase(leftt);
-			_winRoute(true,interfaceLuid,interfaceIndex,leftt,_via);
-		}
-		if ((rightt)&&(_applied.count(rightt))) {
-			_applied.erase(rightt);
-			_winRoute(true,interfaceLuid,interfaceIndex,rightt,_via);
-		}
-		if (!_applied.count(_target)) {
-			_applied.insert(_target);
-			_winRoute(false,interfaceLuid,interfaceIndex,_target,_via);
-		}
-	}*/
+	if (!_applied.count(leftt)) {
+		_applied[leftt] = false; // boolean unused
+		_winRoute(false,interfaceLuid,interfaceIndex,leftt,_via);
+	}
+	if ((rightt)&&(!_applied.count(rightt))) {
+		_applied[rightt] = false; // boolean unused
+		_winRoute(false,interfaceLuid,interfaceIndex,rightt,_via);
+	}
 
 #endif // __WINDOWS__ --------------------------------------------------------
 
@@ -553,9 +515,9 @@ void ManagedRoute::remove()
 	}
 #endif // __BSD__ ------------------------------------------------------------
 
-	for(std::set<InetAddress>::iterator r(_applied.begin());r!=_applied.end();++r) {
+	for(std::map<InetAddress,bool>::iterator r(_applied.begin());r!=_applied.end();++r) {
 #ifdef __BSD__ // ------------------------------------------------------------
-		_routeCmd("delete",*r,_via,(const char *)0,(_via) ? (const char *)0 : _device);
+		_routeCmd("delete",r->first,_via,r->second ? _device : (const char *)0,(_via) ? (const char *)0 : _device);
 #endif // __BSD__ ------------------------------------------------------------
 
 #ifdef __LINUX__ // ----------------------------------------------------------

+ 2 - 2
osdep/ManagedRoute.hpp

@@ -9,7 +9,7 @@
 
 #include <stdexcept>
 #include <vector>
-#include <set>
+#include <map>
 
 namespace ZeroTier {
 
@@ -105,7 +105,7 @@ private:
 	InetAddress _target;
 	InetAddress _via;
 	InetAddress _systemVia; // for route overrides
-	std::set<InetAddress> _applied; // routes currently applied
+	std::map<InetAddress,bool> _applied; // routes currently applied
 	char _device[128];
 	char _systemDevice[128]; // for route overrides
 };

+ 1 - 1
service/ControlPlane.cpp

@@ -215,7 +215,7 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_Peer *peer)
 	const char *prole = "";
 	switch(peer->role) {
 		case ZT_PEER_ROLE_LEAF:  prole = "LEAF"; break;
-		case ZT_PEER_ROLE_RELAY: prole = "RELAY"; break;
+		case ZT_PEER_ROLE_UPSTREAM: prole = "UPSTREAM"; break;
 		case ZT_PEER_ROLE_ROOT:  prole = "ROOT"; break;
 	}