GComm  0.2.3
gmcast.hpp
1 /*
2  * Copyright (C) 2009 Codership Oy <info@codership.com>
3  */
4 
5 /*
6  * Generic multicast transport. Uses tcp connections if real multicast
7  * is not available.
8  */
9 #ifndef GCOMM_GMCAST_HPP
10 #define GCOMM_GMCAST_HPP
11 
12 #include "gcomm/uuid.hpp"
13 #include "gcomm/exception.hpp"
14 #include "gcomm/transport.hpp"
15 #include "gcomm/types.hpp"
16 
17 #include <set>
18 
19 #ifndef GCOMM_GMCAST_MAX_VERSION
20 #define GCOMM_GMCAST_MAX_VERSION 0
21 #endif // GCOMM_GMCAST_MAX_VERSION
22 
23 namespace gcomm
24 {
25  namespace gmcast
26  {
27  class Proto;
28  class ProtoMap;
29  class Node;
30  class Message;
31  }
32 
33  class GMCast : public Transport
34  {
35  public:
36 
37  GMCast (Protonet&, const gu::URI&);
38  ~GMCast();
39 
40  // Protolay interface
41  void handle_up(const void*, const Datagram&, const ProtoUpMeta&);
42  int handle_down(Datagram&, const ProtoDownMeta&);
43  void handle_stable_view(const View& view);
44  bool set_param(const std::string& key, const std::string& val);
45  // Transport interface
46  const UUID& uuid() const { return my_uuid_; }
47  SegmentId segment() const { return segment_; }
48  void connect();
49  void connect(const gu::URI&);
50  void close(bool force = false);
51  void close(const UUID& uuid) { gmcast_forget(uuid); }
52 
53  void listen()
54  {
55  gu_throw_fatal << "gmcast transport listen not implemented";
56  }
57 
58  std::string listen_addr() const
59  {
60  if (listener_ == 0)
61  {
62  gu_throw_error(ENOTCONN) << "not connected";
63  }
64  return listener_->listen_addr();
65  }
66 
67  Transport* accept()
68  {
69  gu_throw_fatal << "gmcast transport accept not implemented";
70  }
71 
72  size_t mtu() const
73  {
74  return pnet_.mtu() - (4 + UUID::serial_size());
75  }
76 
77  private:
78 
79  GMCast (const GMCast&);
80  GMCast& operator=(const GMCast&);
81 
82  static const long max_retry_cnt_;
83 
84  class AddrEntry
85  {
86  public:
87 
88  AddrEntry(const gu::datetime::Date& last_seen,
89  const gu::datetime::Date& next_reconnect,
90  const UUID& uuid)
91  :
92  uuid_ (uuid),
93  last_seen_ (last_seen),
94  next_reconnect_ (next_reconnect),
95  retry_cnt_ (0),
96  max_retries_ (0)
97  { }
98 
99  const UUID& uuid() const { return uuid_; }
100 
101  void set_last_seen(const gu::datetime::Date& d) { last_seen_ = d; }
102 
103  const gu::datetime::Date& last_seen() const
104  { return last_seen_; }
105 
106  void set_next_reconnect(const gu::datetime::Date& d)
107  { next_reconnect_ = d; }
108 
109  const gu::datetime::Date& next_reconnect() const
110  { return next_reconnect_; }
111 
112  void set_retry_cnt(const int r) { retry_cnt_ = r; }
113 
114  int retry_cnt() const { return retry_cnt_; }
115 
116  void set_max_retries(int mr) { max_retries_ = mr; }
117  int max_retries() const { return max_retries_; }
118 
119  private:
120  friend std::ostream& operator<<(std::ostream&, const AddrEntry&);
121  void operator=(const AddrEntry&);
122  UUID uuid_;
123  gu::datetime::Date last_seen_;
124  gu::datetime::Date next_reconnect_;
125  int retry_cnt_;
126  int max_retries_;
127  };
128 
129 
130 
132  class AddrListUUIDCmp
133  {
134  public:
135  AddrListUUIDCmp(const UUID& uuid) : uuid_(uuid) { }
136  bool operator()(const AddrList::value_type& cmp) const
137  {
138  return (cmp.second.uuid() == uuid_);
139  }
140  private:
141  UUID uuid_;
142  };
143 
144  int version_;
145  static const int max_version_ = GCOMM_GMCAST_MAX_VERSION;
146  uint8_t segment_;
147  UUID my_uuid_;
148  bool use_ssl_;
149  std::string group_name_;
150  std::string listen_addr_;
151  std::set<std::string> initial_addrs_;
152  std::string mcast_addr_;
153  std::string bind_ip_;
154  int mcast_ttl_;
155  Acceptor* listener_;
156  SocketPtr mcast_;
157  AddrList pending_addrs_;
158  AddrList remote_addrs_;
159  AddrList addr_blacklist_;
160  bool relaying_;
161  bool isolate_;
162 
163  gmcast::ProtoMap* proto_map_;
164  std::set<Socket*> relay_set_;
165 
166  typedef std::vector<Socket*> Segment;
167  typedef std::map<uint8_t, Segment> SegmentMap;
168  SegmentMap segment_map_;
169  // self index in local segment when ordered by UUID
170  size_t self_index_;
171  gu::datetime::Period time_wait_;
172  gu::datetime::Period check_period_;
173  gu::datetime::Period peer_timeout_;
174  int max_initial_reconnect_attempts_;
175  gu::datetime::Date next_check_;
176  gu::datetime::Date handle_timers();
177 
178  // Accept new connection
179  void gmcast_accept();
180  // Initialize connecting to remote host
181  void gmcast_connect(const std::string&);
182  // Forget node
183  void gmcast_forget(const gcomm::UUID&);
184  // Handle proto entry that has established connection to remote host
185  void handle_connected(gmcast::Proto*);
186  // Handle proto entry that has succesfully finished handshake
187  // sequence
188  void handle_established(gmcast::Proto*);
189  // Handle proto entry that has failed
190  void handle_failed(gmcast::Proto*);
191 
192  // Check if there exists connection that matches to either
193  // remote addr or uuid
194  bool is_connected(const std::string& addr, const UUID& uuid) const;
195  // Inset address to address list
196  void insert_address(const std::string& addr, const UUID& uuid, AddrList&);
197  // Scan through proto entries and update address lists
198  void update_addresses();
199  //
200  void check_liveness();
201  void relay(const gmcast::Message& msg, const Datagram& dg,
202  const void* exclude_id);
203  // Reconnecting
204  void reconnect();
205 
206  void set_initial_addr(const gu::URI&);
207  void add_or_del_addr(const std::string&);
208 
209  std::string self_string() const
210  {
211  std::ostringstream os;
212  os << '(' << my_uuid_ << ", '" << listen_addr_ << "')";
213  return os.str();
214  }
215 
216  friend std::ostream& operator<<(std::ostream&, const AddrEntry&);
217  };
218 
219  inline std::ostream& operator<<(std::ostream& os, const GMCast::AddrEntry& ae)
220  {
221  return (os << ae.uuid_
222  << " last_seen=" << ae.last_seen_
223  << " next_reconnect=" << ae.next_reconnect_
224  << " retry_cnt=" << ae.retry_cnt_);
225  }
226 
227 }
228 
229 #endif // GCOMM_GMCAST_HPP
Definition: protonet.hpp:37
Transport interface.
Definition: transport.hpp:34
Definition: view.hpp:119
Definition: gmcast_proto.hpp:24
GComm exception definitions.
Definition: gmcast.hpp:33
Definition: gmcast_message.hpp:22
Definition: gmcast_proto.hpp:170
Definition: protolay.hpp:77
Definition: socket.hpp:72
Transport interface.
Definition: uuid.hpp:26
Definition: protolay.hpp:168
Datagram container.
Definition: datagram.hpp:151