OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
nexthop_client.cc
Go to the documentation of this file.
1 /*
2  * Each object of NexthopDBClient class interacts with the master
3  * instance of NexthopDBServer and to the underlying (Unix socket) session
4  * connected to the client process:
5  *
6  * {RemoveNexthop()}
7  * {AddNexthop()} {Send()}
8  * [NexthopDBServer] ------ [NexthopDBClient] ----- [UnixDomainSocketSession]
9  * 1:n 1:1
10  */
11 #include <base/logging.h>
13 #include <pthread.h>
14 #include "rapidjson/document.h"
15 #include "rapidjson/stringbuffer.h"
16 #include "rapidjson/writer.h"
17 
18 NexthopDBClient::NexthopDBClient(UnixDomainSocketSession *session,
19  NexthopDBServer *server)
20  : nexthop_list_()
21 {
22  server_ = server;
23  session_ = session;
24  session_->set_observer(boost::bind(&NexthopDBClient::EventHandler, this,
25  _1, _2));
26 }
27 
29 {
30  for (NexthopListIterator iter = nexthop_list_.begin();
31  iter != nexthop_list_.end(); ++iter) {
32  nexthop_list_.erase (iter);
33  }
34 }
35 
36 void
37 NexthopDBClient::EventHandler(UnixDomainSocketSession *session,
39 {
40  if (event == UnixDomainSocketSession::READY) {
41  WriteMessage();
42  } else if (event == UnixDomainSocketSession::CLOSE) {
43  LOG (DEBUG, "[NexthopServer] Client " << session->session_id() <<
44  " closed session");
45  server_->RemoveClient(session->session_id());
46  }
47 }
48 
49 void
51 {
52  nexthop_list_.push_back(nh);
53 }
54 
55 void
57 {
58  for (NexthopListIterator iter = nexthop_list_.begin();
59  iter != nexthop_list_.end(); ++iter) {
60  if (*(*iter) == *nh) {
61  iter = nexthop_list_.erase(iter);
62  break;
63  }
64  }
65 }
66 
67 bool
69 {
70  for (NexthopListIterator iter = nexthop_list_.begin();
71  iter != nexthop_list_.end(); ++iter) {
72  if (*(*iter) == *nh) {
73  return true;
74  }
75  }
76  return false;
77 }
78 
79 /* Caller should free the returned buffer */
80 uint8_t *
82 {
83  contrail_rapidjson::StringBuffer s;
84  contrail_rapidjson::Writer <contrail_rapidjson::StringBuffer> writer(s);
85 
86  writer.StartObject();
87 
88  int pdu_len = 0;
89 
90  for (NexthopListIterator iter = nexthop_list_.begin();
91  iter != nexthop_list_.end();) {
92  NexthopDBEntry::NexthopPtr tnh = *iter;
93 
94  if ((pdu_len + tnh->EncodedLength()) >
95  UnixDomainSocketSession::kPDUDataLen) {
96  break;
97  }
98 
99  writer.String((tnh->nexthop_string()).c_str());
100  writer.StartObject();
101  const char *action = (tnh->state() ==
102  NexthopDBEntry::NEXTHOP_STATE_DELETED) ? "del" : "add";
103  writer.String("action");
104  writer.String(action);
105  writer.EndObject();
106 
107  pdu_len += tnh->EncodedLength();
108 
109  iter = nexthop_list_.erase(iter);
110  }
111 
112  writer.EndObject();
113 
114  /* Nothing to consume? */
115  if (!pdu_len) {
116  return NULL;
117  }
118 
119  const char *nhdata = s.GetString();
120  int nhlen = strlen(nhdata);
121  u_int8_t *out_data = new u_int8_t[nhlen + 4];
122  out_data[0] = (unsigned char) (nhlen >> 24);
123  out_data[1] = (unsigned char) (nhlen >> 16);
124  out_data[2] = (unsigned char) (nhlen >> 8);
125  out_data[3] = (unsigned char) nhlen;
126  memcpy(&out_data[4], nhdata, nhlen);
127  *data_len = nhlen + 4;
128  return out_data;
129 }
130 
131 void
133 {
134  uint8_t *data = NULL;
135  int data_len;
136 
137  while(1) {
138  data_len = 0;
139  data = NextMessage(&data_len);
140  if (!data || !data_len) {
141  break;
142  }
143 
144  /*
145  * Send always succeeds
146  */
147  session_->Send(data, data_len);
148  delete [] data;
149  }
150 }
std::vector< NexthopDBEntry::NexthopPtr >::iterator NexthopListIterator
boost::shared_ptr< NexthopDBEntry > NexthopPtr
Definition: nexthop_entry.h:25
uint8_t * NextMessage(int *length)
void RemoveNexthop(NexthopDBEntry::NexthopPtr nh)
NexthopDBServer * server_
Event
Definition: http_client.h:27
void EventHandler(UnixDomainSocketSession *, UnixDomainSocketSession::Event)
void AddNexthop(NexthopDBEntry::NexthopPtr nh)
#define LOG(_Level, _Msg)
Definition: logging.h:33
bool FindNexthop(NexthopDBEntry::NexthopPtr nh)
NexthopList nexthop_list_
void RemoveClient(uint64_t)
NexthopDBClient(UnixDomainSocketSession *session, NexthopDBServer *server)
UnixDomainSocketSession * session_