summaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/net/socket_address.h
blob: c6810ad6108f7ecfd9f4cd8553919fc672e3fca5 (plain) (blame)
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