Fawkes API  Fawkes Development Version
peer.h
1 
2 /***************************************************************************
3  * server.h - Protobuf stream protocol - broadcast peer
4  *
5  * Created: Wed Jan 30 16:41:22 2013
6  * Copyright 2013 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * - Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  * - Neither the name of the authors nor the names of its contributors
20  * may be used to endorse or promote products derived from this
21  * software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34  * OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #ifndef _PROTOBUF_COMM_PEER_H_
38 #define _PROTOBUF_COMM_PEER_H_
39 
40 #include <google/protobuf/message.h>
41 #include <protobuf_comm/frame_header.h>
42 #include <protobuf_comm/message_register.h>
43 #include <protobuf_comm/queue_entry.h>
44 
45 #include <boost/asio.hpp>
46 #include <boost/signals2.hpp>
47 #include <mutex>
48 #include <queue>
49 #include <thread>
50 
51 namespace protobuf_comm {
52 
53 class BufferEncryptor;
54 class BufferDecryptor;
55 
56 class ProtobufBroadcastPeer
57 {
58 public:
59  /** Anonymus enum for constants. */
60  enum { max_packet_length = 1024 /**< maximum packet length in bytes */ };
61 
62  ProtobufBroadcastPeer(const std::string address, unsigned short port);
63  ProtobufBroadcastPeer(const std::string address,
64  unsigned short send_to_port,
65  unsigned short recv_on_port);
66  ProtobufBroadcastPeer(const std::string address,
67  unsigned short port,
68  std::vector<std::string> &proto_path);
69  ProtobufBroadcastPeer(const std::string address,
70  unsigned short send_to_port,
71  unsigned short recv_on_port,
72  std::vector<std::string> &proto_path);
73  ProtobufBroadcastPeer(const std::string address, unsigned short port, MessageRegister *mr);
74  ProtobufBroadcastPeer(const std::string address,
75  unsigned short send_to_port,
76  unsigned short recv_on_port,
77  MessageRegister * mr,
78  frame_header_version_t header_version = PB_FRAME_V2);
79  ProtobufBroadcastPeer(const std::string address,
80  unsigned short port,
81  const std::string crypto_key,
82  const std::string cipher = "aes-128-ecb");
83  ProtobufBroadcastPeer(const std::string address,
84  unsigned short port,
85  MessageRegister * mr,
86  const std::string crypto_key,
87  const std::string cipher = "aes-128-ecb");
88  ProtobufBroadcastPeer(const std::string address,
89  unsigned short send_to_port,
90  unsigned short recv_on_port,
91  const std::string crypto_key,
92  const std::string cipher = "aes-128-ecb");
93  ProtobufBroadcastPeer(const std::string address,
94  unsigned short send_to_port,
95  unsigned short recv_on_port,
96  MessageRegister * mr,
97  const std::string crypto_key,
98  const std::string cipher = "aes-128-ecb");
100 
101  void set_filter_self(bool filter);
102 
103  void send(uint16_t component_id, uint16_t msg_type, google::protobuf::Message &m);
104  void send(uint16_t component_id, uint16_t msg_type, std::shared_ptr<google::protobuf::Message> m);
105  void send(std::shared_ptr<google::protobuf::Message> m);
106  void send(google::protobuf::Message &m);
107 
108  void send_raw(const frame_header_t &frame_header, const void *data, size_t data_size);
109 
110  void setup_crypto(const std::string &key, const std::string &cipher);
111 
112  /** Get the server's message register.
113  * @return message register
114  */
117  {
118  return *message_register_;
119  }
120 
121  /** Boost signal for a received message. */
122  typedef boost::signals2::signal<void(boost::asio::ip::udp::endpoint &,
123  uint16_t,
124  uint16_t,
125  std::shared_ptr<google::protobuf::Message>)>
127 
128  /** Boost signal for a received raw message. */
129  typedef boost::signals2::signal<
130  void(boost::asio::ip::udp::endpoint &, frame_header_t &, void *, size_t)>
132 
133  /** Boost signal for an error during receiving a message. */
134  typedef boost::signals2::signal<void(boost::asio::ip::udp::endpoint &, std::string)>
136 
137  /** Boost signal for an error during sending a message. */
138  typedef boost::signals2::signal<void(std::string)> signal_send_error_type;
139 
140  /** Signal that is invoked when a message has been received.
141  * @return signal
142  */
145  {
146  return sig_rcvd_;
147  }
148 
149  /** Signal that is invoked when a message has been received.
150  * This allows access to the raw packet data. This allows, for example,
151  * to write an ecryption agnostic repeater.
152  * @return signal
153  */
156  {
157  return sig_rcvd_raw_;
158  }
159 
160  /** Signal that is invoked when receiving a message failed.
161  * @return signal
162  */
165  {
166  return sig_recv_error_;
167  }
168 
169  /** Signal that is invoked when sending a message failed.
170  * @return signal
171  */
174  {
175  return sig_send_error_;
176  }
177 
178 private: // methods
179  void ctor(const std::string &address,
180  unsigned int send_to_port,
181  const std::string crypto_key = "",
182  const std::string cipher = "aes-128-ecb",
183  frame_header_version_t = PB_FRAME_V2);
184  void determine_local_endpoints();
185  void run_asio();
186  void start_send();
187  void start_recv();
188  void start_resolve();
189  void retry_resolve(const boost::system::error_code &ec);
190  void handle_resolve(const boost::system::error_code & err,
191  boost::asio::ip::udp::resolver::iterator endpoint_iterator);
192  void handle_sent(const boost::system::error_code &error,
193  size_t /*bytes_transferred*/,
194  QueueEntry *entry);
195  void handle_recv(const boost::system::error_code &error, size_t bytes_rcvd);
196 
197 private: // members
198  boost::asio::io_service io_service_;
199  boost::asio::ip::udp::resolver resolver_;
200  boost::asio::ip::udp::socket socket_;
201  boost::asio::deadline_timer resolve_retry_timer_;
202 
203  std::list<boost::asio::ip::udp::endpoint> local_endpoints_;
204 
205  signal_received_type sig_rcvd_;
206  signal_received_raw_type sig_rcvd_raw_;
207  signal_recv_error_type sig_recv_error_;
208  signal_send_error_type sig_send_error_;
209 
210  std::string send_to_address_;
211  unsigned int send_to_port_;
212 
213  std::queue<QueueEntry *> outbound_queue_;
214  std::mutex outbound_mutex_;
215  bool outbound_active_;
216  bool outbound_ready_;
217 
218  boost::asio::ip::udp::endpoint outbound_endpoint_;
219  boost::asio::ip::udp::endpoint in_endpoint_;
220 
221  void * in_data_;
222  void * enc_in_data_;
223  size_t in_data_size_;
224  size_t enc_in_data_size_;
225 
226  bool filter_self_;
227 
228  std::thread asio_thread_;
229  MessageRegister *message_register_;
230  bool own_message_register_;
231 
232  frame_header_version_t frame_header_version_;
233 
234  bool crypto_;
235  bool crypto_buf_;
236  BufferEncryptor *crypto_enc_;
237  BufferDecryptor *crypto_dec_;
238 };
239 
240 } // end namespace protobuf_comm
241 
242 #endif
protobuf_comm::ProtobufBroadcastPeer::~ProtobufBroadcastPeer
~ProtobufBroadcastPeer()
Destructor.
Definition: peer.cpp:303
protobuf_comm::ProtobufBroadcastPeer::signal_recv_error_type
boost::signals2::signal< void(boost::asio::ip::udp::endpoint &, std::string)> signal_recv_error_type
Boost signal for an error during receiving a message.
Definition: peer.h:138
protobuf_comm::MessageRegister
Definition: message_register.h:64
protobuf_comm::ProtobufBroadcastPeer::signal_recv_error
signal_recv_error_type & signal_recv_error()
Signal that is invoked when receiving a message failed.
Definition: peer.h:167
protobuf_comm::ProtobufBroadcastPeer::signal_received_raw
signal_received_raw_type & signal_received_raw()
Signal that is invoked when a message has been received.
Definition: peer.h:158
protobuf_comm::ProtobufBroadcastPeer::signal_send_error_type
boost::signals2::signal< void(std::string)> signal_send_error_type
Boost signal for an error during sending a message.
Definition: peer.h:141
protobuf_comm::QueueEntry
Outgoing queue entry.
Definition: queue_entry.h:49
protobuf_comm::ProtobufBroadcastPeer::max_packet_length
maximum packet length in bytes
Definition: peer.h:63
protobuf_comm::ProtobufBroadcastPeer::ProtobufBroadcastPeer
ProtobufBroadcastPeer(const std::string address, unsigned short port)
Constructor.
Definition: peer.cpp:57
protobuf_comm::ProtobufBroadcastPeer::signal_received
signal_received_type & signal_received()
Signal that is invoked when a message has been received.
Definition: peer.h:147
protobuf_comm::ProtobufBroadcastPeer::send_raw
void send_raw(const frame_header_t &frame_header, const void *data, size_t data_size)
Send a raw message.
Definition: peer.cpp:616
protobuf_comm::frame_header_t
Network framing header.
Definition: frame_header.h:74
protobuf_comm::ProtobufBroadcastPeer::set_filter_self
void set_filter_self(bool filter)
Set if to filter out own messages.
Definition: peer.cpp:384
protobuf_comm::ProtobufBroadcastPeer::setup_crypto
void setup_crypto(const std::string &key, const std::string &cipher)
Setup encryption.
Definition: peer.cpp:331
protobuf_comm::BufferDecryptor
Definition: crypto.h:81
protobuf_comm::ProtobufBroadcastPeer::message_register
MessageRegister & message_register()
Get the server's message register.
Definition: peer.h:119
protobuf_comm::ProtobufBroadcastPeer::signal_send_error
signal_send_error_type & signal_send_error()
Signal that is invoked when sending a message failed.
Definition: peer.h:176
protobuf_comm::ProtobufBroadcastPeer::signal_received_raw_type
boost::signals2::signal< void(boost::asio::ip::udp::endpoint &, frame_header_t &, void *, size_t)> signal_received_raw_type
Boost signal for a received raw message.
Definition: peer.h:134
protobuf_comm::ProtobufBroadcastPeer::send
void send(uint16_t component_id, uint16_t msg_type, google::protobuf::Message &m)
Send a message to other peers.
Definition: peer.cpp:574
protobuf_comm::BufferEncryptor
Definition: crypto.h:52
protobuf_comm::ProtobufBroadcastPeer::signal_received_type
boost::signals2::signal< void(boost::asio::ip::udp::endpoint &, uint16_t, uint16_t, std::shared_ptr< google::protobuf::Message >)> signal_received_type
Boost signal for a received message.
Definition: peer.h:129