Coverage Report

Created: 2022-10-16 06:45

/src/curl/lib/hostip6.c
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
25
#include "curl_setup.h"
26
27
/***********************************************************************
28
 * Only for IPv6-enabled builds
29
 **********************************************************************/
30
#ifdef CURLRES_IPV6
31
32
#ifdef HAVE_NETINET_IN_H
33
#include <netinet/in.h>
34
#endif
35
#ifdef HAVE_NETDB_H
36
#include <netdb.h>
37
#endif
38
#ifdef HAVE_ARPA_INET_H
39
#include <arpa/inet.h>
40
#endif
41
#ifdef __VMS
42
#include <in.h>
43
#include <inet.h>
44
#endif
45
46
#ifdef HAVE_PROCESS_H
47
#include <process.h>
48
#endif
49
50
#include "urldata.h"
51
#include "sendf.h"
52
#include "hostip.h"
53
#include "hash.h"
54
#include "share.h"
55
#include "url.h"
56
#include "inet_pton.h"
57
#include "connect.h"
58
/* The last 3 #include files should be in this order */
59
#include "curl_printf.h"
60
#include "curl_memory.h"
61
#include "memdebug.h"
62
63
/*
64
 * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
65
 * been set and returns TRUE if they are OK.
66
 */
67
bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
68
22
{
69
22
  if(conn->ip_version == CURL_IPRESOLVE_V6)
70
0
    return Curl_ipv6works(data);
71
72
22
  return TRUE;
73
22
}
74
75
#if defined(CURLRES_SYNCH)
76
77
#ifdef DEBUG_ADDRINFO
78
static void dump_addrinfo(struct connectdata *conn,
79
                          const struct Curl_addrinfo *ai)
80
{
81
  printf("dump_addrinfo:\n");
82
  for(; ai; ai = ai->ai_next) {
83
    char buf[INET6_ADDRSTRLEN];
84
    printf("    fam %2d, CNAME %s, ",
85
           ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
86
    Curl_printable_address(ai, buf, sizeof(buf));
87
    printf("%s\n", buf);
88
  }
89
}
90
#else
91
#define dump_addrinfo(x,y) Curl_nop_stmt
92
#endif
93
94
/*
95
 * Curl_getaddrinfo() when built IPv6-enabled (non-threading and
96
 * non-ares version).
97
 *
98
 * Returns name information about the given hostname and port number. If
99
 * successful, the 'addrinfo' is returned and the fourth argument will point
100
 * to memory we need to free after use. That memory *MUST* be freed with
101
 * Curl_freeaddrinfo(), nothing else.
102
 */
103
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
104
                                       const char *hostname,
105
                                       int port,
106
                                       int *waitp)
107
{
108
  struct addrinfo hints;
109
  struct Curl_addrinfo *res;
110
  int error;
111
  char sbuf[12];
112
  char *sbufptr = NULL;
113
#ifndef USE_RESOLVE_ON_IPS
114
  char addrbuf[128];
115
#endif
116
  int pf = PF_INET;
117
118
  *waitp = 0; /* synchronous response only */
119
120
  if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
121
    /* The stack seems to be IPv6-enabled */
122
    pf = PF_UNSPEC;
123
124
  memset(&hints, 0, sizeof(hints));
125
  hints.ai_family = pf;
126
  hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
127
    SOCK_STREAM : SOCK_DGRAM;
128
129
#ifndef USE_RESOLVE_ON_IPS
130
  /*
131
   * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from
132
   * an IPv4 address on iOS and Mac OS X.
133
   */
134
  if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
135
     (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
136
    /* the given address is numerical only, prevent a reverse lookup */
137
    hints.ai_flags = AI_NUMERICHOST;
138
  }
139
#endif
140
141
  if(port) {
142
    msnprintf(sbuf, sizeof(sbuf), "%d", port);
143
    sbufptr = sbuf;
144
  }
145
146
  error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
147
  if(error) {
148
    infof(data, "getaddrinfo(3) failed for %s:%d", hostname, port);
149
    return NULL;
150
  }
151
152
  if(port) {
153
    Curl_addrinfo_set_port(res, port);
154
  }
155
156
  dump_addrinfo(conn, res);
157
158
  return res;
159
}
160
#endif /* CURLRES_SYNCH */
161
162
#endif /* CURLRES_IPV6 */