• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #853

19 Dec 2022 01:01AM UTC coverage: 86.287% (+0.4%) from 85.912%
#853

push

StellarBot
Merge #6109

6109: Modernize serialization module r=hkaiser a=hkaiser

- flyby separate serialization of Boost types

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

53 of 53 new or added lines in 6 files covered. (100.0%)

173939 of 201582 relevant lines covered (86.29%)

1931657.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.97
/libs/core/asio/src/asio_util.cpp
1
//  Copyright (c) 2007-2017 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
// hpxinspect:nodeprecatedinclude:boost/system/error_code.hpp
9
// hpxinspect:nodeprecatedname:boost::system::error_code
10
// hpxinspect:nodeprecatedinclude:boost/system/system_error.hpp
11
// hpxinspect:nodeprecatedname:boost::system::system_error
12

13
#include <hpx/config.hpp>
14
#include <hpx/asio/asio_util.hpp>
15
#include <hpx/util/from_string.hpp>
16

17
#include <cstdint>
18
#include <string>
19

20
#include <hpx/config/asio.hpp>
21
#include <hpx/assert.hpp>
22
#include <hpx/modules/errors.hpp>
23

24
#include <asio/io_context.hpp>
25
#include <asio/ip/address_v4.hpp>
26
#include <asio/ip/address_v6.hpp>
27
#include <asio/ip/host_name.hpp>
28
#include <asio/ip/tcp.hpp>
29

30
#include <ctime>
31
#include <exception>
32
#include <system_error>
33

34
#if defined(HPX_WINDOWS) && !defined(HPX_HAVE_STATIC_LINKING)
35
// Prevent asio from initializing Winsock, the object must be constructed
36
// before any Asio's own global objects. With MSVC, this may be accomplished
37
// by adding the following code to the DLL:
38

39
#if defined(HPX_MSVC_WARNING_PRAGMA)
40
#pragma warning(push)
41
#pragma warning(disable : 4073)
42
#endif
43
#pragma init_seg(lib)
44
asio::detail::winsock_init<>::manual manual_winsock_init;
45
#if defined(HPX_MSVC_WARNING_PRAGMA)
46
#pragma warning(pop)
47
#endif
48
#endif
49

