summaryrefslogtreecommitdiff
path: root/node/Demarc.hpp
blob: 767cc864a96a732d8b76ea92763a2375e42d4d65 (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
/*
 * ZeroTier One - Global Peer to Peer Ethernet
 * Copyright (C) 2012-2013  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_DEMARC_HPP
#define _ZT_DEMARC_HPP

#include <stdlib.h>
#include <stdint.h>

#include <map>
#include <string>

#include "Mutex.hpp"
#include "InetAddress.hpp"

namespace ZeroTier {

class RuntimeEnvironment;
class UdpSocket;

/**
 * Local demarcation point
 *
 * This holds and provides unique identifiers for all local communication
 * endpoints, such as UDP sockets, raw Ethernet sockets, tunnels to a relay
 * server, etc. It permits other code to refer to these via Port and forget
 * about what they actually are.
 *
 * All ports are closed when this class is destroyed.
 *
 * Its name "demarcation point" comes from the telco/cable terminology for
 * the box where wires terminate at a customer's property.
 */
class Demarc
{
public:
	/**
	 * Local demarcation port
	 */
	typedef uint64_t Port;

	/**
	 * Port identifier used to refer to any port
	 */
	static const Port ANY_PORT;

	/**
	 * Port identifier used to refer to null port / port not found
	 */
	static const Port NULL_PORT;

	Demarc(const RuntimeEnvironment *renv);
	~Demarc();

	/**
	 * Describe a port
	 *
	 * This can describe even ports that are not bound, e.g. from serialized
	 * data.
	 *
	 * @param p Port
	 * @return Human-readable description of port
	 */
	static std::string describe(Port p);

	/**
	 * @param p Port to check
	 * @return True if this port is bound/connected/etc.
	 */
	bool has(Port p) const
		throw();

	/**
	 * Bind local UDP port for both IPv4 and IPv6 traffic
	 *
	 * @param localPort Local IP port
	 * @return True if successfully bound, or if already bound
	 */
	bool bindLocalUdp(unsigned int localPort)
		throw();

	/**
	 * Pick a port to send to an address of a given type
	 *
	 * @param to Destination address
	 * @return Port or NULL_PORT if none
	 */
	Port pick(const InetAddress &to) const
		throw();

	/**
	 * Send a packet
	 *
	 * If fromPort is ANY_PORT or if the port is not found, a random port is
	 * chosen from those available matching the characteristics of the address
	 * in 'to'.
	 *
	 * @param fromPort Port to send from
	 * @param to Destination IP/port
	 * @param data Data to send
	 * @param len Length of data in bytes
	 * @param hopLimit IP hop limit for UDP packets or -1 for max/unlimited
	 * @return Port actually sent from or NULL_PORT on failure
	 */
	Port send(Port fromPort,const InetAddress &to,const void *data,unsigned int len,int hopLimit) const
		throw();

	/**
	 * @param p Port
	 * @return 64-bit integer suitable for serialization
	 */
	static inline uint64_t portToInt(const Port p) throw() { return (uint64_t)p; }

	/**
	 * @param p 64-bit integer from serialized representation
	 * @return Port suitable for use in code
	 */
	static inline Port intToPort(const uint64_t p) throw() { return (Port)p; }

private:
	const RuntimeEnvironment *_r;

	static void _CBudpSocketPacketHandler(UdpSocket *sock,void *arg,const InetAddress &from,const void *data,unsigned int len);

	enum DemarcPortType
	{
		PORT_TYPE_UDP_SOCKET_V4 = 1,
		PORT_TYPE_UDP_SOCKET_V6 = 2,
		PORT_TYPE_LOCAL_ETHERNET = 3,
		PORT_TYPE_RELAY_TUNNEL = 4
	};

	// Variant holding instances of UdpSocket, etc.
	struct DemarcPortObj
	{
		Demarc::Port port;
		Demarc *parent;
		void *obj;
		DemarcPortType type;
	};

	std::map< Port,DemarcPortObj > _ports;
	Mutex _ports_m;
};

} // namespace ZeroTier

#endif