summaryrefslogtreecommitdiff
path: root/node/Service.hpp
blob: 64ed108f72f4637d490742fc9b5c7f8f6b740f7b (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
/*
 * ZeroTier One - Global Peer to Peer Ethernet
 * Copyright (C) 2011-2014  ZeroTier Networks LLC
 *
 * 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_SERVICE_HPP
#define ZT_SERVICE_HPP

#include <string>
#include <stdexcept>

#include "Constants.hpp"
#include "Dictionary.hpp"
#include "Thread.hpp"
#include "Mutex.hpp"

/**
 * Maximum size of a service message in bytes (sanity limit)
 */
#define ZT_SERVICE_MAX_MESSAGE_SIZE 131072

namespace ZeroTier {

class RuntimeEnvironment;

#ifndef __WINDOWS__
/**
 * A subprocess that communicates with the host via a simple protocol
 *
 * This is currently only supported on *nix systems, and is used to implement
 * special plugins that are used by supernodes and network configuration
 * master nodes. Users will probably have no use for it.
 *
 * The simple binary protocol consists of a bidirectional stream of string-
 * serialized Dictionaries prefixed by a 32-bit message length. Input
 * messages are sent to the subprocess via its stdin, and output is read
 * from its stdout. Messages printed by the subprocess on its stderr are
 * logged via the standard Logger instance. If the subprocess dies, an
 * attempt is made to restart it every second.
 */
class Service
{
public:
	/**
	 * Create and launch a new service
	 *
	 * @param renv Runtime environment
	 * @param name Name of service
	 * @param path Path to service binary
	 * @param handler Handler function to call when service generates output
	 * @param arg First argument to service
	 */
	Service(const RuntimeEnvironment *renv,
	        const char *name,
	        const char *path,
	        void (*handler)(void *,Service &,const Dictionary &),
	        void *arg);

	~Service();

	/**
	 * Send a message to service subprocess
	 *
	 * @param msg Message in key/value dictionary form
	 * @return True if message was sent
	 */
	bool send(const Dictionary &msg);

	/**
	 * @return Name of service
	 */
	inline const char *name() const
		throw()
	{
		return _name.c_str();
	}

	/**
	 * @return True if subprocess is running
	 */
	inline bool running() const
		throw()
	{
		return (_pid > 0);
	}

	/**
	 * Thread main method; do not call elsewhere
	 */
	void threadMain()
		throw();

private:
	const RuntimeEnvironment *_r;
	Thread _thread;
	std::string _path;
	std::string _name;
	void *_arg;
	void (*_handler)(void *,Service &,const Dictionary &);
	long _pid;
	int _childStdin;
	int _childStdout;
	int _childStderr;
	volatile bool _run;
};
#endif // __WINDOWS__

} // namespace ZeroTier

#endif