OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
nexthop_server.cc
Go to the documentation of this file.
1 /*
2  * NexthopDBServer maintains two primary data structures:
3  * (1) nexthop_table: a std::map DB of nexthop entries (NexthopDBEntry)
4  * keyed through a string representation of the nexthop address.
5  * (2) client_table: a std::map DB of client entries (NexthopDBClient)
6  * keyed through the session_id of the underlying session
7  * (UnixDomainSocketSession).
8  */
9 #include <base/logging.h>
10 #include "nexthop_client.h"
11 #include "nexthop_server.h"
12 #include <pthread.h>
13 #include "rapidjson/document.h"
14 #include "rapidjson/stringbuffer.h"
15 #include "rapidjson/writer.h"
16 
17 NexthopDBServer::NexthopDBServer(boost::asio::io_context &io,
18  const std::string &path)
19  : io_service_(io), endpoint_path_(path), nexthop_table_(), client_table_()
20 {
21  std::remove(endpoint_path_.c_str());
22  io_server_.reset(new UnixDomainSocketServer(&io_service_, endpoint_path_));
23  io_server_->set_observer(boost::bind(&NexthopDBServer::EventHandler, this,
24  _1, _2, _3));
25 }
26 
27 void
29 {
30  io_service_.run();
31 }
32 
33 void
34 NexthopDBServer::EventHandler(UnixDomainSocketServer * server,
35  UnixDomainSocketSession * session,
37 {
38  tbb::mutex::scoped_lock lock(mutex_);
39  if (event == UnixDomainSocketServer::NEW_SESSION) {
40  NexthopDBClient::ClientPtr cl(new NexthopDBClient(session, this));
41  AddClient(cl);
42  } else if (event == UnixDomainSocketServer::DELETE_SESSION) {
43  NexthopDBClient::ClientPtr cl = client_table_[session->session_id()];
44  if (cl) {
45  RemoveClient(session->session_id());
46  }
47  }
48 }
49 
50 void
52 {
53  /* Add client to the client table */
54  assert (client_table_[cl->session_->session_id()] == NULL);
55  client_table_[cl->session_->session_id()] = cl;
56 
57  /* Build the client's nexthop list */
58  for (NexthopIterator iter = nexthop_table_.begin();
59  iter != nexthop_table_.end(); ++iter) {
60  if (iter->second) {
61  cl->AddNexthop(iter->second);
62  }
63  }
64 
65  cl->WriteMessage();
66  LOG (DEBUG, "[NexthopServer] New client: " << cl->session_->session_id());
67 }
68 
69 void
70 NexthopDBServer::RemoveClient(uint64_t session_id)
71 {
72  LOG (DEBUG, "[NexthopServer] Remove client " << session_id);
73  client_table_.erase(session_id);
74 }
75 
76 void
78 {
79  for (ClientIterator iter = client_table_.begin();
80  iter != client_table_.end(); ++iter) {
81  iter->second->WriteMessage();
82  }
83 }
84 
85 void
87 {
88  for (ClientIterator iter = client_table_.begin();
89  iter != client_table_.end(); ++iter) {
90  iter->second->AddNexthop(nh);
91  }
92 }
93 
95 NexthopDBServer::FindOrCreateNexthop(const std::string &nh_str)
96 {
97  tbb::mutex::scoped_lock lock (mutex_);
98 
99  /*
100  * Does the nexthop exist? If so, return.
101  */
102  if (nexthop_table_[nh_str] != NULL) {
103  return nexthop_table_[nh_str];
104  }
105 
107  nexthop_table_[nh_str] = nh;
108 
109  /*
110  * Add the nexthop to the tail of each client's announce list and trigger
111  * clients so they are notified of the new nexthop.
112  */
113  AddNexthop(nh);
114  TriggerClients();
115  return nh;
116 }
117 
118 void
120 {
121  tbb::mutex::scoped_lock lock(mutex_);
122 
123  if (nexthop_table_[str] == NULL) {
124  return;
125  }
127  RemoveNexthop(nh);
128  nexthop_table_.erase(str);
129  TriggerClients();
130 }
131 
132 void
134 {
136  for (ClientIterator iter = client_table_.begin();
137  iter != client_table_.end(); ++iter) {
138  if (!iter->second->FindNexthop(nh)) {
139  iter->second->AddNexthop(nh);
140  }
141  }
142 }
ClientDB client_table_
void AddClient(NexthopDBClient::ClientPtr cl)
boost::scoped_ptr< UnixDomainSocketServer > io_server_
boost::shared_ptr< NexthopDBEntry > NexthopPtr
Definition: nexthop_entry.h:25
void FindAndRemoveNexthop(const std::string &str)
void AddNexthop(NexthopDBEntry::NexthopPtr nh)
boost::shared_ptr< NexthopDBClient > ClientPtr
void EventHandler(UnixDomainSocketServer *, UnixDomainSocketSession *, UnixDomainSocketServer::Event)
std::map< uint64_t, NexthopDBClient::ClientPtr >::iterator ClientIterator
Event
Definition: http_client.h:27
NexthopDBEntry::NexthopPtr FindOrCreateNexthop(const std::string &str)
void RemoveNexthop(NexthopDBEntry::NexthopPtr nh)
std::string endpoint_path_
NexthopDB nexthop_table_
boost::asio::io_context & io_service_
#define LOG(_Level, _Msg)
Definition: logging.h:33
void RemoveClient(uint64_t)
std::map< std::string, NexthopDBEntry::NexthopPtr >::iterator NexthopIterator
NexthopDBServer(boost::asio::io_context &io, const std::string &path)
tbb::mutex mutex_