Line data Source code
1 : /*
2 : * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef SRC_BFD_BFD_SERVER_H_
6 : #define SRC_BFD_BFD_SERVER_H_
7 :
8 : #include "base/queue_task.h"
9 : #include "bfd/bfd_common.h"
10 :
11 : #include <map>
12 : #include <set>
13 : #include <boost/asio.hpp>
14 : #include <boost/asio/ip/address.hpp>
15 : #include <boost/scoped_ptr.hpp>
16 :
17 : class EventManager;
18 :
19 : namespace BFD {
20 : class Connection;
21 : class Session;
22 : struct ControlPacket;
23 : struct SessionConfig;
24 :
25 : typedef std::set<SessionKey> Sessions;
26 :
27 : // This class manages sessions with other BFD peers.
28 : class Server {
29 : struct Event;
30 : public:
31 : Server(EventManager *evm, Connection *communicator);
32 : virtual ~Server();
33 : ResultCode ProcessControlPacketActual(const ControlPacket *packet);
34 : void ProcessControlPacket(
35 : const boost::asio::ip::udp::endpoint &local_endpoint,
36 : const boost::asio::ip::udp::endpoint &remote_endpoint,
37 : const SessionIndex &session_index,
38 : const boost::asio::const_buffer &recv_buffer,
39 : std::size_t bytes_transferred, const boost::system::error_code& error);
40 :
41 : // If a BFD session with specified [remoteHost] already exists, its
42 : // configuration is updated with [config], otherwise it gets created.
43 : // ! TODO implement configuration update
44 : ResultCode ConfigureSession(const SessionKey &key,
45 : const SessionConfig &config,
46 : Discriminator *assignedDiscriminator);
47 :
48 : // Instances of BFD::Session are removed after last IP address
49 : // reference is gone.
50 : ResultCode RemoveSessionReference(const SessionKey &key);
51 : Session *SessionByKey(const boost::asio::ip::address &address,
52 : const SessionIndex &index = SessionIndex());
53 : Session *SessionByKey(const SessionKey &key);
54 : Session *SessionByKey(const SessionKey &key) const;
55 : Connection *communicator() const { return communicator_; }
56 : void AddSession(const SessionKey &key, const SessionConfig &config,
57 : ChangeCb cb);
58 : void DeleteSession(const SessionKey &key);
59 : void DeleteClientSessions();
60 8 : Sessions *GetSessions() { return &sessions_; }
61 45 : WorkQueue<Event *> *event_queue() { return event_queue_.get(); }
62 :
63 : private:
64 : class SessionManager : boost::noncopyable {
65 : public:
66 20 : explicit SessionManager(EventManager *evm) : evm_(evm) {}
67 : ~SessionManager();
68 :
69 : ResultCode ConfigureSession(const SessionKey &key,
70 : const SessionConfig &config,
71 : Connection *communicator,
72 : Discriminator *assignedDiscriminator);
73 :
74 : // see: Server:RemoveSessionReference
75 : ResultCode RemoveSessionReference(const SessionKey &key);
76 :
77 : Session *SessionByDiscriminator(Discriminator discriminator);
78 : Session *SessionByKey(const SessionKey &key);
79 : Session *SessionByKey(const SessionKey &key) const;
80 :
81 : private:
82 : typedef std::map<Discriminator, Session *> DiscriminatorSessionMap;
83 : typedef std::map<SessionKey, Session *> KeySessionMap;
84 : typedef std::map<Session *, unsigned int> RefcountMap;
85 :
86 : Discriminator GenerateUniqueDiscriminator();
87 :
88 : EventManager *evm_;
89 : DiscriminatorSessionMap by_discriminator_;
90 : KeySessionMap by_key_;
91 : RefcountMap refcounts_;
92 : };
93 :
94 : enum EventType {
95 : BEGIN_EVENT,
96 : ADD_CONNECTION = BEGIN_EVENT,
97 : DELETE_CONNECTION,
98 : DELETE_CLIENT_CONNECTIONS,
99 : PROCESS_PACKET,
100 : END_EVENT = PROCESS_PACKET,
101 : };
102 :
103 : struct Event {
104 28 : Event(EventType type, const SessionKey &key,
105 28 : const SessionConfig &config, ChangeCb cb) :
106 28 : type(type), key(key), config(config), cb(cb) {
107 28 : }
108 25 : Event(EventType type, const SessionKey &key) :
109 25 : type(type), key(key) {
110 25 : }
111 118 : Event(EventType type, boost::asio::ip::udp::endpoint local_endpoint,
112 : boost::asio::ip::udp::endpoint remote_endpoint,
113 : const SessionIndex &session_index,
114 : const boost::asio::const_buffer &recv_buffer,
115 118 : std::size_t bytes_transferred) :
116 118 : type(type), local_endpoint(local_endpoint),
117 118 : remote_endpoint(remote_endpoint), session_index(session_index),
118 118 : recv_buffer(recv_buffer), bytes_transferred(bytes_transferred) {
119 118 : }
120 18 : Event(EventType type) : type(type) {
121 18 : }
122 :
123 : EventType type;
124 : SessionKey key;
125 : SessionConfig config;
126 : ChangeCb cb;
127 : boost::asio::ip::udp::endpoint local_endpoint;
128 : boost::asio::ip::udp::endpoint remote_endpoint;
129 : const SessionIndex session_index;
130 : const boost::asio::const_buffer recv_buffer;
131 : std::size_t bytes_transferred;
132 : };
133 :
134 : void AddSession(Event *event);
135 : void DeleteSession(Event *event);
136 : void DeleteClientSessions(Event *event);
137 : void ProcessControlPacket(Event *event);
138 : void EnqueueEvent(Event *event);
139 : bool EventCallback(Event *event);
140 :
141 : Session *GetSession(const ControlPacket *packet);
142 :
143 : EventManager *evm_;
144 : Connection *communicator_;
145 : SessionManager session_manager_;
146 : boost::scoped_ptr<WorkQueue<Event *> > event_queue_;
147 : Sessions sessions_;
148 : };
149 :
150 : } // namespace BFD
151 :
152 : #endif // SRC_BFD_BFD_SERVER_H_
|