]> granicus.if.org Git - icinga2/blob - lib/base/tcpsocket.hpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / tcpsocket.hpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #ifndef TCPSOCKET_H
4 #define TCPSOCKET_H
5
6 #include "base/i2-base.hpp"
7 #include "base/socket.hpp"
8 #include <boost/asio/ip/tcp.hpp>
9 #include <boost/asio/spawn.hpp>
10
11 namespace icinga
12 {
13
14 /**
15  * A TCP socket.
16  *
17  * @ingroup base
18  */
19 class TcpSocket final : public Socket
20 {
21 public:
22         DECLARE_PTR_TYPEDEFS(TcpSocket);
23
24         void Bind(const String& service, int family);
25         void Bind(const String& node, const String& service, int family);
26
27         void Connect(const String& node, const String& service);
28 };
29
30 template<class Socket>
31 void Connect(Socket& socket, const String& node, const String& service)
32 {
33         using boost::asio::ip::tcp;
34
35         tcp::resolver resolver (socket.get_io_service());
36         tcp::resolver::query query (node, service);
37         auto result (resolver.resolve(query));
38         auto current (result.begin());
39
40         for (;;) {
41                 try {
42                         socket.open(current->endpoint().protocol());
43                         socket.set_option(tcp::socket::keep_alive(true));
44                         socket.connect(current->endpoint());
45
46                         break;
47                 } catch (const std::exception&) {
48                         if (++current == result.end()) {
49                                 throw;
50                         }
51
52                         if (socket.is_open()) {
53                                 socket.close();
54                         }
55                 }
56         }
57 }
58
59 template<class Socket>
60 void Connect(Socket& socket, const String& node, const String& service, boost::asio::yield_context yc)
61 {
62         using boost::asio::ip::tcp;
63
64         tcp::resolver resolver (socket.get_io_service());
65         tcp::resolver::query query (node, service);
66         auto result (resolver.async_resolve(query, yc));
67         auto current (result.begin());
68
69         for (;;) {
70                 try {
71                         socket.open(current->endpoint().protocol());
72                         socket.set_option(tcp::socket::keep_alive(true));
73                         socket.async_connect(current->endpoint(), yc);
74
75                         break;
76                 } catch (const std::exception&) {
77                         if (++current == result.end()) {
78                                 throw;
79                         }
80
81                         if (socket.is_open()) {
82                                 socket.close();
83                         }
84                 }
85         }
86 }
87
88 }
89
90 #endif /* TCPSOCKET_H */