1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #ifndef CEPH_MSG_TYPES_H
16 #define CEPH_MSG_TYPES_H
18 #include <netinet/in.h>
20 #include "include/ceph_features.h"
21 #include "include/types.h"
22 #include "include/blobhash.h"
23 #include "include/encoding.h"
29 extern ostream& operator<<(ostream& out, const sockaddr_storage &ss);
30 extern ostream& operator<<(ostream& out, const sockaddr *sa);
32 typedef uint8_t entity_type_t;
40 static const int TYPE_MON = CEPH_ENTITY_TYPE_MON;
41 static const int TYPE_MDS = CEPH_ENTITY_TYPE_MDS;
42 static const int TYPE_OSD = CEPH_ENTITY_TYPE_OSD;
43 static const int TYPE_CLIENT = CEPH_ENTITY_TYPE_CLIENT;
44 static const int TYPE_MGR = CEPH_ENTITY_TYPE_MGR;
46 static const int64_t NEW = -1;
49 entity_name_t() : _type(0), _num(0) { }
50 entity_name_t(int t, int64_t n) : _type(t), _num(n) { }
51 explicit entity_name_t(const ceph_entity_name &n) :
52 _type(n.type), _num(n.num) { }
55 static entity_name_t MON(int64_t i=NEW) { return entity_name_t(TYPE_MON, i); }
56 static entity_name_t MDS(int64_t i=NEW) { return entity_name_t(TYPE_MDS, i); }
57 static entity_name_t OSD(int64_t i=NEW) { return entity_name_t(TYPE_OSD, i); }
58 static entity_name_t CLIENT(int64_t i=NEW) { return entity_name_t(TYPE_CLIENT, i); }
59 static entity_name_t MGR(int64_t i=NEW) { return entity_name_t(TYPE_MGR, i); }
61 int64_t num() const { return _num; }
62 int type() const { return _type; }
63 const char *type_str() const {
64 return ceph_entity_type_name(type());
67 bool is_new() const { return num() < 0; }
69 bool is_client() const { return type() == TYPE_CLIENT; }
70 bool is_mds() const { return type() == TYPE_MDS; }
71 bool is_osd() const { return type() == TYPE_OSD; }
72 bool is_mon() const { return type() == TYPE_MON; }
73 bool is_mgr() const { return type() == TYPE_MGR; }
75 operator ceph_entity_name() const {
76 ceph_entity_name n = { _type, init_le64(_num) };
80 bool parse(const string& s) {
81 const char *start = s.c_str();
83 bool got = parse(start, &end);
84 return got && end == start + s.length();
86 bool parse(const char *start, char **end) {
87 if (strstr(start, "mon.") == start) {
90 } else if (strstr(start, "osd.") == start) {
93 } else if (strstr(start, "mds.") == start) {
96 } else if (strstr(start, "client.") == start) {
99 } else if (strstr(start, "mgr.") == start) {
107 _num = strtoll(start, end, 10);
108 if (*end == NULL || *end == start)
113 DENC(entity_name_t, v, p) {
117 void dump(Formatter *f) const;
119 static void generate_test_instances(list<entity_name_t*>& o);
121 WRITE_CLASS_DENC(entity_name_t)
123 inline bool operator== (const entity_name_t& l, const entity_name_t& r) {
124 return (l.type() == r.type()) && (l.num() == r.num()); }
125 inline bool operator!= (const entity_name_t& l, const entity_name_t& r) {
126 return (l.type() != r.type()) || (l.num() != r.num()); }
127 inline bool operator< (const entity_name_t& l, const entity_name_t& r) {
128 return (l.type() < r.type()) || (l.type() == r.type() && l.num() < r.num()); }
130 inline std::ostream& operator<<(std::ostream& out, const entity_name_t& addr) {
131 //if (addr.is_namer()) return out << "namer";
132 if (addr.is_new() || addr.num() < 0)
133 return out << addr.type_str() << ".?";
135 return out << addr.type_str() << '.' << addr.num();
137 inline std::ostream& operator<<(std::ostream& out, const ceph_entity_name& addr) {
138 return out << *(const entity_name_t*)&addr;
142 template<> struct hash< entity_name_t >
144 size_t operator()( const entity_name_t &m ) const
146 return rjhash32(m.type() ^ m.num());
152 * an entity's network address.
153 * includes a random value that prevents it from being reused.
154 * thus identifies a particular process instance.
158 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
160 * encode sockaddr.ss_family as network byte order
162 static inline void encode(const sockaddr_storage& a, bufferlist& bl) {
163 struct sockaddr_storage ss = a;
164 #if defined(DARWIN) || defined(__FreeBSD__)
165 unsigned short *ss_family = reinterpret_cast<unsigned short*>(&ss);
166 *ss_family = htons(a.ss_family);
168 ss.ss_family = htons(ss.ss_family);
170 ::encode_raw(ss, bl);
172 static inline void decode(sockaddr_storage& a, bufferlist::iterator& bl) {
174 #if defined(DARWIN) || defined(__FreeBSD__)
175 unsigned short *ss_family = reinterpret_cast<unsigned short *>(&a);
176 a.ss_family = ntohs(*ss_family);
179 a.ss_family = ntohs(a.ss_family);
184 // define a wire format for sockaddr that matches Linux's.
185 struct ceph_sockaddr_storage {
187 __u8 __ss_padding[128 - sizeof(__le16)];
189 void encode(bufferlist& bl) const {
190 struct ceph_sockaddr_storage ss = *this;
191 ss.ss_family = htons(ss.ss_family);
192 ::encode_raw(ss, bl);
195 void decode(bufferlist::iterator& bl) {
196 struct ceph_sockaddr_storage ss;
197 ::decode_raw(ss, bl);
198 ss.ss_family = ntohs(ss.ss_family);
201 } __attribute__ ((__packed__));
202 WRITE_CLASS_ENCODER(ceph_sockaddr_storage)
204 struct entity_addr_t {
207 TYPE_LEGACY = 1, ///< legacy msgr1 protocol (ceph jewel and older)
208 TYPE_MSGR2 = 2, ///< msgr2 protocol (new in ceph kraken)
210 static const type_t TYPE_DEFAULT = TYPE_LEGACY;
211 static const char *get_type_name(int t) {
213 case TYPE_NONE: return "none";
214 case TYPE_LEGACY: return "legacy";
215 case TYPE_MSGR2: return "msgr2";
216 default: return "???";
228 entity_addr_t() : type(0), nonce(0) {
229 memset(&u, 0, sizeof(u));
231 entity_addr_t(__u32 _type, __u32 _nonce) : type(_type), nonce(_nonce) {
232 memset(&u, 0, sizeof(u));
234 explicit entity_addr_t(const ceph_entity_addr &o) {
237 memcpy(&u, &o.in_addr, sizeof(u));
238 #if !defined(__FreeBSD__)
239 u.sa.sa_family = ntohs(u.sa.sa_family);
243 uint32_t get_type() const { return type; }
244 void set_type(uint32_t t) { type = t; }
246 __u32 get_nonce() const { return nonce; }
247 void set_nonce(__u32 n) { nonce = n; }
249 int get_family() const {
250 return u.sa.sa_family;
252 void set_family(int f) {
256 sockaddr_in &in4_addr() {
259 const sockaddr_in &in4_addr() const{
262 sockaddr_in6 &in6_addr(){
265 const sockaddr_in6 &in6_addr() const{
268 const sockaddr *get_sockaddr() const {
271 size_t get_sockaddr_len() const {
272 switch (u.sa.sa_family) {
274 return sizeof(u.sin);
276 return sizeof(u.sin6);
280 bool set_sockaddr(const struct sockaddr *sa)
282 switch (sa->sa_family) {
284 memcpy(&u.sin, sa, sizeof(u.sin));
287 memcpy(&u.sin6, sa, sizeof(u.sin6));
295 sockaddr_storage get_sockaddr_storage() const {
297 memcpy(&ss, &u, sizeof(u));
298 memset((char*)&ss + sizeof(u), 0, sizeof(ss) - sizeof(u));
302 void set_in4_quad(int pos, int val) {
303 u.sin.sin_family = AF_INET;
304 unsigned char *ipq = (unsigned char*)&u.sin.sin_addr.s_addr;
307 void set_port(int port) {
308 switch (u.sa.sa_family) {
310 u.sin.sin_port = htons(port);
313 u.sin6.sin6_port = htons(port);
319 int get_port() const {
320 switch (u.sa.sa_family) {
322 return ntohs(u.sin.sin_port);
325 return ntohs(u.sin6.sin6_port);
331 operator ceph_entity_addr() const {
335 a.in_addr = get_sockaddr_storage();
336 #if !defined(__FreeBSD__)
337 a.in_addr.ss_family = htons(a.in_addr.ss_family);
342 bool probably_equals(const entity_addr_t &o) const {
343 if (get_port() != o.get_port())
345 if (get_nonce() != o.get_nonce())
347 if (is_blank_ip() || o.is_blank_ip())
349 if (memcmp(&u, &o.u, sizeof(u)) == 0)
354 bool is_same_host(const entity_addr_t &o) const {
355 if (u.sa.sa_family != o.u.sa.sa_family)
357 if (u.sa.sa_family == AF_INET)
358 return u.sin.sin_addr.s_addr == o.u.sin.sin_addr.s_addr;
359 if (u.sa.sa_family == AF_INET6)
360 return memcmp(u.sin6.sin6_addr.s6_addr,
361 o.u.sin6.sin6_addr.s6_addr,
362 sizeof(u.sin6.sin6_addr.s6_addr)) == 0;
366 bool is_blank_ip() const {
367 switch (u.sa.sa_family) {
369 return u.sin.sin_addr.s_addr == INADDR_ANY;
371 return memcmp(&u.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0;
378 switch (u.sa.sa_family) {
387 bool parse(const char *s, const char **end = 0);
389 void decode_legacy_addr_after_marker(bufferlist::iterator& bl)
393 ::decode(marker, bl);
398 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
401 ceph_sockaddr_storage wireaddr;
402 ::memset(&wireaddr, '\0', sizeof(wireaddr));
403 ::decode(wireaddr, bl);
404 unsigned copysize = MIN(sizeof(wireaddr), sizeof(ss));
405 ::memcpy(&ss, &wireaddr, copysize);
407 set_sockaddr((sockaddr*)&ss);
410 // Right now, these only deal with sockaddr_storage that have only family and content.
411 // Apparently on BSD there is also an ss_len that we need to handle; this requires
414 void encode(bufferlist& bl, uint64_t features) const {
415 if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
416 ::encode((__u32)0, bl);
418 sockaddr_storage ss = get_sockaddr_storage();
419 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
422 ceph_sockaddr_storage wireaddr;
423 ::memset(&wireaddr, '\0', sizeof(wireaddr));
424 unsigned copysize = MIN(sizeof(wireaddr), sizeof(ss));
425 // ceph_sockaddr_storage is in host byte order
426 ::memcpy(&wireaddr, &ss, copysize);
427 ::encode(wireaddr, bl);
431 ::encode((__u8)1, bl);
432 ENCODE_START(1, 1, bl);
435 __u32 elen = get_sockaddr_len();
438 bl.append((char*)get_sockaddr(), elen);
442 void decode(bufferlist::iterator& bl) {
444 ::decode(marker, bl);
446 decode_legacy_addr_after_marker(bl);
450 throw buffer::malformed_input("entity_addr_t marker != 1");
457 bl.copy(elen, (char*)get_sockaddr());
462 void dump(Formatter *f) const;
464 static void generate_test_instances(list<entity_addr_t*>& o);
466 WRITE_CLASS_ENCODER_FEATURES(entity_addr_t)
468 ostream& operator<<(ostream& out, const entity_addr_t &addr);
470 inline bool operator==(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) == 0; }
471 inline bool operator!=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) != 0; }
472 inline bool operator<(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) < 0; }
473 inline bool operator<=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) <= 0; }
474 inline bool operator>(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) > 0; }
475 inline bool operator>=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) >= 0; }
478 template<> struct hash< entity_addr_t >
480 size_t operator()( const entity_addr_t& x ) const
483 return H((const char*)&x, sizeof(x));
488 struct entity_addrvec_t {
489 vector<entity_addr_t> v;
491 unsigned size() const { return v.size(); }
492 bool empty() const { return v.empty(); }
494 void encode(bufferlist& bl, uint64_t features) const;
495 void decode(bufferlist::iterator& bl);
496 void dump(Formatter *f) const;
497 static void generate_test_instances(list<entity_addrvec_t*>& ls);
499 WRITE_CLASS_ENCODER_FEATURES(entity_addrvec_t);
502 * a particular entity instance
504 struct entity_inst_t {
508 entity_inst_t(entity_name_t n, const entity_addr_t& a) : name(n), addr(a) {}
509 // cppcheck-suppress noExplicitConstructor
510 entity_inst_t(const ceph_entity_inst& i) : name(i.name), addr(i.addr) { }
511 entity_inst_t(const ceph_entity_name& n, const ceph_entity_addr &a) : name(n), addr(a) {}
512 operator ceph_entity_inst() {
513 ceph_entity_inst i = {name, addr};
517 void encode(bufferlist& bl, uint64_t features) const {
519 ::encode(addr, bl, features);
521 void decode(bufferlist::iterator& bl) {
526 void dump(Formatter *f) const;
527 static void generate_test_instances(list<entity_inst_t*>& o);
529 WRITE_CLASS_ENCODER_FEATURES(entity_inst_t)
532 inline bool operator==(const entity_inst_t& a, const entity_inst_t& b) {
533 return a.name == b.name && a.addr == b.addr;
535 inline bool operator!=(const entity_inst_t& a, const entity_inst_t& b) {
536 return a.name != b.name || a.addr != b.addr;
538 inline bool operator<(const entity_inst_t& a, const entity_inst_t& b) {
539 return a.name < b.name || (a.name == b.name && a.addr < b.addr);
541 inline bool operator<=(const entity_inst_t& a, const entity_inst_t& b) {
542 return a.name < b.name || (a.name == b.name && a.addr <= b.addr);
544 inline bool operator>(const entity_inst_t& a, const entity_inst_t& b) { return b < a; }
545 inline bool operator>=(const entity_inst_t& a, const entity_inst_t& b) { return b <= a; }
548 template<> struct hash< entity_inst_t >
550 size_t operator()( const entity_inst_t& x ) const
552 static hash< entity_name_t > H;
553 static hash< entity_addr_t > I;
554 return H(x.name) ^ I(x.addr);
560 inline ostream& operator<<(ostream& out, const entity_inst_t &i)
562 return out << i.name << " " << i.addr;
564 inline ostream& operator<<(ostream& out, const ceph_entity_inst &i)