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
|
// Copyright 2016 Yahoo Inc. 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>
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() { memset(this, 0, sizeof(SocketAddress)); }
SocketAddress(const SocketAddress &rhs) { memcpy(this, &rhs, sizeof(SocketAddress)); }
SocketAddress &operator=(const SocketAddress &rhs) {
memcpy(this, &rhs, sizeof(SocketAddress));
return *this;
}
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 path() const;
vespalib::string name() const;
vespalib::string spec() const;
SocketHandle connect() const;
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);
};
} // namespace vespalib
|