1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include <vespa/vespalib/stllike/string.h>
#include "socket_handle.h"
#include <vector>
#include <sys/socket.h>
#include <functional>
struct sockaddr_in;
struct sockaddr_in6;
struct sockaddr_un;
namespace vespalib {
/**
* Wrapper class for low-level TCP/IP and IPC socket addresses.
**/
class SocketAddress
{
private:
socklen_t _size;
sockaddr_storage _addr;
const sockaddr *addr() const { return reinterpret_cast<const sockaddr *>(&_addr); }
const sockaddr_in *addr_in() const { return reinterpret_cast<const sockaddr_in *>(&_addr); }
const sockaddr_in6 *addr_in6() const { return reinterpret_cast<const sockaddr_in6 *>(&_addr); }
const sockaddr_un *addr_un() const { return reinterpret_cast<const sockaddr_un *>(&_addr); }
SocketAddress(const sockaddr *addr_in, socklen_t addrlen_in);
public:
SocketAddress() noexcept { memset(this, 0, sizeof(SocketAddress)); }
SocketAddress(const SocketAddress &rhs) noexcept { memcpy(this, &rhs, sizeof(SocketAddress)); }
SocketAddress &operator=(const SocketAddress &rhs) noexcept {
memcpy(this, &rhs, sizeof(SocketAddress));
return *this;
}
const sockaddr *raw_addr() const { return addr(); }
socklen_t raw_addr_len() const { return _size; }
bool valid() const { return (_size >= sizeof(sa_family_t)); }
bool is_ipv4() const { return (valid() && (_addr.ss_family == AF_INET)); }
bool is_ipv6() const { return (valid() && (_addr.ss_family == AF_INET6)); }
bool is_ipc() const { return (valid() && (_addr.ss_family == AF_UNIX)); }
bool is_wildcard() const;
bool is_abstract() const;
int port() const;
vespalib::string ip_address() const;
vespalib::string reverse_lookup() const;
vespalib::string path() const;
vespalib::string name() const;
vespalib::string spec() const;
SocketHandle raw_socket() const;
SocketHandle connect(const std::function<bool(SocketHandle&)> &tweak) const;
SocketHandle connect() const { return connect([](SocketHandle&) noexcept { return true; }); }
SocketHandle connect_async() const {
return connect([](SocketHandle &handle){ return handle.set_blocking(false); });
}
SocketHandle listen(int backlog = 500) const;
static SocketAddress address_of(int sockfd);
static SocketAddress peer_address(int sockfd);
static std::vector<SocketAddress> resolve(int port, const char *node = nullptr);
static SocketAddress select_local(int port, const char *node = nullptr);
static SocketAddress select_remote(int port, const char *node = nullptr);
template <typename SELECTOR>
static SocketAddress select(const SELECTOR &replace, int port, const char *node = nullptr) {
auto list = resolve(port, node);
if (!list.empty()) {
size_t best = 0;
for (size_t i = 1; i < list.size(); ++i) {
if (replace(list[best], list[i])) {
best = i;
}
}
return list[best];
}
return SocketAddress();
}
static SocketAddress from_path(const vespalib::string &path);
static SocketAddress from_name(const vespalib::string &name);
static std::vector<SocketAddress> get_interfaces();
static vespalib::string normalize(const vespalib::string &host_name);
};
} // namespace vespalib
|