aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/aws-crt-cpp/source/io/HostResolver.cpp
blob: 18173fc413659be48b3cac8252e016ce434b6bda (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
#include <aws/crt/io/HostResolver.h>

#include <aws/crt/io/EventLoopGroup.h>

#include <aws/common/string.h>
#include <aws/crt/Api.h>

namespace Aws
{
    namespace Crt
    {
        namespace Io
        {
            HostResolver::~HostResolver() {}

            DefaultHostResolver::DefaultHostResolver(
                EventLoopGroup &elGroup,
                size_t maxHosts,
                size_t maxTTL,
                Allocator *allocator) noexcept
                : m_resolver(nullptr), m_allocator(allocator), m_initialized(false)
            {
                AWS_ZERO_STRUCT(m_config);

                struct aws_host_resolver_default_options resolver_options;
                AWS_ZERO_STRUCT(resolver_options);
                resolver_options.max_entries = maxHosts;
                resolver_options.el_group = elGroup.GetUnderlyingHandle();

                m_resolver = aws_host_resolver_new_default(allocator, &resolver_options);
                if (m_resolver != nullptr)
                {
                    m_initialized = true;
                }

                m_config.impl = aws_default_dns_resolve;
                m_config.impl_data = nullptr;
                m_config.max_ttl = maxTTL;
            }

            DefaultHostResolver::DefaultHostResolver(size_t maxHosts, size_t maxTTL, Allocator *allocator) noexcept
                : DefaultHostResolver(
                      *Crt::ApiHandle::GetOrCreateStaticDefaultEventLoopGroup(),
                      maxHosts,
                      maxTTL,
                      allocator)
            {
            }

            DefaultHostResolver::~DefaultHostResolver()
            {
                aws_host_resolver_release(m_resolver);
                m_initialized = false;
            }

            /**
             * @private
             */
            struct DefaultHostResolveArgs
            {
                Allocator *allocator;
                HostResolver *resolver;
                OnHostResolved onResolved;
                aws_string *host;
            };

            void DefaultHostResolver::s_onHostResolved(
                struct aws_host_resolver *,
                const struct aws_string *hostName,
                int errCode,
                const struct aws_array_list *hostAddresses,
                void *userData)
            {
                DefaultHostResolveArgs *args = static_cast<DefaultHostResolveArgs *>(userData);

                size_t len = aws_array_list_length(hostAddresses);
                Vector<HostAddress> addresses;

                for (size_t i = 0; i < len; ++i)
                {
                    HostAddress *address_ptr = NULL;
                    aws_array_list_get_at_ptr(hostAddresses, reinterpret_cast<void **>(&address_ptr), i);
                    addresses.push_back(*address_ptr);
                }

                String host(aws_string_c_str(hostName), hostName->len);
                args->onResolved(*args->resolver, addresses, errCode);
                aws_string_destroy(args->host);
                Delete(args, args->allocator);
            }

            bool DefaultHostResolver::ResolveHost(const String &host, const OnHostResolved &onResolved) noexcept
            {
                DefaultHostResolveArgs *args = New<DefaultHostResolveArgs>(m_allocator);
                if (!args)
                {
                    return false;
                }

                args->host = aws_string_new_from_array(
                    m_allocator, reinterpret_cast<const uint8_t *>(host.data()), host.length());
                args->onResolved = onResolved;
                args->resolver = this;
                args->allocator = m_allocator;

                if (!args->host ||
                    aws_host_resolver_resolve_host(m_resolver, args->host, s_onHostResolved, &m_config, args))
                {
                    Delete(args, m_allocator);
                    return false;
                }

                return true;
            }
        } // namespace Io
    }     // namespace Crt
} // namespace Aws