583
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9 #include <ngx_event.h>
|
|
10
|
|
11
|
|
12 typedef struct {
|
|
13 ngx_connection_t *connection;
|
|
14
|
|
15 struct sockaddr *sockaddr;
|
|
16 socklen_t socklen;
|
|
17
|
|
18 ngx_str_r server;
|
|
19 ngx_str_r name;
|
|
20
|
|
21 ngx_event_handler_pt handler;
|
|
22
|
|
23 ngx_log_t *pool;
|
|
24 ngx_log_t *log;
|
|
25 } ngx_resolver_t;
|
|
26
|
|
27
|
|
28 ngx_int_t
|
|
29 ngx_gethostbyname(ngx_resolver_t *r)
|
|
30 {
|
|
31 ngx_socket_t s;
|
|
32
|
|
33 if (r->connection) {
|
|
34 return NGX_OK;
|
|
35 }
|
|
36
|
|
37 s = ngx_socket(AF_INET, SOCK_DGRAM, 0);
|
|
38
|
|
39 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, r->log, 0, "socket %d", s);
|
|
40
|
|
41 if (s == -1) {
|
|
42 ngx_log_error(NGX_LOG_ALERT, r->log, ngx_socket_errno,
|
|
43 ngx_socket_n " failed");
|
|
44 return NGX_ERROR;
|
|
45 }
|
|
46
|
|
47 c = ngx_get_connection(s, r->log);
|
|
48
|
|
49 if (c == NULL) {
|
|
50 if (ngx_close_socket(s) == -1) {
|
|
51 ngx_log_error(NGX_LOG_ALERT, r->log, ngx_socket_errno,
|
|
52 ngx_close_socket_n "failed");
|
|
53 }
|
|
54
|
|
55 return NGX_ERROR;
|
|
56 }
|
|
57
|
|
58 rev = c->read;
|
|
59 wev = c->write;
|
|
60
|
|
61 rev->log = pc->log;
|
|
62 wev->log = pc->log;
|
|
63
|
|
64 r->connection = c;
|
|
65
|
|
66 /*
|
|
67 * TODO: MT: - ngx_atomic_fetch_add()
|
|
68 * or protection by critical section or mutex
|
|
69 *
|
|
70 * TODO: MP: - allocated in a shared memory
|
|
71 * - ngx_atomic_fetch_add()
|
|
72 * or protection by critical section or mutex
|
|
73 */
|
|
74
|
|
75 c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
|
76
|
|
77 #if (NGX_THREADS)
|
|
78 rev->lock = pc->lock;
|
|
79 wev->lock = pc->lock;
|
|
80 rev->own_lock = &c->lock;
|
|
81 wev->own_lock = &c->lock;
|
|
82 #endif
|
|
83
|
|
84 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
|
85 "connect to %V, fd:%d #%d", &r->server, s, c->number);
|
|
86
|
|
87 rc = connect(s, r->sockaddr, r->socklen);
|
|
88
|
|
89 if (rc == -1) {
|
|
90 ngx_log_error(level, r->log, ngx_socket_errno,
|
|
91 "connect() to %V failed", &r->server);
|
|
92
|
|
93 return NGX_ERROR;
|
|
94 }
|
|
95
|
|
96
|
|
97
|
|
98
|
|
99
|
|
100
|
|
101
|
|
102 if (ngx_add_conn) {
|
|
103 if (ngx_add_conn(c) == NGX_ERROR) {
|
|
104 return NGX_ERROR;
|
|
105 }
|
|
106 }
|
|
107
|
|
108
|
|
109 if (ngx_add_conn) {
|
|
110 if (rc == -1) {
|
|
111
|
|
112 /* NGX_EINPROGRESS */
|
|
113
|
|
114 return NGX_AGAIN;
|
|
115 }
|
|
116
|
|
117 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
|
|
118
|
|
119 wev->ready = 1;
|
|
120
|
|
121 return NGX_OK;
|
|
122 }
|
|
123
|
|
124 if (ngx_event_flags & NGX_USE_AIO_EVENT) {
|
|
125
|
|
126 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno,
|
|
127 "connect(): %d", rc);
|
|
128
|
|
129 /* aio, iocp */
|
|
130
|
|
131 if (ngx_blocking(s) == -1) {
|
|
132 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
|
133 ngx_blocking_n " failed");
|
|
134 return NGX_ERROR;
|
|
135 }
|
|
136
|
|
137 /*
|
|
138 * FreeBSD's aio allows to post an operation on non-connected socket.
|
|
139 * NT does not support it.
|
|
140 *
|
|
141 * TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
|
|
142 */
|
|
143
|
|
144 rev->ready = 1;
|
|
145 wev->ready = 1;
|
|
146
|
|
147 return NGX_OK;
|
|
148 }
|
|
149
|
|
150 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
|
151
|
|
152 /* kqueue */
|
|
153
|
|
154 event = NGX_CLEAR_EVENT;
|
|
155
|
|
156 } else {
|
|
157
|
|
158 /* select, poll, /dev/poll */
|
|
159
|
|
160 event = NGX_LEVEL_EVENT;
|
|
161 }
|
|
162
|
|
163 if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
|
164 return NGX_ERROR;
|
|
165 }
|
|
166
|
|
167 if (rc == -1) {
|
|
168
|
|
169 /* NGX_EINPROGRESS */
|
|
170
|
|
171 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) {
|
|
172 return NGX_ERROR;
|
|
173 }
|
|
174
|
|
175 return NGX_AGAIN;
|
|
176 }
|
|
177
|
|
178 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
|
|
179
|
|
180 wev->ready = 1;
|
|
181
|
|
182 return NGX_OK;
|
|
183 }
|