summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/ControlPlane.cpp7
-rw-r--r--service/OneService.cpp41
-rw-r--r--service/OneService.hpp4
-rw-r--r--service/README.md19
4 files changed, 43 insertions, 28 deletions
diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp
index 5c135636..150bba1b 100644
--- a/service/ControlPlane.cpp
+++ b/service/ControlPlane.cpp
@@ -222,8 +222,6 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_Peer *peer)
Utils::snprintf(json,sizeof(json),
"%s{\n"
"%s\t\"address\": \"%.10llx\",\n"
- "%s\t\"lastUnicastFrame\": %llu,\n"
- "%s\t\"lastMulticastFrame\": %llu,\n"
"%s\t\"versionMajor\": %d,\n"
"%s\t\"versionMinor\": %d,\n"
"%s\t\"versionRev\": %d,\n"
@@ -234,8 +232,6 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_Peer *peer)
"%s}",
prefix,
prefix,peer->address,
- prefix,peer->lastUnicastFrame,
- prefix,peer->lastMulticastFrame,
prefix,peer->versionMajor,
prefix,peer->versionMinor,
prefix,peer->versionRev,
@@ -274,9 +270,6 @@ unsigned int ControlPlane::handleRequest(
std::map<std::string,std::string> urlArgs;
Mutex::Lock _l(_lock);
- if (!((fromAddress.ipsEqual(InetAddress::LO4))||(fromAddress.ipsEqual(InetAddress::LO6))))
- return 403; // Forbidden: we only allow access from localhost right now
-
/* Note: this is kind of restricted in what it'll take. It does not support
* URL encoding, and /'s in URL args will screw it up. But the only URL args
* it really uses in ?jsonp=funcionName, and otherwise it just takes simple
diff --git a/service/OneService.cpp b/service/OneService.cpp
index 30e6c938..91063bad 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -483,6 +483,7 @@ public:
const std::string _homePath;
BackgroundResolver _tcpFallbackResolver;
+ InetAddress _allowManagementFrom;
EmbeddedNetworkController *_controller;
Phy<OneServiceImpl *> _phy;
Node *_node;
@@ -570,7 +571,7 @@ public:
// end member variables ----------------------------------------------------
- OneServiceImpl(const char *hp,unsigned int port) :
+ OneServiceImpl(const char *hp,unsigned int port,const char *allowManagementFrom) :
_homePath((hp) ? hp : ".")
,_tcpFallbackResolver(ZT_TCP_FALLBACK_RELAY)
,_controller((EmbeddedNetworkController *)0)
@@ -595,6 +596,9 @@ public:
#endif
,_run(true)
{
+ if (allowManagementFrom)
+ _allowManagementFrom.fromString(allowManagementFrom);
+
_ports[0] = 0;
_ports[1] = 0;
_ports[2] = 0;
@@ -614,7 +618,7 @@ public:
struct sockaddr_in in4;
memset(&in4,0,sizeof(in4));
in4.sin_family = AF_INET;
- in4.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); // right now we just listen for TCP @127.0.0.1
+ in4.sin_addr.s_addr = Utils::hton((uint32_t)((allowManagementFrom) ? 0 : 0x7f000001)); // right now we just listen for TCP @127.0.0.1
in4.sin_port = Utils::hton((uint16_t)port);
_v4TcpControlSocket = _phy.tcpListen((const struct sockaddr *)&in4,this);
@@ -622,7 +626,8 @@ public:
memset((void *)&in6,0,sizeof(in6));
in6.sin6_family = AF_INET6;
in6.sin6_port = in4.sin_port;
- in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1
+ if (!allowManagementFrom)
+ in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1
_v6TcpControlSocket = _phy.tcpListen((const struct sockaddr *)&in6,this);
// We must bind one of IPv4 or IPv6 -- support either failing to support hosts that
@@ -1259,12 +1264,10 @@ public:
inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from)
{
- if ((!from)||(reinterpret_cast<const InetAddress *>(from)->ipScope() != InetAddress::IP_SCOPE_LOOPBACK)) {
- // Non-Loopback: deny (for now)
+ if (!from) {
_phy.close(sockN,false);
return;
} else {
- // Loopback == HTTP JSON API request
TcpConnection *tc = new TcpConnection();
_tcpConnections.insert(tc);
tc->type = TcpConnection::TCP_HTTP_INCOMING;
@@ -1701,16 +1704,20 @@ public:
std::string contentType("text/plain"); // default if not changed in handleRequest()
unsigned int scode = 404;
- try {
- if (_controlPlane)
- scode = _controlPlane->handleRequest(tc->from,tc->parser.method,tc->url,tc->headers,tc->body,data,contentType);
- else scode = 500;
- } catch (std::exception &exc) {
- fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: %s" ZT_EOL_S,exc.what());
- scode = 500;
- } catch ( ... ) {
- fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: unknown exceptino" ZT_EOL_S);
- scode = 500;
+ if ( ((!_allowManagementFrom)&&(tc->from.ipScope() == InetAddress::IP_SCOPE_LOOPBACK)) || (_allowManagementFrom.containsAddress(tc->from)) ) {
+ try {
+ if (_controlPlane)
+ scode = _controlPlane->handleRequest(tc->from,tc->parser.method,tc->url,tc->headers,tc->body,data,contentType);
+ else scode = 500;
+ } catch (std::exception &exc) {
+ fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: %s" ZT_EOL_S,exc.what());
+ scode = 500;
+ } catch ( ... ) {
+ fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: unknown exceptino" ZT_EOL_S);
+ scode = 500;
+ }
+ } else {
+ scode = 401;
}
const char *scodestr;
@@ -1975,7 +1982,7 @@ std::string OneService::autoUpdateUrl()
return std::string();
}
-OneService *OneService::newInstance(const char *hp,unsigned int port) { return new OneServiceImpl(hp,port); }
+OneService *OneService::newInstance(const char *hp,unsigned int port,const char *allowManagementFrom) { return new OneServiceImpl(hp,port,allowManagementFrom); }
OneService::~OneService() {}
} // namespace ZeroTier
diff --git a/service/OneService.hpp b/service/OneService.hpp
index 72ff7d84..553bfd5e 100644
--- a/service/OneService.hpp
+++ b/service/OneService.hpp
@@ -98,10 +98,12 @@ public:
*
* @param hp Home path
* @param port TCP and UDP port for packets and HTTP control (if 0, pick random port)
+ * @param allowManagementFrom If non-NULL, allow control from supplied IP/netmask
*/
static OneService *newInstance(
const char *hp,
- unsigned int port);
+ unsigned int port,
+ const char *allowManagementFrom = (const char *)0);
virtual ~OneService();
diff --git a/service/README.md b/service/README.md
index 75c437dd..f487f2bc 100644
--- a/service/README.md
+++ b/service/README.md
@@ -25,6 +25,8 @@ A *jsonp* URL argument may be supplied to request JSONP encapsulation. A JSONP r
<tr><td><b>Field</b></td><td><b>Type</b></td><td><b>Description</b></td><td><b>Writable</b></td></tr>
<tr><td>address</td><td>string</td><td>10-digit hexadecimal ZeroTier address of this node</td><td>no</td></tr>
<tr><td>publicIdentity</td><td>string</td><td>Full public ZeroTier identity of this node</td><td>no</td></tr>
+<tr><td>worldId</td><td>integer</td><td>Fixed value representing the virtual data center of Earth.</td><td>no</td></tr>
+<tr><td>worldTimestamp</td><td>integer</td><td>Timestamp of the last root server topology change.</td><td>no</td></tr>
<tr><td>online</td><td>boolean</td><td>Does this node appear to have upstream network access?</td><td>no</td></tr>
<tr><td>tcpFallbackActive</td><td>boolean</td><td>Is TCP fallback mode active?</td><td>no</td></tr>
<tr><td>versionMajor</td><td>integer</td><td>ZeroTier major version</td><td>no</td></tr>
@@ -77,9 +79,22 @@ Most network settings are not writable, as they are defined by the network contr
<tr><td>broadcastEnabled</td><td>boolean</td><td>Is Ethernet broadcast (ff:ff:ff:ff:ff:ff) allowed?</td><td>no</td></tr>
<tr><td>portError</td><td>integer</td><td>Error code (if any) returned by underlying OS "tap" driver</td><td>no</td></tr>
<tr><td>netconfRevision</td><td>integer</td><td>Network configuration revision ID</td><td>no</td></tr>
-<tr><td>multicastSubscriptions</td><td>[string]</td><td>Multicast memberships as array of MAC/ADI tuples</td><td>no</td></tr>
<tr><td>assignedAddresses</td><td>[string]</td><td>ZeroTier-managed IP address assignments as array of IP/netmask bits tuples</td><td>no</td></tr>
+<tr><td>routes</td><td>[route]</td><td>ZeroTier-managed route assignments for a network. See below for a description of the route object.</td><td>no</td></tr>
<tr><td>portDeviceName</td><td>string</td><td>OS-specific network device name (if available)</td><td>no</td></tr>
+<tr><td>allowManaged</td><td>boolean</td><td>Whether ZeroTier-managed IP addresses are allowed.</td><td>yes</td></tr>
+<tr><td>allowGlobal</td><td>boolean</td><td>Whether globally-reachable IP addresses are allowed to be assigned.</td><td>yes</td></tr>
+<tr><td>allowDefault</td><td>boolean</td><td>Whether a default route is allowed to be assigned for the network (route all traffic via ZeroTier)</td><td>yes</td></tr>
+</table>
+
+`route` objects
+
+<table>
+<tr><td><b>Field</b></td><td><b>Type</b></td><td><b>Description</b></td><td><b>Writable</b></td></tr>
+<tr><td>target</td><td>string</td><td>Target network / netmask bits, NULL, or 0.0.0.0/0 for default route</td><td>no</td></tr>
+<tr><td>via</td><td>string</td><td>Gateway IP address</td><td>no</td></tr>
+<tr><td>flags</td><td>integer</td><td>Route flags</td><td>no</td></tr>
+<tr><td>metric</td><td>integer</td><td>Route metric (not currently used)</td><td>no</td></tr>
</table>
#### /peer
@@ -99,8 +114,6 @@ Getting /peer returns an array of peer objects for all current peers. See below
<table>
<tr><td><b>Field</b></td><td><b>Type</b></td><td><b>Description</b></td><td><b>Writable</b></td></tr>
<tr><td>address</td><td>string</td><td>10-digit hex ZeroTier address</td><td>no</td></tr>
-<tr><td>lastUnicastFrame</td><td>integer</td><td>Time of last unicast frame in ms since epoch</td><td>no</td></tr>
-<tr><td>lastMulticastFrame</td><td>integer</td><td>Time of last multicast frame in ms since epoch</td><td>no</td></tr>
<tr><td>versionMajor</td><td>integer</td><td>Major version of remote if known</td><td>no</td></tr>
<tr><td>versionMinor</td><td>integer</td><td>Minor version of remote if known</td><td>no</td></tr>
<tr><td>versionRev</td><td>integer</td><td>Revision of remote if known</td><td>no</td></tr>