50
///////////////////////////////////////////////////////////////////////////////
51
namespace hpx { namespace util {
52

53
    ///////////////////////////////////////////////////////////////////////////
54
    bool get_endpoint(std::string const& addr, std::uint16_t port,
3,549✔
55
        asio::ip::tcp::endpoint& ep, bool force_ipv4)
56
    {
57
        using namespace asio::ip;
58
        std::error_code ec;
3,545✔
59
        address_v4 addr4 = address_v4::from_string(addr.c_str(), ec);
3,545✔
60
        if (!ec)
3,545✔
61
        {    // it's an IPV4 address
62
            ep = tcp::endpoint(address(addr4), port);
3,539✔
63
            return true;
3,539✔
64
        }
65

66
        if (!force_ipv4)
×
67
        {
68
            address_v6 addr6 = address_v6::from_string(addr.c_str(), ec);
×
69
            if (!ec)
×
70
            {    // it's an IPV6 address
71
                ep = tcp::endpoint(address(addr6), port);
×
72
                return true;
×
73
            }
74
        }
×
75
        return false;
×
76
    }
3,539✔
77

78
    ///////////////////////////////////////////////////////////////////////////
79
    std::string get_endpoint_name(asio::ip::tcp::endpoint const& ep)
2,384✔
80
    {
81
        return ep.address().to_string();
2,384✔
82
    }
83

84
    ///////////////////////////////////////////////////////////////////////////
85
    // properly resolve a give host name to the corresponding IP address
86
    asio::ip::tcp::endpoint resolve_hostname(std::string const& hostname,
2,384✔
87
        std::uint16_t port, asio::io_context& io_service, bool force_ipv4)
88
    {
89
        using asio::ip::tcp;
90

91
        // collect errors here
92
        exception_list errors;
2,384✔
93

94
        // try to directly create an endpoint from the address
95
        try
96
        {
97
            tcp::endpoint ep;
2,384✔
98
            if (util::get_endpoint(hostname, port, ep))
2,384✔
99
                return ep;
2,384✔
100
        }
×
101
        catch (std::system_error const&)
102
        {
103
            errors.add(std::current_exception());
×
104
        }
×
105

106
        // it's not an address, try to treat it as a host name
107
        try
108
        {
109
            // resolve the given address
110
            tcp::resolver resolver(io_service);
×
111
            tcp::resolver::query query(hostname, std::to_string(port));
×
112

113
            asio::ip::tcp::resolver::iterator it = resolver.resolve(query);
×
114

115
            while (force_ipv4 && it != tcp::resolver::iterator() &&
×
116
                !it->endpoint().address().is_v4())
×
117
            {
118
                ++it;
×
119
            }
120

121
            HPX_ASSERT(it != asio::ip::tcp::resolver::iterator());
×
122
            return *it;
×
123
        }
×
124
        catch (std::system_error const&)
125
        {
126
            errors.add(std::current_exception());
×
127
        }
×
128

129
        // report errors
130
        HPX_THROW_EXCEPTION(hpx::error::network_error, "util::resolve_hostname",
×
131
            "{} (while trying to resolve: {}:{})", errors.get_message(),
132
            hostname, port);
133
        return tcp::endpoint();
134
    }
2,384✔
135

136
    ///////////////////////////////////////////////////////////////////////////
137
    // return the public IP address of the local node
138
    std::string resolve_public_ip_address()
2✔
139
    {
140
        using asio::ip::tcp;
141

142
        // collect errors here
143
        exception_list errors;
2✔
144

145
        try
146
        {
147
            asio::io_context io_service;
2✔
148
            tcp::resolver resolver(io_service);
2✔
149
            tcp::resolver::query query(asio::ip::host_name(), "");
2✔
150
            tcp::resolver::iterator it = resolver.resolve(query);
2✔
151
            tcp::endpoint endpoint = *it;
2✔
152
            return endpoint.address().to_string();
2✔
153
        }
2✔
154
        catch (std::system_error const&)
155
        {
156
            errors.add(std::current_exception());
×
157
        }
×
158

159
        // report errors
160
        HPX_THROW_EXCEPTION(hpx::error::network_error,
×
161
            "util::resolve_public_ip_address",
162
            "{} (while trying to resolve public ip address)",
163
            errors.get_message());
164
        return "";
165
    }
2✔
166

167
    ///////////////////////////////////////////////////////////////////////
168
    // Take an ip v4 or v6 address and "standardize" it for comparison checks
169
    // note that this code doesn't work as expected if we use the boost
170
    // inet_pton functions on linux. see issue #2177 for further info
171
    std::string cleanup_ip_address(std::string const& addr)
861,434✔
172
    {
173
        char buf[sizeof(struct in6_addr)];
174
        int i = 0, domain[2] = {AF_INET, AF_INET6};
861,435✔
175
        char str[INET6_ADDRSTRLEN];
176

177
#if defined(HPX_WINDOWS)
178
        unsigned long scope_id;
179
        std::error_code ec;
180
#endif
181

182
        for (i = 0; i < 2; ++i)
861,434✔
183
        {
184
#if defined(HPX_WINDOWS)
185
            int s = asio::detail::socket_ops::inet_pton(
186
                domain[i], &addr[0], buf, &scope_id, ec);
187
            if (s > 0 && !ec)
188
                break;
189
#else
190
            int s = inet_pton(domain[i], &addr[0], buf);
861,461✔
191
            if (s > 0)
861,461✔
192
                break;
861,461✔
193
#endif
194
        }
×
195
        if (i == 2)
861,457✔
196
        {
197
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter, "cleanup_ip_address",
×
198
                "Invalid IP address string");
199
        }
200

201
#if defined(HPX_WINDOWS)
202
        if (asio::detail::socket_ops::inet_ntop(
203
                domain[i], buf, str, INET6_ADDRSTRLEN, scope_id, ec) == nullptr)
204
        {
205
#else
206
        if (inet_ntop(domain[i], buf, str, INET6_ADDRSTRLEN) == nullptr)
861,456✔
207
        {
208
#endif
209
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter, "cleanup_ip_address",
×
210
                "inet_ntop failure");
211
        }
212
        return std::string(str);
861,456✔
213
    }
×
214

215
    endpoint_iterator_type connect_begin(std::string const& address,
883✔
216
        std::uint16_t port, asio::io_context& io_service)
217
    {
218
        using asio::ip::tcp;
219

220
        // collect errors here
221
        exception_list errors;
882✔
222

223
        std::string port_str(std::to_string(port));
882✔
224

225
        // try to directly create an endpoint from the address
226
        try
227
        {
228
            tcp::endpoint ep;
872✔
229
            if (util::get_endpoint(address, port, ep))
882✔
230
            {
231
                return endpoint_iterator_type(
877✔
232
                    tcp::resolver::results_type::create(ep, address, port_str));
872✔
233
            }
234
        }
×
235
        catch (std::system_error const&)
236
        {
237
            errors.add(std::current_exception());
×
238
        }
×
239

240
        // it's not an address, try to treat it as a host name
241
        try
242
        {
243
            // resolve the given address
244
            tcp::resolver resolver(io_service);
×
245
            tcp::resolver::query query(
×
246
                !address.empty() ? address : asio::ip::host_name(), port_str);
×
247

248
            return endpoint_iterator_type(resolver.resolve(query));
×
249
        }
×
250
        catch (std::system_error const&)
251
        {
252
            errors.add(std::current_exception());
×
253
        }
×
254

255
        // report errors
256
        HPX_THROW_EXCEPTION(hpx::error::network_error, "connect_begin",
×
257
            "{} (while trying to connect to: {}:{})", errors.get_message(),
258
            address, port);
259

260
        return endpoint_iterator_type();
261
    }
877✔
262

263
    endpoint_iterator_type accept_begin(std::string const& address,
282✔
264
        std::uint16_t port, asio::io_context& io_service)
265
    {
266
        using asio::ip::tcp;
267

268
        // collect errors here
269
        exception_list errors;
282✔
270

271
        std::string port_str(std::to_string(port));
282✔
272

273
        // try to directly create an endpoint from the address
274
        try
275
        {
276
            tcp::endpoint ep;
282✔
277
            if (util::get_endpoint(address, port, ep))
282✔
278
            {
279
                return endpoint_iterator_type(
282✔
280
                    tcp::resolver::results_type::create(ep, address, port_str));
282✔
281
            }
282
        }
×
283
        catch (std::system_error const&)
284
        {
285
            errors.add(std::current_exception());
×
286
        }
×
287

288
        // it's not an address, try to treat it as a host name
289
        try
290
        {
291
            // resolve the given address
292
            tcp::resolver resolver(io_service);
×
293
            tcp::resolver::query query(address, port_str);
×
294

295
            return endpoint_iterator_type(resolver.resolve(query));
×
296
        }
×
297
        catch (std::system_error const&)
298
        {
299
            errors.add(std::current_exception());
×
300
        }
×
301

302
        // it's not a host name either, create a custom iterator allowing to
303
        // filter the returned endpoints, for this we use "localhost" as the
304
        // address to enumerate endpoints
305
        try
306
        {
307
            // resolve the given address
308
            tcp::resolver resolver(io_service);
×
309
            tcp::resolver::query query(asio::ip::host_name(), port_str);
×
310

311
            return endpoint_iterator_type(resolver.resolve(query));
×
312
        }
×
313
        catch (std::system_error const&)
314
        {
315
            errors.add(std::current_exception());
×
316
        }
×
317

318
        // report errors
319
        HPX_THROW_EXCEPTION(hpx::error::network_error, "accept_begin",
×
320
            "{} (while trying to resolve: {}:{}))", errors.get_message(),
321
            address, port);
322
        return endpoint_iterator_type();
323
    }
282✔
324
}}    // namespace hpx::util
325

