OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tcp_server.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "io/tcp_server.h"
6 
7 #include <errno.h>
8 
9 #include <boost/asio/connect.hpp>
10 #include <boost/asio/placeholders.hpp>
11 #include <boost/bind.hpp>
12 #include <netinet/tcp.h>
13 
14 #include "base/logging.h"
15 #include "io/event_manager.h"
16 #include "io/tcp_session.h"
17 #include "io/io_log.h"
18 #include "io/io_utils.h"
19 
20 using boost::asio::ip::address;
21 using boost::asio::ip::tcp;
22 using boost::asio::placeholders::error;
23 using boost::asio::socket_base;
24 using boost::bind;
25 using boost::system::error_code;
26 
27 using boost::asio::socket_base;
28 using std::ostringstream;
29 using std::string;
30 
32  : evm_(evm), socket_open_failure_(false), intf_id_(-1) {
33  refcount_ = 0;
35 }
36 
37 // TcpServer delete procedure:
38 // 1. Shutdown() to stop accepting incoming sessions.
39 // 2. Close and terminate current sessions. ASIO callbacks maybe in-flight.
40 // 3. Optionally: WaitForEmpty().
41 // 4. Destroy TcpServer.
43  assert(acceptor_ == NULL);
44  assert(session_ref_.empty());
45  assert(session_map_.empty());
46 }
47 
49  ostringstream out;
50  out << local_endpoint;
51  name_ = out.str();
52 }
53 
55  acceptor_.reset();
56  name_ = "";
57 }
58 
59 bool TcpServer::Initialize(unsigned short port) {
60  intf_id_ = -1; //this initializer is only for IPv4
61  tcp::endpoint localaddr(tcp::v4(), port);
62  return InitializeInternal(localaddr);
63 }
64 
65 bool TcpServer::Initialize(unsigned short port,
66  const IpAddress &host_ip,
67  int intf_id) {
68  tcp::endpoint localaddr(host_ip, port);
69  tcp::endpoint serv_ep(host_ip, port);
70  intf_id_ = intf_id;
71  if (host_ip.is_v6()) {
72  Ip6Address ipaddr = host_ip.to_v6();
73  if (intf_id_ > 0) {
74  ipaddr.scope_id(this->intf_id_);
75  serv_ep.address(ipaddr);
76  }
77  }
78  return InitializeInternal(serv_ep);
79 }
80 
81 bool TcpServer::InitializeInternal(tcp::endpoint localaddr) {
82  acceptor_.reset(new tcp::acceptor(*evm_->io_service()));
83  if (!acceptor_) {
84  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "Cannot create acceptor");
85  return false;
86  }
87 
88  error_code ec;
89  if (localaddr.address().is_v4())
90  acceptor_->open(tcp::v4(), ec);
91  else
92  acceptor_->open(tcp::v6(), ec);
93 
94  if (ec) {
95  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "TCP open: " << ec.message());
96  ResetAcceptor();
97  return false;
98  }
99 
100  acceptor_->set_option(socket_base::reuse_address(true), ec);
101  if (ec) {
102  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "TCP reuse_address: "
103  << ec.message());
104  ResetAcceptor();
105  return false;
106  }
107 
108  acceptor_->bind(localaddr, ec);
109  if (ec) {
110  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "TCP bind(" << localaddr.address() <<
111  ":" << localaddr.port() << "): " << ec.message());
112  ResetAcceptor();
113  return false;
114  }
115 
116  tcp::endpoint local_endpoint = acceptor_->local_endpoint(ec);
117  if (ec) {
119  "Cannot retrieve acceptor local-endpont");
120  ResetAcceptor();
121  return false;
122  }
123 
124  //
125  // Server name can be set after local-endpoint information is available.
126  //
127  SetName(local_endpoint);
128 
129  acceptor_->listen(socket_base::max_connections, ec);
130  if (ec) {
131  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "TCP listen(" << localaddr.port() <<
132  "): " << ec.message());
133  ResetAcceptor();
134  return false;
135  }
136 
137  TCP_SERVER_LOG_DEBUG(this, TCP_DIR_NA, "Initialization complete");
138  AsyncAccept();
139 
140  return true;
141 }
142 
144  tbb::mutex::scoped_lock lock(mutex_);
145  error_code ec;
146 
147  if (acceptor_) {
148  acceptor_->close(ec);
149  if (ec) {
150  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "Error during shutdown: "
151  << ec.message());
152  }
153  ResetAcceptor();
154  }
155 }
156 
157 // Close and remove references from all sessions. The application code must
158 // make sure it no longer holds any references to these sessions.
160  tbb::mutex::scoped_lock lock(mutex_);
161  SessionSet refs;
162  refs.swap(session_ref_);
163  lock.release();
164 
165  for (SessionSet::iterator iter = refs.begin(), next = iter;
166  iter != refs.end(); iter = next) {
167  ++next;
168  TcpSession *session = iter->get();
169  session->Close();
170  }
171  refs.clear();
172  if (session_ref_.empty() && session_map_.empty()) {
173  cond_var_.notify_all();
174  }
175 }
176 
177 void TcpServer::UpdateSessionsDscp(uint8_t dscp) {
178  tbb::mutex::scoped_lock lock(mutex_);
179 
180  for (SessionSet::iterator iter = session_ref_.begin(), next = iter;
181  iter != session_ref_.end(); iter = next) {
182  ++next;
183  TcpSession *session = iter->get();
184  session->SetDscpSocketOption(dscp);
185  }
186 }
187 
189  TcpSession *session = AllocSession(false);
190  {
191  tbb::mutex::scoped_lock lock(mutex_);
192  session_ref_.insert(TcpSessionPtr(session));
193  }
194  return session;
195 }
196 
198  // The caller will typically close the socket before deleting the
199  // session.
200  session->Close();
201  {
202  tbb::mutex::scoped_lock lock(mutex_);
203  assert(session->refcount_);
204  session_ref_.erase(TcpSessionPtr(session));
205  if (session_ref_.empty() && session_map_.empty()) {
206  cond_var_.notify_all();
207  }
208  }
209 }
210 
211 //
212 // Insert into SessionMap.
213 // Assumes that caller has the mutex.
214 //
216  session_map_.insert(make_pair(remote, session));
217 }
218 
219 //
220 // Remove from SessionMap.
221 // Assumes that caller has the mutex.
222 // Return true if the session is found.
223 //
225  for (SessionMap::iterator iter = session_map_.find(remote);
226  iter != session_map_.end() && iter->first == remote; ++iter) {
227  if (iter->second == session) {
228  session_map_.erase(iter);
229  return true;
230  }
231  }
232  return false;
233 }
234 
236  tbb::mutex::scoped_lock lock(mutex_);
237 
238  // CloseSessions closes and removes all the sessions from the map.
239  if (session_map_.empty()) {
240  return;
241  }
242 
243  bool found = RemoveSessionFromMap(session->remote_endpoint(), session);
244  if (session_map_.empty() && session_ref_.empty()) {
245  cond_var_.notify_all();
246  }
247  assert(found);
248 }
249 
250 // This method ensures that the application code requested the session to be
251 // deleted (which may be a delayed action). It does not guarantee that the
252 // session object has actually been freed yet as ASIO callbacks can be in
253 // progress.
255  tbb::interface5::unique_lock<tbb::mutex> lock(mutex_);
256  while (!session_ref_.empty() || !session_map_.empty()) {
257  cond_var_.wait(lock);
258  }
259 }
260 
262  tbb::mutex::scoped_lock lock(mutex_);
263  if (acceptor_ == NULL) {
264  return;
265  }
267  acceptor_->async_accept(*accept_socket(),
269  TcpServerPtr(this), error));
270 }
271 
272 int TcpServer::GetPort() const {
273  tbb::mutex::scoped_lock lock(mutex_);
274  if (acceptor_.get() == NULL) {
275  return -1;
276  }
277  error_code ec;
278  tcp::endpoint ep = acceptor_->local_endpoint(ec);
279  if (ec) {
280  return -1;
281  }
282  return ep.port();
283 }
284 
286  tbb::mutex::scoped_lock lock(mutex_);
287  return !session_map_.empty();
288 }
289 
291  tbb::mutex::scoped_lock lock(mutex_);
292  error_code error;
293  if (accept_socket()->available(error) > 0) {
294  return true;
295  }
296  for (SessionMap::const_iterator iter = session_map_.begin();
297  iter != session_map_.end();
298  ++iter) {
299  if (iter->second->socket()->available(error) > 0) {
300  return true;
301  }
302  }
303  return false;
304 }
305 
307  tbb::mutex::scoped_lock lock(mutex_);
308  if (acceptor_.get() == NULL) {
309  return Endpoint();
310  }
311  error_code ec;
312  Endpoint local = acceptor_->local_endpoint(ec);
313  if (ec) {
314  return Endpoint();
315  }
316  return local;
317 }
318 
319 TcpSession *TcpServer::AllocSession(bool server_session) {
320  TcpSession *session;
321  if (server_session) {
322  session = AllocSession(so_accept_.get());
323 
324  // if session allocate succeeds release ownership to so_accept.
325  if (session != NULL) {
326  so_accept_.release();
327  }
328  } else {
329  Socket *socket = new Socket(*evm_->io_service());
330  session = AllocSession(socket);
331  }
332 
333  return session;
334 }
335 
337  return so_accept_.get();
338 }
339 
341  so_accept_.reset(new Socket(*evm_->io_service()));
342 }
343 
345  return true;
346 }
347 
348 //
349 // concurrency: called from the event_manager thread.
350 //
351 // accept() tcp connections. Once done, must register with boost again
352 // via AsyncAccept() in order to process future accept calls
353 //
355  const error_code& error) {
356  tcp::endpoint remote;
357  error_code ec;
358  TcpSessionPtr session;
359  bool need_close = false;
360 
361  if (error) {
362  goto done;
363  }
364 
365  remote = accept_socket()->remote_endpoint(ec);
366  if (ec) {
368  "Accept: No remote endpoint: " << ec.message());
369  goto done;
370  }
371 
372  if (acceptor_ == NULL) {
374  "Session accepted after server shutdown: "
375  << remote.address().to_string()
376  << ":" << remote.port());
377  accept_socket()->close(ec);
378  goto done;
379  }
380 
381  session.reset(AllocSession(true));
382  if (session == NULL) {
383  TCP_SERVER_LOG_DEBUG(this, TCP_DIR_IN, "Session not created");
384  goto done;
385  }
386 
387  ec = session->SetSocketOptions();
388  if (ec) {
390  "Accept: Non-blocking error: " << ec.message());
391  need_close = true;
392  goto done;
393  }
394 
395  session->SessionEstablished(remote, TcpSession::PASSIVE);
396  AcceptHandlerComplete(session);
397 
398 done:
399  if (need_close) {
400  session->CloseInternal(ec, false, false);
401  }
402  AsyncAccept();
403 }
404 
406  tcp::endpoint remote = session->remote_endpoint();
407  {
408  tbb::mutex::scoped_lock lock(mutex_);
409  if (AcceptSession(session.get())) {
411  "Accepted session from "
412  << remote.address().to_string()
413  << ":" << remote.port());
414  session_ref_.insert(session);
415  InsertSessionToMap(remote, session.get());
416  } else {
418  "Rejected session from "
419  << remote.address().to_string()
420  << ":" << remote.port());
421  error_code ec;
422  session->CloseInternal(ec, false, false);
423  return;
424  }
425  }
426 
427  session->Accepted();
428 }
429 
431  tbb::mutex::scoped_lock lock(mutex_);
432  SessionMap::const_iterator iter = session_map_.find(remote);
433  if (iter != session_map_.end()) {
434  return iter->second;
435  }
436  return NULL;
437 }
438 
440  const error_code &error) {
441  if (error) {
443  "Connect failure: " << error.message());
444  session->ConnectFailed();
445  return;
446  }
447 
448  ConnectHandlerComplete(session);
449 }
450 
452  error_code ec;
453  Endpoint remote = session->socket()->remote_endpoint(ec);
454  if (ec) {
456  "Connect getsockaddr: " << ec.message());
457  session->ConnectFailed();
458  return;
459  }
460 
461  {
462  tbb::mutex::scoped_lock lock(mutex_);
463  InsertSessionToMap(remote, session.get());
464  }
465 
466  // Connected verifies whether the session has been closed or is still
467  // active.
468  if (!session->Connected(remote)) {
469  tbb::mutex::scoped_lock lock(mutex_);
470  RemoveSessionFromMap(remote, session.get());
471  }
472 }
473 
474 void TcpServer::Connect(TcpSession *session, Endpoint remote) {
475  assert(session->refcount_);
476  Socket *socket = session->socket();
477  socket->async_connect(remote,
478  bind(&TcpServer::ConnectHandler, this, TcpServerPtr(this),
479  TcpSessionPtr(session), error));
480 }
481 
483  const string &md5_password) {
484  assert(md5_password.size() <= TCP_MD5SIG_MAXKEYLEN);
485  if (!peer_ip) {
486  TCP_SERVER_LOG_ERROR(this, TCP_DIR_NA, "Invalid peer IP");
487  return 0;
488  }
489 
490  struct sockaddr_in local_addr;
491  memset(&local_addr, 0, sizeof(local_addr));
492 
493  local_addr.sin_family = AF_INET;
494  local_addr.sin_addr.s_addr = htonl(peer_ip);
495 
496  struct tcp_md5sig md5sig;
497  memset(&md5sig, 0, sizeof (md5sig));
498 
499  memcpy(md5sig.tcpm_key, md5_password.c_str(), md5_password.size());
500  md5sig.tcpm_keylen = md5_password.size();
501  memcpy(&md5sig.tcpm_addr, &local_addr, sizeof(local_addr));
502  int retval = setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, (const char *)&md5sig,
503  sizeof(md5sig));
504  if (retval < 0) {
506  "Failure in setting md5 key on the socket " +
507  integerToString(fd) + " for peer " + integerToString(peer_ip) +
508  " with errno " + strerror(errno));
509  } else {
511  "Success in setting md5 key on the socket " +
512  integerToString(fd) + " for peer " + integerToString(peer_ip));
513  }
514  return retval;
515 }
516 
518  const string &md5_password) {
519  int retval = 0;
520  if (acceptor_) {
521  retval = SetMd5SocketOption(acceptor_->native_handle(), peer_ip,
522  md5_password);
523  }
524  return retval;
525 }
526 
527 int TcpServer::SetListenSocketDscp(uint8_t value) {
528  int retval = 0;
529  if (acceptor_) {
530  retval = SetDscpSocketOption(acceptor_->native_handle(), value);
531  }
532  return retval;
533 }
534 
536  /* The 'value' argument is expected to have DSCP value between 0 and 63 ie
537  * in the lower order 6 bits of a byte. However, setsockopt expects DSCP
538  * value in upper 6 bits of a byte. Hence left shift the value by 2 digits
539  * before passing it to setsockopt */
540  value = value << 2;
541  int retval = setsockopt(fd, IPPROTO_IP, IP_TOS,
542  reinterpret_cast<const char *>(&value), sizeof(value));
543  if (retval < 0) {
545  "Failure in setting DSCP value on the socket " +
546  integerToString(fd) + " for value " + integerToString(value) +
547  " with errno " + strerror(errno));
548  }
549  return retval;
550 }
551 
553  uint8_t dscp = 0;
554  unsigned int optlen = sizeof(dscp);
555  int retval = getsockopt(fd, IPPROTO_IP, IP_TOS,
556  reinterpret_cast<char *>(&dscp),
557  reinterpret_cast<socklen_t *>(&optlen));
558  if (retval < 0) {
560  "Failure in getting DSCP value on the socket " +
561  integerToString(fd) + " with errno " + strerror(errno));
562  }
563  return dscp;
564 }
565 
566 int TcpServer::SetSocketOptions(const SandeshConfig &sandesh_config) {
567  int retval = 0;
568  if (acceptor_ && sandesh_config.tcp_keepalive_enable) {
569  retval = SetKeepAliveSocketOption(acceptor_->native_handle(), sandesh_config);
570  }
571  return retval;
572 }
573 
574 int TcpServer::SetKeepAliveSocketOption(int fd, const SandeshConfig &sandesh_config) {
575  int tcp_keepalive_enable = 1, retval = 0;
576  int tcp_keepalive_idle_time = sandesh_config.tcp_keepalive_idle_time;
577  int tcp_keepalive_probes = sandesh_config.tcp_keepalive_probes;
578  int tcp_keepalive_interval = sandesh_config.tcp_keepalive_interval;
579  retval = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
580  reinterpret_cast<const char *>(&tcp_keepalive_enable), sizeof(tcp_keepalive_enable));
581  if (retval < 0) {
583  "Failure in setting Keepalive enable on the socket " +
584  integerToString(fd) +
585  " with errno " + strerror(errno));
586  return retval;
587  }
588 
589 #ifdef TCP_KEEPIDLE
590  retval = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE,
591  reinterpret_cast<const char *>(&tcp_keepalive_idle_time), sizeof(tcp_keepalive_idle_time));
592  if (retval < 0) {
594  "Failure in setting keepalive idle time on the socket " +
595  integerToString(fd) +
596  " with errno " + strerror(errno));
597  return retval;
598  }
599 #elif TCP_KEEPALIVE
600  retval = setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE,
601  reinterpret_cast<const char *>(&tcp_keepalive_idle_time), sizeof(tcp_keepalive_idle_time));
602  if (retval < 0) {
604  "Failure in setting keepalive time on the socket " +
605  integerToString(fd) +
606  " with errno " + strerror(errno));
607  return retval;
608  }
609 #else
610 #error No TCP keepalive option defined.
611 #endif
612 
613 #ifdef TCP_KEEPCNT
614  retval = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT,
615  reinterpret_cast<const char *>(&tcp_keepalive_probes), sizeof(tcp_keepalive_probes));
616  if (retval < 0) {
618  "Failure in setting keepalive probes on the socket " +
619  integerToString(fd) +
620  " with errno " + strerror(errno));
621  return retval;
622  }
623 #endif
624 
625 #ifdef TCP_KEEPINTVL
626  retval = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL,
627  reinterpret_cast<const char *>(&tcp_keepalive_interval), sizeof(tcp_keepalive_interval));
628  if (retval < 0) {
630  "Failure in setting keepalive interval on the socket " +
631  integerToString(fd) +
632  " with errno " + strerror(errno));
633  return retval;
634  }
635 #endif
636  return retval;
637 }
638 
639 void TcpServer::GetRxSocketStats(SocketIOStats *socket_stats) const {
640  stats_.GetRxStats(socket_stats);
641 }
642 
643 void TcpServer::GetTxSocketStats(SocketIOStats *socket_stats) const {
644  stats_.GetTxStats(socket_stats);
645 }
646 
647 //
648 // TcpServerManager class routines
649 //
651 
653  impl_.AddServer(server);
654 }
655 
657  // Wait for pending writes to be complete
658  server->WaitForEmpty();
659  impl_.DeleteServer(server);
660 }
661 
663  return impl_.GetServerCount();
664 }
std::string name_
Definition: tcp_server.h:184
void Close()
Definition: tcp_session.cc:354
virtual ~TcpServer()
Definition: tcp_server.cc:42
static void AddServer(TcpServer *server)
Definition: tcp_server.cc:652
void UpdateSessionsDscp(uint8_t dscp)
Definition: tcp_server.cc:177
bool HasSessions() const
Definition: tcp_server.cc:285
Endpoint local_endpoint() const
Definition: tcp_session.cc:205
virtual void DeleteSession(TcpSession *session)
Definition: tcp_server.cc:197
static void DeleteServer(ServerType *server)
boost::asio::ip::tcp::socket Socket
Definition: tcp_server.h:31
tbb::atomic< int > refcount_
Definition: tcp_server.h:183
tbb::interface5::condition_variable cond_var_
Definition: tcp_server.h:178
virtual void Connect(TcpSession *session, Endpoint remote)
Definition: tcp_server.cc:474
std::set< TcpSessionPtr, TcpSessionPtrCmp > SessionSet
Definition: tcp_server.h:155
SessionMap session_map_
Definition: tcp_server.h:180
#define TCP_SERVER_LOG_UT_DEBUG(server, dir, arg)
Definition: io_log.h:109
boost::asio::ip::address IpAddress
Definition: address.h:13
TcpSession * GetSession(Endpoint remote)
Definition: tcp_server.cc:430
virtual TcpSession * CreateSession()
Definition: tcp_server.cc:188
void GetTxStats(SocketIOStats *socket_stats) const
Definition: io_utils.cc:47
void GetTxSocketStats(SocketIOStats *socket_stats) const
Definition: tcp_server.cc:643
#define TCP_SERVER_LOG_INFO(server, dir, arg)
Definition: io_log.h:103
bool tcp_keepalive_enable
std::unique_ptr< Socket > so_accept_
Definition: tcp_server.h:181
boost::asio::io_context * io_service()
Definition: event_manager.h:42
static ServerManager< TcpServer, TcpServerPtr > impl_
Definition: tcp_server.h:211
int SetKeepAliveSocketOption(int fd, const SandeshConfig &sandesh_config)
Definition: tcp_server.cc:574
static void AddServer(ServerType *server)
void GetRxSocketStats(SocketIOStats *socket_stats) const
Definition: tcp_server.cc:639
#define TCP_SERVER_LOG_DEBUG(server, dir, arg)
Definition: io_log.h:106
void AcceptHandlerInternal(TcpServerPtr server, const boost::system::error_code &error)
Definition: tcp_server.cc:354
int tcp_keepalive_idle_time
#define TCP_DIR_NA
Definition: io_log.h:48
tbb::atomic< int > refcount_
Definition: tcp_session.h:282
Endpoint LocalEndpoint() const
Definition: tcp_server.cc:306
virtual void AcceptHandlerComplete(TcpSessionPtr session)
Definition: tcp_server.cc:405
void ConnectHandler(TcpServerPtr server, TcpSessionPtr session, const boost::system::error_code &error)
Definition: tcp_server.cc:439
boost::intrusive_ptr< TcpServer > TcpServerPtr
Definition: tcp_server.h:110
void Shutdown()
Definition: tcp_server.cc:143
int SetDscpSocketOption(NativeSocketType fd, uint8_t value)
Definition: tcp_server.cc:535
virtual TcpSession * AllocSession(Socket *socket)=0
bool HasSessionReadAvailable() const
Definition: tcp_server.cc:290
#define TCP_SESSION_LOG_DEBUG(session, dir, arg)
Definition: io_log.h:123
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
void AsyncAccept()
Definition: tcp_server.cc:261
void GetRxStats(SocketIOStats *socket_stats) const
Definition: io_utils.cc:28
int SetSocketOptions(const SandeshConfig &sandesh_config)
Definition: tcp_server.cc:566
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
size_t GetServerCount()
boost::scoped_ptr< boost::asio::ip::tcp::acceptor > acceptor_
Definition: tcp_server.h:182
EventManager * evm_
Definition: tcp_server.h:175
#define TCP_SESSION_LOG_ERROR(session, dir, arg)
Definition: io_log.h:117
int GetPort() const
Definition: tcp_server.cc:272
int intf_id_
Definition: tcp_server.h:186
static void DeleteServer(TcpServer *server)
Definition: tcp_server.cc:656
TcpServer(EventManager *evm)
Definition: tcp_server.cc:31
#define TCP_DIR_OUT
Definition: io_log.h:46
void ResetAcceptor()
Definition: tcp_server.cc:54
static size_t GetServerCount()
Definition: tcp_server.cc:662
bool InitializeInternal(boost::asio::ip::tcp::endpoint localaddr)
Definition: tcp_server.cc:81
void OnSessionClose(TcpSession *session)
Definition: tcp_server.cc:235
uint8_t GetDscpValue(NativeSocketType fd) const
Definition: tcp_server.cc:552
void InsertSessionToMap(Endpoint remote, TcpSession *session)
Definition: tcp_server.cc:215
int SetListenSocketMd5Option(uint32_t peer_ip, const std::string &md5_password)
Definition: tcp_server.cc:517
virtual bool AcceptSession(TcpSession *session)
Definition: tcp_server.cc:344
io::SocketStats stats_
Definition: tcp_server.h:174
int SetListenSocketDscp(uint8_t value)
Definition: tcp_server.cc:527
int SetDscpSocketOption(uint8_t value)
Definition: tcp_session.cc:569
TcpServer * server()
Definition: tcp_session.h:88
Endpoint remote_endpoint() const
Definition: tcp_session.h:135
virtual bool Initialize(unsigned short port)
Definition: tcp_server.cc:59
void ClearSessions()
Definition: tcp_server.cc:159
#define TCP_DIR_IN
Definition: io_log.h:47
#define TCP_SESSION_LOG_UT_DEBUG(session, dir, arg)
Definition: io_log.h:126
virtual void ConnectHandlerComplete(TcpSessionPtr session)
Definition: tcp_server.cc:451
bool RemoveSessionFromMap(Endpoint remote, TcpSession *session)
Definition: tcp_server.cc:224
int tcp_keepalive_interval
virtual Socket * accept_socket() const
Definition: tcp_server.cc:336
boost::asio::ip::tcp::socket::native_handle_type NativeSocketType
Definition: tcp_server.h:32
virtual Socket * socket() const
Definition: tcp_session.h:86
#define TCP_SERVER_LOG_ERROR(server, dir, arg)
Definition: io_log.h:100
boost::asio::ip::tcp::endpoint Endpoint
Definition: tcp_server.h:30
int SetMd5SocketOption(NativeSocketType fd, uint32_t peer_ip, const std::string &md5_password)
Definition: tcp_server.cc:482
void SetName(Endpoint local_endpoint)
Definition: tcp_server.cc:48
SessionSet session_ref_
Definition: tcp_server.h:179
void WaitForEmpty()
Definition: tcp_server.cc:254
virtual void set_accept_socket()
Definition: tcp_server.cc:340
boost::intrusive_ptr< TcpSession > TcpSessionPtr
Definition: tcp_server.h:111
static EventManager evm
tbb::mutex mutex_
Definition: tcp_server.h:177