Warning, file /sdk/dferry/transport/ipresolver.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002    Copyright (C) 2023 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 #include "ipresolver.h"
0025 
0026 #include "connectaddress.h"
0027 
0028 #include <cstring>
0029 
0030 IpResolver::IpResolver(const ConnectAddress& ca)
0031 {
0032     std::string hostname = ca.hostname();
0033     if (hostname.empty() || hostname == "localhost") {
0034         hostname = "127.0.0.1";
0035     }
0036 
0037 #ifdef USE_GETADDRINFO
0038     struct addrinfo hints;
0039     memset(&hints, 0, sizeof(hints));
0040     hints.ai_flags = AI_NUMERICHOST;
0041     hints.ai_family = AF_INET;
0042 
0043     m_resultValid = getaddrinfo(hostname.c_str(), nullptr, &hints, &m_resolved) == 0;
0044     if (m_resultValid) {
0045         // ### Careful with that cast - if we ever support IPv6, casting to sockaddr_in might be unsafe!
0046         // (Though sin_port is the second field in both, and the first two fields of sockaddr_in and
0047         // sockaddr_in6 seem to be the same - check if that is guaranteed!)
0048         auto in_addr = reinterpret_cast<struct sockaddr_in *>(m_resolved->ai_addr);
0049         in_addr->sin_port = htons(ca.port());
0050     }
0051 #else
0052     memset(&m_resolved, 0, sizeof(m_resolved));
0053     m_resultValid = inet_aton(hostname.c_str(), &m_resolved.sin_addr) == 1;
0054     // The m_resultValid check is not really necessary, unlike in the getaddrinfo() codepath. We do it
0055     // to ensure that resolved() returns something unusable with both codepaths, to detect errors.
0056     if (m_resultValid) {
0057         m_resolved.sin_family = AF_INET;
0058         m_resolved.sin_port = htons(ca.port());
0059     }
0060 #endif
0061 }
0062 
0063 IpResolver::~IpResolver()
0064 {
0065 #ifdef USE_GETADDRINFO
0066     if (m_resultValid) {
0067         freeaddrinfo(m_resolved);
0068     }
0069 #endif
0070 }
0071 
0072 bool IpResolver::resultValid() const
0073 {
0074     return m_resultValid;
0075 }
0076 
0077 const struct sockaddr* IpResolver::resolved() const
0078 {
0079 #ifdef USE_GETADDRINFO
0080     return m_resolved->ai_addr;
0081 #else
0082     return reinterpret_cast<const struct sockaddr *>(&m_resolved);
0083 #endif
0084 }
0085 
0086 socklen_t IpResolver::resolvedLength() const
0087 {
0088 #ifdef USE_GETADDRINFO
0089     return m_resolved->ai_addrlen;
0090 #else
0091     return sizeof(m_resolved);
0092 #endif
0093 }