Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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       bl.append((char*)get_sockaddr(), elen);
439     }
440     ENCODE_FINISH(bl);
441   }
442   void decode(bufferlist::iterator& bl) {
443     __u8 marker;
444     ::decode(marker, bl);
445     if (marker == 0) {
446       decode_legacy_addr_after_marker(bl);
447       return;
448     }
449     if (marker != 1)
450       throw buffer::malformed_input("entity_addr_t marker != 1");
451     DECODE_START(1, bl);
452     ::decode(type, bl);
453     ::decode(nonce, bl);
454     __u32 elen;
455     ::decode(elen, bl);
456     if (elen) {
457       bl.copy(elen, (char*)get_sockaddr());
458     }
459     DECODE_FINISH(bl);
460   }
461
462   void dump(Formatter *f) const;
463
464   static void generate_test_instances(list<entity_addr_t*>& o);
465 };
466 WRITE_CLASS_ENCODER_FEATURES(entity_addr_t)
467
468 ostream& operator<<(ostream& out, const entity_addr_t &addr);
469
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; }
476
477 namespace std {
478   template<> struct hash< entity_addr_t >
479   {
480     size_t operator()( const entity_addr_t& x ) const
481     {
482       static blobhash H;
483       return H((const char*)&x, sizeof(x));
484     }
485   };
486 } // namespace std
487
488 struct entity_addrvec_t {
489   vector<entity_addr_t> v;
490
491   unsigned size() const { return v.size(); }
492   bool empty() const { return v.empty(); }
493
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);
498 };
499 WRITE_CLASS_ENCODER_FEATURES(entity_addrvec_t);
500
501 /*
502  * a particular entity instance
503  */
504 struct entity_inst_t {
505   entity_name_t name;
506   entity_addr_t addr;
507   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};
514     return i;
515   }
516
517   void encode(bufferlist& bl, uint64_t features) const {
518     ::encode(name, bl);
519     ::encode(addr, bl, features);
520   }
521   void decode(bufferlist::iterator& bl) {
522     ::decode(name, bl);
523     ::decode(addr, bl);
524   }
525
526   void dump(Formatter *f) const;
527   static void generate_test_instances(list<entity_inst_t*>& o);
528 };
529 WRITE_CLASS_ENCODER_FEATURES(entity_inst_t)
530
531
532 inline bool operator==(const entity_inst_t& a, const entity_inst_t& b) { 
533   return a.name == b.name && a.addr == b.addr;
534 }
535 inline bool operator!=(const entity_inst_t& a, const entity_inst_t& b) { 
536   return a.name != b.name || a.addr != b.addr;
537 }
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);
540 }
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);
543 }
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; }
546
547 namespace std {
548   template<> struct hash< entity_inst_t >
549   {
550     size_t operator()( const entity_inst_t& x ) const
551     {
552       static hash< entity_name_t > H;
553       static hash< entity_addr_t > I;
554       return H(x.name) ^ I(x.addr);
555     }
556   };
557 } // namespace std
558
559
560 inline ostream& operator<<(ostream& out, const entity_inst_t &i)
561 {
562   return out << i.name << " " << i.addr;
563 }
564 inline ostream& operator<<(ostream& out, const ceph_entity_inst &i)
565 {
566   entity_inst_t n = i;
567   return out << n;
568 }
569
570 #endif