1    	
2    	#include "msg_types.h"
3    	
4    	#include <arpa/inet.h>
5    	#include <stdlib.h>
6    	#include <string.h>
7    	#include <netdb.h>
8    	
9    	#include "common/Formatter.h"
10   	
11   	void entity_name_t::dump(Formatter *f) const
12   	{
13   	  f->dump_string("type", type_str());
14   	  f->dump_unsigned("num", num());
15   	}
16   	
17   	void entity_addr_t::dump(Formatter *f) const
18   	{
19   	  f->dump_string("type", get_type_name(type));
20   	  f->dump_stream("addr") << get_sockaddr();
21   	  f->dump_unsigned("nonce", nonce);
22   	}
23   	
24   	void entity_inst_t::dump(Formatter *f) const
25   	{
26   	  f->dump_object("name", name);
27   	  f->dump_object("addr", addr);
28   	}
29   	
30   	void entity_name_t::generate_test_instances(list<entity_name_t*>& o)
31   	{
32   	  o.push_back(new entity_name_t(entity_name_t::MON()));
33   	  o.push_back(new entity_name_t(entity_name_t::MON(1)));
34   	  o.push_back(new entity_name_t(entity_name_t::OSD(1)));
35   	  o.push_back(new entity_name_t(entity_name_t::CLIENT(1)));
36   	}
37   	
38   	void entity_addr_t::generate_test_instances(list<entity_addr_t*>& o)
39   	{
40   	  o.push_back(new entity_addr_t());
41   	  entity_addr_t *a = new entity_addr_t();
42   	  a->set_nonce(1);
43   	  o.push_back(a);
44   	  entity_addr_t *b = new entity_addr_t();
45   	  b->set_type(entity_addr_t::TYPE_LEGACY);
46   	  b->set_nonce(5);
47   	  b->set_family(AF_INET);
48   	  b->set_in4_quad(0, 127);
49   	  b->set_in4_quad(1, 0);
50   	  b->set_in4_quad(2, 1);
51   	  b->set_in4_quad(3, 2);
52   	  b->set_port(2);
53   	  o.push_back(b);
54   	}
55   	
56   	void entity_inst_t::generate_test_instances(list<entity_inst_t*>& o)
57   	{
58   	  o.push_back(new entity_inst_t());
59   	  entity_name_t name;
60   	  entity_addr_t addr;
61   	  entity_inst_t *a = new entity_inst_t(name, addr);
62   	  o.push_back(a);
63   	}
64   	
65   	bool entity_addr_t::parse(const char *s, const char **end, int default_type)
66   	{
67   	  *this = entity_addr_t();
68   	
69   	  const char *start = s;
70   	  if (end) {
71   	    *end = s;
72   	  }
73   	
74   	  int newtype;
75   	  if (strncmp("v1:", s, 3) == 0) {
76   	    start += 3;
77   	    newtype = TYPE_LEGACY;
78   	  } else if (strncmp("v2:", s, 3) == 0) {
79   	    start += 3;
80   	    newtype = TYPE_MSGR2;
81   	  } else if (strncmp("any:", s, 4) == 0) {
82   	    start += 4;
83   	    newtype = TYPE_ANY;
84   	  } else if (*s == '-') {
85   	    newtype = TYPE_NONE;
86   	    if (end) {
87   	      *end = s + 1;
88   	    }
89   	    return true;
90   	  } else {
91   	    newtype = default_type ? default_type : TYPE_DEFAULT;
92   	  }
93   	
94   	  bool brackets = false;
95   	  if (*start == '[') {
96   	    start++;
97   	    brackets = true;
98   	  }
99   	  
100  	  // inet_pton() requires a null terminated input, so let's fill two
101  	  // buffers, one with ipv4 allowed characters, and one with ipv6, and
102  	  // then see which parses.
103  	  char buf4[39];
104  	  char *o = buf4;
105  	  const char *p = start;
106  	  while (o < buf4 + sizeof(buf4) &&
107  		 *p && ((*p == '.') ||
108  			(*p >= '0' && *p <= '9'))) {
109  	    *o++ = *p++;
110  	  }
111  	  *o = 0;
112  	
113  	  char buf6[64];  // actually 39 + null is sufficient.
114  	  o = buf6;
115  	  p = start;
116  	  while (o < buf6 + sizeof(buf6) &&
117  		 *p && ((*p == ':') ||
118  			(*p >= '0' && *p <= '9') ||
119  			(*p >= 'a' && *p <= 'f') ||
120  			(*p >= 'A' && *p <= 'F'))) {
121  	    *o++ = *p++;
122  	  }
123  	  *o = 0;
124  	  //cout << "buf4 is '" << buf4 << "', buf6 is '" << buf6 << "'" << std::endl;
125  	
126  	  // ipv4?
127  	  struct in_addr a4;
128  	  struct in6_addr a6;
129  	  if (inet_pton(AF_INET, buf4, &a4)) {
130  	    u.sin.sin_addr.s_addr = a4.s_addr;
131  	    u.sa.sa_family = AF_INET;
132  	    p = start + strlen(buf4);
133  	  } else if (inet_pton(AF_INET6, buf6, &a6)) {
134  	    u.sa.sa_family = AF_INET6;
135  	    memcpy(&u.sin6.sin6_addr, &a6, sizeof(a6));
136  	    p = start + strlen(buf6);
137  	  } else {
138  	    return false;
139  	  }
140  	
141  	  if (brackets) {
142  	    if (*p != ']')
143  	      return false;
144  	    p++;
145  	  }
146  	  
147  	  //cout << "p is " << *p << std::endl;
148  	  if (*p == ':') {
149  	    // parse a port, too!
150  	    p++;
151  	    int port = atoi(p);
152  	    if (port > MAX_PORT_NUMBER) {
153  	      return false;
154  	    }
155  	    set_port(port);
156  	    while (*p && *p >= '0' && *p <= '9')
157  	      p++;
158  	  }
159  	
160  	  if (*p == '/') {
161  	    // parse nonce, too
162  	    p++;
163  	    int non = atoi(p);
164  	    set_nonce(non);
165  	    while (*p && *p >= '0' && *p <= '9')
166  	      p++;
167  	  }
168  	
169  	  if (end)
170  	    *end = p;
171  	
172  	  type = newtype;
173  	
174  	  //cout << *this << std::endl;
175  	  return true;
176  	}
177  	
178  	ostream& operator<<(ostream& out, const entity_addr_t &addr)
179  	{
180  	  if (addr.type == entity_addr_t::TYPE_NONE) {
181  	    return out << "-";
182  	  }
183  	  if (addr.type != entity_addr_t::TYPE_ANY) {
184  	    out << entity_addr_t::get_type_name(addr.type) << ":";
185  	  }
186  	  out << addr.get_sockaddr() << '/' << addr.nonce;
187  	  return out;
188  	}
189  	
190  	ostream& operator<<(ostream& out, const sockaddr *psa)
191  	{
192  	  char buf[NI_MAXHOST] = { 0 };
193  	
194  	  switch (psa->sa_family) {
195  	  case AF_INET:
196  	    {
197  	      const sockaddr_in *sa = (const sockaddr_in*)psa;
198  	      inet_ntop(AF_INET, &sa->sin_addr, buf, NI_MAXHOST);
199  	      return out << buf << ':'
200  			 << ntohs(sa->sin_port);
201  	    }
202  	  case AF_INET6:
203  	    {
204  	      const sockaddr_in6 *sa = (const sockaddr_in6*)psa;
205  	      inet_ntop(AF_INET6, &sa->sin6_addr, buf, NI_MAXHOST);
206  	      return out << '[' << buf << "]:"
207  			 << ntohs(sa->sin6_port);
208  	    }
209  	  default:
210  	    return out << "(unrecognized address family " << psa->sa_family << ")";
211  	  }
212  	}
213  	
214  	ostream& operator<<(ostream& out, const sockaddr_storage &ss)
215  	{
216  	  return out << (const sockaddr*)&ss;
217  	}
218  	
219  	
220  	// entity_addrvec_t
221  	
222  	bool entity_addrvec_t::parse(const char *s, const char **end)
223  	{
224  	  const char *orig_s = s;
225  	  const char *static_end;
226  	  if (!end) {
227  	    end = &static_end;
228  	  } else {
229  	    *end = s;
230  	  }
231  	  v.clear();
232  	  bool brackets = false;
233  	  if (*s == '[') {
234  	    // weirdness: make sure this isn't an IPV6 addr!
235  	    entity_addr_t a;
236  	    const char *p;
237  	    if (!a.parse(s, &p) || !a.is_ipv6()) {
238  	      // it's not
239  	      brackets = true;
240  	      ++s;
241  	    }
242  	  }
243  	  while (*s) {
244  	    entity_addr_t a;
245  	    bool r = a.parse(s, end);
246  	    if (!r) {
247  	      if (brackets) {
248  		v.clear();
249  		*end = orig_s;
250  		return false;
251  	      }
252  	      break;
253  	    }
254  	    v.push_back(a);
255  	    s = *end;
256  	    if (!brackets) {
257  	      break;
258  	    }
259  	    if (*s != ',') {
260  	      break;
261  	    }
262  	    ++s;
263  	  }
264  	  if (brackets) {
265  	    if (*s == ']') {
266  	      ++s;
267  	      *end = s;
268  	    } else {
269  	      *end = orig_s;
270  	      v.clear();
271  	      return false;
272  	    }
273  	  }
274  	  return !v.empty();
275  	}
276  	
277  	void entity_addrvec_t::encode(bufferlist& bl, uint64_t features) const
278  	{
279  	  using ceph::encode;
(1) Event cond_false: Condition "(features & 576460752303423488UL /* CEPH_FEATURE_MSG_ADDR2 */) == 0", taking false branch.
280  	  if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
281  	    // encode a single legacy entity_addr_t for unfeatured peers
282  	    encode(legacy_addr(), bl, 0);
283  	    return;
(2) Event if_end: End of if statement.
284  	  }
(3) Event overrun-buffer-val: Overrunning buffer pointed to by "__u8 const(2)" of 1 bytes by passing it to a function which accesses it at byte offset 7. [details]
285  	  encode((__u8)2, bl);
286  	  encode(v, bl, features);
287  	}
288  	
289  	void entity_addrvec_t::decode(bufferlist::const_iterator& bl)
290  	{
291  	  using ceph::decode;
292  	  __u8 marker;
293  	  decode(marker, bl);
294  	  if (marker == 0) {
295  	    // legacy!
296  	    entity_addr_t addr;
297  	    addr.decode_legacy_addr_after_marker(bl);
298  	    v.clear();
299  	    v.push_back(addr);
300  	    return;
301  	  }
302  	  if (marker == 1) {
303  	    entity_addr_t addr;
304  	    DECODE_START(1, bl);
305  	    decode(addr.type, bl);
306  	    decode(addr.nonce, bl);
307  	    __u32 elen;
308  	    decode(elen, bl);
309  	    if (elen) {
310  	      bl.copy(elen, (char*)addr.get_sockaddr());
311  	    }
312  	    DECODE_FINISH(bl);
313  	    v.clear();
314  	    v.push_back(addr);
315  	    return;
316  	  }
317  	  if (marker > 2)
318  	    throw buffer::malformed_input("entity_addrvec_marker > 2");
319  	  decode(v, bl);
320  	}
321  	
322  	void entity_addrvec_t::dump(Formatter *f) const
323  	{
324  	  f->open_array_section("addrvec");
325  	  for (vector<entity_addr_t>::const_iterator p = v.begin();
326  	       p != v.end(); ++p) {
327  	    f->dump_object("addr", *p);
328  	  }
329  	  f->close_section();
330  	}
331  	
332  	void entity_addrvec_t::generate_test_instances(list<entity_addrvec_t*>& ls)
333  	{
334  	  ls.push_back(new entity_addrvec_t());
335  	  ls.push_back(new entity_addrvec_t());
336  	  ls.back()->v.push_back(entity_addr_t());
337  	  ls.push_back(new entity_addrvec_t());
338  	  ls.back()->v.push_back(entity_addr_t());
339  	  ls.back()->v.push_back(entity_addr_t());
340  	}
341  	
342  	std::string entity_addr_t::ip_only_to_str() const 
343  	{
344  	  const char *host_ip = NULL;
345  	  char addr_buf[INET6_ADDRSTRLEN];
346  	  switch (get_family()) {
347  	  case AF_INET:
348  	    host_ip = inet_ntop(AF_INET, &in4_addr().sin_addr, 
349  	                        addr_buf, INET_ADDRSTRLEN);
350  	    break;
351  	  case AF_INET6:
352  	    host_ip = inet_ntop(AF_INET6, &in6_addr().sin6_addr, 
353  	                        addr_buf, INET6_ADDRSTRLEN);
354  	    break;
355  	  default:
356  	    break;
357  	  }
358  	  return host_ip ? host_ip : "";
359  	}
360