comparison src/core/ngx_connection.c @ 218:05592fd7a436

nginx-0.0.1-2004-01-05-23:55:48 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 05 Jan 2004 20:55:48 +0000
parents
children f57597ec5249
comparison
equal deleted inserted replaced
217:c5d1cdcb04ec 218:05592fd7a436
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_event.h>
5 /* STUB */
6 #include <nginx.h>
7
8
9 ngx_os_io_t ngx_io;
10
11
12 ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle, char **envp)
13 {
14 char *p, *v;
15 ngx_socket_t s;
16 ngx_listening_t *ls;
17 struct sockaddr_in *addr_in;
18
19 for ( /* void */ ; *envp; envp++) {
20 if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) {
21 continue;
22 }
23
24 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
25 "using inherited sockets from \"%s\"", *envp);
26
27 ngx_init_array(cycle->listening, cycle->pool,
28 10, sizeof(ngx_listening_t), NGX_ERROR);
29
30 for (p = *envp + NGINX_VAR_LEN, v = p; *p; p++) {
31 if (*p == ':' || *p == ';') {
32 s = ngx_atoi(v, p - v);
33 if (s == NGX_ERROR) {
34 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
35 "invalid socket number \"%s\" "
36 "in NGINX enviroment variable, "
37 "ignoring the rest of the variable", v);
38 break;
39 }
40 v = p + 1;
41
42 if (!(ls = ngx_push_array(&cycle->listening))) {
43 return NGX_ERROR;
44 }
45
46 ls->fd = s;
47
48 /* AF_INET only */
49
50 ls->sockaddr = ngx_palloc(cycle->pool,
51 sizeof(struct sockaddr_in));
52 if (ls->sockaddr == NULL) {
53 return NGX_ERROR;
54 }
55
56 ls->socklen = sizeof(struct sockaddr_in);
57 if (getsockname(s, ls->sockaddr, &ls->socklen) == -1) {
58 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
59 "getsockname() of the inherited "
60 "socket #%d failed", s);
61 ls->ignore = 1;
62 continue;
63 }
64
65 addr_in = (struct sockaddr_in *) ls->sockaddr;
66
67 if (addr_in->sin_family != AF_INET) {
68 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
69 "the inherited socket #%d has "
70 "unsupported family", s);
71 ls->ignore = 1;
72 continue;
73 }
74 ls->addr_text_max_len = INET_ADDRSTRLEN;
75
76 ls->addr_text.data = ngx_palloc(cycle->pool,
77 ls->addr_text_max_len);
78 if (ls->addr_text.data == NULL) {
79 return NGX_ERROR;
80 }
81
82 addr_in->sin_len = 0;
83
84 ls->family = addr_in->sin_family;
85 ls->addr_text.len = ngx_sock_ntop(ls->family, ls->sockaddr,
86 ls->addr_text.data,
87 ls->addr_text_max_len);
88 if (ls->addr_text.len == 0) {
89 return NGX_ERROR;
90 }
91 }
92 }
93
94 break;
95 }
96
97 return NGX_OK;
98 }
99
100
101 ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle)
102 {
103 int tries, failed, reuseaddr, i;
104 ngx_err_t err;
105 ngx_log_t *log;
106 ngx_socket_t s;
107 ngx_listening_t *ls;
108
109 reuseaddr = 1;
110 #if (NGX_SUPPRESS_WARN)
111 failed = 0;
112 #endif
113
114 log = cycle->log;
115
116 /* TODO: tries configurable */
117
118 for (tries = 10; tries; tries--) {
119 failed = 0;
120
121 /* for each listening socket */
122
123 ls = cycle->listening.elts;
124 for (i = 0; i < cycle->listening.nelts; i++) {
125
126 if (ls[i].ignore) {
127 continue;
128 }
129
130 if (ls[i].fd != -1) {
131 continue;
132 }
133
134 if (ls[i].inherited) {
135
136 /* TODO: close on exit */
137 /* TODO: nonblocking */
138 /* TODO: deferred accept */
139
140 continue;
141 }
142
143 s = ngx_socket(ls[i].family, ls[i].type, ls[i].protocol,
144 ls[i].flags);
145
146 if (s == -1) {
147 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
148 ngx_socket_n " %s failed", ls[i].addr_text.data);
149 return NGX_ERROR;
150 }
151
152 #if (WIN32)
153 /*
154 * Winsock assignes a socket number divisible by 4
155 * so to find a connection we divide a socket number by 4.
156 */
157
158 if (s % 4) {
159 ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
160 ngx_socket_n " created socket %d", s);
161 return NGX_ERROR;
162 }
163 #endif
164
165 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
166 (const void *) &reuseaddr, sizeof(int)) == -1) {
167 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
168 "setsockopt(SO_REUSEADDR) %s failed",
169 ls[i].addr_text.data);
170 return NGX_ERROR;
171 }
172
173 /* TODO: close on exit */
174
175 if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
176 if (ngx_nonblocking(s) == -1) {
177 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
178 ngx_nonblocking_n " %s failed",
179 ls[i].addr_text.data);
180 return NGX_ERROR;
181 }
182 }
183
184 #if 0
185 if (ls[i].nonblocking) {
186 if (ngx_nonblocking(s) == -1) {
187 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
188 ngx_nonblocking_n " %s failed",
189 ls[i].addr_text.data);
190 return NGX_ERROR;
191 }
192 }
193 #endif
194
195 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
196 err = ngx_socket_errno;
197 ngx_log_error(NGX_LOG_EMERG, log, err,
198 "bind() to %s failed", ls[i].addr_text.data);
199
200 if (err != NGX_EADDRINUSE)
201 return NGX_ERROR;
202
203 if (ngx_close_socket(s) == -1)
204 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
205 ngx_close_socket_n " %s failed",
206 ls[i].addr_text.data);
207
208 failed = 1;
209 continue;
210 }
211
212 if (listen(s, ls[i].backlog) == -1) {
213 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
214 "listen() to %s failed", ls[i].addr_text.data);
215 return NGX_ERROR;
216 }
217
218 /* TODO: deferred accept */
219
220 ls[i].fd = s;
221 }
222
223 if (!failed)
224 break;
225
226 /* TODO: delay configurable */
227
228 ngx_log_error(NGX_LOG_NOTICE, log, 0,
229 "try again to bind() after 500ms");
230 ngx_msleep(500);
231 }
232
233 if (failed) {
234 ngx_log_error(NGX_LOG_EMERG, log, 0, "still can not bind()");
235 return NGX_ERROR;
236 }
237
238 return NGX_OK;
239 }
240
241
242 void ngx_close_listening_sockets(ngx_cycle_t *cycle)
243 {
244 ngx_int_t i;
245 ngx_socket_t fd;
246 ngx_listening_t *ls;
247
248 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
249 return;
250 }
251
252 ls = cycle->listening.elts;
253 for (i = 0; i < cycle->listening.nelts; i++) {
254 fd = ls[i].fd;
255
256 #if (WIN32)
257 /*
258 * Winsock assignes a socket number divisible by 4
259 * so to find a connection we divide a socket number by 4.
260 */
261
262 fd /= 4;
263 #endif
264
265 ngx_del_event(&cycle->read_events[fd], NGX_READ_EVENT, NGX_CLOSE_EVENT);
266
267 if (ngx_close_socket(ls[i].fd) == -1) {
268 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
269 ngx_close_socket_n " %s failed",
270 ls[i].addr_text.data);
271 }
272
273 cycle->connections[fd].fd = -1;
274 }
275 }