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 <protobuf_comm/frame_header.h>
41 #include <protobuf_comm/message_register.h>
42 #include <protobuf_comm/queue_entry.h>
43 
44 #include <boost/asio.hpp>
45 #include <boost/signals2.hpp>
46 #include <google/protobuf/message.h>
47 
48 #include <thread>
49 #include <mutex>
50 #include <queue>
51 
52 namespace protobuf_comm {
53 #if 0 /* just to make Emacs auto-indent happy */
54 }
55 #endif
56 
57 class BufferEncryptor;
58 class BufferDecryptor;
59 
61 {
62  public:
63  enum { max_packet_length = 1024 };
64 
65  ProtobufBroadcastPeer(const std::string address, unsigned short port);
66  ProtobufBroadcastPeer(const std::string address, unsigned short send_to_port,
67  unsigned short recv_on_port);
68  ProtobufBroadcastPeer(const std::string address, unsigned short port,
69  std::vector<std::string> &proto_path);
70  ProtobufBroadcastPeer(const std::string address, unsigned short send_to_port,
71  unsigned short recv_on_port, std::vector<std::string> &proto_path);
72  ProtobufBroadcastPeer(const std::string address, unsigned short port, MessageRegister *mr);
73  ProtobufBroadcastPeer(const std::string address, unsigned short send_to_port,
74  unsigned short recv_on_port, MessageRegister *mr,
75  frame_header_version_t header_version = PB_FRAME_V2);
76  ProtobufBroadcastPeer(const std::string address, unsigned short port,
77  const std::string crypto_key, const std::string cipher = "aes-128-ecb");
78  ProtobufBroadcastPeer(const std::string address, unsigned short port, MessageRegister *mr,
79  const std::string crypto_key, const std::string cipher = "aes-128-ecb");
80  ProtobufBroadcastPeer(const std::string address, unsigned short send_to_port,
81  unsigned short recv_on_port,
82  const std::string crypto_key, const std::string cipher = "aes-128-ecb");
83  ProtobufBroadcastPeer(const std::string address, unsigned short send_to_port,
84  unsigned short recv_on_port, MessageRegister *mr,
85  const std::string crypto_key, const std::string cipher = "aes-128-ecb");
87 
88  void set_filter_self(bool filter);
89 
90  void send(uint16_t component_id, uint16_t msg_type,
91  google::protobuf::Message &m);
92  void send(uint16_t component_id, uint16_t msg_type,
93  std::shared_ptr<google::protobuf::Message> m);
94  void send(std::shared_ptr<google::protobuf::Message> m);
95  void send(google::protobuf::Message &m);
96 
97  void send_raw(const frame_header_t &frame_header, const void *data, size_t data_size);
98 
99  void setup_crypto(const std::string &key, const std::string &cipher);
100 
101  /** Get the server's message register.
102  * @return message register
103  */
105  { return *message_register_; }
106 
107  /** Boost signal for a received message. */
108  typedef
109  boost::signals2::signal<void (boost::asio::ip::udp::endpoint &, uint16_t, uint16_t,
110  std::shared_ptr<google::protobuf::Message>)>
112 
113  /** Boost signal for a received raw message. */
114  typedef
115  boost::signals2::signal<void (boost::asio::ip::udp::endpoint &, frame_header_t &,
116  void *, size_t)>
118 
119  /** Boost signal for an error during receiving a message. */
120  typedef
121  boost::signals2::signal<void (boost::asio::ip::udp::endpoint &, std::string)>
123 
124  /** Boost signal for an error during sending a message. */
125  typedef
126  boost::signals2::signal<void (std::string)>
128 
129  /** Signal that is invoked when a message has been received.
130  * @return signal
131  */
133  { return sig_rcvd_; }
134 
135  /** Signal that is invoked when a message has been received.
136  * This allows access to the raw packet data. This allows, for example,
137  * to write an ecryption agnostic repeater.
138  * @return signal
139  */
141  { return sig_rcvd_raw_; }
142 
143  /** Signal that is invoked when receiving a message failed.
144  * @return signal
145  */
147  { return sig_recv_error_; }
148 
149  /** Signal that is invoked when sending a message failed.
150  * @return signal
151  */
153  { return sig_send_error_; }
154 
155 
156  private: // methods
157  void ctor(const std::string &address, unsigned int send_to_port,
158  const std::string crypto_key = "", const std::string cipher = "aes-128-ecb",
159  frame_header_version_t = PB_FRAME_V2);
160  void determine_local_endpoints();
161  void run_asio();
162  void start_send();
163  void start_recv();
164  void handle_resolve(const boost::system::error_code& err,
165  boost::asio::ip::udp::resolver::iterator endpoint_iterator);
166  void handle_sent(const boost::system::error_code& error,
167  size_t /*bytes_transferred*/, QueueEntry *entry);
168  void handle_recv(const boost::system::error_code& error, size_t bytes_rcvd);
169 
170  private: // members
171  boost::asio::io_service io_service_;
172  boost::asio::ip::udp::resolver resolver_;
173  boost::asio::ip::udp::socket socket_;
174 
175  std::list<boost::asio::ip::udp::endpoint> local_endpoints_;
176 
177  signal_received_type sig_rcvd_;
178  signal_received_raw_type sig_rcvd_raw_;
179  signal_recv_error_type sig_recv_error_;
180  signal_send_error_type sig_send_error_;
181 
182  std::string send_to_address_;
183 
184  std::queue<QueueEntry *> outbound_queue_;
185  std::mutex outbound_mutex_;
186  bool outbound_active_;
187 
188  boost::asio::ip::udp::endpoint outbound_endpoint_;
189  boost::asio::ip::udp::endpoint in_endpoint_;
190 
191  void * in_data_;
192  void * enc_in_data_;
193  size_t in_data_size_;
194  size_t enc_in_data_size_;
195 
196  bool filter_self_;
197 
198  std::thread asio_thread_;
199  MessageRegister *message_register_;
200  bool own_message_register_;
201 
202  frame_header_version_t frame_header_version_;
203 
204  bool crypto_;
205  bool crypto_buf_;
206  BufferEncryptor *crypto_enc_;
207  BufferDecryptor *crypto_dec_;
208 };
209 
210 } // end namespace protobuf_comm
211 
212 #endif
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:122
void send(uint16_t component_id, uint16_t msg_type, google::protobuf::Message &m)
Send a message to other peers.
Definition: peer.cpp:525
Outgoing queue entry.
Definition: queue_entry.h:49
void send_raw(const frame_header_t &frame_header, const void *data, size_t data_size)
Send a raw message.
Definition: peer.cpp:565
Register to map msg type numbers to Protobuf messages.
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:117
Network framing header.
Definition: frame_header.h:74
void setup_crypto(const std::string &key, const std::string &cipher)
Setup encryption.
Definition: peer.cpp:304
Communicate by broadcasting protobuf messages.
Definition: peer.h:60
boost::signals2::signal< void(std::string)> signal_send_error_type
Boost signal for an error during sending a message.
Definition: peer.h:127
signal_send_error_type & signal_send_error()
Signal that is invoked when sending a message failed.
Definition: peer.h:152
signal_received_type & signal_received()
Signal that is invoked when a message has been received.
Definition: peer.h:132
Decrypt buffers encrypted with BufferEncryptor.
Definition: crypto.h:76
ProtobufBroadcastPeer(const std::string address, unsigned short port)
Constructor.
Definition: peer.cpp:61
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:111
void set_filter_self(bool filter)
Set if to filter out own messages.
Definition: peer.cpp:357
signal_received_raw_type & signal_received_raw()
Signal that is invoked when a message has been received.
Definition: peer.h:140
signal_recv_error_type & signal_recv_error()
Signal that is invoked when receiving a message failed.
Definition: peer.h:146
~ProtobufBroadcastPeer()
Destructor.
Definition: peer.cpp:277
Encrypt buffers using AES128 in ECB mode.
Definition: crypto.h:52
MessageRegister & message_register()
Get the server&#39;s message register.
Definition: peer.h:104