]> git.proxmox.com Git - ceph.git/blame - ceph/src/msg/msg_types.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / msg / msg_types.h
CommitLineData
11fdf7f2 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
7c673cae
FG
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
11fdf7f2 10 * License version 2.1, as published by the Free Software
7c673cae 11 * Foundation. See file COPYING.
11fdf7f2 12 *
7c673cae
FG
13 */
14
15#ifndef CEPH_MSG_TYPES_H
16#define CEPH_MSG_TYPES_H
17
11fdf7f2
TL
18#include <sstream>
19
7c673cae
FG
20#include <netinet/in.h>
21
22#include "include/ceph_features.h"
23#include "include/types.h"
24#include "include/blobhash.h"
25#include "include/encoding.h"
26
11fdf7f2
TL
27#define MAX_PORT_NUMBER 65535
28
7c673cae
FG
29namespace ceph {
30 class Formatter;
31}
32
33extern ostream& operator<<(ostream& out, const sockaddr_storage &ss);
34extern ostream& operator<<(ostream& out, const sockaddr *sa);
35
36typedef uint8_t entity_type_t;
37
38class entity_name_t {
39public:
40 entity_type_t _type;
41 int64_t _num;
42
43public:
44 static const int TYPE_MON = CEPH_ENTITY_TYPE_MON;
45 static const int TYPE_MDS = CEPH_ENTITY_TYPE_MDS;
46 static const int TYPE_OSD = CEPH_ENTITY_TYPE_OSD;
47 static const int TYPE_CLIENT = CEPH_ENTITY_TYPE_CLIENT;
48 static const int TYPE_MGR = CEPH_ENTITY_TYPE_MGR;
49
50 static const int64_t NEW = -1;
51
52 // cons
53 entity_name_t() : _type(0), _num(0) { }
54 entity_name_t(int t, int64_t n) : _type(t), _num(n) { }
11fdf7f2 55 explicit entity_name_t(const ceph_entity_name &n) :
7c673cae
FG
56 _type(n.type), _num(n.num) { }
57
58 // static cons
59 static entity_name_t MON(int64_t i=NEW) { return entity_name_t(TYPE_MON, i); }
60 static entity_name_t MDS(int64_t i=NEW) { return entity_name_t(TYPE_MDS, i); }
61 static entity_name_t OSD(int64_t i=NEW) { return entity_name_t(TYPE_OSD, i); }
62 static entity_name_t CLIENT(int64_t i=NEW) { return entity_name_t(TYPE_CLIENT, i); }
63 static entity_name_t MGR(int64_t i=NEW) { return entity_name_t(TYPE_MGR, i); }
11fdf7f2 64
7c673cae
FG
65 int64_t num() const { return _num; }
66 int type() const { return _type; }
67 const char *type_str() const {
68 return ceph_entity_type_name(type());
69 }
70
71 bool is_new() const { return num() < 0; }
72
73 bool is_client() const { return type() == TYPE_CLIENT; }
74 bool is_mds() const { return type() == TYPE_MDS; }
75 bool is_osd() const { return type() == TYPE_OSD; }
76 bool is_mon() const { return type() == TYPE_MON; }
77 bool is_mgr() const { return type() == TYPE_MGR; }
78
79 operator ceph_entity_name() const {
80 ceph_entity_name n = { _type, init_le64(_num) };
81 return n;
82 }
83
84 bool parse(const string& s) {
85 const char *start = s.c_str();
86 char *end;
87 bool got = parse(start, &end);
88 return got && end == start + s.length();
89 }
90 bool parse(const char *start, char **end) {
91 if (strstr(start, "mon.") == start) {
92 _type = TYPE_MON;
93 start += 4;
94 } else if (strstr(start, "osd.") == start) {
95 _type = TYPE_OSD;
96 start += 4;
97 } else if (strstr(start, "mds.") == start) {
98 _type = TYPE_MDS;
99 start += 4;
100 } else if (strstr(start, "client.") == start) {
101 _type = TYPE_CLIENT;
102 start += 7;
103 } else if (strstr(start, "mgr.") == start) {
104 _type = TYPE_MGR;
105 start += 4;
106 } else {
107 return false;
108 }
109 if (isspace(*start))
110 return false;
111 _num = strtoll(start, end, 10);
112 if (*end == NULL || *end == start)
113 return false;
114 return true;
115 }
116
117 DENC(entity_name_t, v, p) {
118 denc(v._type, p);
119 denc(v._num, p);
120 }
121 void dump(Formatter *f) const;
122
123 static void generate_test_instances(list<entity_name_t*>& o);
124};
125WRITE_CLASS_DENC(entity_name_t)
126
11fdf7f2 127inline bool operator== (const entity_name_t& l, const entity_name_t& r) {
7c673cae 128 return (l.type() == r.type()) && (l.num() == r.num()); }
11fdf7f2 129inline bool operator!= (const entity_name_t& l, const entity_name_t& r) {
7c673cae 130 return (l.type() != r.type()) || (l.num() != r.num()); }
11fdf7f2 131inline bool operator< (const entity_name_t& l, const entity_name_t& r) {
7c673cae
FG
132 return (l.type() < r.type()) || (l.type() == r.type() && l.num() < r.num()); }
133
134inline std::ostream& operator<<(std::ostream& out, const entity_name_t& addr) {
135 //if (addr.is_namer()) return out << "namer";
136 if (addr.is_new() || addr.num() < 0)
137 return out << addr.type_str() << ".?";
138 else
139 return out << addr.type_str() << '.' << addr.num();
140}
141inline std::ostream& operator<<(std::ostream& out, const ceph_entity_name& addr) {
11fdf7f2 142 return out << entity_name_t{addr.type, static_cast<int64_t>(addr.num)};
7c673cae
FG
143}
144
145namespace std {
146 template<> struct hash< entity_name_t >
147 {
148 size_t operator()( const entity_name_t &m ) const
149 {
150 return rjhash32(m.type() ^ m.num());
151 }
152 };
153} // namespace std
154
7c673cae
FG
155// define a wire format for sockaddr that matches Linux's.
156struct ceph_sockaddr_storage {
157 __le16 ss_family;
158 __u8 __ss_padding[128 - sizeof(__le16)];
159
160 void encode(bufferlist& bl) const {
161 struct ceph_sockaddr_storage ss = *this;
162 ss.ss_family = htons(ss.ss_family);
163 ::encode_raw(ss, bl);
164 }
165
11fdf7f2 166 void decode(bufferlist::const_iterator& bl) {
7c673cae
FG
167 struct ceph_sockaddr_storage ss;
168 ::decode_raw(ss, bl);
169 ss.ss_family = ntohs(ss.ss_family);
170 *this = ss;
171 }
172} __attribute__ ((__packed__));
173WRITE_CLASS_ENCODER(ceph_sockaddr_storage)
174
11fdf7f2
TL
175/*
176 * encode sockaddr.ss_family as network byte order
177 */
178static inline void encode(const sockaddr_storage& a, bufferlist& bl) {
179#if defined(__linux__)
180 struct sockaddr_storage ss = a;
181 ss.ss_family = htons(ss.ss_family);
182 ::encode_raw(ss, bl);
183#elif defined(__FreeBSD__) || defined(__APPLE__)
184 ceph_sockaddr_storage ss{};
185 auto src = (unsigned char const *)&a;
186 auto dst = (unsigned char *)&ss;
187 src += sizeof(a.ss_len);
188 ss.ss_family = a.ss_family;
189 src += sizeof(a.ss_family);
190 dst += sizeof(ss.ss_family);
191 const auto copy_size = std::min((unsigned char*)(&a + 1) - src,
192 (unsigned char*)(&ss + 1) - dst);
193 ::memcpy(dst, src, copy_size);
194 encode(ss, bl);
195#else
196 ceph_sockaddr_storage ss{};
197 ::memset(&ss, '\0', sizeof(ss));
198 ::memcpy(&wireaddr, &ss, std::min(sizeof(ss), sizeof(a)));
199 encode(ss, bl);
200#endif
201}
202static inline void decode(sockaddr_storage& a, bufferlist::const_iterator& bl) {
203#if defined(__linux__)
204 ::decode_raw(a, bl);
205 a.ss_family = ntohs(a.ss_family);
206#elif defined(__FreeBSD__) || defined(__APPLE__)
207 ceph_sockaddr_storage ss{};
208 decode(ss, bl);
209 auto src = (unsigned char const *)&ss;
210 auto dst = (unsigned char *)&a;
211 a.ss_len = 0;
212 dst += sizeof(a.ss_len);
213 a.ss_family = ss.ss_family;
214 src += sizeof(ss.ss_family);
215 dst += sizeof(a.ss_family);
216 auto const copy_size = std::min((unsigned char*)(&ss + 1) - src,
217 (unsigned char*)(&a + 1) - dst);
218 ::memcpy(dst, src, copy_size);
219#else
220 ceph_sockaddr_storage ss{};
221 decode(ss, bl);
222 ::memcpy(&a, &ss, std::min(sizeof(ss), sizeof(a)));
223#endif
224}
225
226/*
227 * an entity's network address.
228 * includes a random value that prevents it from being reused.
229 * thus identifies a particular process instance.
230 * ipv4 for now.
231 */
7c673cae
FG
232struct entity_addr_t {
233 typedef enum {
234 TYPE_NONE = 0,
235 TYPE_LEGACY = 1, ///< legacy msgr1 protocol (ceph jewel and older)
236 TYPE_MSGR2 = 2, ///< msgr2 protocol (new in ceph kraken)
11fdf7f2 237 TYPE_ANY = 3, ///< ambiguous
7c673cae 238 } type_t;
11fdf7f2
TL
239 static const type_t TYPE_DEFAULT = TYPE_MSGR2;
240 static std::string_view get_type_name(int t) {
7c673cae
FG
241 switch (t) {
242 case TYPE_NONE: return "none";
11fdf7f2
TL
243 case TYPE_LEGACY: return "v1";
244 case TYPE_MSGR2: return "v2";
245 case TYPE_ANY: return "any";
7c673cae
FG
246 default: return "???";
247 }
248 };
249
250 __u32 type;
251 __u32 nonce;
252 union {
253 sockaddr sa;
254 sockaddr_in sin;
255 sockaddr_in6 sin6;
256 } u;
257
11fdf7f2 258 entity_addr_t() : type(0), nonce(0) {
7c673cae
FG
259 memset(&u, 0, sizeof(u));
260 }
261 entity_addr_t(__u32 _type, __u32 _nonce) : type(_type), nonce(_nonce) {
262 memset(&u, 0, sizeof(u));
263 }
264 explicit entity_addr_t(const ceph_entity_addr &o) {
265 type = o.type;
266 nonce = o.nonce;
267 memcpy(&u, &o.in_addr, sizeof(u));
268#if !defined(__FreeBSD__)
269 u.sa.sa_family = ntohs(u.sa.sa_family);
270#endif
271 }
272
273 uint32_t get_type() const { return type; }
274 void set_type(uint32_t t) { type = t; }
11fdf7f2
TL
275 bool is_legacy() const { return type == TYPE_LEGACY; }
276 bool is_msgr2() const { return type == TYPE_MSGR2; }
277 bool is_any() const { return type == TYPE_ANY; }
7c673cae
FG
278
279 __u32 get_nonce() const { return nonce; }
280 void set_nonce(__u32 n) { nonce = n; }
281
282 int get_family() const {
283 return u.sa.sa_family;
284 }
285 void set_family(int f) {
286 u.sa.sa_family = f;
287 }
288
11fdf7f2
TL
289 bool is_ipv4() const {
290 return u.sa.sa_family == AF_INET;
291 }
292 bool is_ipv6() const {
293 return u.sa.sa_family == AF_INET6;
294 }
295
7c673cae
FG
296 sockaddr_in &in4_addr() {
297 return u.sin;
298 }
299 const sockaddr_in &in4_addr() const{
300 return u.sin;
301 }
302 sockaddr_in6 &in6_addr(){
303 return u.sin6;
304 }
305 const sockaddr_in6 &in6_addr() const{
306 return u.sin6;
307 }
308 const sockaddr *get_sockaddr() const {
309 return &u.sa;
310 }
311 size_t get_sockaddr_len() const {
312 switch (u.sa.sa_family) {
313 case AF_INET:
314 return sizeof(u.sin);
315 case AF_INET6:
316 return sizeof(u.sin6);
317 }
318 return sizeof(u);
319 }
320 bool set_sockaddr(const struct sockaddr *sa)
321 {
322 switch (sa->sa_family) {
323 case AF_INET:
11fdf7f2
TL
324 // pre-zero, since we're only copying a portion of the source
325 memset(&u, 0, sizeof(u));
7c673cae
FG
326 memcpy(&u.sin, sa, sizeof(u.sin));
327 break;
328 case AF_INET6:
11fdf7f2
TL
329 // pre-zero, since we're only copying a portion of the source
330 memset(&u, 0, sizeof(u));
7c673cae
FG
331 memcpy(&u.sin6, sa, sizeof(u.sin6));
332 break;
11fdf7f2
TL
333 case AF_UNSPEC:
334 memset(&u, 0, sizeof(u));
335 break;
7c673cae
FG
336 default:
337 return false;
338 }
339 return true;
340 }
341
342 sockaddr_storage get_sockaddr_storage() const {
343 sockaddr_storage ss;
344 memcpy(&ss, &u, sizeof(u));
345 memset((char*)&ss + sizeof(u), 0, sizeof(ss) - sizeof(u));
346 return ss;
347 }
348
349 void set_in4_quad(int pos, int val) {
350 u.sin.sin_family = AF_INET;
351 unsigned char *ipq = (unsigned char*)&u.sin.sin_addr.s_addr;
352 ipq[pos] = val;
353 }
354 void set_port(int port) {
355 switch (u.sa.sa_family) {
356 case AF_INET:
357 u.sin.sin_port = htons(port);
358 break;
359 case AF_INET6:
360 u.sin6.sin6_port = htons(port);
361 break;
362 default:
363 ceph_abort();
364 }
365 }
366 int get_port() const {
367 switch (u.sa.sa_family) {
368 case AF_INET:
369 return ntohs(u.sin.sin_port);
370 break;
371 case AF_INET6:
372 return ntohs(u.sin6.sin6_port);
373 break;
374 }
375 return 0;
376 }
377
378 operator ceph_entity_addr() const {
379 ceph_entity_addr a;
380 a.type = 0;
381 a.nonce = nonce;
382 a.in_addr = get_sockaddr_storage();
383#if !defined(__FreeBSD__)
384 a.in_addr.ss_family = htons(a.in_addr.ss_family);
385#endif
386 return a;
387 }
388
389 bool probably_equals(const entity_addr_t &o) const {
390 if (get_port() != o.get_port())
391 return false;
392 if (get_nonce() != o.get_nonce())
393 return false;
394 if (is_blank_ip() || o.is_blank_ip())
395 return true;
396 if (memcmp(&u, &o.u, sizeof(u)) == 0)
397 return true;
398 return false;
399 }
11fdf7f2 400
7c673cae
FG
401 bool is_same_host(const entity_addr_t &o) const {
402 if (u.sa.sa_family != o.u.sa.sa_family)
403 return false;
404 if (u.sa.sa_family == AF_INET)
405 return u.sin.sin_addr.s_addr == o.u.sin.sin_addr.s_addr;
406 if (u.sa.sa_family == AF_INET6)
407 return memcmp(u.sin6.sin6_addr.s6_addr,
408 o.u.sin6.sin6_addr.s6_addr,
409 sizeof(u.sin6.sin6_addr.s6_addr)) == 0;
410 return false;
411 }
412
413 bool is_blank_ip() const {
414 switch (u.sa.sa_family) {
415 case AF_INET:
416 return u.sin.sin_addr.s_addr == INADDR_ANY;
417 case AF_INET6:
418 return memcmp(&u.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0;
419 default:
420 return true;
421 }
422 }
423
424 bool is_ip() const {
425 switch (u.sa.sa_family) {
426 case AF_INET:
427 case AF_INET6:
428 return true;
429 default:
430 return false;
431 }
432 }
433
11fdf7f2 434 std::string ip_only_to_str() const;
7c673cae 435
11fdf7f2
TL
436 std::string get_legacy_str() const {
437 ostringstream ss;
438 ss << get_sockaddr() << "/" << get_nonce();
439 return ss.str();
440 }
441
442 bool parse(const char *s, const char **end = 0, int type=0);
443
444 void decode_legacy_addr_after_marker(bufferlist::const_iterator& bl)
7c673cae 445 {
11fdf7f2 446 using ceph::decode;
7c673cae
FG
447 __u8 marker;
448 __u16 rest;
11fdf7f2
TL
449 decode(marker, bl);
450 decode(rest, bl);
451 decode(nonce, bl);
7c673cae 452 sockaddr_storage ss;
11fdf7f2 453 decode(ss, bl);
7c673cae 454 set_sockaddr((sockaddr*)&ss);
11fdf7f2
TL
455 if (get_family() == AF_UNSPEC) {
456 type = TYPE_NONE;
457 } else {
458 type = TYPE_LEGACY;
459 }
7c673cae
FG
460 }
461
462 // Right now, these only deal with sockaddr_storage that have only family and content.
463 // Apparently on BSD there is also an ss_len that we need to handle; this requires
464 // broader study
465
466 void encode(bufferlist& bl, uint64_t features) const {
11fdf7f2 467 using ceph::encode;
7c673cae 468 if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
11fdf7f2
TL
469 encode((__u32)0, bl);
470 encode(nonce, bl);
7c673cae 471 sockaddr_storage ss = get_sockaddr_storage();
11fdf7f2 472 encode(ss, bl);
7c673cae
FG
473 return;
474 }
11fdf7f2 475 encode((__u8)1, bl);
7c673cae 476 ENCODE_START(1, 1, bl);
11fdf7f2
TL
477 if (HAVE_FEATURE(features, SERVER_NAUTILUS)) {
478 encode(type, bl);
479 } else {
480 // map any -> legacy for old clients. this is primary for the benefit
481 // of OSDMap's blacklist, but is reasonable in general since any: is
482 // meaningless for pre-nautilus clients or daemons.
483 auto t = type;
484 if (t == TYPE_ANY) {
485 t = TYPE_LEGACY;
486 }
487 encode(t, bl);
488 }
489 encode(nonce, bl);
7c673cae 490 __u32 elen = get_sockaddr_len();
11fdf7f2 491 encode(elen, bl);
7c673cae 492 if (elen) {
a8e16298
TL
493#if (__FreeBSD__) || defined(__APPLE__)
494 __le16 ss_family = u.sa.sa_family;
11fdf7f2 495 encode(ss_family, bl);
a8e16298
TL
496 bl.append(u.sa.sa_data,
497 elen - sizeof(u.sa.sa_len) - sizeof(u.sa.sa_family));
498#else
7c673cae 499 bl.append((char*)get_sockaddr(), elen);
a8e16298 500#endif
7c673cae
FG
501 }
502 ENCODE_FINISH(bl);
503 }
11fdf7f2
TL
504 void decode(bufferlist::const_iterator& bl) {
505 using ceph::decode;
7c673cae 506 __u8 marker;
11fdf7f2 507 decode(marker, bl);
7c673cae
FG
508 if (marker == 0) {
509 decode_legacy_addr_after_marker(bl);
510 return;
511 }
512 if (marker != 1)
513 throw buffer::malformed_input("entity_addr_t marker != 1");
514 DECODE_START(1, bl);
11fdf7f2
TL
515 decode(type, bl);
516 decode(nonce, bl);
7c673cae 517 __u32 elen;
11fdf7f2 518 decode(elen, bl);
7c673cae 519 if (elen) {
a8e16298
TL
520#if defined(__FreeBSD__) || defined(__APPLE__)
521 u.sa.sa_len = 0;
522 __le16 ss_family;
523 if (elen < sizeof(ss_family)) {
524 throw buffer::malformed_input("elen smaller than family len");
525 }
11fdf7f2 526 decode(ss_family, bl);
a8e16298
TL
527 u.sa.sa_family = ss_family;
528 elen -= sizeof(ss_family);
529 if (elen > get_sockaddr_len() - sizeof(u.sa.sa_family)) {
530 throw buffer::malformed_input("elen exceeds sockaddr len");
531 }
532 bl.copy(elen, u.sa.sa_data);
533#else
534 if (elen < sizeof(u.sa.sa_family)) {
535 throw buffer::malformed_input("elen smaller than family len");
536 }
537 bl.copy(sizeof(u.sa.sa_family), (char*)&u.sa.sa_family);
538 if (elen > get_sockaddr_len()) {
539 throw buffer::malformed_input("elen exceeds sockaddr len");
540 }
541 elen -= sizeof(u.sa.sa_family);
542 bl.copy(elen, u.sa.sa_data);
543#endif
7c673cae
FG
544 }
545 DECODE_FINISH(bl);
546 }
547
548 void dump(Formatter *f) const;
549
550 static void generate_test_instances(list<entity_addr_t*>& o);
551};
552WRITE_CLASS_ENCODER_FEATURES(entity_addr_t)
553
554ostream& operator<<(ostream& out, const entity_addr_t &addr);
555
556inline bool operator==(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) == 0; }
557inline bool operator!=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) != 0; }
558inline bool operator<(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) < 0; }
559inline bool operator<=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) <= 0; }
560inline bool operator>(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) > 0; }
561inline bool operator>=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) >= 0; }
562
563namespace std {
564 template<> struct hash< entity_addr_t >
565 {
566 size_t operator()( const entity_addr_t& x ) const
567 {
568 static blobhash H;
569 return H((const char*)&x, sizeof(x));
570 }
571 };
572} // namespace std
573
574struct entity_addrvec_t {
575 vector<entity_addr_t> v;
576
11fdf7f2
TL
577 entity_addrvec_t() {}
578 explicit entity_addrvec_t(const entity_addr_t& a) : v({ a }) {}
579
7c673cae
FG
580 unsigned size() const { return v.size(); }
581 bool empty() const { return v.empty(); }
582
11fdf7f2
TL
583 entity_addr_t legacy_addr() const {
584 for (auto& a : v) {
585 if (a.type == entity_addr_t::TYPE_LEGACY) {
586 return a;
587 }
588 }
589 return entity_addr_t();
590 }
591 entity_addr_t as_legacy_addr() const {
592 for (auto& a : v) {
593 if (a.is_legacy()) {
594 return a;
595 }
596 if (a.is_any()) {
597 auto b = a;
598 b.set_type(entity_addr_t::TYPE_LEGACY);
599 return b;
600 }
601 }
602 // hrm... lie!
603 auto a = front();
604 a.set_type(entity_addr_t::TYPE_LEGACY);
605 return a;
606 }
607 entity_addr_t front() const {
608 if (!v.empty()) {
609 return v.front();
610 }
611 return entity_addr_t();
612 }
613 entity_addr_t legacy_or_front_addr() const {
614 for (auto& a : v) {
615 if (a.type == entity_addr_t::TYPE_LEGACY) {
616 return a;
617 }
618 }
619 if (!v.empty()) {
620 return v.front();
621 }
622 return entity_addr_t();
623 }
624 string get_legacy_str() const {
625 return legacy_or_front_addr().get_legacy_str();
626 }
627
628 entity_addr_t msgr2_addr() const {
629 for (auto &a : v) {
630 if (a.type == entity_addr_t::TYPE_MSGR2) {
631 return a;
632 }
633 }
634 return entity_addr_t();
635 }
636 bool has_msgr2() const {
637 for (auto& a : v) {
638 if (a.is_msgr2()) {
639 return true;
640 }
641 }
642 return false;
643 }
644
645 bool parse(const char *s, const char **end = 0);
646
647 void get_ports(set<int> *ports) const {
648 for (auto& a : v) {
649 ports->insert(a.get_port());
650 }
651 }
652 set<int> get_ports() const {
653 set<int> r;
654 get_ports(&r);
655 return r;
656 }
657
7c673cae 658 void encode(bufferlist& bl, uint64_t features) const;
11fdf7f2 659 void decode(bufferlist::const_iterator& bl);
7c673cae
FG
660 void dump(Formatter *f) const;
661 static void generate_test_instances(list<entity_addrvec_t*>& ls);
11fdf7f2
TL
662
663 bool legacy_equals(const entity_addrvec_t& o) const {
664 if (v == o.v) {
665 return true;
666 }
667 if (v.size() == 1 &&
668 front().is_legacy() &&
669 front() == o.legacy_addr()) {
670 return true;
671 }
672 if (o.v.size() == 1 &&
673 o.front().is_legacy() &&
674 o.front() == legacy_addr()) {
675 return true;
676 }
677 return false;
678 }
679
680 bool probably_equals(const entity_addrvec_t& o) const {
681 for (unsigned i = 0; i < v.size(); ++i) {
682 if (!v[i].probably_equals(o.v[i])) {
683 return false;
684 }
685 }
686 return true;
687 }
688 bool contains(const entity_addr_t& a) const {
689 for (auto& i : v) {
690 if (a == i) {
691 return true;
692 }
693 }
694 return false;
695 }
696 bool is_same_host(const entity_addr_t& a) const {
697 for (auto& i : v) {
698 if (i.is_same_host(a)) {
699 return true;
700 }
701 }
702 return false;
703 }
704
705 friend ostream& operator<<(ostream& out, const entity_addrvec_t& av) {
706 if (av.v.empty()) {
707 return out;
708 } else if (av.v.size() == 1) {
709 return out << av.v[0];
710 } else {
711 return out << av.v;
712 }
713 }
714
715 friend bool operator==(const entity_addrvec_t& l, const entity_addrvec_t& r) {
716 return l.v == r.v;
717 }
718 friend bool operator!=(const entity_addrvec_t& l, const entity_addrvec_t& r) {
719 return l.v != r.v;
720 }
721 friend bool operator<(const entity_addrvec_t& l, const entity_addrvec_t& r) {
722 return l.v < r.v; // see lexicographical_compare()
723 }
7c673cae
FG
724};
725WRITE_CLASS_ENCODER_FEATURES(entity_addrvec_t);
726
11fdf7f2
TL
727namespace std {
728 template<> struct hash< entity_addrvec_t >
729 {
730 size_t operator()( const entity_addrvec_t& x ) const
731 {
732 static blobhash H;
733 size_t r = 0;
734 for (auto& i : x.v) {
735 r += H((const char*)&i, sizeof(i));
736 }
737 return r;
738 }
739 };
740} // namespace std
741
7c673cae
FG
742/*
743 * a particular entity instance
744 */
745struct entity_inst_t {
746 entity_name_t name;
747 entity_addr_t addr;
748 entity_inst_t() {}
749 entity_inst_t(entity_name_t n, const entity_addr_t& a) : name(n), addr(a) {}
750 // cppcheck-suppress noExplicitConstructor
751 entity_inst_t(const ceph_entity_inst& i) : name(i.name), addr(i.addr) { }
752 entity_inst_t(const ceph_entity_name& n, const ceph_entity_addr &a) : name(n), addr(a) {}
753 operator ceph_entity_inst() {
754 ceph_entity_inst i = {name, addr};
755 return i;
756 }
757
758 void encode(bufferlist& bl, uint64_t features) const {
11fdf7f2
TL
759 using ceph::encode;
760 encode(name, bl);
761 encode(addr, bl, features);
7c673cae 762 }
11fdf7f2
TL
763 void decode(bufferlist::const_iterator& bl) {
764 using ceph::decode;
765 decode(name, bl);
766 decode(addr, bl);
7c673cae
FG
767 }
768
769 void dump(Formatter *f) const;
770 static void generate_test_instances(list<entity_inst_t*>& o);
771};
772WRITE_CLASS_ENCODER_FEATURES(entity_inst_t)
773
774
11fdf7f2 775inline bool operator==(const entity_inst_t& a, const entity_inst_t& b) {
7c673cae
FG
776 return a.name == b.name && a.addr == b.addr;
777}
11fdf7f2 778inline bool operator!=(const entity_inst_t& a, const entity_inst_t& b) {
7c673cae
FG
779 return a.name != b.name || a.addr != b.addr;
780}
11fdf7f2 781inline bool operator<(const entity_inst_t& a, const entity_inst_t& b) {
7c673cae
FG
782 return a.name < b.name || (a.name == b.name && a.addr < b.addr);
783}
784inline bool operator<=(const entity_inst_t& a, const entity_inst_t& b) {
785 return a.name < b.name || (a.name == b.name && a.addr <= b.addr);
786}
787inline bool operator>(const entity_inst_t& a, const entity_inst_t& b) { return b < a; }
788inline bool operator>=(const entity_inst_t& a, const entity_inst_t& b) { return b <= a; }
789
790namespace std {
791 template<> struct hash< entity_inst_t >
792 {
793 size_t operator()( const entity_inst_t& x ) const
794 {
795 static hash< entity_name_t > H;
796 static hash< entity_addr_t > I;
797 return H(x.name) ^ I(x.addr);
798 }
799 };
800} // namespace std
801
802
803inline ostream& operator<<(ostream& out, const entity_inst_t &i)
804{
805 return out << i.name << " " << i.addr;
806}
807inline ostream& operator<<(ostream& out, const ceph_entity_inst &i)
808{
809 entity_inst_t n = i;
810 return out << n;
811}
812
813#endif