blob: 28b5fa9fb1eef4ffd5e68d9385e04f8b830cbdeb [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00002
3#include <ngx_config.h>
Igor Sysoevb2620632003-01-10 06:09:20 +00004#include <ngx_core.h>
Igor Sysoev239baac2003-06-11 15:28:34 +00005#include <ngx_event.h>
Igor Sysoevaa3436c2003-05-30 14:27:59 +00006#include <nginx.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00007
8
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009
Igor Sysoevaa3436c2003-05-30 14:27:59 +000010static int ngx_open_listening_sockets(ngx_log_t *log);
Igor Sysoev2b542382002-08-20 14:48:28 +000011
Igor Sysoev2b542382002-08-20 14:48:28 +000012
Igor Sysoeva9830112003-05-19 16:39:14 +000013ngx_log_t ngx_log;
14ngx_pool_t *ngx_pool;
15void ****ngx_conf_ctx;
16
17
18ngx_os_io_t ngx_io;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000019
20
Igor Sysoevaa3436c2003-05-30 14:27:59 +000021int ngx_max_module;
22void *ctx_conf;
Igor Sysoeve2a31542003-04-08 15:40:10 +000023
Igor Sysoev42feecb2002-12-15 06:25:09 +000024int ngx_connection_counter;
25
Igor Sysoev4e9393a2003-01-09 05:36:00 +000026ngx_array_t ngx_listening_sockets;
Igor Sysoeve0af1b82002-08-16 15:27:03 +000027
28
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000029int main(int argc, char *const *argv)
30{
Igor Sysoevb2620632003-01-10 06:09:20 +000031 int i;
Igor Sysoev1c104622003-06-03 15:42:58 +000032 ngx_str_t conf_file;
33 ngx_log_t *log;
34 ngx_conf_t conf;
Igor Sysoeva6717c42002-12-23 06:29:22 +000035
Igor Sysoev1c13c662003-05-20 15:37:55 +000036 ngx_max_sockets = -1;
37
Igor Sysoev1c104622003-06-03 15:42:58 +000038#if 0
Igor Sysoev1c13c662003-05-20 15:37:55 +000039 ngx_log.fd = STDERR_FILENO;
40 ngx_log.log_level = NGX_LOG_INFO;
41
42 /* STUB */ ngx_log.log_level = NGX_LOG_DEBUG;
Igor Sysoev1c104622003-06-03 15:42:58 +000043#endif
Igor Sysoevbe2cfc32003-06-15 18:32:13 +000044
Igor Sysoev1c104622003-06-03 15:42:58 +000045 log = ngx_log_init_errlog();
Igor Sysoev2b542382002-08-20 14:48:28 +000046
Igor Sysoev1c104622003-06-03 15:42:58 +000047 if (ngx_os_init(log) == NGX_ERROR) {
Igor Sysoeva9830112003-05-19 16:39:14 +000048 return 1;
Igor Sysoev79a80482003-05-14 17:13:13 +000049 }
50
Igor Sysoev1c104622003-06-03 15:42:58 +000051 ngx_pool = ngx_create_pool(16 * 1024, log);
Igor Sysoev2b542382002-08-20 14:48:28 +000052 /* */
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000053
Igor Sysoeve2a31542003-04-08 15:40:10 +000054 ngx_max_module = 0;
55 for (i = 0; ngx_modules[i]; i++) {
56 ngx_modules[i]->index = ngx_max_module++;
57 }
58
Igor Sysoeva9830112003-05-19 16:39:14 +000059 /* life cycle */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000060
Igor Sysoeva9830112003-05-19 16:39:14 +000061 {
62 ngx_init_array(ngx_listening_sockets,
Igor Sysoev239baac2003-06-11 15:28:34 +000063 ngx_pool, 10, sizeof(ngx_listening_t),
Igor Sysoeva9830112003-05-19 16:39:14 +000064 1);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000065
Igor Sysoeva9830112003-05-19 16:39:14 +000066 ngx_memzero(&conf, sizeof(ngx_conf_t));
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000067
Igor Sysoeva9830112003-05-19 16:39:14 +000068 ngx_test_null(conf.args,
69 ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)),
70 1);
Igor Sysoeva6717c42002-12-23 06:29:22 +000071
Igor Sysoeva9830112003-05-19 16:39:14 +000072 ngx_test_null(ngx_conf_ctx,
73 ngx_pcalloc(ngx_pool, ngx_max_module * sizeof(void *)),
74 1);
Igor Sysoeva6717c42002-12-23 06:29:22 +000075
Igor Sysoeva9830112003-05-19 16:39:14 +000076 conf.ctx = ngx_conf_ctx;
77 conf.pool = ngx_pool;
Igor Sysoev1c104622003-06-03 15:42:58 +000078 conf.log = log;
Igor Sysoev6253ca12003-05-27 12:18:54 +000079 conf.module_type = NGX_CORE_MODULE;
Igor Sysoeva9830112003-05-19 16:39:14 +000080 conf.cmd_type = NGX_MAIN_CONF;
Igor Sysoeva6717c42002-12-23 06:29:22 +000081
Igor Sysoev13933252003-05-29 13:02:09 +000082 conf_file.len = sizeof(NGINX_CONF) - 1;
83 conf_file.data = NGINX_CONF;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +000084
Igor Sysoeva9830112003-05-19 16:39:14 +000085 if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
86 return 1;
87 }
88
Igor Sysoev1c104622003-06-03 15:42:58 +000089#if 0
90 log = (ngx_log_t *) ngx_get_conf(ngx_errlog_module);
91 /* STUB */ log->log_level = NGX_LOG_DEBUG;
92#endif
93
Igor Sysoeva9830112003-05-19 16:39:14 +000094 ngx_init_temp_number();
95
96 ngx_io = ngx_os_io;
97
98 for (i = 0; ngx_modules[i]; i++) {
99 if (ngx_modules[i]->init_module) {
100 if (ngx_modules[i]->init_module(ngx_pool) == NGX_ERROR) {
101 return 1;
102 }
Igor Sysoevb2620632003-01-10 06:09:20 +0000103 }
104 }
Igor Sysoevb2620632003-01-10 06:09:20 +0000105
Igor Sysoev1c104622003-06-03 15:42:58 +0000106 if (ngx_open_listening_sockets(log) == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000107 return 1;
108 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000109
Igor Sysoeva9830112003-05-19 16:39:14 +0000110 /* TODO: daemon, once only */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000111
Igor Sysoeva9830112003-05-19 16:39:14 +0000112 /* TODO: fork */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000113
Igor Sysoev1c104622003-06-03 15:42:58 +0000114 ngx_pre_thread(&ngx_listening_sockets, ngx_pool, log);
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000115
Igor Sysoeva9830112003-05-19 16:39:14 +0000116 /* TODO: threads */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000117
Igor Sysoeva9830112003-05-19 16:39:14 +0000118 /* STUB */
Igor Sysoev1c104622003-06-03 15:42:58 +0000119 ngx_worker(log);
Igor Sysoev6253ca12003-05-27 12:18:54 +0000120 }
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000121
122 return 0;
Igor Sysoev2b542382002-08-20 14:48:28 +0000123}
124
Igor Sysoevb0869052002-12-10 18:05:12 +0000125
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000126static int ngx_open_listening_sockets(ngx_log_t *log)
Igor Sysoev2b542382002-08-20 14:48:28 +0000127{
Igor Sysoev239baac2003-06-11 15:28:34 +0000128 int times, failed, reuseaddr, i;
129 ngx_err_t err;
130 ngx_socket_t s;
131 ngx_listening_t *ls;
Igor Sysoev2b542382002-08-20 14:48:28 +0000132
133 reuseaddr = 1;
134
135 for (times = 10; times; times--) {
136 failed = 0;
137
138 /* for each listening socket */
Igor Sysoev239baac2003-06-11 15:28:34 +0000139
140 ls = ngx_listening_sockets.elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000141 for (i = 0; i < ngx_listening_sockets.nelts; i++) {
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000142
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000143 if (ls[i].bound)
Igor Sysoev2b542382002-08-20 14:48:28 +0000144 continue;
145
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000146 if (ls[i].inherited) {
147
148 /* TODO: close on exit */
149 /* TODO: nonblocking */
150 /* TODO: deferred accept */
151
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000152 ls[i].bound = 1;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000153 continue;
154 }
155
156 s = ngx_socket(ls[i].family, ls[i].type, ls[i].protocol,
157 ls[i].flags);
158 if (s == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000159 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev88092572002-12-19 07:08:55 +0000160 ngx_socket_n " %s falied", ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000161 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000162 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000163
Igor Sysoev239baac2003-06-11 15:28:34 +0000164#if (WIN32)
165 /*
166 * Winsock assignes a socket number divisible by 4
167 * so to find a connection we divide a socket number by 4.
168 */
169
170 if (s % 4) {
171 ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
172 ngx_socket_n " created socket %d", s);
173 return NGX_ERROR;
174 }
175#endif
176
Igor Sysoev2b542382002-08-20 14:48:28 +0000177 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000178 (const void *) &reuseaddr, sizeof(int)) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000179 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000180 "setsockopt(SO_REUSEADDR) %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000181 ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000182 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000183 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000184
185 /* TODO: close on exit */
186
187 if (ls[i].nonblocking) {
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000188 if (ngx_nonblocking(s) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000189 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
190 ngx_nonblocking_n " %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000191 ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000192 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000193 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000194 }
195
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000196 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000197 err = ngx_socket_errno;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000198 ngx_log_error(NGX_LOG_EMERG, log, err,
Igor Sysoev88092572002-12-19 07:08:55 +0000199 "bind() to %s failed", ls[i].addr_text.data);
Igor Sysoev2b542382002-08-20 14:48:28 +0000200
201 if (err != NGX_EADDRINUSE)
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000202 return NGX_ERROR;
Igor Sysoev2b542382002-08-20 14:48:28 +0000203
204 if (ngx_close_socket(s) == -1)
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000205 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev2b542382002-08-20 14:48:28 +0000206 ngx_close_socket_n " %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000207 ls[i].addr_text.data);
Igor Sysoev2b542382002-08-20 14:48:28 +0000208
209 failed = 1;
210 continue;
211 }
212
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000213 if (listen(s, ls[i].backlog) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000214 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev88092572002-12-19 07:08:55 +0000215 "listen() to %s failed", ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000216 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000217 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000218
219 /* TODO: deferred accept */
220
221 ls[i].fd = s;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000222 ls[i].bound = 1;
Igor Sysoev2b542382002-08-20 14:48:28 +0000223 }
224
225 if (!failed)
226 break;
227
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000228 ngx_log_error(NGX_LOG_NOTICE, log, 0,
229 "try again to bind() after 500ms");
Igor Sysoev2b542382002-08-20 14:48:28 +0000230 ngx_msleep(500);
231 }
232
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000233 if (failed) {
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000234
235 /* TODO: configurable */
236
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000237 ngx_log_error(NGX_LOG_EMERG, log, 0, "can not bind(), exiting");
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000238 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000239 }
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000240
241 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000242}