]> git.proxmox.com Git - ceph.git/blame - ceph/src/msg/msg_types.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / msg / msg_types.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
7c673cae
FG
3
4#include "msg_types.h"
5
6#include <arpa/inet.h>
7#include <stdlib.h>
8#include <string.h>
9#include <netdb.h>
10
11#include "common/Formatter.h"
12
f67539c2 13void entity_name_t::dump(ceph::Formatter *f) const
7c673cae
FG
14{
15 f->dump_string("type", type_str());
16 f->dump_unsigned("num", num());
17}
18
f67539c2 19void entity_addr_t::dump(ceph::Formatter *f) const
7c673cae 20{
11fdf7f2 21 f->dump_string("type", get_type_name(type));
7c673cae 22 f->dump_stream("addr") << get_sockaddr();
11fdf7f2 23 f->dump_unsigned("nonce", nonce);
7c673cae
FG
24}
25
f67539c2 26void entity_inst_t::dump(ceph::Formatter *f) const
7c673cae
FG
27{
28 f->dump_object("name", name);
29 f->dump_object("addr", addr);
30}
31
f67539c2 32void entity_name_t::generate_test_instances(std::list<entity_name_t*>& o)
7c673cae
FG
33{
34 o.push_back(new entity_name_t(entity_name_t::MON()));
35 o.push_back(new entity_name_t(entity_name_t::MON(1)));
36 o.push_back(new entity_name_t(entity_name_t::OSD(1)));
37 o.push_back(new entity_name_t(entity_name_t::CLIENT(1)));
38}
39
f67539c2 40void entity_addr_t::generate_test_instances(std::list<entity_addr_t*>& o)
7c673cae
FG
41{
42 o.push_back(new entity_addr_t());
43 entity_addr_t *a = new entity_addr_t();
44 a->set_nonce(1);
45 o.push_back(a);
46 entity_addr_t *b = new entity_addr_t();
47 b->set_type(entity_addr_t::TYPE_LEGACY);
48 b->set_nonce(5);
49 b->set_family(AF_INET);
50 b->set_in4_quad(0, 127);
51 b->set_in4_quad(1, 0);
52 b->set_in4_quad(2, 1);
53 b->set_in4_quad(3, 2);
54 b->set_port(2);
55 o.push_back(b);
56}
57
f67539c2 58void entity_inst_t::generate_test_instances(std::list<entity_inst_t*>& o)
7c673cae
FG
59{
60 o.push_back(new entity_inst_t());
61 entity_name_t name;
62 entity_addr_t addr;
63 entity_inst_t *a = new entity_inst_t(name, addr);
64 o.push_back(a);
65}
66
f67539c2
TL
67bool entity_addr_t::parse(const std::string_view s)
68{
69 const char* start = s.data();
70 const char* end = nullptr;
71 bool got = parse(start, &end);
72 return got && end == start + s.size();
73}
74
11fdf7f2 75bool entity_addr_t::parse(const char *s, const char **end, int default_type)
7c673cae 76{
11fdf7f2 77 *this = entity_addr_t();
7c673cae
FG
78
79 const char *start = s;
11fdf7f2
TL
80 if (end) {
81 *end = s;
82 }
7c673cae 83
11fdf7f2
TL
84 int newtype;
85 if (strncmp("v1:", s, 3) == 0) {
86 start += 3;
7c673cae 87 newtype = TYPE_LEGACY;
11fdf7f2
TL
88 } else if (strncmp("v2:", s, 3) == 0) {
89 start += 3;
7c673cae 90 newtype = TYPE_MSGR2;
11fdf7f2
TL
91 } else if (strncmp("any:", s, 4) == 0) {
92 start += 4;
93 newtype = TYPE_ANY;
7c673cae 94 } else if (*s == '-') {
11fdf7f2 95 newtype = TYPE_NONE;
7c673cae
FG
96 if (end) {
97 *end = s + 1;
98 }
99 return true;
11fdf7f2
TL
100 } else {
101 newtype = default_type ? default_type : TYPE_DEFAULT;
7c673cae
FG
102 }
103
104 bool brackets = false;
105 if (*start == '[') {
106 start++;
107 brackets = true;
108 }
109
110 // inet_pton() requires a null terminated input, so let's fill two
111 // buffers, one with ipv4 allowed characters, and one with ipv6, and
112 // then see which parses.
113 char buf4[39];
114 char *o = buf4;
115 const char *p = start;
116 while (o < buf4 + sizeof(buf4) &&
117 *p && ((*p == '.') ||
118 (*p >= '0' && *p <= '9'))) {
119 *o++ = *p++;
120 }
121 *o = 0;
122
123 char buf6[64]; // actually 39 + null is sufficient.
124 o = buf6;
125 p = start;
126 while (o < buf6 + sizeof(buf6) &&
127 *p && ((*p == ':') ||
128 (*p >= '0' && *p <= '9') ||
129 (*p >= 'a' && *p <= 'f') ||
130 (*p >= 'A' && *p <= 'F'))) {
131 *o++ = *p++;
132 }
133 *o = 0;
134 //cout << "buf4 is '" << buf4 << "', buf6 is '" << buf6 << "'" << std::endl;
135
136 // ipv4?
137 struct in_addr a4;
138 struct in6_addr a6;
139 if (inet_pton(AF_INET, buf4, &a4)) {
140 u.sin.sin_addr.s_addr = a4.s_addr;
141 u.sa.sa_family = AF_INET;
142 p = start + strlen(buf4);
143 } else if (inet_pton(AF_INET6, buf6, &a6)) {
144 u.sa.sa_family = AF_INET6;
145 memcpy(&u.sin6.sin6_addr, &a6, sizeof(a6));
146 p = start + strlen(buf6);
147 } else {
148 return false;
149 }
150
151 if (brackets) {
152 if (*p != ']')
153 return false;
154 p++;
155 }
156
157 //cout << "p is " << *p << std::endl;
158 if (*p == ':') {
159 // parse a port, too!
160 p++;
161 int port = atoi(p);
11fdf7f2
TL
162 if (port > MAX_PORT_NUMBER) {
163 return false;
164 }
7c673cae
FG
165 set_port(port);
166 while (*p && *p >= '0' && *p <= '9')
167 p++;
168 }
169
170 if (*p == '/') {
171 // parse nonce, too
172 p++;
173 int non = atoi(p);
174 set_nonce(non);
175 while (*p && *p >= '0' && *p <= '9')
176 p++;
177 }
178
179 if (end)
180 *end = p;
181
182 type = newtype;
183
184 //cout << *this << std::endl;
185 return true;
186}
187
f67539c2 188std::ostream& operator<<(std::ostream& out, const entity_addr_t &addr)
7c673cae
FG
189{
190 if (addr.type == entity_addr_t::TYPE_NONE) {
191 return out << "-";
192 }
11fdf7f2 193 if (addr.type != entity_addr_t::TYPE_ANY) {
7c673cae
FG
194 out << entity_addr_t::get_type_name(addr.type) << ":";
195 }
196 out << addr.get_sockaddr() << '/' << addr.nonce;
197 return out;
198}
199
f67539c2 200std::ostream& operator<<(std::ostream& out, const sockaddr *psa)
7c673cae
FG
201{
202 char buf[NI_MAXHOST] = { 0 };
7c673cae 203
9f95a23c
TL
204 switch (psa->sa_family) {
205 case AF_INET:
206 {
207 const sockaddr_in *sa = (const sockaddr_in*)psa;
208 inet_ntop(AF_INET, &sa->sin_addr, buf, NI_MAXHOST);
209 return out << buf << ':'
210 << ntohs(sa->sin_port);
211 }
212 case AF_INET6:
213 {
214 const sockaddr_in6 *sa = (const sockaddr_in6*)psa;
215 inet_ntop(AF_INET6, &sa->sin6_addr, buf, NI_MAXHOST);
216 return out << '[' << buf << "]:"
217 << ntohs(sa->sin6_port);
218 }
219 default:
220 return out << "(unrecognized address family " << psa->sa_family << ")";
221 }
7c673cae
FG
222}
223
f67539c2 224std::ostream& operator<<(std::ostream& out, const sockaddr_storage &ss)
7c673cae 225{
9f95a23c 226 return out << (const sockaddr*)&ss;
7c673cae
FG
227}
228
9f95a23c 229
7c673cae
FG
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
f67539c2 287void entity_addrvec_t::encode(ceph::buffer::list& bl, uint64_t features) const
11fdf7f2
TL
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
f67539c2 299void entity_addrvec_t::decode(ceph::buffer::list::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 319 if (elen) {
f91f0fd5
TL
320 struct sockaddr *sa = (struct sockaddr *)addr.get_sockaddr();
321#if defined(__FreeBSD__) || defined(__APPLE__)
322 sa->sa_len = 0;
323#endif
324 uint16_t ss_family;
325 if (elen < sizeof(ss_family)) {
326 throw ceph::buffer::malformed_input("elen smaller than family len");
327 }
328 decode(ss_family, bl);
329 sa->sa_family = ss_family;
330 elen -= sizeof(ss_family);
331 if (elen > addr.get_sockaddr_len() - sizeof(sa->sa_family)) {
332 throw ceph::buffer::malformed_input("elen exceeds sockaddr len");
333 }
334 bl.copy(elen, sa->sa_data);
7c673cae
FG
335 }
336 DECODE_FINISH(bl);
337 v.clear();
338 v.push_back(addr);
339 return;
340 }
341 if (marker > 2)
f67539c2 342 throw ceph::buffer::malformed_input("entity_addrvec_marker > 2");
11fdf7f2 343 decode(v, bl);
7c673cae
FG
344}
345
f67539c2 346void entity_addrvec_t::dump(ceph::Formatter *f) const
7c673cae
FG
347{
348 f->open_array_section("addrvec");
f67539c2 349 for (auto p = v.begin(); p != v.end(); ++p) {
7c673cae
FG
350 f->dump_object("addr", *p);
351 }
352 f->close_section();
353}
354
f67539c2 355void entity_addrvec_t::generate_test_instances(std::list<entity_addrvec_t*>& ls)
7c673cae
FG
356{
357 ls.push_back(new entity_addrvec_t());
358 ls.push_back(new entity_addrvec_t());
359 ls.back()->v.push_back(entity_addr_t());
360 ls.push_back(new entity_addrvec_t());
361 ls.back()->v.push_back(entity_addr_t());
362 ls.back()->v.push_back(entity_addr_t());
363}
11fdf7f2
TL
364
365std::string entity_addr_t::ip_only_to_str() const
366{
367 const char *host_ip = NULL;
368 char addr_buf[INET6_ADDRSTRLEN];
369 switch (get_family()) {
370 case AF_INET:
371 host_ip = inet_ntop(AF_INET, &in4_addr().sin_addr,
372 addr_buf, INET_ADDRSTRLEN);
373 break;
374 case AF_INET6:
375 host_ip = inet_ntop(AF_INET6, &in6_addr().sin6_addr,
376 addr_buf, INET6_ADDRSTRLEN);
377 break;
378 default:
379 break;
380 }
381 return host_ip ? host_ip : "";
382}