Rizin
unix-like reverse engineering framework and cli tools
getaddrinfo.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  * Permission is hereby granted, free of charge, to any person obtaining a copy
3  * of this software and associated documentation files (the "Software"), to
4  * deal in the Software without restriction, including without limitation the
5  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6  * sell copies of the Software, and to permit persons to whom the Software is
7  * furnished to do so, subject to the following conditions:
8  *
9  * The above copyright notice and this permission notice shall be included in
10  * all copies or substantial portions of the Software.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18  * IN THE SOFTWARE.
19  */
20 
21 /* Expose glibc-specific EAI_* error codes. Needs to be defined before we
22  * include any headers.
23  */
24 #ifndef _GNU_SOURCE
25 # define _GNU_SOURCE
26 #endif
27 
28 #include "uv.h"
29 #include "internal.h"
30 #include "idna.h"
31 
32 #include <errno.h>
33 #include <stddef.h> /* NULL */
34 #include <stdlib.h>
35 #include <string.h>
36 #include <net/if.h> /* if_indextoname() */
37 
38 /* EAI_* constants. */
39 #include <netdb.h>
40 
41 
43  switch (sys_err) {
44  case 0: return 0;
45 #if defined(EAI_ADDRFAMILY)
46  case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
47 #endif
48 #if defined(EAI_AGAIN)
49  case EAI_AGAIN: return UV_EAI_AGAIN;
50 #endif
51 #if defined(EAI_BADFLAGS)
52  case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
53 #endif
54 #if defined(EAI_BADHINTS)
55  case EAI_BADHINTS: return UV_EAI_BADHINTS;
56 #endif
57 #if defined(EAI_CANCELED)
58  case EAI_CANCELED: return UV_EAI_CANCELED;
59 #endif
60 #if defined(EAI_FAIL)
61  case EAI_FAIL: return UV_EAI_FAIL;
62 #endif
63 #if defined(EAI_FAMILY)
64  case EAI_FAMILY: return UV_EAI_FAMILY;
65 #endif
66 #if defined(EAI_MEMORY)
67  case EAI_MEMORY: return UV_EAI_MEMORY;
68 #endif
69 #if defined(EAI_NODATA)
70  case EAI_NODATA: return UV_EAI_NODATA;
71 #endif
72 #if defined(EAI_NONAME)
73 # if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
74  case EAI_NONAME: return UV_EAI_NONAME;
75 # endif
76 #endif
77 #if defined(EAI_OVERFLOW)
78  case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
79 #endif
80 #if defined(EAI_PROTOCOL)
81  case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
82 #endif
83 #if defined(EAI_SERVICE)
84  case EAI_SERVICE: return UV_EAI_SERVICE;
85 #endif
86 #if defined(EAI_SOCKTYPE)
87  case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
88 #endif
89 #if defined(EAI_SYSTEM)
90  case EAI_SYSTEM: return UV__ERR(errno);
91 #endif
92  }
93  assert(!"unknown EAI_* error code");
94  abort();
95 #ifndef __SUNPRO_C
96  return 0; /* Pacify compiler. */
97 #endif
98 }
99 
100 
101 static void uv__getaddrinfo_work(struct uv__work* w) {
103  int err;
104 
105  req = container_of(w, uv_getaddrinfo_t, work_req);
106  err = getaddrinfo(req->hostname, req->service, req->hints, &req->addrinfo);
108 }
109 
110 
111 static void uv__getaddrinfo_done(struct uv__work* w, int status) {
113 
114  req = container_of(w, uv_getaddrinfo_t, work_req);
115  uv__req_unregister(req->loop, req);
116 
117  /* See initialization in uv_getaddrinfo(). */
118  if (req->hints)
119  uv__free(req->hints);
120  else if (req->service)
121  uv__free(req->service);
122  else if (req->hostname)
123  uv__free(req->hostname);
124  else
125  assert(0);
126 
127  req->hints = NULL;
128  req->service = NULL;
129  req->hostname = NULL;
130 
131  if (status == UV_ECANCELED) {
132  assert(req->retcode == 0);
133  req->retcode = UV_EAI_CANCELED;
134  }
135 
136  if (req->cb)
137  req->cb(req, req->retcode, req->addrinfo);
138 }
139 
140 
144  const char* hostname,
145  const char* service,
146  const struct addrinfo* hints) {
147  char hostname_ascii[256];
148  size_t hostname_len;
149  size_t service_len;
150  size_t hints_len;
151  size_t len;
152  char* buf;
153  long rc;
154 
155  if (req == NULL || (hostname == NULL && service == NULL))
156  return UV_EINVAL;
157 
158  /* FIXME(bnoordhuis) IDNA does not seem to work z/OS,
159  * probably because it uses EBCDIC rather than ASCII.
160  */
161 #ifdef __MVS__
162  (void) &hostname_ascii;
163 #else
164  if (hostname != NULL) {
165  rc = uv__idna_toascii(hostname,
166  hostname + strlen(hostname),
167  hostname_ascii,
168  hostname_ascii + sizeof(hostname_ascii));
169  if (rc < 0)
170  return rc;
171  hostname = hostname_ascii;
172  }
173 #endif
174 
175  hostname_len = hostname ? strlen(hostname) + 1 : 0;
176  service_len = service ? strlen(service) + 1 : 0;
177  hints_len = hints ? sizeof(*hints) : 0;
178  buf = uv__malloc(hostname_len + service_len + hints_len);
179 
180  if (buf == NULL)
181  return UV_ENOMEM;
182 
183  uv__req_init(loop, req, UV_GETADDRINFO);
184  req->loop = loop;
185  req->cb = cb;
186  req->addrinfo = NULL;
187  req->hints = NULL;
188  req->service = NULL;
189  req->hostname = NULL;
190  req->retcode = 0;
191 
192  /* order matters, see uv_getaddrinfo_done() */
193  len = 0;
194 
195  if (hints) {
196  req->hints = memcpy(buf + len, hints, sizeof(*hints));
197  len += sizeof(*hints);
198  }
199 
200  if (service) {
201  req->service = memcpy(buf + len, service, service_len);
202  len += service_len;
203  }
204 
205  if (hostname)
206  req->hostname = memcpy(buf + len, hostname, hostname_len);
207 
208  if (cb) {
210  &req->work_req,
214  return 0;
215  } else {
216  uv__getaddrinfo_work(&req->work_req);
217  uv__getaddrinfo_done(&req->work_req, 0);
218  return req->retcode;
219  }
220 }
221 
222 
223 void uv_freeaddrinfo(struct addrinfo* ai) {
224  if (ai)
225  freeaddrinfo(ai);
226 }
227 
228 
229 int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
230  char ifname_buf[UV_IF_NAMESIZE];
231  size_t len;
232 
233  if (buffer == NULL || size == NULL || *size == 0)
234  return UV_EINVAL;
235 
236  if (if_indextoname(ifindex, ifname_buf) == NULL)
237  return UV__ERR(errno);
238 
239  len = strnlen(ifname_buf, sizeof(ifname_buf));
240 
241  if (*size <= len) {
242  *size = len + 1;
243  return UV_ENOBUFS;
244  }
245 
246  memcpy(buffer, ifname_buf, len);
247  buffer[len] = '\0';
248  *size = len;
249 
250  return 0;
251 }
252 
253 int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) {
254  return uv_if_indextoname(ifindex, buffer, size);
255 }
size_t len
Definition: 6502dis.c:15
static bool err
Definition: armass.c:435
#define NULL
Definition: cris-opc.c:27
#define w
Definition: crypto_rc6.c:13
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
#define UV__ERR(x)
Definition: errno.h:29
long uv__idna_toascii(const char *s, const char *se, char *d, char *de)
Definition: idna.c:250
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
assert(limit<=UINT32_MAX/2)
size_t strnlen(const char *str, size_t maxlen)
#define container_of(ptr, type, member)
Definition: rz_types.h:650
Definition: buffer.h:15
Definition: uv.h:1780
uv_loop_t * loop
Definition: main.c:7
void uv__work_submit(uv_loop_t *loop, struct uv__work *w, enum uv__work_kind kind, void(*work)(struct uv__work *w), void(*done)(struct uv__work *w, int status))
Definition: threadpool.c:256
int uv_if_indextoiid(unsigned int ifindex, char *buffer, size_t *size)
Definition: getaddrinfo.c:253
static void uv__getaddrinfo_work(struct uv__work *w)
Definition: getaddrinfo.c:101
void uv_freeaddrinfo(struct addrinfo *ai)
Definition: getaddrinfo.c:223
static void uv__getaddrinfo_done(struct uv__work *w, int status)
Definition: getaddrinfo.c:111
int uv_getaddrinfo(uv_loop_t *loop, uv_getaddrinfo_t *req, uv_getaddrinfo_cb cb, const char *hostname, const char *service, const struct addrinfo *hints)
Definition: getaddrinfo.c:141
int uv__getaddrinfo_translate_error(int sys_err)
Definition: getaddrinfo.c:42
int uv_if_indextoname(unsigned int ifindex, char *buffer, size_t *size)
Definition: getaddrinfo.c:229
void * uv__malloc(size_t size)
Definition: uv-common.c:75
void uv__free(void *ptr)
Definition: uv-common.c:81
@ UV__WORK_SLOW_IO
Definition: uv-common.h:194
#define uv__req_init(loop, req, typ)
Definition: uv-common.h:329
#define uv__req_unregister(loop, req)
Definition: uv-common.h:230
void(* uv_getaddrinfo_cb)(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
Definition: uv.h:331
#define UV_IF_NAMESIZE
Definition: uv.h:1668
static const char * cb[]
Definition: z80_tab.h:176