forked from dyninc/OpenBFDD
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Beacon.h
285 lines (244 loc) · 8.34 KB
/
Beacon.h
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/**************************************************************
* Copyright (c) 2010-2013, Dynamic Network Services, Inc.
* Jake Montgomery ([email protected]) & Tom Daly ([email protected])
* Distributed under the FreeBSD License - see LICENSE
***************************************************************/
/**
The main bfdd-beacon application.
*/
#pragma once
#include "Session.h"
#include "threads.h"
#include "hash_map.h"
#include "RecvMsg.h"
#include "SockAddr.h"
#include <deque>
#include <vector>
#include <set>
#include <list>
struct sockaddr_in;
namespace openbfdd
{
class Socket;
class Scheduler;
class Beacon
{
public:
Beacon();
~Beacon();
/**
* Start the beacon.
*
* @param controlPorts [in] - A list of address and port combinations on which
* to listen for control commands.
* @param listenAddrs [in] - A list of address on which to listen for new BDF
* sessions. 'ANY' is allowed.
*
*
* @return - false on failure
*/
bool Run(const std::list<SockAddr> &controlPorts, const std::list<IpAddr> &listenAddrs);
typedef void (*OperationCallback)(Beacon *beacon, void *userdata);
/**
* Queue up a shutdown.
*
* @Note can be called from any thread.
*
*/
void RequestShutdown();
/**
* Checks a shutdown has been requested and is pending.
*
* @Note can be called from any thread.
*
* @return bool
*/
bool IsShutdownRequested();
/**
* Queues a callback to occur on the main thread so that the beacon and sessions
* can be freely accessed. Be aware that the callback code will be blocking all
* BFD activity, so keep it brief. In addition, Check IsShutdownRequested() in
* your callback and exit as soon as possible if a shutdown was requested.
*
* @Note can be called from any thread.
*
* @param callback [in] - The callback.
* @param userdata [in]- The user data.
* @param waitForCompletion [in] - Should this thread sleep until the callback
* has been executed?
*
* @return bool - false if the operation was not queued because a shutdown had
* already been requested or memory failure.
*/
bool QueueOperation(OperationCallback callback, void *userdata, bool waitForCompletion);
/**
* Starts an active session for the given system. If there is already a session
* for the given system then this currently does nothing.
*
* TODO: should change an existing session from passive to active?
*
* @Note can only on the main thread.
*
* @param remoteAddr [in] - remote address.
* @param localAddr [in]- address on which to receive and send packets. .
*
* @return bool - false on failure. If there is already a session, then this
* returns true.
*/
bool StartActiveSession(const IpAddr &remoteAddr, const IpAddr &localAddr);
/**
* Allows us to accept connections from the given ip address.
*
* @Note can be called only on the main thread.
*
* @throw - yes.
*
*/
void AllowPassiveIP(const IpAddr &addr);
/**
* Stops us from accepting new connections from the given ip address.
* If AllowAllPassiveConnections() is enabled, then this is ignored.
*
* If there is already an active session for this IP, then it is not effected.
*
* @Note can be called only on the main thread.
*
*/
void BlockPassiveIP(const IpAddr &addr);
/**
* Allow or disallow accepting every invitation.
*
* @Note can be called only on the main thread.
*
* @param allow
*/
void AllowAllPassiveConnections(bool allow);
/**
* Find Session by discriminator.
*
* @Note can be called only on the main thread.
*
* @return Session* - NULL on failure
*/
Session* FindSessionId(uint32_t id);
/**
* Find Session by remote and local ip.
*
* @Note can be called only on the main thread.
*
* @param remoteAddr [in] - Port ignored
* @param localAddr [in] - Port ignored
*
* @return Session* - NULL on failure
*/
Session* FindSessionIp(const IpAddr &remoteAddr, const IpAddr &localAddr);
/**
* Clears and fill the vector with all the sessions.
*
* @Note can be called only on the main thread.
*
* @throw - yes
*
* @param outList
*/
void GetSessionIdList(std::vector<uint32_t> &outList);
/**
* Will delete the session.
*
* @Note can be called only on the main thread.
*
* Session must be from this beacon.
*/
void KillSession(Session *session);
/**
* Sets the DectectMulti for future sessions.
*
* @Note can be called only on the main thread.
*/
void SetDefMulti(uint8_t val);
/**
* Sets the 'default' DesiredMinTXInterval state variable for future sessions.
*
* @Note can be called only on the main thread.
*/
void SetDefMinTxInterval(uint32_t val);
/**
* Sets the 'default' RequiredMinTXInterval state variable for future sessions.
*
* @Note can be called only on the main thread.
*/
void SetDefMinRxInterval(uint32_t val);
/**
* Changes the default C bit value on for future sessions.
*
* @Note can be called only on the main thread.
*/
void SetDefControlPlaneIndependent(bool cpi);
/**
* Enables or disables a workaround that allows fast Up->AdminDown->Up
* transitions.
*
* @Note can be called only on the main thread.
*
* @param enable
*/
void SetDefAdminUpPollWorkaround(bool enable);
private:
void makeListenSocket(const IpAddr &listenAddr, Socket &outSocket);
static void handleListenSocketCallback(int socket, void *userdata);
void handleListenSocket(Socket &socket);
static void handleSelfMessageCallback(int sigId, void *userdata) { reinterpret_cast<Beacon *>(userdata)->handleSelfMessage(sigId);}
void handleSelfMessage(int sigId);
uint32_t makeUniqueDiscriminator();
bool triggerSelfMessage();
Session* addSession(const IpAddr &remoteAddr, const IpAddr &localAddr);
Session* findInSourceMap(const IpAddr &remoteAddr, const IpAddr &localAddr);
private:
struct SourceMapKey
{
SourceMapKey(IpAddr remoteAddr, IpAddr localAddr) : remoteAddr(remoteAddr), localAddr(localAddr) { }
IpAddr remoteAddr;
IpAddr localAddr;
bool operator==(const SourceMapKey &other) const { return remoteAddr == other.remoteAddr && localAddr == other.localAddr;}
struct hasher
{size_t operator()(const SourceMapKey &me) const { return me.remoteAddr.hash() + me.localAddr.hash();}
};
};
typedef hash_map<uint32_t, class Session *>::Type DiscMap;
typedef DiscMap::iterator DiscMapIt;
typedef hash_map<SourceMapKey, class Session *, SourceMapKey::hasher>::Type SourceMap;
typedef SourceMap::iterator SourceMapIt;
typedef hash_map<uint32_t, class Session *>::Type IdMap;
typedef IdMap::iterator IdMapIt;
// Used to queue up operation
struct PendingOperation
{
inline PendingOperation() : callback(NULL) { }
OperationCallback callback;
void *userdata;
bool completed;
class WaitCondition *waitCondition; // lock with m_paramsLock
};
typedef std::deque<Beacon::PendingOperation *> OperationQueue;
// All items in this block are used only in the Scheduler thread, so no
// locking needed
//
Scheduler *m_scheduler; // This is only valid after Run() is called.
RecvMsg m_packet;
DiscMap m_discMap; // Your Discriminator -> Session
IdMap m_IdMap; // Human readable session id -> Session
SourceMap m_sourceMap; // ip/ip -> Session
std::set<IpAddr, IpAddr::LessClass> m_allowedPassiveIP;
bool m_allowAnyPassiveIP;
bool m_strictPorts; // Should incoming ports be limited as described in draft-ietf-bfd-v4v6-1hop-11.txt
Session::InitialParams m_initialSessionParams;
// These items are set at startup, so no locking is needed.
int m_selfSignalId;
// m_paramsLock locks the parameters that can be adjusted externally. All items
// in this block are protected by this lock.
//
QuickLock m_paramsLock;
bool m_shutownRequested;
OperationQueue m_operations;
};
}