]> git.proxmox.com Git - ceph.git/blob - ceph/src/msg/msg_types.h
import ceph 12.2.12
[ceph.git] / ceph / src / msg / msg_types.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
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
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_MSG_TYPES_H
16 #define CEPH_MSG_TYPES_H
17
18 #include <netinet/in.h>
19
20 #include "include/ceph_features.h"
21 #include "include/types.h"
22 #include "include/blobhash.h"
23 #include "include/encoding.h"
24
25 namespace ceph {
26 class Formatter;
27 }
28
29 extern ostream& operator<<(ostream& out, const sockaddr_storage &ss);
30 extern ostream& operator<<(ostream& out, const sockaddr *sa);
31
32 typedef uint8_t entity_type_t;
33
34 class entity_name_t {
35 public:
36 entity_type_t _type;
37 int64_t _num;
38
39 public:
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;
45
46 static const int64_t NEW = -1;
47
48 // cons
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) { }
53
54 // static cons
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); }
60
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());
65 }
66
67 bool is_new() const { return num() < 0; }
68
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; }
74
75 operator ceph_entity_name() const {
76 ceph_entity_name n = { _type, init_le64(_num) };
77 return n;
78 }
79
80 bool parse(const string& s) {
81 const char *start = s.c_str();
82 char *end;
83 bool got = parse(start, &end);
84 return got && end == start + s.length();
85 }
86 bool parse(const char *start, char **end) {
87 if (strstr(start, "mon.") == start) {
88 _type = TYPE_MON;
89 start += 4;
90 } else if (strstr(start, "osd.") == start) {
91 _type = TYPE_OSD;
92 start += 4;
93 } else if (strstr(start, "mds.") == start) {
94 _type = TYPE_MDS;
95 start += 4;
96 } else if (strstr(start, "client.") == start) {
97 _type = TYPE_CLIENT;
98 start += 7;
99 } else if (strstr(start, "mgr.") == start) {
100 _type = TYPE_MGR;
101 start += 4;
102 } else {
103 return false;
104 }
105 if (isspace(*start))
106 return false;
107 _num = strtoll(start, end, 10);
108 if (*end == NULL || *end == start)
109 return false;
110 return true;
111 }
112
113 DENC(entity_name_t, v, p) {
114 denc(v._type, p);
115 denc(v._num, p);
116 }
117 void dump(Formatter *f) const;
118
119 static void generate_test_instances(list<entity_name_t*>& o);
120 };
121 WRITE_CLASS_DENC(entity_name_t)
122
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()); }
129
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() << ".?";
134 else
135 return out << addr.type_str() << '.' << addr.num();
136 }
137 inline std::ostream& operator<<(std::ostream& out, const ceph_entity_name& addr) {
138 return out << *(const entity_name_t*)&addr;
139 }
140
141 namespace std {
142 template<> struct hash< entity_name_t >
143 {
144 size_t operator()( const entity_name_t &m ) const
145 {
146 return rjhash32(m.type() ^ m.num());
147 }
148 };
149 } // namespace std
150
151 /*
152 * an entity's network address.
153 * includes a random value that prevents it from being reused.
154 * thus identifies a particular process instance.
155 * ipv4 for now.
156 */
157
158 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
159 /*
160 * encode sockaddr.ss_family as network byte order
161 */
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);
167 #else
168 ss.ss_family = htons(ss.ss_family);
169 #endif
170 ::encode_raw(ss, bl);
171 }
172 static inline void decode(sockaddr_storage& a, bufferlist::iterator& bl) {
173 ::decode_raw(a, bl);
174 #if defined(DARWIN) || defined(__FreeBSD__)
175 unsigned short *ss_family = reinterpret_cast<unsigned short *>(&a);
176 a.ss_family = ntohs(*ss_family);
177 a.ss_len = 0;
178 #else
179 a.ss_family = ntohs(a.ss_family);
180 #endif
181 }
182 #endif
183
184 // define a wire format for sockaddr that matches Linux's.
185 struct ceph_sockaddr_storage {
186 __le16 ss_family;
187 __u8 __ss_padding[128 - sizeof(__le16)];
188
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);
193 }
194
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);
199 *this = ss;
200 }
201 } __attribute__ ((__packed__));
202 WRITE_CLASS_ENCODER(ceph_sockaddr_storage)
203
204 struct entity_addr_t {
205 typedef enum {
206 TYPE_NONE = 0,
207 TYPE_LEGACY = 1, ///< legacy msgr1 protocol (ceph jewel and older)
208 TYPE_MSGR2 = 2, ///< msgr2 protocol (new in ceph kraken)
209 } type_t;
210 static const type_t TYPE_DEFAULT = TYPE_LEGACY;
211 static const char *get_type_name(int t) {
212 switch (t) {
213 case TYPE_NONE: return "none";
214 case TYPE_LEGACY: return "legacy";
215 case TYPE_MSGR2: return "msgr2";
216 default: return "???";
217 }
218 };
219
220 __u32 type;
221 __u32 nonce;
222 union {
223 sockaddr sa;
224 sockaddr_in sin;
225 sockaddr_in6 sin6;
226 } u;
227
228 entity_addr_t() : type(0), nonce(0) {
229 memset(&u, 0, sizeof(u));
230 }
231 entity_addr_t(__u32 _type, __u32 _nonce) : type(_type), nonce(_nonce) {
232 memset(&u, 0, sizeof(u));
233 }
234 explicit entity_addr_t(const ceph_entity_addr &o) {
235 type = o.type;
236 nonce = o.nonce;
237 memcpy(&u, &o.in_addr, sizeof(u));
238 #if !defined(__FreeBSD__)
239 u.sa.sa_family = ntohs(u.sa.sa_family);
240 #endif
241 }
242
243 uint32_t get_type() const { return type; }
244 void set_type(uint32_t t) { type = t; }
245
246 __u32 get_nonce() const { return nonce; }
247 void set_nonce(__u32 n) { nonce = n; }
248
249 int get_family() const {
250 return u.sa.sa_family;
251 }
252 void set_family(int f) {
253 u.sa.sa_family = f;
254 }
255
256 sockaddr_in &in4_addr() {
257 return u.sin;
258 }
259 const sockaddr_in &in4_addr() const{
260 return u.sin;
261 }
262 sockaddr_in6 &in6_addr(){
263 return u.sin6;
264 }
265 const sockaddr_in6 &in6_addr() const{
266 return u.sin6;
267 }
268 const sockaddr *get_sockaddr() const {
269 return &u.sa;
270 }
271 size_t get_sockaddr_len() const {
272 switch (u.sa.sa_family) {
273 case AF_INET:
274 return sizeof(u.sin);
275 case AF_INET6:
276 return sizeof(u.sin6);
277 }
278 return sizeof(u);
279 }
280 bool set_sockaddr(const struct sockaddr *sa)
281 {
282 switch (sa->sa_family) {
283 case AF_INET:
284 memcpy(&u.sin, sa, sizeof(u.sin));
285 break;
286 case AF_INET6:
287 memcpy(&u.sin6, sa, sizeof(u.sin6));
288 break;
289 default:
290 return false;
291 }
292 return true;
293 }
294
295 sockaddr_storage get_sockaddr_storage() const {
296 sockaddr_storage ss;
297 memcpy(&ss, &u, sizeof(u));
298 memset((char*)&ss + sizeof(u), 0, sizeof(ss) - sizeof(u));
299 return ss;
300 }
301
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;
305 ipq[pos] = val;
306 }
307 void set_port(int port) {
308 switch (u.sa.sa_family) {
309 case AF_INET:
310 u.sin.sin_port = htons(port);
311 break;
312 case AF_INET6:
313 u.sin6.sin6_port = htons(port);
314 break;
315 default:
316 ceph_abort();
317 }
318 }
319 int get_port() const {
320 switch (u.sa.sa_family) {
321 case AF_INET:
322 return ntohs(u.sin.sin_port);
323 break;
324 case AF_INET6:
325 return ntohs(u.sin6.sin6_port);
326 break;
327 }
328 return 0;
329 }
330
331 operator ceph_entity_addr() const {
332 ceph_entity_addr a;
333 a.type = 0;
334 a.nonce = nonce;
335 a.in_addr = get_sockaddr_storage();
336 #if !defined(__FreeBSD__)
337 a.in_addr.ss_family = htons(a.in_addr.ss_family);
338 #endif
339 return a;
340 }
341
342 bool probably_equals(const entity_addr_t &o) const {
343 if (get_port() != o.get_port())
344 return false;
345 if (get_nonce() != o.get_nonce())
346 return false;
347 if (is_blank_ip() || o.is_blank_ip())
348 return true;
349 if (memcmp(&u, &o.u, sizeof(u)) == 0)
350 return true;
351 return false;
352 }
353
354 bool is_same_host(const entity_addr_t &o) const {
355 if (u.sa.sa_family != o.u.sa.sa_family)
356 return false;
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;
363 return false;
364 }
365
366 bool is_blank_ip() const {
367 switch (u.sa.sa_family) {
368 case AF_INET:
369 return u.sin.sin_addr.s_addr == INADDR_ANY;
370 case AF_INET6:
371 return memcmp(&u.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0;
372 default:
373 return true;
374 }
375 }
376
377 bool is_ip() const {
378 switch (u.sa.sa_family) {
379 case AF_INET:
380 case AF_INET6:
381 return true;
382 default:
383 return false;
384 }
385 }
386
387 bool parse(const char *s, const char **end = 0);
388
389 void decode_legacy_addr_after_marker(bufferlist::iterator& bl)
390 {
391 __u8 marker;
392 __u16 rest;
393 ::decode(marker, bl);
394 ::decode(rest, bl);
395 type = TYPE_LEGACY;
396 ::decode(nonce, bl);
397 sockaddr_storage ss;
398 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
399 ::decode(ss, bl);
400 #else
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);
406 #endif
407 set_sockaddr((sockaddr*)&ss);
408 }
409
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
412 // broader study
413
414 void encode(bufferlist& bl, uint64_t features) const {
415 if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
416 ::encode((__u32)0, bl);
417 ::encode(nonce, bl);
418 sockaddr_storage ss = get_sockaddr_storage();
419 #if defined(__linux__) || defined(DARWIN) || defined(__FreeBSD__)
420 ::encode(ss, bl);
421 #else
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);
428 #endif
429 return;
430 }
431 ::encode((__u8)1, bl);
432 ENCODE_START(1, 1, bl);
433 ::encode(type, bl);
434 ::encode(nonce, bl);
435 __u32 elen = get_sockaddr_len();
436 ::encode(elen, bl);
437 if (elen) {
438 #if (__FreeBSD__) || defined(__APPLE__)
439 __le16 ss_family = u.sa.sa_family;
440 ::encode(ss_family, bl);
441 bl.append(u.sa.sa_data,
442 elen - sizeof(u.sa.sa_len) - sizeof(u.sa.sa_family));
443 #else
444 bl.append((char*)get_sockaddr(), elen);
445 #endif
446 }
447 ENCODE_FINISH(bl);
448 }
449 void decode(bufferlist::iterator& bl) {
450 __u8 marker;
451 ::decode(marker, bl);
452 if (marker == 0) {
453 decode_legacy_addr_after_marker(bl);
454 return;
455 }
456 if (marker != 1)
457 throw buffer::malformed_input("entity_addr_t marker != 1");
458 DECODE_START(1, bl);
459 ::decode(type, bl);
460 ::decode(nonce, bl);
461 __u32 elen;
462 ::decode(elen, bl);
463 if (elen) {
464 #if defined(__FreeBSD__) || defined(__APPLE__)
465 u.sa.sa_len = 0;
466 __le16 ss_family;
467 if (elen < sizeof(ss_family)) {
468 throw buffer::malformed_input("elen smaller than family len");
469 }
470 ::decode(ss_family, bl);
471 u.sa.sa_family = ss_family;
472 elen -= sizeof(ss_family);
473 if (elen > get_sockaddr_len() - sizeof(u.sa.sa_family)) {
474 throw buffer::malformed_input("elen exceeds sockaddr len");
475 }
476 bl.copy(elen, u.sa.sa_data);
477 #else
478 if (elen < sizeof(u.sa.sa_family)) {
479 throw buffer::malformed_input("elen smaller than family len");
480 }
481 bl.copy(sizeof(u.sa.sa_family), (char*)&u.sa.sa_family);
482 if (elen > get_sockaddr_len()) {
483 throw buffer::malformed_input("elen exceeds sockaddr len");
484 }
485 elen -= sizeof(u.sa.sa_family);
486 bl.copy(elen, u.sa.sa_data);
487 #endif
488 }
489 DECODE_FINISH(bl);
490 }
491
492 void dump(Formatter *f) const;
493
494 static void generate_test_instances(list<entity_addr_t*>& o);
495 };
496 WRITE_CLASS_ENCODER_FEATURES(entity_addr_t)
497
498 ostream& operator<<(ostream& out, const entity_addr_t &addr);
499
500 inline bool operator==(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) == 0; }
501 inline bool operator!=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) != 0; }
502 inline bool operator<(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) < 0; }
503 inline bool operator<=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) <= 0; }
504 inline bool operator>(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) > 0; }
505 inline bool operator>=(const entity_addr_t& a, const entity_addr_t& b) { return memcmp(&a, &b, sizeof(a)) >= 0; }
506
507 namespace std {
508 template<> struct hash< entity_addr_t >
509 {
510 size_t operator()( const entity_addr_t& x ) const
511 {
512 static blobhash H;
513 return H((const char*)&x, sizeof(x));
514 }
515 };
516 } // namespace std
517
518 struct entity_addrvec_t {
519 vector<entity_addr_t> v;
520
521 unsigned size() const { return v.size(); }
522 bool empty() const { return v.empty(); }
523
524 void encode(bufferlist& bl, uint64_t features) const;
525 void decode(bufferlist::iterator& bl);
526 void dump(Formatter *f) const;
527 static void generate_test_instances(list<entity_addrvec_t*>& ls);
528 };
529 WRITE_CLASS_ENCODER_FEATURES(entity_addrvec_t);
530
531 /*
532 * a particular entity instance
533 */
534 struct entity_inst_t {
535 entity_name_t name;
536 entity_addr_t addr;
537 entity_inst_t() {}
538 entity_inst_t(entity_name_t n, const entity_addr_t& a) : name(n), addr(a) {}
539 // cppcheck-suppress noExplicitConstructor
540 entity_inst_t(const ceph_entity_inst& i) : name(i.name), addr(i.addr) { }
541 entity_inst_t(const ceph_entity_name& n, const ceph_entity_addr &a) : name(n), addr(a) {}
542 operator ceph_entity_inst() {
543 ceph_entity_inst i = {name, addr};
544 return i;
545 }
546
547 void encode(bufferlist& bl, uint64_t features) const {
548 ::encode(name, bl);
549 ::encode(addr, bl, features);
550 }
551 void decode(bufferlist::iterator& bl) {
552 ::decode(name, bl);
553 ::decode(addr, bl);
554 }
555
556 void dump(Formatter *f) const;
557 static void generate_test_instances(list<entity_inst_t*>& o);
558 };
559 WRITE_CLASS_ENCODER_FEATURES(entity_inst_t)
560
561
562 inline bool operator==(const entity_inst_t& a, const entity_inst_t& b) {
563 return a.name == b.name && a.addr == b.addr;
564 }
565 inline bool operator!=(const entity_inst_t& a, const entity_inst_t& b) {
566 return a.name != b.name || a.addr != b.addr;
567 }
568 inline bool operator<(const entity_inst_t& a, const entity_inst_t& b) {
569 return a.name < b.name || (a.name == b.name && a.addr < b.addr);
570 }
571 inline bool operator<=(const entity_inst_t& a, const entity_inst_t& b) {
572 return a.name < b.name || (a.name == b.name && a.addr <= b.addr);
573 }
574 inline bool operator>(const entity_inst_t& a, const entity_inst_t& b) { return b < a; }
575 inline bool operator>=(const entity_inst_t& a, const entity_inst_t& b) { return b <= a; }
576
577 namespace std {
578 template<> struct hash< entity_inst_t >
579 {
580 size_t operator()( const entity_inst_t& x ) const
581 {
582 static hash< entity_name_t > H;
583 static hash< entity_addr_t > I;
584 return H(x.name) ^ I(x.addr);
585 }
586 };
587 } // namespace std
588
589
590 inline ostream& operator<<(ostream& out, const entity_inst_t &i)
591 {
592 return out << i.name << " " << i.addr;
593 }
594 inline ostream& operator<<(ostream& out, const ceph_entity_inst &i)
595 {
596 entity_inst_t n = i;
597 return out << n;
598 }
599
600 #endif