comparison src/event/ngx_event_connect.c @ 92:45945fa8b8ba NGINX_0_2_0

nginx 0.2.0 *) The pid-file names used during online upgrade was changed and now is not required a manual rename operation. The old master process adds the ".oldbin" suffix to its pid-file and executes a new binary file. The new master process creates usual pid-file without the ".newbin" suffix. If the master process exits, then old master process renames back its pid-file with the ".oldbin" suffix to the pid-file without suffix. *) Change: the "worker_connections" directive, new name of the "connections" directive; now the directive specifies maximum number of connections, but not maximum socket descriptor number. *) Feature: SSL supports the session cache inside one worker process. *) Feature: the "satisfy_any" directive. *) Change: the ngx_http_access_module and ngx_http_auth_basic_module do not run for subrequests. *) Feature: the "worker_rlimit_nofile" and "worker_rlimit_sigpending" directives. *) Bugfix: if all backend using in load-balancing failed after one error, then nginx did not try do connect to them during 60 seconds. *) Bugfix: in IMAP/POP3 command argument parsing. Thanks to Rob Mueller. *) Bugfix: errors while using SSL in IMAP/POP3 proxy. *) Bugfix: errors while using SSI and gzipping. *) Bugfix: the "Expires" and "Cache-Control" header lines were omitted from the 304 responses. Thanks to Alexandr Kukushkin.
author Igor Sysoev <http://sysoev.ru>
date Fri, 23 Sep 2005 00:00:00 +0400
parents 71c46860eb55
children c96cb248dc4b
comparison
equal deleted inserted replaced
91:c3eee83ea942 92:45945fa8b8ba
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_event_connect.h> 10 #include <ngx_event_connect.h>
11 11
12 12
13 #define NGX_RESOLVER_BUFSIZE 8192
14
15
16 ngx_int_t 13 ngx_int_t
17 ngx_event_connect_peer(ngx_peer_connection_t *pc) 14 ngx_event_connect_peer(ngx_peer_connection_t *pc)
18 { 15 {
19 int rc; 16 int rc;
20 ngx_uint_t instance, level; 17 ngx_uint_t instance, level, i;
21 u_int event; 18 u_int event;
22 time_t now; 19 time_t now;
23 ngx_err_t err; 20 ngx_err_t err;
24 ngx_peer_t *peer; 21 ngx_peer_t *peer;
25 ngx_socket_t s; 22 ngx_socket_t s;
26 ngx_event_t *rev, *wev; 23 ngx_event_t *rev, *wev;
27 ngx_connection_t *c; 24 ngx_connection_t *c;
28 ngx_event_conf_t *ecf;
29 25
30 now = ngx_time(); 26 now = ngx_time();
31 27
32 /* ngx_lock_mutex(pc->peers->mutex); */ 28 /* ngx_lock_mutex(pc->peers->mutex); */
33 29
45 c->write->lock = c->write->own_lock; 41 c->write->lock = c->write->own_lock;
46 #endif 42 #endif
47 43
48 pc->connection = c; 44 pc->connection = c;
49 pc->cached = 1; 45 pc->cached = 1;
46
50 return NGX_OK; 47 return NGX_OK;
51 } 48 }
52 49
53 pc->cached = 0; 50 pc->cached = 0;
54 pc->connection = NULL; 51 pc->connection = NULL;
100 } 97 }
101 98
102 pc->tries--; 99 pc->tries--;
103 100
104 if (pc->tries == 0) { 101 if (pc->tries == 0) {
102
103 /* all peers failed, mark them as live for quick recovery */
104
105 for (i = 0; i < pc->peers->number; i++) {
106 pc->peers->peer[i].fails = 0;
107 }
108
105 /* ngx_unlock_mutex(pc->peers->mutex); */ 109 /* ngx_unlock_mutex(pc->peers->mutex); */
106 110
107 return NGX_ERROR; 111 return NGX_BUSY;
108 } 112 }
109 } 113 }
110 } 114 }
111 115
112 /* ngx_unlock_mutex(pc->peers->mutex); */ 116 /* ngx_unlock_mutex(pc->peers->mutex); */
122 ngx_socket_n " failed"); 126 ngx_socket_n " failed");
123 return NGX_ERROR; 127 return NGX_ERROR;
124 } 128 }
125 129
126 130
127 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); 131 c = ngx_get_connection(s, pc->log);
128 132
129 /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ 133 if (c == NULL) {
130
131 if ((ngx_uint_t) s >= ecf->connections) {
132
133 ngx_log_error(NGX_LOG_ALERT, pc->log, 0,
134 "socket() returned socket #%d while only %d "
135 "connections was configured, closing the socket",
136 s, ecf->connections);
137
138 if (ngx_close_socket(s) == -1) { 134 if (ngx_close_socket(s) == -1) {
139 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 135 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
140 ngx_close_socket_n "failed"); 136 ngx_close_socket_n "failed");
141 } 137 }
142 138
143 /* TODO: sleep for some time */
144
145 return NGX_ERROR; 139 return NGX_ERROR;
146 } 140 }
147 141
142 rev = c->read;
143 wev = c->write;
144
145 ngx_memzero(c, sizeof(ngx_connection_t));
146
147 c->read = rev;
148 c->write = wev;
149 c->fd = s;
150 c->log = pc->log;
148 151
149 if (pc->rcvbuf) { 152 if (pc->rcvbuf) {
150 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 153 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
151 (const void *) &pc->rcvbuf, sizeof(int)) == -1) { 154 (const void *) &pc->rcvbuf, sizeof(int)) == -1) {
152 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 155 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
153 "setsockopt(SO_RCVBUF) failed"); 156 "setsockopt(SO_RCVBUF) failed");
154 157
158 ngx_free_connection(c);
159
155 if (ngx_close_socket(s) == -1) { 160 if (ngx_close_socket(s) == -1) {
156 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 161 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
157 ngx_close_socket_n " failed"); 162 ngx_close_socket_n " failed");
158 } 163 }
159 164
163 168
164 if (ngx_nonblocking(s) == -1) { 169 if (ngx_nonblocking(s) == -1) {
165 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 170 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
166 ngx_nonblocking_n " failed"); 171 ngx_nonblocking_n " failed");
167 172
173 ngx_free_connection(c);
174
168 if (ngx_close_socket(s) == -1) { 175 if (ngx_close_socket(s) == -1) {
169 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 176 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
170 ngx_close_socket_n " failed"); 177 ngx_close_socket_n " failed");
171 } 178 }
172 179
173 return NGX_ERROR; 180 return NGX_ERROR;
174 } 181 }
175 182
176 #if (NGX_WIN32)
177
178 /*
179 * Winsock assignes a socket number divisible by 4
180 * so to find a connection we divide a socket number by 4.
181 */
182
183 if (s % 4) {
184 ngx_log_error(NGX_LOG_EMERG, pc->log, 0,
185 ngx_socket_n
186 " created socket %d, not divisible by 4", s);
187 exit(1);
188 }
189
190 c = &ngx_cycle->connections[s / 4];
191 rev = &ngx_cycle->read_events[s / 4];
192 wev = &ngx_cycle->write_events[s / 4];
193
194 #else
195
196 c = &ngx_cycle->connections[s];
197 rev = &ngx_cycle->read_events[s];
198 wev = &ngx_cycle->write_events[s];
199
200 #endif
201
202 instance = rev->instance;
203
204 #if (NGX_THREADS)
205
206 if (*(&c->lock)) {
207 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
208 "spinlock in connect, fd:%d", s);
209 ngx_spinlock(&c->lock, 1000);
210 ngx_unlock(&c->lock);
211 }
212
213 #endif
214
215 ngx_memzero(c, sizeof(ngx_connection_t));
216 ngx_memzero(rev, sizeof(ngx_event_t));
217 ngx_memzero(wev, sizeof(ngx_event_t));
218
219 rev->instance = !instance;
220 wev->instance = !instance;
221
222 rev->index = NGX_INVALID_INDEX;
223 wev->index = NGX_INVALID_INDEX;
224
225 rev->data = c;
226 wev->data = c;
227
228 c->read = rev;
229 c->write = wev;
230 wev->write = 1;
231
232 c->recv = ngx_recv; 183 c->recv = ngx_recv;
233 c->send = ngx_send; 184 c->send = ngx_send;
234 c->send_chain = ngx_send_chain; 185 c->send_chain = ngx_send_chain;
235 186
236 c->log = pc->log;
237 rev->log = pc->log;
238 wev->log = pc->log;
239
240 c->fd = s;
241
242 c->log_error = pc->log_error; 187 c->log_error = pc->log_error;
243 188
244 if (peer->sockaddr->sa_family != AF_INET) { 189 if (peer->sockaddr->sa_family != AF_INET) {
245 c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; 190 c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
246 c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; 191 c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
247 } 192 }
193
194 instance = rev->instance;
195
196 ngx_memzero(rev, sizeof(ngx_event_t));
197 ngx_memzero(wev, sizeof(ngx_event_t));
198
199 rev->instance = !instance;
200 wev->instance = !instance;
201
202 rev->index = NGX_INVALID_INDEX;
203 wev->index = NGX_INVALID_INDEX;
204
205 rev->data = c;
206 wev->data = c;
207
208 wev->write = 1;
209
210 rev->log = pc->log;
211 wev->log = pc->log;
248 212
249 pc->connection = c; 213 pc->connection = c;
250 214
251 /* 215 /*
252 * TODO: MT: - atomic increment (x86: lock xadd) 216 * TODO: MT: - atomic increment (x86: lock xadd)
270 if (ngx_add_conn(c) == NGX_ERROR) { 234 if (ngx_add_conn(c) == NGX_ERROR) {
271 return NGX_ERROR; 235 return NGX_ERROR;
272 } 236 }
273 } 237 }
274 238
275 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, 239 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
276 "connect to %V, #%d", &peer->name, c->number); 240 "connect to %V, fd:%d #%d", &peer->name, s, c->number);
277 241
278 rc = connect(s, peer->sockaddr, peer->socklen); 242 rc = connect(s, peer->sockaddr, peer->socklen);
279 243
280 if (rc == -1) { 244 if (rc == -1) {
281 err = ngx_socket_errno; 245 err = ngx_socket_errno;
291 } 255 }
292 256
293 ngx_log_error(level, c->log, err, "connect() to %V failed", 257 ngx_log_error(level, c->log, err, "connect() to %V failed",
294 &peer->name); 258 &peer->name);
295 259
296 return NGX_CONNECT_ERROR; 260 return NGX_DECLINED;
297 } 261 }
298 } 262 }
299 263
300 if (ngx_add_conn) { 264 if (ngx_add_conn) {
301 if (rc == -1) { 265 if (rc == -1) {