OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bfd_udp_connection.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
3  */
4 
5 #include <boost/asio.hpp>
6 #include <boost/scoped_ptr.hpp>
7 #include <boost/random.hpp>
8 
10 #include "bfd/bfd_connection.h"
11 #include "bfd/bfd_control_packet.h"
12 #include "bfd/bfd_common.h"
13 #include "bfd/bfd_server.h"
14 
15 #include "base/logging.h"
16 
17 namespace BFD {
18 
21  int recvPort)
22  : UdpServer(evm), parent_(parent) {
23  Initialize(recvPort);
24 }
25 
27  RecvCallback callback) {
28  this->callback_ = callback;
29 }
30 
32  const boost::asio::const_buffer &recv_buffer,
33  boost::asio::ip::udp::endpoint remote_endpoint,
34  std::size_t bytes_transferred,
35  const boost::system::error_code &error) {
36  if (callback_) {
37  callback_.get()(remote_endpoint, recv_buffer, bytes_transferred, error);
38  return;
39  }
40 
41  boost::system::error_code err;
42  parent_->HandleReceive(recv_buffer, GetLocalEndpoint(&err),
43  remote_endpoint, SessionIndex(), bytes_transferred,
44  error);
45 }
46 
48  int remotePort)
49  : UdpServer(evm), remotePort_(remotePort) {
50  boost::random::uniform_int_distribution<> dist(kSendPortMin, kSendPortMax);
51  for (int i = 0; i < 100 && GetServerState() != OK; ++i) {
52  int localPort = dist(randomGen);
53  LOG(DEBUG, "Bind UDPCommunicator to localport: " << localPort);
54  Initialize(localPort);
55  if (GetServerState() != OK) {
56  Shutdown();
57  }
58  }
59 
60  if (GetServerState() != OK) {
61  LOG(ERROR, "Unable to bind to port in range: " << kSendPortMin
62  << "-" << kSendPortMax);
63  }
64 }
65 
67  int remotePort)
68  : udpRecv_(new BFD::UDPConnectionManager::UDPRecvServer(this, evm,
69  recvPort)),
71  remotePort)), server_(NULL) {
73  LOG(ERROR, "Unable to listen on port " << recvPort);
74  else
76 }
77 
79  return server_;
80 }
81 
83  server_ = server;
84 }
85 
87  udpRecv_->RegisterCallback(callback);
88 }
89 
90 void UDPConnectionManager::SendPacket(boost::asio::ip::address remoteHost,
91  const ControlPacket *packet) {
92  boost::asio::mutable_buffer send =
93  boost::asio::mutable_buffer(new uint8_t[kMinimalPacketLength],
94  kMinimalPacketLength);
95  int pktSize = EncodeControlPacket(packet,
96  boost::asio::buffer_cast<uint8_t *>(send),
97  kMinimalPacketLength);
98  if (pktSize != kMinimalPacketLength) {
99  LOG(ERROR, "Unable to encode packet");
100  const uint8_t *p = boost::asio::buffer_cast<const uint8_t *>(send);
101  delete[] p;
102  return;
103  }
104  boost::asio::ip::udp::endpoint remote_endpoint(remoteHost,
105  udpSend_->remotePort());
106  SendPacket(boost::asio::ip::udp::endpoint(), remote_endpoint, 0, send,
107  pktSize);
108 }
109 
111  const boost::asio::ip::udp::endpoint &local_endpoint,
112  const boost::asio::ip::udp::endpoint &remote_endpoint,
113  const SessionIndex &index, const boost::asio::mutable_buffer &send,
114  int pktSize) {
115  udpSend_->StartSend(remote_endpoint, pktSize, send);
116 }
117 
119  udpRecv_->Shutdown();
120  udpSend_->Shutdown();
123 }
124 
126  const bool &up) {
127 }
128 
129 } // namespace BFD
int EncodeControlPacket(const ControlPacket *msg, uint8_t *data, size_t size)
UDPRecvServer(UDPConnectionManager *parent, EventManager *evm, int recvPort)
virtual void Shutdown()
Definition: udp_server.cc:98
void RegisterCallback(RecvCallback callback)
UDPConnectionManager(EventManager *evm, int recvPort=kSingleHop, int remotePort=kSingleHop)
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)
BFD::UDPConnectionManager::UDPCommunicator * udpSend_
boost::random::taus88 randomGen
Definition: bfd_common.cc:43
void StartSend(boost::asio::ip::udp::endpoint ep, std::size_t bytes_to_send, boost::asio::const_buffer buffer)
Definition: udp_server.cc:194
virtual void SendPacket(const boost::asio::ip::udp::endpoint &local_endpoint, const boost::asio::ip::udp::endpoint &remote_endpoint, const SessionIndex &session_index, const boost::asio::mutable_buffer &send, int pktSize)
BFD::UDPConnectionManager::UDPRecvServer * udpRecv_
UDPCommunicator(EventManager *evm, int remotePort)
const int kMinimalPacketLength
Definition: bfd_common.cc:41
virtual Server * GetServer() const
virtual void SetServer(Server *server)
static void DeleteServer(UdpServer *server)
Definition: udp_server.cc:338
#define LOG(_Level, _Msg)
Definition: logging.h:33
void RegisterCallback(RecvCallback callback)
boost::function< void(boost::asio::ip::udp::endpoint remote_endpoint, const boost::asio::const_buffer &recv_buffer, std::size_t bytes_transferred, const boost::system::error_code &error)> RecvCallback
void StartReceive()
Definition: udp_server.cc:235
ServerState GetServerState() const
Definition: udp_server.h:48
virtual void NotifyStateChange(const SessionKey &key, const bool &up)
virtual bool Initialize(unsigned short port)
Definition: udp_server.cc:136
static EventManager evm