Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / msg / msg_types.cc
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_unsigned("nonce", nonce);
20   f->dump_stream("addr") << get_sockaddr();
21 }
22
23 void entity_inst_t::dump(Formatter *f) const
24 {
25   f->dump_object("name", name);
26   f->dump_object("addr", addr);
27 }
28
29 void entity_name_t::generate_test_instances(list<entity_name_t*>& o)
30 {
31   o.push_back(new entity_name_t(entity_name_t::MON()));
32   o.push_back(new entity_name_t(entity_name_t::MON(1)));
33   o.push_back(new entity_name_t(entity_name_t::OSD(1)));
34   o.push_back(new entity_name_t(entity_name_t::CLIENT(1)));
35 }
36
37 void entity_addr_t::generate_test_instances(list<entity_addr_t*>& o)
38 {
39   o.push_back(new entity_addr_t());
40   entity_addr_t *a = new entity_addr_t();
41   a->set_nonce(1);
42   o.push_back(a);
43   entity_addr_t *b = new entity_addr_t();
44   b->set_type(entity_addr_t::TYPE_LEGACY);
45   b->set_nonce(5);
46   b->set_family(AF_INET);
47   b->set_in4_quad(0, 127);
48   b->set_in4_quad(1, 0);
49   b->set_in4_quad(2, 1);
50   b->set_in4_quad(3, 2);
51   b->set_port(2);
52   o.push_back(b);
53 }
54
55 void entity_inst_t::generate_test_instances(list<entity_inst_t*>& o)
56 {
57   o.push_back(new entity_inst_t());
58   entity_name_t name;
59   entity_addr_t addr;
60   entity_inst_t *a = new entity_inst_t(name, addr);
61   o.push_back(a);
62 }
63
64 bool entity_addr_t::parse(const char *s, const char **end)
65 {
66   memset(this, 0, sizeof(*this));
67
68   const char *start = s;
69
70   int newtype = TYPE_DEFAULT;
71   if (strncmp("legacy:", s, 7) == 0) {
72     start += 7;
73     newtype = TYPE_LEGACY;
74   } else if (strncmp("msgr2:", s, 6) == 0) {
75     start += 6;
76     newtype = TYPE_MSGR2;
77   } else if (*s == '-') {
78     *this = entity_addr_t();
79     if (end) {
80       *end = s + 1;
81     }
82     return true;
83   }
84
85   bool brackets = false;
86   if (*start == '[') {
87     start++;
88     brackets = true;
89   }
90   
91   // inet_pton() requires a null terminated input, so let's fill two
92   // buffers, one with ipv4 allowed characters, and one with ipv6, and
93   // then see which parses.
94   char buf4[39];
95   char *o = buf4;
96   const char *p = start;
97   while (o < buf4 + sizeof(buf4) &&
98          *p && ((*p == '.') ||
99                 (*p >= '0' && *p <= '9'))) {
100     *o++ = *p++;
101   }
102   *o = 0;
103
104   char buf6[64];  // actually 39 + null is sufficient.
105   o = buf6;
106   p = start;
107   while (o < buf6 + sizeof(buf6) &&
108          *p && ((*p == ':') ||
109                 (*p >= '0' && *p <= '9') ||
110                 (*p >= 'a' && *p <= 'f') ||
111                 (*p >= 'A' && *p <= 'F'))) {
112     *o++ = *p++;
113   }
114   *o = 0;
115   //cout << "buf4 is '" << buf4 << "', buf6 is '" << buf6 << "'" << std::endl;
116
117   // ipv4?
118   struct in_addr a4;
119   struct in6_addr a6;
120   if (inet_pton(AF_INET, buf4, &a4)) {
121     u.sin.sin_addr.s_addr = a4.s_addr;
122     u.sa.sa_family = AF_INET;
123     p = start + strlen(buf4);
124   } else if (inet_pton(AF_INET6, buf6, &a6)) {
125     u.sa.sa_family = AF_INET6;
126     memcpy(&u.sin6.sin6_addr, &a6, sizeof(a6));
127     p = start + strlen(buf6);
128   } else {
129     return false;
130   }
131
132   if (brackets) {
133     if (*p != ']')
134       return false;
135     p++;
136   }
137   
138   //cout << "p is " << *p << std::endl;
139   if (*p == ':') {
140     // parse a port, too!
141     p++;
142     int port = atoi(p);
143     set_port(port);
144     while (*p && *p >= '0' && *p <= '9')
145       p++;
146   }
147
148   if (*p == '/') {
149     // parse nonce, too
150     p++;
151     int non = atoi(p);
152     set_nonce(non);
153     while (*p && *p >= '0' && *p <= '9')
154       p++;
155   }
156
157   if (end)
158     *end = p;
159
160   type = newtype;
161
162   //cout << *this << std::endl;
163   return true;
164 }
165
166 ostream& operator<<(ostream& out, const entity_addr_t &addr)
167 {
168   if (addr.type == entity_addr_t::TYPE_NONE) {
169     return out << "-";
170   }
171   if (addr.type != entity_addr_t::TYPE_DEFAULT) {
172     out << entity_addr_t::get_type_name(addr.type) << ":";
173   }
174   out << addr.get_sockaddr() << '/' << addr.nonce;
175   return out;
176 }
177
178 ostream& operator<<(ostream& out, const sockaddr_storage &ss)
179 {
180   char buf[NI_MAXHOST] = { 0 };
181   char serv[NI_MAXSERV] = { 0 };
182   size_t hostlen;
183
184   if (ss.ss_family == AF_INET)
185     hostlen = sizeof(struct sockaddr_in);
186   else if (ss.ss_family == AF_INET6)
187     hostlen = sizeof(struct sockaddr_in6);
188   else
189     hostlen = sizeof(struct sockaddr_storage);
190   getnameinfo((struct sockaddr *)&ss, hostlen, buf, sizeof(buf),
191               serv, sizeof(serv),
192               NI_NUMERICHOST | NI_NUMERICSERV);
193   if (ss.ss_family == AF_INET6)
194     return out << '[' << buf << "]:" << serv;
195   return out << buf << ':' << serv;
196 }
197
198 ostream& operator<<(ostream& out, const sockaddr *sa)
199 {
200   char buf[NI_MAXHOST] = { 0 };
201   char serv[NI_MAXSERV] = { 0 };
202   size_t hostlen;
203
204   if (sa->sa_family == AF_INET)
205     hostlen = sizeof(struct sockaddr_in);
206   else if (sa->sa_family == AF_INET6)
207     hostlen = sizeof(struct sockaddr_in6);
208   else
209     hostlen = sizeof(struct sockaddr_storage);
210   getnameinfo(sa, hostlen, buf, sizeof(buf),
211               serv, sizeof(serv),
212               NI_NUMERICHOST | NI_NUMERICSERV);
213   if (sa->sa_family == AF_INET6)
214     return out << '[' << buf << "]:" << serv;
215   return out << buf << ':' << serv;
216 }
217
218 // entity_addrvec_t
219
220 void entity_addrvec_t::encode(bufferlist& bl, uint64_t features) const
221 {
222   if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
223     // encode a single legacy entity_addr_t for unfeatured peers
224     if (v.size() > 0) {
225       for (vector<entity_addr_t>::const_iterator p = v.begin();
226            p != v.end(); ++p) {
227         if ((*p).type == entity_addr_t::TYPE_LEGACY) {
228           ::encode(*p, bl, 0);
229           return;
230         }
231       }
232       ::encode(v[0], bl, 0);
233     } else {
234       ::encode(entity_addr_t(), bl, 0);
235     }
236     return;
237   }
238   ::encode((__u8)2, bl);
239   ::encode(v, bl, features);
240 }
241
242 void entity_addrvec_t::decode(bufferlist::iterator& bl)
243 {
244   __u8 marker;
245   ::decode(marker, bl);
246   if (marker == 0) {
247     // legacy!
248     entity_addr_t addr;
249     addr.decode_legacy_addr_after_marker(bl);
250     v.clear();
251     v.push_back(addr);
252     return;
253   }
254   if (marker == 1) {
255     entity_addr_t addr;
256     DECODE_START(1, bl);
257     ::decode(addr.type, bl);
258     ::decode(addr.nonce, bl);
259     __u32 elen;
260     ::decode(elen, bl);
261     if (elen) {
262       bl.copy(elen, (char*)addr.get_sockaddr());
263     }
264     DECODE_FINISH(bl);
265     v.clear();
266     v.push_back(addr);
267     return;
268   }
269   if (marker > 2)
270     throw buffer::malformed_input("entity_addrvec_marker > 2");
271   ::decode(v, bl);
272 }
273
274 void entity_addrvec_t::dump(Formatter *f) const
275 {
276   f->open_array_section("addrvec");
277   for (vector<entity_addr_t>::const_iterator p = v.begin();
278        p != v.end(); ++p) {
279     f->dump_object("addr", *p);
280   }
281   f->close_section();
282 }
283
284 void entity_addrvec_t::generate_test_instances(list<entity_addrvec_t*>& ls)
285 {
286   ls.push_back(new entity_addrvec_t());
287   ls.push_back(new entity_addrvec_t());
288   ls.back()->v.push_back(entity_addr_t());
289   ls.push_back(new entity_addrvec_t());
290   ls.back()->v.push_back(entity_addr_t());
291   ls.back()->v.push_back(entity_addr_t());
292 }