summaryrefslogtreecommitdiff
path: root/node/NodeConfig.hpp
blob: d85578bf08473be507db19a7681e1fdf58666bc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * ZeroTier One - Global Peer to Peer Ethernet
 * Copyright (C) 2011-2015  ZeroTier Networks
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * --
 *
 * ZeroTier may be used and distributed under the terms of the GPLv3, which
 * are available at: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * If you would like to embed ZeroTier into a commercial application or
 * redistribute it in a modified binary form, please contact ZeroTier Networks
 * LLC. Start here: http://www.zerotier.com/
 */

#ifndef ZT_NODECONFIG_HPP
#define ZT_NODECONFIG_HPP

#include <stdint.h>

#include <map>
#include <set>
#include <string>
#include <vector>
#include <stdexcept>

#include "SharedPtr.hpp"
#include "Network.hpp"
#include "Utils.hpp"
#include "Buffer.hpp"
#include "Dictionary.hpp"

namespace ZeroTier {

class RuntimeEnvironment;

/**
 * Node configuration endpoint
 */
class NodeConfig
{
public:
	/**
	 * @param renv Runtime environment
	 * @throws std::runtime_error Unable to initialize or listen for IPC connections
	 */
	NodeConfig(const RuntimeEnvironment *renv);

	~NodeConfig();

	/**
	 * Store something in local configuration cache
	 *
	 * By convention, keys starting with _ will not be shown in the command bus
	 * local config functions.
	 *
	 * @param key Configuration key
	 * @param value Configuration value
	 */
	void putLocalConfig(const std::string &key,const char *value);
	void putLocalConfig(const std::string &key,const std::string &value);

	/**
	 * @param key Configuration key
	 * @return Value or empty string if not found
	 */
	std::string getLocalConfig(const std::string &key) const;

	/**
	 * @param nwid Network ID
	 * @return Network or NULL if no network for that ID
	 */
	inline SharedPtr<Network> network(uint64_t nwid) const
	{
		Mutex::Lock _l(_networks_m);
		std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.find(nwid));
		return ((n == _networks.end()) ? SharedPtr<Network>() : n->second);
	}

	/**
	 * @return Vector containing all networks
	 */
	inline std::vector< SharedPtr<Network> > networks() const
	{
		std::vector< SharedPtr<Network> > nwlist;
		Mutex::Lock _l(_networks_m);
		for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n)
			nwlist.push_back(n->second);
		return nwlist;
	}

	/**
	 * Join a network or return existing network if already joined
	 *
	 * @param nwid Network ID to join
	 * @return New network instance
	 */
	inline SharedPtr<Network> join(uint64_t nwid)
	{
		Mutex::Lock _l(_networks_m);
		SharedPtr<Network> &nw = _networks[nwid];
		if (nw)
			return nw;
		else return (nw = Network::newInstance(RR,this,nwid));
	}

	/**
	 * Leave a network
	 *
	 * @param nwid Network ID
	 * @return True if network was left, false if we were not a member of this network
	 */
	inline bool leave(uint64_t nwid)
	{
		Mutex::Lock _l(_networks_m);
		std::map< uint64_t,SharedPtr<Network> >::iterator n(_networks.find(nwid));
		if (n != _networks.end()) {
			n->second->destroy();
			_networks.erase(n);
			return true;
		} else return false;
	}

	/**
	 * Perform cleanup and possibly persist saved state
	 */
	void clean();

	/**
	 * @param nwid Network ID
	 * @return True if this network exists
	 */
	inline bool hasNetwork(uint64_t nwid)
	{
		Mutex::Lock _l(_networks_m);
		return (_networks.find(nwid) != _networks.end());
	}

	/**
	 * @return Sorted vector of network tap device names from our virtual networks (not other taps on system)
	 */
	inline std::vector<std::string> networkTapDeviceNames() const
	{
		std::vector<std::string> tapDevs;
		Mutex::Lock _l(_networks_m);
		for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
			std::string dn(n->second->tapDeviceName());
			if (dn.length())
				tapDevs.push_back(dn);
		}
		return tapDevs;
	}

private:
	void _readLocalConfig();
	void _writeLocalConfig();

	const RuntimeEnvironment *RR;

	Dictionary _localConfig; // persisted as local.conf
	Mutex _localConfig_m;

	std::map< uint64_t,SharedPtr<Network> > _networks; // persisted in networks.d/
	Mutex _networks_m;
};

} // namespace ZeroTier

#endif