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 /* Expose glibc-specific EAI_* error codes. Needs to be defined before we
23  * include any headers.
24  */
25 #ifndef _GNU_SOURCE
26 # define _GNU_SOURCE
27 #endif
28 
29 #include "uv.h"
30 #include "uv-common.h"
31 
32 #include <stdio.h>
33 #include <assert.h>
34 #include <stddef.h> /* NULL */
35 #include <stdlib.h> /* malloc */
36 #include <string.h> /* memset */
37 
38 #if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
39 # include <net/if.h> /* if_nametoindex */
40 #endif
41 
42 /* EAI_* constants. */
43 #if !defined(_WIN32)
44 # include <sys/types.h>
45 # include <sys/socket.h>
46 # include <netdb.h>
47 #endif
48 
49 #define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
50 
uv_handle_size(uv_handle_type type)51 size_t uv_handle_size(uv_handle_type type) {
52   switch (type) {
53     UV_HANDLE_TYPE_MAP(XX)
54     default:
55       return -1;
56   }
57 }
58 
uv_req_size(uv_req_type type)59 size_t uv_req_size(uv_req_type type) {
60   switch(type) {
61     UV_REQ_TYPE_MAP(XX)
62     default:
63       return -1;
64   }
65 }
66 
67 #undef XX
68 
69 
uv_buf_init(char * base,unsigned int len)70 uv_buf_t uv_buf_init(char* base, unsigned int len) {
71   uv_buf_t buf;
72   buf.base = base;
73   buf.len = len;
74   return buf;
75 }
76 
77 
78 #define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
uv_err_name(int err)79 const char* uv_err_name(int err) {
80   switch (err) {
81     UV_ERRNO_MAP(UV_ERR_NAME_GEN)
82     default:
83       assert(0);
84       return NULL;
85   }
86 }
87 #undef UV_ERR_NAME_GEN
88 
89 
90 #define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
uv_strerror(int err)91 const char* uv_strerror(int err) {
92   switch (err) {
93     UV_ERRNO_MAP(UV_STRERROR_GEN)
94     default:
95       return "Unknown system error";
96   }
97 }
98 #undef UV_STRERROR_GEN
99 
100 
uv_ip4_addr(const char * ip,int port,struct sockaddr_in * addr)101 int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
102   memset(addr, 0, sizeof(*addr));
103   addr->sin_family = AF_INET;
104   addr->sin_port = htons(port);
105   return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
106 }
107 
108 
uv_ip6_addr(const char * ip,int port,struct sockaddr_in6 * addr)109 int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
110 #if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
111   char address_part[40];
112   size_t address_part_size;
113   const char* zone_index;
114 #endif
115 
116   memset(addr, 0, sizeof(*addr));
117   addr->sin6_family = AF_INET6;
118   addr->sin6_port = htons(port);
119 
120 #if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
121   zone_index = strchr(ip, '%');
122   if (zone_index != NULL) {
123     address_part_size = zone_index - ip;
124     if (address_part_size >= sizeof(address_part))
125       address_part_size = sizeof(address_part) - 1;
126 
127     memcpy(address_part, ip, address_part_size);
128     address_part[address_part_size] = '\0';
129     ip = address_part;
130 
131     zone_index++; /* skip '%' */
132     /* NOTE: unknown interface (id=0) is silently ignored */
133 #ifdef _WIN32
134     addr->sin6_scope_id = atoi(zone_index);
135 #else
136     addr->sin6_scope_id = if_nametoindex(zone_index);
137 #endif
138   }
139 #endif
140 
141   return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
142 }
143 
144 
uv_ip4_name(struct sockaddr_in * src,char * dst,size_t size)145 int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
146   return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
147 }
148 
149 
uv_ip6_name(struct sockaddr_in6 * src,char * dst,size_t size)150 int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
151   return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
152 }
153 
154 
uv_tcp_bind(uv_tcp_t * handle,const struct sockaddr * addr,unsigned int flags)155 int uv_tcp_bind(uv_tcp_t* handle,
156                 const struct sockaddr* addr,
157                 unsigned int flags) {
158   unsigned int addrlen;
159 
160   if (handle->type != UV_TCP)
161     return UV_EINVAL;
162 
163   if (addr->sa_family == AF_INET)
164     addrlen = sizeof(struct sockaddr_in);
165   else if (addr->sa_family == AF_INET6)
166     addrlen = sizeof(struct sockaddr_in6);
167   else
168     return UV_EINVAL;
169 
170   return uv__tcp_bind(handle, addr, addrlen, flags);
171 }
172 
173 
uv_udp_bind(uv_udp_t * handle,const struct sockaddr * addr,unsigned int flags)174 int uv_udp_bind(uv_udp_t* handle,
175                 const struct sockaddr* addr,
176                 unsigned int flags) {
177   unsigned int addrlen;
178 
179   if (handle->type != UV_UDP)
180     return UV_EINVAL;
181 
182   if (addr->sa_family == AF_INET)
183     addrlen = sizeof(struct sockaddr_in);
184   else if (addr->sa_family == AF_INET6)
185     addrlen = sizeof(struct sockaddr_in6);
186   else
187     return UV_EINVAL;
188 
189   return uv__udp_bind(handle, addr, addrlen, flags);
190 }
191 
192 
uv_tcp_connect(uv_connect_t * req,uv_tcp_t * handle,const struct sockaddr * addr,uv_connect_cb cb)193 int uv_tcp_connect(uv_connect_t* req,
194                    uv_tcp_t* handle,
195                    const struct sockaddr* addr,
196                    uv_connect_cb cb) {
197   unsigned int addrlen;
198 
199   if (handle->type != UV_TCP)
200     return UV_EINVAL;
201 
202   if (addr->sa_family == AF_INET)
203     addrlen = sizeof(struct sockaddr_in);
204   else if (addr->sa_family == AF_INET6)
205     addrlen = sizeof(struct sockaddr_in6);
206   else
207     return UV_EINVAL;
208 
209   return uv__tcp_connect(req, handle, addr, addrlen, cb);
210 }
211 
212 
uv_udp_send(uv_udp_send_t * req,uv_udp_t * handle,const uv_buf_t bufs[],unsigned int nbufs,const struct sockaddr * addr,uv_udp_send_cb send_cb)213 int uv_udp_send(uv_udp_send_t* req,
214                 uv_udp_t* handle,
215                 const uv_buf_t bufs[],
216                 unsigned int nbufs,
217                 const struct sockaddr* addr,
218                 uv_udp_send_cb send_cb) {
219   unsigned int addrlen;
220 
221   if (handle->type != UV_UDP)
222     return UV_EINVAL;
223 
224   if (addr->sa_family == AF_INET)
225     addrlen = sizeof(struct sockaddr_in);
226   else if (addr->sa_family == AF_INET6)
227     addrlen = sizeof(struct sockaddr_in6);
228   else
229     return UV_EINVAL;
230 
231   return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
232 }
233 
234 
uv_udp_recv_start(uv_udp_t * handle,uv_alloc_cb alloc_cb,uv_udp_recv_cb recv_cb)235 int uv_udp_recv_start(uv_udp_t* handle,
236                       uv_alloc_cb alloc_cb,
237                       uv_udp_recv_cb recv_cb) {
238   if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
239     return UV_EINVAL;
240   else
241     return uv__udp_recv_start(handle, alloc_cb, recv_cb);
242 }
243 
244 
uv_udp_recv_stop(uv_udp_t * handle)245 int uv_udp_recv_stop(uv_udp_t* handle) {
246   if (handle->type != UV_UDP)
247     return UV_EINVAL;
248   else
249     return uv__udp_recv_stop(handle);
250 }
251 
252 
253 struct thread_ctx {
254   void (*entry)(void* arg);
255   void* arg;
256 };
257 
258 
259 #ifdef _WIN32
uv__thread_start(void * arg)260 static UINT __stdcall uv__thread_start(void* arg)
261 #else
262 static void* uv__thread_start(void *arg)
263 #endif
264 {
265   struct thread_ctx *ctx_p;
266   struct thread_ctx ctx;
267 
268   ctx_p = arg;
269   ctx = *ctx_p;
270   free(ctx_p);
271   ctx.entry(ctx.arg);
272 
273   return 0;
274 }
275 
276 
uv_thread_create(uv_thread_t * tid,void (* entry)(void * arg),void * arg)277 int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
278   struct thread_ctx* ctx;
279   int err;
280 
281   ctx = malloc(sizeof(*ctx));
282   if (ctx == NULL)
283     return UV_ENOMEM;
284 
285   ctx->entry = entry;
286   ctx->arg = arg;
287 
288 #ifdef _WIN32
289   *tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
290   err = *tid ? 0 : errno;
291 #else
292   err = pthread_create(tid, NULL, uv__thread_start, ctx);
293 #endif
294 
295   if (err)
296     free(ctx);
297 
298   return err ? -1 : 0;
299 }
300 
301 
uv_thread_self(void)302 unsigned long uv_thread_self(void) {
303 #ifdef _WIN32
304   return (unsigned long) GetCurrentThreadId();
305 #else
306   return (unsigned long) pthread_self();
307 #endif
308 }
309 
310 
uv_walk(uv_loop_t * loop,uv_walk_cb walk_cb,void * arg)311 void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
312   QUEUE* q;
313   uv_handle_t* h;
314 
315   QUEUE_FOREACH(q, &loop->handle_queue) {
316     h = QUEUE_DATA(q, uv_handle_t, handle_queue);
317     if (h->flags & UV__HANDLE_INTERNAL) continue;
318     walk_cb(h, arg);
319   }
320 }
321 
322 
323 #ifndef NDEBUG
uv__print_handles(uv_loop_t * loop,int only_active)324 static void uv__print_handles(uv_loop_t* loop, int only_active) {
325   const char* type;
326   QUEUE* q;
327   uv_handle_t* h;
328 
329   if (loop == NULL)
330     loop = uv_default_loop();
331 
332   QUEUE_FOREACH(q, &loop->handle_queue) {
333     h = QUEUE_DATA(q, uv_handle_t, handle_queue);
334 
335     if (only_active && !uv__is_active(h))
336       continue;
337 
338     switch (h->type) {
339 #define X(uc, lc) case UV_##uc: type = #lc; break;
340       UV_HANDLE_TYPE_MAP(X)
341 #undef X
342       default: type = "<unknown>";
343     }
344 
345     fprintf(stderr,
346             "[%c%c%c] %-8s %p\n",
347             "R-"[!(h->flags & UV__HANDLE_REF)],
348             "A-"[!(h->flags & UV__HANDLE_ACTIVE)],
349             "I-"[!(h->flags & UV__HANDLE_INTERNAL)],
350             type,
351             (void*)h);
352   }
353 }
354 
355 
uv_print_all_handles(uv_loop_t * loop)356 void uv_print_all_handles(uv_loop_t* loop) {
357   uv__print_handles(loop, 0);
358 }
359 
360 
uv_print_active_handles(uv_loop_t * loop)361 void uv_print_active_handles(uv_loop_t* loop) {
362   uv__print_handles(loop, 1);
363 }
364 #endif
365 
366 
uv_ref(uv_handle_t * handle)367 void uv_ref(uv_handle_t* handle) {
368   uv__handle_ref(handle);
369 }
370 
371 
uv_unref(uv_handle_t * handle)372 void uv_unref(uv_handle_t* handle) {
373   uv__handle_unref(handle);
374 }
375 
376 
uv_has_ref(const uv_handle_t * handle)377 int uv_has_ref(const uv_handle_t* handle) {
378   return uv__has_ref(handle);
379 }
380 
381 
uv_stop(uv_loop_t * loop)382 void uv_stop(uv_loop_t* loop) {
383   loop->stop_flag = 1;
384 }
385 
386 
uv_now(uv_loop_t * loop)387 uint64_t uv_now(uv_loop_t* loop) {
388   return loop->time;
389 }
390 
391 
uv__getaddrinfo_translate_error(int sys_err)392 int uv__getaddrinfo_translate_error(int sys_err) {
393   switch (sys_err) {
394   case 0: return 0;
395 #if defined(EAI_ADDRFAMILY)
396   case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
397 #endif
398 #if defined(EAI_AGAIN)
399   case EAI_AGAIN: return UV_EAI_AGAIN;
400 #endif
401 #if defined(EAI_BADFLAGS)
402   case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
403 #endif
404 #if defined(EAI_BADHINTS)
405   case EAI_BADHINTS: return UV_EAI_BADHINTS;
406 #endif
407 #if defined(EAI_CANCELED)
408   case EAI_CANCELED: return UV_EAI_CANCELED;
409 #endif
410 #if defined(EAI_FAIL)
411   case EAI_FAIL: return UV_EAI_FAIL;
412 #endif
413 #if defined(EAI_FAMILY)
414   case EAI_FAMILY: return UV_EAI_FAMILY;
415 #endif
416 #if defined(EAI_MEMORY)
417   case EAI_MEMORY: return UV_EAI_MEMORY;
418 #endif
419 #if defined(EAI_NODATA)
420   case EAI_NODATA: return UV_EAI_NODATA;
421 #endif
422 #if defined(EAI_NONAME)
423 # if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
424   case EAI_NONAME: return UV_EAI_NONAME;
425 # endif
426 #endif
427 #if defined(EAI_OVERFLOW)
428   case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
429 #endif
430 #if defined(EAI_PROTOCOL)
431   case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
432 #endif
433 #if defined(EAI_SERVICE)
434   case EAI_SERVICE: return UV_EAI_SERVICE;
435 #endif
436 #if defined(EAI_SOCKTYPE)
437   case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
438 #endif
439 #if defined(EAI_SYSTEM)
440   case EAI_SYSTEM: return UV_EAI_SYSTEM;
441 #endif
442   }
443   assert(!"unknown EAI_* error code");
444   abort();
445   return 0;  /* Pacify compiler. */
446 }
447