15 #include <boost/foreach.hpp>
16 #include <boost/random/mersenne_twister.hpp>
25 communicator_(communicator),
26 session_manager_(
evm),
63 LOG(ERROR, __func__ <<
"Cannot find session: " <<
74 for (Sessions::iterator it =
sessions_.begin(), next;
88 switch (event->
type) {
119 if (session_bydesc && session_bydesc->
Stats().
rx_count == 0) {
124 if (!session_bykey) {
125 if ((session_bydesc->
key()).local_address ==
127 LOG(ERROR, __func__ <<
" SRC-ADDR Changed, on Peer:" <<
129 "on Agent:" << (session_bydesc->
key()).remote_address.to_string());
132 LOG(ERROR, __func__ <<
" Session from Key NULL: " <<
140 LOG(ERROR, __func__ <<
" DISC -> Session MISMATCH: " <<
144 LOG(ERROR,
"PACKET Your_Discriminator mapped session: " <<
149 return session_bydesc;
181 const boost::asio::ip::udp::endpoint &local_endpoint,
182 const boost::asio::ip::udp::endpoint &remote_endpoint,
184 const boost::asio::const_buffer &recv_buffer,
185 std::size_t bytes_transferred,
const boost::system::error_code& error) {
187 session_index, recv_buffer, bytes_transferred));
192 LOG(ERROR, __func__ <<
"Wrong packet size: " <<
198 boost::asio::buffer_cast<const uint8_t *>(event->
recv_buffer),
200 if (packet == NULL) {
201 LOG(ERROR, __func__ <<
"Unable to parse packet");
204 packet->local_endpoint =
event->local_endpoint;
205 packet->remote_endpoint =
event->remote_endpoint;
206 packet->session_index =
event->session_index;
208 delete[] boost::asio::buffer_cast<const uint8_t *>(event->
recv_buffer);
213 result = packet->
Verify();
215 LOG(ERROR,
"Wrong packet: " << result);
220 if (session == NULL) {
221 LOG(ERROR,
"Unknown session: " <<
229 LOG(ERROR,
"Unable to process session: result " << result
230 <<
", session: " << session->
toString());
241 assignedDiscriminator);
250 DiscriminatorSessionMap::const_iterator it =
258 KeySessionMap::const_iterator it = by_key_.find(key);
259 return it != by_key_.end() ? it->second : NULL;
263 KeySessionMap::const_iterator it = by_key_.find(key);
264 return it != by_key_.end() ? it->second : NULL;
270 if (session == NULL) {
271 LOG(DEBUG, __FUNCTION__ <<
" No such session: " << key.
to_string());
275 if (!--refcounts_[session]) {
291 LOG(INFO, __func__ <<
": UpdateConfig : "
298 *assignedDiscriminator = GenerateUniqueDiscriminator();
299 session =
new Session(*assignedDiscriminator, key,
evm_, config,
302 by_discriminator_[*assignedDiscriminator] = session;
303 by_key_[key] = session;
304 refcounts_[session] = 1;
306 LOG(INFO, __func__ <<
": New session configured: " << key.
to_string() <<
"/"
307 << *assignedDiscriminator);
313 class DiscriminatorGenerator {
315 DiscriminatorGenerator() {
316 next_ = gen()%0x1000000 + 1;
320 return next_.fetch_add(1);
324 std::atomic<Discriminator> next_;
325 boost::random::mt19937 gen;
328 static DiscriminatorGenerator generator;
330 return generator.Next();
334 for (DiscriminatorSessionMap::iterator it = by_discriminator_.begin();
335 it != by_discriminator_.end(); ++it) {
virtual void SetServer(Server *server)=0
Session * SessionByKey(const SessionKey &key)
ResultCode ConfigureSession(const SessionKey &key, const SessionConfig &config, Connection *communicator, Discriminator *assignedDiscriminator)
Discriminator GenerateUniqueDiscriminator()
Session * SessionByDiscriminator(Discriminator discriminator)
DiscriminatorSessionMap by_discriminator_
ResultCode RemoveSessionReference(const SessionKey &key)
ResultCode ProcessControlPacketActual(const ControlPacket *packet)
bool EventCallback(Event *event)
SessionManager session_manager_
void DeleteClientSessions()
boost::scoped_ptr< WorkQueue< Event * > > event_queue_
void AddSession(const SessionKey &key, const SessionConfig &config, ChangeCb cb)
ResultCode ConfigureSession(const SessionKey &key, const SessionConfig &config, Discriminator *assignedDiscriminator)
Session * SessionByKey(const boost::asio::ip::address &address, const SessionIndex &index=SessionIndex())
Server(EventManager *evm, Connection *communicator)
Session * GetSession(const ControlPacket *packet)
Connection * communicator_
void EnqueueEvent(Event *event)
void DeleteSession(const SessionKey &key)
@ DELETE_CLIENT_CONNECTIONS
Connection * communicator() const
ResultCode RemoveSessionReference(const SessionKey &key)
void ProcessControlPacket(const boost::asio::ip::udp::endpoint &local_endpoint, const boost::asio::ip::udp::endpoint &remote_endpoint, const SessionIndex &session_index, const boost::asio::const_buffer &recv_buffer, std::size_t bytes_transferred, const boost::system::error_code &error)
ResultCode ProcessControlPacket(const ControlPacket *packet)
void UpdateConfig(const SessionConfig &config)
void RegisterChangeCallback(ClientId client_id, ChangeCb cb)
BFDState local_state() const
std::string toString() const
Discriminator local_discriminator() const
const SessionKey & key() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
#define LOG(_Level, _Msg)
ControlPacket * ParseControlPacket(const uint8_t *data, size_t size)
boost::function< void(const SessionKey &key, const BFD::BFDState &state)> ChangeCb
@ kResultCode_UnknownSession
const int kMinimalPacketLength
boost::asio::ip::udp::endpoint local_endpoint
boost::asio::ip::udp::endpoint remote_endpoint
BFD::Discriminator receiver_discriminator
SessionIndex session_index
ResultCode Verify() const
std::size_t bytes_transferred
const boost::asio::const_buffer recv_buffer
const std::string to_string() const
#define CHECK_CONCURRENCY(...)