blob: 295e2a946772d21e1bfc501bb458267e0f09a9d9 [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 Sysoevaa3436c2003-05-30 14:27:59 +00005
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00006#include <ngx_listen.h>
7
Igor Sysoevaa3436c2003-05-30 14:27:59 +00008#include <nginx.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009
10
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000011
Igor Sysoevaa3436c2003-05-30 14:27:59 +000012static int ngx_open_listening_sockets(ngx_log_t *log);
Igor Sysoev2b542382002-08-20 14:48:28 +000013
Igor Sysoev2b542382002-08-20 14:48:28 +000014
Igor Sysoeva9830112003-05-19 16:39:14 +000015ngx_log_t ngx_log;
16ngx_pool_t *ngx_pool;
17void ****ngx_conf_ctx;
18
19
20ngx_os_io_t ngx_io;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000021
22
Igor Sysoevaa3436c2003-05-30 14:27:59 +000023int ngx_max_module;
24void *ctx_conf;
Igor Sysoeve2a31542003-04-08 15:40:10 +000025
Igor Sysoev42feecb2002-12-15 06:25:09 +000026int ngx_connection_counter;
27
Igor Sysoev4e9393a2003-01-09 05:36:00 +000028ngx_array_t ngx_listening_sockets;
Igor Sysoeve0af1b82002-08-16 15:27:03 +000029
30
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000031int main(int argc, char *const *argv)
32{
Igor Sysoevb2620632003-01-10 06:09:20 +000033 int i;
Igor Sysoev1c104622003-06-03 15:42:58 +000034 ngx_str_t conf_file;
35 ngx_log_t *log;
36 ngx_conf_t conf;
Igor Sysoeva6717c42002-12-23 06:29:22 +000037
Igor Sysoev1c13c662003-05-20 15:37:55 +000038 ngx_max_sockets = -1;
39
Igor Sysoev1c104622003-06-03 15:42:58 +000040#if 0
Igor Sysoev1c13c662003-05-20 15:37:55 +000041 ngx_log.fd = STDERR_FILENO;
42 ngx_log.log_level = NGX_LOG_INFO;
43
44 /* STUB */ ngx_log.log_level = NGX_LOG_DEBUG;
Igor Sysoev1c104622003-06-03 15:42:58 +000045#endif
46 log = ngx_log_init_errlog();
Igor Sysoev2b542382002-08-20 14:48:28 +000047
Igor Sysoev1c104622003-06-03 15:42:58 +000048 if (ngx_os_init(log) == NGX_ERROR) {
Igor Sysoeva9830112003-05-19 16:39:14 +000049 return 1;
Igor Sysoev79a80482003-05-14 17:13:13 +000050 }
51
Igor Sysoev1c104622003-06-03 15:42:58 +000052 ngx_pool = ngx_create_pool(16 * 1024, log);
Igor Sysoev2b542382002-08-20 14:48:28 +000053 /* */
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000054
Igor Sysoeve2a31542003-04-08 15:40:10 +000055 ngx_max_module = 0;
56 for (i = 0; ngx_modules[i]; i++) {
57 ngx_modules[i]->index = ngx_max_module++;
58 }
59
Igor Sysoeva9830112003-05-19 16:39:14 +000060 /* life cycle */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000061
Igor Sysoeva9830112003-05-19 16:39:14 +000062 {
63 ngx_init_array(ngx_listening_sockets,
64 ngx_pool, 10, sizeof(ngx_listen_t),
65 1);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000066
Igor Sysoeva9830112003-05-19 16:39:14 +000067 ngx_memzero(&conf, sizeof(ngx_conf_t));
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000068
Igor Sysoeva9830112003-05-19 16:39:14 +000069 ngx_test_null(conf.args,
70 ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)),
71 1);
Igor Sysoeva6717c42002-12-23 06:29:22 +000072
Igor Sysoeva9830112003-05-19 16:39:14 +000073 ngx_test_null(ngx_conf_ctx,
74 ngx_pcalloc(ngx_pool, ngx_max_module * sizeof(void *)),
75 1);
Igor Sysoeva6717c42002-12-23 06:29:22 +000076
Igor Sysoeva9830112003-05-19 16:39:14 +000077 conf.ctx = ngx_conf_ctx;
78 conf.pool = ngx_pool;
Igor Sysoev1c104622003-06-03 15:42:58 +000079 conf.log = log;
Igor Sysoev6253ca12003-05-27 12:18:54 +000080 conf.module_type = NGX_CORE_MODULE;
Igor Sysoeva9830112003-05-19 16:39:14 +000081 conf.cmd_type = NGX_MAIN_CONF;
Igor Sysoeva6717c42002-12-23 06:29:22 +000082
Igor Sysoev13933252003-05-29 13:02:09 +000083 conf_file.len = sizeof(NGINX_CONF) - 1;
84 conf_file.data = NGINX_CONF;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +000085
Igor Sysoeva9830112003-05-19 16:39:14 +000086 if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
87 return 1;
88 }
89
Igor Sysoev1c104622003-06-03 15:42:58 +000090#if 0
91 log = (ngx_log_t *) ngx_get_conf(ngx_errlog_module);
92 /* STUB */ log->log_level = NGX_LOG_DEBUG;
93#endif
94
Igor Sysoeva9830112003-05-19 16:39:14 +000095 ngx_init_temp_number();
96
97 ngx_io = ngx_os_io;
98
99 for (i = 0; ngx_modules[i]; i++) {
100 if (ngx_modules[i]->init_module) {
101 if (ngx_modules[i]->init_module(ngx_pool) == NGX_ERROR) {
102 return 1;
103 }
Igor Sysoevb2620632003-01-10 06:09:20 +0000104 }
105 }
Igor Sysoevb2620632003-01-10 06:09:20 +0000106
Igor Sysoev1c104622003-06-03 15:42:58 +0000107 if (ngx_open_listening_sockets(log) == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000108 return 1;
109 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000110
Igor Sysoeva9830112003-05-19 16:39:14 +0000111 /* TODO: daemon, once only */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000112
Igor Sysoeva9830112003-05-19 16:39:14 +0000113 /* TODO: fork */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000114
Igor Sysoev1c104622003-06-03 15:42:58 +0000115 ngx_pre_thread(&ngx_listening_sockets, ngx_pool, log);
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000116
Igor Sysoeva9830112003-05-19 16:39:14 +0000117 /* TODO: threads */
Igor Sysoeve0af1b82002-08-16 15:27:03 +0000118
Igor Sysoeva9830112003-05-19 16:39:14 +0000119 /* STUB */
Igor Sysoev1c104622003-06-03 15:42:58 +0000120 ngx_worker(log);
Igor Sysoev6253ca12003-05-27 12:18:54 +0000121 }
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000122
123 return 0;
Igor Sysoev2b542382002-08-20 14:48:28 +0000124}
125
Igor Sysoevb0869052002-12-10 18:05:12 +0000126
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000127static int ngx_open_listening_sockets(ngx_log_t *log)
Igor Sysoev2b542382002-08-20 14:48:28 +0000128{
129 int times, failed, reuseaddr, i;
130 ngx_err_t err;
131 ngx_socket_t s;
132 ngx_listen_t *ls;
133
134 reuseaddr = 1;
135
136 for (times = 10; times; times--) {
137 failed = 0;
138
139 /* for each listening socket */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000140 ls = (ngx_listen_t *) ngx_listening_sockets.elts;
141 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
164 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000165 (const void *) &reuseaddr, sizeof(int)) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000166 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000167 "setsockopt(SO_REUSEADDR) %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000168 ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000169 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000170 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000171
172 /* TODO: close on exit */
173
174 if (ls[i].nonblocking) {
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000175 if (ngx_nonblocking(s) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000176 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
177 ngx_nonblocking_n " %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000178 ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000179 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000180 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000181 }
182
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000183 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000184 err = ngx_socket_errno;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000185 ngx_log_error(NGX_LOG_EMERG, log, err,
Igor Sysoev88092572002-12-19 07:08:55 +0000186 "bind() to %s failed", ls[i].addr_text.data);
Igor Sysoev2b542382002-08-20 14:48:28 +0000187
188 if (err != NGX_EADDRINUSE)
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000189 return NGX_ERROR;
Igor Sysoev2b542382002-08-20 14:48:28 +0000190
191 if (ngx_close_socket(s) == -1)
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000192 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev2b542382002-08-20 14:48:28 +0000193 ngx_close_socket_n " %s failed",
Igor Sysoev88092572002-12-19 07:08:55 +0000194 ls[i].addr_text.data);
Igor Sysoev2b542382002-08-20 14:48:28 +0000195
196 failed = 1;
197 continue;
198 }
199
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000200 if (listen(s, ls[i].backlog) == -1) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000201 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev88092572002-12-19 07:08:55 +0000202 "listen() to %s failed", ls[i].addr_text.data);
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000203 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000204 }
Igor Sysoev2b542382002-08-20 14:48:28 +0000205
206 /* TODO: deferred accept */
207
208 ls[i].fd = s;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000209 ls[i].bound = 1;
Igor Sysoev2b542382002-08-20 14:48:28 +0000210 }
211
212 if (!failed)
213 break;
214
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000215 ngx_log_error(NGX_LOG_NOTICE, log, 0,
216 "try again to bind() after 500ms");
Igor Sysoev2b542382002-08-20 14:48:28 +0000217 ngx_msleep(500);
218 }
219
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000220 if (failed) {
221 ngx_log_error(NGX_LOG_EMERG, log, 0, "can not bind(), exiting");
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000222 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000223 }
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000224
225 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000226}