1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #include <nxt_main.h>
8
9
10 void
nxt_job_resolve(nxt_job_resolve_t * jbr)11 nxt_job_resolve(nxt_job_resolve_t *jbr)
12 {
13 int err;
14 u_char *host;
15 size_t length;
16 nxt_mp_t *mp;
17 nxt_uint_t n;
18 nxt_sockaddr_t *sa;
19 struct addrinfo hint, *res, *r;
20 nxt_work_handler_t handler;
21
22 #define NXT_BUFSIZE 64
23 u_char buf[NXT_BUFSIZE];
24
25 handler = jbr->error_handler;
26 res = NULL;
27
28 length = jbr->name.length + 1;
29
30 if (nxt_fast_path(length <= NXT_BUFSIZE)) {
31 host = buf;
32
33 } else {
34 host = nxt_mp_alloc(jbr->job.mem_pool, length);
35 if (nxt_slow_path(host == NULL)) {
36 goto fail;
37 }
38 }
39
40 nxt_cpystrn(host, jbr->name.start, length);
41
42 nxt_memzero(&hint, sizeof(struct addrinfo));
43 hint.ai_socktype = SOCK_STREAM;
44
45 err = getaddrinfo((char *) host, NULL, &hint, &res);
46
47 if (err != 0) {
48 nxt_thread_log_error(jbr->log_level,
49 "getaddrinfo(\"%s\") failed (%d: %s)",
50 host, err, gai_strerror(err));
51 goto fail;
52 }
53
54 n = 0;
55 for (r = res; r != NULL; r = r->ai_next) {
56
57 switch (r->ai_addr->sa_family) {
58 #if (NXT_INET6)
59 case AF_INET6:
60 #endif
61 case AF_INET:
62 n++;
63 break;
64
65 default:
66 break;
67 }
68 }
69
70 jbr->count = n;
71 mp = jbr->job.mem_pool;
72
73 jbr->sockaddrs = nxt_mp_alloc(mp, n * sizeof(nxt_sockaddr_t *));
74 if (nxt_slow_path(jbr->sockaddrs == NULL)) {
75 goto fail;
76 }
77
78 n = 0;
79 for (r = res; r != NULL; r = r->ai_next) {
80
81 switch (r->ai_addr->sa_family) {
82 #if (NXT_INET6)
83 case AF_INET6:
84 length = NXT_INET6_ADDR_STR_LEN;
85 break;
86 #endif
87 case AF_INET:
88 length = NXT_INET_ADDR_STR_LEN;
89 break;
90
91 default:
92 continue;
93 }
94
95 sa = nxt_sockaddr_create(mp, r->ai_addr, r->ai_addrlen, length);
96 if (nxt_slow_path(sa == NULL)) {
97 goto fail;
98 }
99
100 jbr->sockaddrs[n++] = sa;
101
102 if (jbr->port != 0) {
103
104 switch (sa->u.sockaddr.sa_family) {
105 case AF_INET:
106 sa->u.sockaddr_in.sin_port = jbr->port;
107 break;
108 #if (NXT_INET6)
109 case AF_INET6:
110 sa->u.sockaddr_in6.sin6_port = jbr->port;
111 break;
112 #endif
113 default:
114 break;
115 }
116 }
117 }
118
119 handler = jbr->ready_handler;
120
121 fail:
122
123 if (nxt_fast_path(res != NULL)) {
124 freeaddrinfo(res);
125 }
126
127 if (host != buf) {
128 nxt_mp_free(jbr->job.mem_pool, host);
129 }
130
131 nxt_job_return(jbr->job.task, &jbr->job, handler);
132 }
133