326
///////////////////////////////////////////////////////////////////////////////
327
namespace hpx { namespace util {
328

329
    ///////////////////////////////////////////////////////////////////////
330
    // Addresses are supposed to have the format <hostname>[:port]
331
    bool split_ip_address(
×
332
        std::string const& v, std::string& host, std::uint16_t& port)
333
    {
334
        std::string::size_type p = v.find_last_of(':');
×
335

336
        std::string tmp_host;
×
337
        std::uint16_t tmp_port = 0;
×
338

339
        try
340
        {
341
            if (p != std::string::npos)
×
342
            {
343
                if (v.find_first_of(':') != p)
×
344
                {
345
                    // IPv6
346
                    std::string::size_type begin_of_address =
×
347
                        v.find_first_of('[');
×
348
                    if (begin_of_address != std::string::npos)
×
349
                    {
350
                        // IPv6 with a port has to be written as: [address]:port
351
                        std::string::size_type end_of_address =
×
352
                            v.find_last_of(']');
×
353
                        if (end_of_address == std::string::npos)
×
354
                            return false;
×
355

356
                        tmp_host =
×
357
                            v.substr(begin_of_address + 1, end_of_address - 1);
×
358
                        if (end_of_address < p)
×
359
                        {
360
                            tmp_port = hpx::util::from_string<std::uint16_t>(
×
361
                                v.substr(p + 1));
×
362
                        }
×
363
                    }
×
364
                    else
365
                    {
366
                        // IPv6 without a port
367
                        tmp_host = v;
×
368
                    }
369
                }
×
370
                else
371
                {
372
                    // IPv4
373
                    tmp_host = v.substr(0, p);
×
374
                    tmp_port =
×
375
                        hpx::util::from_string<std::uint16_t>(v.substr(p + 1));
×
376
                }
377
            }
×
378
            else
379
            {
380
                tmp_host = v;
×
381
            }
382

383
            if (!tmp_host.empty())
×
384
            {
385
                host = tmp_host;
×
386
                if (tmp_port)
×
387
                    port = tmp_port;
×
388
            }
×
389
        }
×
390
        catch (hpx::util::bad_lexical_cast const& /*e*/)
391
        {
392
            // port number is invalid
393
            return false;
×
394
        }
×
395
        return true;
×
396
    }
×
397
}}    // namespace hpx::util
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc