OpenVPN 3 Core Library
Loading...
Searching...
No Matches
asioboundsock.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// Asio TCP socket that can be configured so that open() method
13// always prebinds the socket to a given local address. Useful
14// for TCP clients.
15
16#ifndef OPENVPN_ASIO_ASIOBOUNDSOCK_H
17#define OPENVPN_ASIO_ASIOBOUNDSOCK_H
18
19#include <openvpn/io/io.hpp>
20
21#include <openvpn/addr/ip.hpp>
23
25
26typedef openvpn_io::basic_stream_socket<openvpn_io::ip::tcp> SocketBase;
27
28class Socket : public SocketBase
29{
30 public:
31 explicit Socket(openvpn_io::io_context &io_context)
32 : SocketBase(io_context)
33 {
34 }
35
36 // May be called twice with IPv4 and IPv6 address.
37 // If port 0, kernel will dynamically allocate free port.
38 void bind_local(const IP::Addr &addr, const unsigned short port = 0)
39 {
40 switch (addr.version())
41 {
42 case IP::Addr::V4:
43 v4.bind_local(addr.to_ipv4(), port);
44 break;
45 case IP::Addr::V6:
46 v6.bind_local(addr.to_ipv6(), port);
47 break;
48 default:
49 return;
50 }
51 }
52
53 std::string to_string() const
54 {
55 std::string ret;
56 ret.reserve(64);
57
58 if (v4.defined())
59 {
60 ret += "local4=";
61 ret += v4.to_string();
62 }
63 if (v6.defined())
64 {
65 if (!ret.empty())
66 ret += ' ';
67 ret += "local6=";
68 ret += v6.to_string();
69 }
70
71 try
72 {
73 const std::string re = openvpn::to_string(remote_endpoint());
74 if (!ret.empty())
75 ret += ' ';
76 ret += "remote=";
77 ret += re;
78 }
79 catch (const std::exception &e)
80 {
81 }
82 return ret;
83 }
84
85 protected:
86 template <typename IP_ADDR>
87 class Proto
88 {
89 public:
91 {
92 local_.zero();
93 port_ = 0;
94 }
95
96 bool defined() const
97 {
98 return local_.specified();
99 }
100
101 void bind_local(const IP_ADDR &local, const unsigned short port)
102 {
103 local_ = local;
104 port_ = port;
105 }
106
107 template <typename PARENT>
108 void post_open(PARENT *parent, openvpn_io::error_code &ec) const
109 {
110 if (defined())
111 {
112 parent->set_option(openvpn_io::socket_base::reuse_address(true), ec);
113 if (!ec)
114 parent->bind(openvpn_io::ip::tcp::endpoint(local_.to_asio(), port_), ec);
115 }
116 }
117
118 std::string to_string() const
119 {
120 return '[' + local_.to_string() + "]:" + std::to_string(port_);
121 }
122
123 private:
124 IP_ADDR local_;
125 unsigned short port_;
126 };
127
128 virtual void async_connect_post_open(const protocol_type &protocol, openvpn_io::error_code &ec) override
129 {
130 if (protocol == openvpn_io::ip::tcp::v4())
131 v4.post_open(this, ec);
132 else if (protocol == openvpn_io::ip::tcp::v6())
133 v6.post_open(this, ec);
134 }
135
136 private:
139};
140
141} // namespace openvpn::AsioBoundSocket
142
143#endif
void bind_local(const IP_ADDR &local, const unsigned short port)
void post_open(PARENT *parent, openvpn_io::error_code &ec) const
void bind_local(const IP::Addr &addr, const unsigned short port=0)
virtual void async_connect_post_open(const protocol_type &protocol, openvpn_io::error_code &ec) override
Socket(openvpn_io::io_context &io_context)
Version version() const
Definition ip.hpp:895
const IPv4::Addr & to_ipv4() const
Definition ip.hpp:276
const IPv6::Addr & to_ipv6() const
Definition ip.hpp:296
openvpn_io::basic_stream_socket< openvpn_io::ip::tcp > SocketBase
std::string to_string(const T &t)
Convert a value to a string.
Definition to_string.hpp:45
proxy_host_port port
std::string ret