OpenSDN source code
udp_server.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef SRC_IO_UDP_SERVER_H_
6 #define SRC_IO_UDP_SERVER_H_
7 
8 #include <atomic>
9 #include <string>
10 #include <vector>
11 #include <mutex>
12 
13 #include <boost/asio.hpp>
14 #include <boost/intrusive_ptr.hpp>
15 #include "io/event_manager.h"
16 #include "io/server_manager.h"
17 #include "io/io_utils.h"
18 
19 class SocketIOStats;
20 
21 class UdpServer {
22 public:
23  typedef boost::asio::ip::udp::endpoint Endpoint;
24  typedef boost::asio::ip::udp::socket Socket;
25 
26  enum ServerState {
27  OK = 42,
31  };
32  static const int kDefaultBufferSize = 4 * 1024;
33 
34  explicit UdpServer(EventManager *evm, int buffer_size = kDefaultBufferSize);
35  explicit UdpServer(boost::asio::io_context *io_service,
36  int buffer_size = kDefaultBufferSize);
37  virtual ~UdpServer();
38 
39  virtual bool Initialize(unsigned short port);
40  virtual bool Initialize(const std::string &ipaddress, unsigned short port);
41  virtual bool Initialize(boost::asio::ip::udp::endpoint local_endpoint);
42  virtual void Shutdown();
43 
44  // tx-rx
45  // Assumes mutex is locked or called from the main thread
46  void StartSend(boost::asio::ip::udp::endpoint ep, std::size_t bytes_to_send,
47  boost::asio::const_buffer buffer);
48  // Assumes mutex is locked or called from the main thread
49  void StartReceive();
50  // state
51  ServerState GetServerState() const { return state_; }
52  boost::asio::ip::udp::endpoint GetLocalEndpoint(
53  boost::system::error_code *error) const;
54  std::string GetLocalEndpointAddress() const;
55  int GetLocalEndpointPort() const;
56 
57  // buffers
58  // Assumes mutex is locked or called from the main thread
59  boost::asio::mutable_buffer AllocateBuffer();
60  boost::asio::mutable_buffer AllocateBuffer(std::size_t s);
61  // Assumes mutex is locked or called from the main thread
62  void DeallocateBuffer(const boost::asio::const_buffer &buffer);
63 
64  // statistics
65  const io::SocketStats &GetSocketStats() const { return stats_; }
66  void GetRxSocketStats(SocketIOStats *socket_stats) const;
67  void GetTxSocketStats(SocketIOStats *socket_stats) const;
68 
69 protected:
71  virtual bool DisableSandeshLogMessages() { return false; }
72  virtual std::string ToString() { return name_; }
73 
74  // Assumes mutex is locked, deallocates the buffer
75  virtual void HandleReceive(
76  const boost::asio::const_buffer &recv_buffer,
77  boost::asio::ip::udp::endpoint remote_endpoint,
78  std::size_t bytes_transferred,
79  const boost::system::error_code& error);
80 
81  virtual void OnRead(const boost::asio::const_buffer &recv_buffer,
82  const boost::asio::ip::udp::endpoint &remote_endpoint);
83 
84  virtual int reader_task_id() const {
85  return reader_task_id_;
86  }
87  // This function returns the instance to run ReaderTask.
88  // Returning Task::kTaskInstanceAny would allow multiple reader tasks to
89  // run in parallel.
90  // Derived class may override implementation if it expects that all the
91  // tasks of the reader to run in specific instance
92  // Note: Two tasks of same task ID and task instance can't run
93  // at in parallel
94  // E.g. User can create task per remote endpoint to ensure that
95  // there is one ReaderTask per remote endpoint
96  virtual int reader_task_instance(
97  const boost::asio::ip::udp::endpoint &remote_endpoint) const;
98 
99  // Assumes mutex is locked, deallocates the buffer
100  virtual void HandleSend(boost::asio::const_buffer send_buffer,
101  boost::asio::ip::udp::endpoint remote_endpoint,
102  std::size_t bytes_transferred,
103  const boost::system::error_code& error);
104 
105 private:
106  class Reader;
107  friend void intrusive_ptr_add_ref(UdpServer *server);
108  friend void intrusive_ptr_release(UdpServer *server);
109  void SetName(boost::asio::ip::udp::endpoint ep);
110 
111  // Locks the mutex
113  boost::asio::const_buffer recv_buffer,
114  std::size_t bytes_transferred,
115  const boost::system::error_code& error);
116 
117  // Locks the mutex
118  void HandleSendInternal(boost::asio::const_buffer send_buffer,
119  boost::asio::ip::udp::endpoint remote_endpoint,
120  std::size_t bytes_transferred,
121  const boost::system::error_code& error);
122 
123  static int reader_task_id_;
124  boost::asio::ip::udp::socket socket_;
128  std::string name_;
129  boost::asio::ip::udp::endpoint remote_endpoint_;
130  std::mutex state_guard_;
131  std::mutex pbuf_guard_;
132  std::vector<uint8_t *> pbuf_;
133  std::atomic<int> refcount_;
135 
137 };
138 
139 typedef boost::intrusive_ptr<UdpServer> UdpServerPtr;
140 
141 inline void intrusive_ptr_add_ref(UdpServer *server) {
142  server->refcount_.fetch_add(1);
143 }
144 
145 inline void intrusive_ptr_release(UdpServer *server) {
146  int prev = server->refcount_.fetch_sub(1);
147  if (prev == 1) {
148  delete server;
149  }
150 }
151 
153 public:
154  static void AddServer(UdpServer *server);
155  static void DeleteServer(UdpServer *server);
156 
157 private:
159 };
160 
161 #endif // SRC_IO_UDP_SERVER_H_
static ServerManager< UdpServer, UdpServerPtr > impl_
Definition: udp_server.h:158
static void DeleteServer(UdpServer *server)
Definition: udp_server.cc:339
static void AddServer(UdpServer *server)
Definition: udp_server.cc:335
void HandleReceiveInternal(boost::asio::const_buffer recv_buffer, std::size_t bytes_transferred, const boost::system::error_code &error)
Definition: udp_server.cc:252
std::string name_
Definition: udp_server.h:128
const io::SocketStats & GetSocketStats() const
Definition: udp_server.h:65
std::vector< uint8_t * > pbuf_
Definition: udp_server.h:132
virtual void Shutdown()
Definition: udp_server.cc:99
UdpServer(EventManager *evm, int buffer_size=kDefaultBufferSize)
Definition: udp_server.cc:63
virtual bool Initialize(unsigned short port)
Definition: udp_server.cc:137
std::mutex pbuf_guard_
Definition: udp_server.h:131
boost::asio::ip::udp::endpoint Endpoint
Definition: udp_server.h:23
virtual int reader_task_instance(const boost::asio::ip::udp::endpoint &remote_endpoint) const
Definition: udp_server.cc:76
@ SocketOpenFailed
Definition: udp_server.h:29
@ SocketBindFailed
Definition: udp_server.h:30
@ Uninitialized
Definition: udp_server.h:28
boost::asio::ip::udp::endpoint remote_endpoint_
Definition: udp_server.h:129
boost::asio::ip::udp::socket socket_
Definition: udp_server.h:124
friend void intrusive_ptr_add_ref(UdpServer *server)
Definition: udp_server.h:141
void StartReceive()
Definition: udp_server.cc:236
boost::asio::ip::udp::socket Socket
Definition: udp_server.h:24
EventManager * evm_
Definition: udp_server.h:127
io::SocketStats stats_
Definition: udp_server.h:134
virtual bool DisableSandeshLogMessages()
Definition: udp_server.h:71
boost::asio::ip::udp::endpoint GetLocalEndpoint(boost::system::error_code *error) const
Definition: udp_server.cc:301
virtual void OnRead(const boost::asio::const_buffer &recv_buffer, const boost::asio::ip::udp::endpoint &remote_endpoint)
Definition: udp_server.cc:289
virtual bool Initialize(boost::asio::ip::udp::endpoint local_endpoint)
int GetLocalEndpointPort() const
Definition: udp_server.cc:314
boost::asio::mutable_buffer AllocateBuffer()
Definition: udp_server.cc:179
std::mutex state_guard_
Definition: udp_server.h:130
friend void intrusive_ptr_release(UdpServer *server)
Definition: udp_server.h:145
virtual std::string ToString()
Definition: udp_server.h:72
void GetTxSocketStats(SocketIOStats *socket_stats) const
Definition: udp_server.cc:326
int buffer_size_
Definition: udp_server.h:125
virtual int reader_task_id() const
Definition: udp_server.h:84
virtual void HandleReceive(const boost::asio::const_buffer &recv_buffer, boost::asio::ip::udp::endpoint remote_endpoint, std::size_t bytes_transferred, const boost::system::error_code &error)
Definition: udp_server.cc:277
static int reader_task_id_
Definition: udp_server.h:123
DISALLOW_COPY_AND_ASSIGN(UdpServer)
void StartSend(boost::asio::ip::udp::endpoint ep, std::size_t bytes_to_send, boost::asio::const_buffer buffer)
Definition: udp_server.cc:195
std::atomic< int > refcount_
Definition: udp_server.h:133
ServerState GetServerState() const
Definition: udp_server.h:51
EventManager * event_manager()
Definition: udp_server.h:70
void HandleSendInternal(boost::asio::const_buffer send_buffer, boost::asio::ip::udp::endpoint remote_endpoint, std::size_t bytes_transferred, const boost::system::error_code &error)
Definition: udp_server.cc:211
static const int kDefaultBufferSize
Definition: udp_server.h:32
void GetRxSocketStats(SocketIOStats *socket_stats) const
Definition: udp_server.cc:322
void SetName(boost::asio::ip::udp::endpoint ep)
Definition: udp_server.cc:80
ServerState state_
Definition: udp_server.h:126
std::string GetLocalEndpointAddress() const
Definition: udp_server.cc:306
virtual ~UdpServer()
Definition: udp_server.cc:87
virtual void HandleSend(boost::asio::const_buffer send_buffer, boost::asio::ip::udp::endpoint remote_endpoint, std::size_t bytes_transferred, const boost::system::error_code &error)
Definition: udp_server.cc:295
void DeallocateBuffer(const boost::asio::const_buffer &buffer)
Definition: udp_server.cc:183
static EventManager evm
boost::intrusive_ptr< UdpServer > UdpServerPtr
Definition: udp_server.h:139
void intrusive_ptr_add_ref(UdpServer *server)
Definition: udp_server.h:141
void intrusive_ptr_release(UdpServer *server)
Definition: udp_server.h:145