]> git.proxmox.com Git - ceph.git/blame - ceph/src/msg/msg_types.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / msg / msg_types.cc
CommitLineData
7c673cae
FG
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
11void entity_name_t::dump(Formatter *f) const
12{
13 f->dump_string("type", type_str());
14 f->dump_unsigned("num", num());
15}
16
17void entity_addr_t::dump(Formatter *f) const
18{
11fdf7f2 19 f->dump_string("type", get_type_name(type));
7c673cae 20 f->dump_stream("addr") << get_sockaddr();
11fdf7f2 21 f->dump_unsigned("nonce", nonce);
7c673cae
FG
22}
23
24void entity_inst_t::dump(Formatter *f) const
25{
26 f->dump_object("name", name);
27 f->dump_object("addr", addr);
28}
29
30void entity_name_t::generate_test_instances(list<entity_name_t*>& o)
31{
32 o.push_back(new entity_name_t(entity_name_t::MON()));
33 o.push_back(new entity_name_t(entity_name_t::MON(1)));
34 o.push_back(new entity_name_t(entity_name_t::OSD(1)));
35 o.push_back(new entity_name_t(entity_name_t::CLIENT(1)));
36}
37
38void entity_addr_t::generate_test_instances(list<entity_addr_t*>& o)
39{
40 o.push_back(new entity_addr_t());
41 entity_addr_t *a = new entity_addr_t();
42 a->set_nonce(1);
43 o.push_back(a);
44 entity_addr_t *b = new entity_addr_t();
45 b->set_type(entity_addr_t::TYPE_LEGACY);
46 b->set_nonce(5);
47 b->set_family(AF_INET);
48 b->set_in4_quad(0, 127);
49 b->set_in4_quad(1, 0);
50 b->set_in4_quad(2, 1);
51 b->set_in4_quad(3, 2);
52 b->set_port(2);
53 o.push_back(b);
54}
55
56void entity_inst_t::generate_test_instances(list<entity_inst_t*>& o)
57{
58 o.push_back(new entity_inst_t());
59 entity_name_t name;
60 entity_addr_t addr;
61 entity_inst_t *a = new entity_inst_t(name, addr);
62 o.push_back(a);
63}
64
11fdf7f2 65bool entity_addr_t::parse(const char *s, const char **end, int default_type)
7c673cae 66{
11fdf7f2 67 *this = entity_addr_t();
7c673cae
FG
68
69 const char *start = s;
11fdf7f2
TL
70 if (end) {
71 *end = s;
72 }
7c673cae 73
11fdf7f2
TL
74 int newtype;
75 if (strncmp("v1:", s, 3) == 0) {
76 start += 3;
7c673cae 77 newtype = TYPE_LEGACY;
11fdf7f2
TL
78 } else if (strncmp("v2:", s, 3) == 0) {
79 start += 3;
7c673cae 80 newtype = TYPE_MSGR2;
11fdf7f2
TL
81 } else if (strncmp("any:", s, 4) == 0) {
82 start += 4;
83 newtype = TYPE_ANY;
7c673cae 84 } else if (*s == '-') {
11fdf7f2 85 newtype = TYPE_NONE;
7c673cae
FG
86 if (end) {
87 *end = s + 1;
88 }
89 return true;
11fdf7f2
TL
90 } else {
91 newtype = default_type ? default_type : TYPE_DEFAULT;
7c673cae
FG
92 }
93
94 bool brackets = false;
95 if (*start == '[') {
96 start++;
97 brackets = true;
98 }
99
100 // inet_pton() requires a null terminated input, so let's fill two
101 // buffers, one with ipv4 allowed characters, and one with ipv6, and
102 // then see which parses.
103 char buf4[39];
104 char *o = buf4;
105 const char *p = start;
106 while (o < buf4 + sizeof(buf4) &&
107 *p && ((*p == '.') ||
108 (*p >= '0' && *p <= '9'))) {
109 *o++ = *p++;
110 }
111 *o = 0;
112
113 char buf6[64]; // actually 39 + null is sufficient.
114 o = buf6;
115 p = start;
116 while (o < buf6 + sizeof(buf6) &&
117 *p && ((*p == ':') ||
118 (*p >= '0' && *p <= '9') ||
119 (*p >= 'a' && *p <= 'f') ||
120 (*p >= 'A' && *p <= 'F'))) {
121 *o++ = *p++;
122 }
123 *o = 0;
124 //cout << "buf4 is '" << buf4 << "', buf6 is '" << buf6 << "'" << std::endl;
125
126 // ipv4?
127 struct in_addr a4;
128 struct in6_addr a6;
129 if (inet_pton(AF_INET, buf4, &a4)) {
130 u.sin.sin_addr.s_addr = a4.s_addr;
131 u.sa.sa_family = AF_INET;
132 p = start + strlen(buf4);
133 } else if (inet_pton(AF_INET6, buf6, &a6)) {
134 u.sa.sa_family = AF_INET6;
135 memcpy(&u.sin6.sin6_addr, &a6, sizeof(a6));
136 p = start + strlen(buf6);
137 } else {
138 return false;
139 }
140
141 if (brackets) {
142 if (*p != ']')
143 return false;
144 p++;
145 }
146
147 //cout << "p is " << *p << std::endl;
148 if (*p == ':') {
149 // parse a port, too!
150 p++;
151 int port = atoi(p);
11fdf7f2
TL
152 if (port > MAX_PORT_NUMBER) {
153 return false;
154 }
7c673cae
FG
155 set_port(port);
156 while (*p && *p >= '0' && *p <= '9')
157 p++;
158 }
159
160 if (*p == '/') {
161 // parse nonce, too
162 p++;
163 int non = atoi(p);
164 set_nonce(non);
165 while (*p && *p >= '0' && *p <= '9')
166 p++;
167 }
168
169 if (end)
170 *end = p;
171
172 type = newtype;
173
174 //cout << *this << std::endl;
175 return true;
176}
177
178ostream& operator<<(ostream& out, const entity_addr_t &addr)
179{
180 if (addr.type == entity_addr_t::TYPE_NONE) {
181 return out << "-";
182 }
11fdf7f2 183 if (addr.type != entity_addr_t::TYPE_ANY) {
7c673cae
FG
184 out << entity_addr_t::get_type_name(addr.type) << ":";
185 }
186 out << addr.get_sockaddr() << '/' << addr.nonce;
187 return out;
188}
189
190ostream& operator<<(ostream& out, const sockaddr_storage &ss)
191{
192 char buf[NI_MAXHOST] = { 0 };
193 char serv[NI_MAXSERV] = { 0 };
194 size_t hostlen;
195
196 if (ss.ss_family == AF_INET)
197 hostlen = sizeof(struct sockaddr_in);
198 else if (ss.ss_family == AF_INET6)
199 hostlen = sizeof(struct sockaddr_in6);
200 else
201 hostlen = sizeof(struct sockaddr_storage);
202 getnameinfo((struct sockaddr *)&ss, hostlen, buf, sizeof(buf),
203 serv, sizeof(serv),
204 NI_NUMERICHOST | NI_NUMERICSERV);
205 if (ss.ss_family == AF_INET6)
206 return out << '[' << buf << "]:" << serv;
207 return out << buf << ':' << serv;
208}
209
210ostream& operator<<(ostream& out, const sockaddr *sa)
211{
212 char buf[NI_MAXHOST] = { 0 };
213 char serv[NI_MAXSERV] = { 0 };
214 size_t hostlen;
215
216 if (sa->sa_family == AF_INET)
217 hostlen = sizeof(struct sockaddr_in);
218 else if (sa->sa_family == AF_INET6)
219 hostlen = sizeof(struct sockaddr_in6);
220 else
221 hostlen = sizeof(struct sockaddr_storage);
222 getnameinfo(sa, hostlen, buf, sizeof(buf),
223 serv, sizeof(serv),
224 NI_NUMERICHOST | NI_NUMERICSERV);
225 if (sa->sa_family == AF_INET6)
226 return out << '[' << buf << "]:" << serv;
227 return out << buf << ':' << serv;
228}
229
230// entity_addrvec_t
231
11fdf7f2 232bool entity_addrvec_t::parse(const char *s, const char **end)
7c673cae 233{
11fdf7f2
TL
234 const char *orig_s = s;
235 const char *static_end;
236 if (!end) {
237 end = &static_end;
238 } else {
239 *end = s;
240 }
241 v.clear();
242 bool brackets = false;
243 if (*s == '[') {
244 // weirdness: make sure this isn't an IPV6 addr!
245 entity_addr_t a;
246 const char *p;
247 if (!a.parse(s, &p) || !a.is_ipv6()) {
248 // it's not
249 brackets = true;
250 ++s;
251 }
252 }
253 while (*s) {
254 entity_addr_t a;
255 bool r = a.parse(s, end);
256 if (!r) {
257 if (brackets) {
258 v.clear();
259 *end = orig_s;
260 return false;
7c673cae 261 }
11fdf7f2
TL
262 break;
263 }
264 v.push_back(a);
265 s = *end;
266 if (!brackets) {
267 break;
268 }
269 if (*s != ',') {
270 break;
271 }
272 ++s;
273 }
274 if (brackets) {
275 if (*s == ']') {
276 ++s;
277 *end = s;
7c673cae 278 } else {
11fdf7f2
TL
279 *end = orig_s;
280 v.clear();
281 return false;
7c673cae 282 }
11fdf7f2
TL
283 }
284 return !v.empty();
285}
286
287void entity_addrvec_t::encode(bufferlist& bl, uint64_t features) const
288{
289 using ceph::encode;
290 if ((features & CEPH_FEATURE_MSG_ADDR2) == 0) {
291 // encode a single legacy entity_addr_t for unfeatured peers
292 encode(legacy_addr(), bl, 0);
7c673cae
FG
293 return;
294 }
11fdf7f2
TL
295 encode((__u8)2, bl);
296 encode(v, bl, features);
7c673cae
FG
297}
298
11fdf7f2 299void entity_addrvec_t::decode(bufferlist::const_iterator& bl)
7c673cae 300{
11fdf7f2 301 using ceph::decode;
7c673cae 302 __u8 marker;
11fdf7f2 303 decode(marker, bl);
7c673cae
FG
304 if (marker == 0) {
305 // legacy!
306 entity_addr_t addr;
307 addr.decode_legacy_addr_after_marker(bl);
308 v.clear();
309 v.push_back(addr);
310 return;
311 }
312 if (marker == 1) {
313 entity_addr_t addr;
314 DECODE_START(1, bl);
11fdf7f2
TL
315 decode(addr.type, bl);
316 decode(addr.nonce, bl);
7c673cae 317 __u32 elen;
11fdf7f2 318 decode(elen, bl);
7c673cae
FG
319 if (elen) {
320 bl.copy(elen, (char*)addr.get_sockaddr());
321 }
322 DECODE_FINISH(bl);
323 v.clear();
324 v.push_back(addr);
325 return;
326 }
327 if (marker > 2)
328 throw buffer::malformed_input("entity_addrvec_marker > 2");
11fdf7f2 329 decode(v, bl);
7c673cae
FG
330}
331
332void entity_addrvec_t::dump(Formatter *f) const
333{
334 f->open_array_section("addrvec");
335 for (vector<entity_addr_t>::const_iterator p = v.begin();
336 p != v.end(); ++p) {
337 f->dump_object("addr", *p);
338 }
339 f->close_section();
340}
341
342void entity_addrvec_t::generate_test_instances(list<entity_addrvec_t*>& ls)
343{
344 ls.push_back(new entity_addrvec_t());
345 ls.push_back(new entity_addrvec_t());
346 ls.back()->v.push_back(entity_addr_t());
347 ls.push_back(new entity_addrvec_t());
348 ls.back()->v.push_back(entity_addr_t());
349 ls.back()->v.push_back(entity_addr_t());
350}
11fdf7f2
TL
351
352std::string entity_addr_t::ip_only_to_str() const
353{
354 const char *host_ip = NULL;
355 char addr_buf[INET6_ADDRSTRLEN];
356 switch (get_family()) {
357 case AF_INET:
358 host_ip = inet_ntop(AF_INET, &in4_addr().sin_addr,
359 addr_buf, INET_ADDRSTRLEN);
360 break;
361 case AF_INET6:
362 host_ip = inet_ntop(AF_INET6, &in6_addr().sin6_addr,
363 addr_buf, INET6_ADDRSTRLEN);
364 break;
365 default:
366 break;
367 }
368 return host_ip ? host_ip : "";
369}