• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21 
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "uv.h"
28 #include "internal.h"
29 
30 
31 #ifdef USE_FFRT
uv__getnameinfo_work(struct uv__work * w,int qos)32 static void uv__getnameinfo_work(struct uv__work* w, int qos) {
33 #else
34 static void uv__getnameinfo_work(struct uv__work* w) {
35 #endif
36   uv_getnameinfo_t* req;
37   int err;
38   socklen_t salen;
39 
40   req = container_of(w, uv_getnameinfo_t, work_req);
41 
42   if (req->storage.ss_family == AF_INET)
43     salen = sizeof(struct sockaddr_in);
44   else if (req->storage.ss_family == AF_INET6)
45     salen = sizeof(struct sockaddr_in6);
46   else
47     abort();
48 
49   err = getnameinfo((struct sockaddr*) &req->storage,
50                     salen,
51                     req->host,
52                     sizeof(req->host),
53                     req->service,
54                     sizeof(req->service),
55                     req->flags);
56   req->retcode = uv__getaddrinfo_translate_error(err);
57 #ifdef USE_FFRT
58   if (qos != -1) {
59     uv__work_submit_to_eventloop((uv_req_t*)req, w, qos);
60   }
61 #endif
62 }
63 
64 static void uv__getnameinfo_done(struct uv__work* w, int status) {
65   uv_getnameinfo_t* req;
66   char* host;
67   char* service;
68 
69   req = container_of(w, uv_getnameinfo_t, work_req);
70   uv__req_unregister(req->loop, req);
71   host = service = NULL;
72 
73   if (status == UV_ECANCELED) {
74     assert(req->retcode == 0);
75     req->retcode = UV_EAI_CANCELED;
76   } else if (req->retcode == 0) {
77     host = req->host;
78     service = req->service;
79   }
80 
81   if (req->getnameinfo_cb)
82     req->getnameinfo_cb(req, req->retcode, host, service);
83 }
84 
85 /*
86 * Entry point for getnameinfo
87 * return 0 if a callback will be made
88 * return error code if validation fails
89 */
90 int uv_getnameinfo(uv_loop_t* loop,
91                    uv_getnameinfo_t* req,
92                    uv_getnameinfo_cb getnameinfo_cb,
93                    const struct sockaddr* addr,
94                    int flags) {
95   if (req == NULL || addr == NULL)
96     return UV_EINVAL;
97 
98   if (addr->sa_family == AF_INET) {
99     memcpy(&req->storage,
100            addr,
101            sizeof(struct sockaddr_in));
102   } else if (addr->sa_family == AF_INET6) {
103     memcpy(&req->storage,
104            addr,
105            sizeof(struct sockaddr_in6));
106   } else {
107     return UV_EINVAL;
108   }
109 
110   uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO);
111 
112   req->getnameinfo_cb = getnameinfo_cb;
113   req->flags = flags;
114   req->type = UV_GETNAMEINFO;
115   req->loop = loop;
116   req->retcode = 0;
117 
118   if (getnameinfo_cb) {
119     uv__work_submit(loop,
120 #ifdef USE_FFRT
121                     (uv_req_t*)req,
122 #endif
123                     &req->work_req,
124                     UV__WORK_SLOW_IO,
125                     uv__getnameinfo_work,
126                     uv__getnameinfo_done);
127     return 0;
128   } else {
129 #ifdef USE_FFRT
130     uv__getnameinfo_work(&req->work_req, -1);
131 #else
132     uv__getnameinfo_work(&req->work_req);
133 #endif
134     uv__getnameinfo_done(&req->work_req, 0);
135     return req->retcode;
136   }
137 }
138