-
Notifications
You must be signed in to change notification settings - Fork 14
/
per-worker-listener
196 lines (177 loc) · 6.41 KB
/
per-worker-listener
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 6b6e3b3..5c9529c 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -8,6 +8,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
+#include <nginx.h>
ngx_os_io_t ngx_io;
@@ -311,6 +312,13 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
ngx_socket_t s;
ngx_listening_t *ls;
+ size_t len;
+ struct sockaddr *sockaddr;
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
reuseaddr = 1;
#if (NGX_SUPPRESS_WARN)
failed = 0;
@@ -336,6 +344,57 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
continue;
}
+ sockaddr = ls[i].sockaddr;
+
+ if (ngx_process == NGX_PROCESS_WORKER) {
+
+ if (!ls[i].per_worker) {
+ continue;
+ }
+
+ sockaddr = ngx_palloc(cycle->pool, ls[i].socklen);
+ if (sockaddr == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(sockaddr, ls[i].sockaddr, ls[i].socklen);
+
+ switch (ls[i].sockaddr->sa_family) {
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) sockaddr;
+ sin6->sin6_port = htons(ntohs(sin6->sin6_port) +
+ ngx_worker_slot);
+ break;
+#endif
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) sockaddr;
+ sin->sin_port = htons(ntohs(sin->sin_port) +
+ ngx_worker_slot);
+ }
+
+ len = ls[i].addr_text_max_len;
+ ls[i].addr_text.data = ngx_palloc(cycle->pool, len);
+
+ if (ls[i].addr_text.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ len = ngx_sock_ntop(sockaddr,
+#if (nginx_version >= 1005003)
+ ls[i].socklen,
+#endif
+ ls[i].addr_text.data, len, 1);
+ if (len == 0) {
+ return NGX_ERROR;
+ }
+
+ ls[i].addr_text.len = len;
+
+ } else if (ls[i].per_worker) {
+ continue;
+ }
+
if (ls[i].inherited) {
/* TODO: close on exit */
@@ -408,7 +467,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
"bind() %V #%d ", &ls[i].addr_text, s);
- if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
+ if (bind(s, sockaddr, ls[i].socklen) == -1) {
err = ngx_socket_errno;
if (err == NGX_EADDRINUSE && ngx_test_config) {
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index d9bc60a..2b22808 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -54,6 +54,7 @@ struct ngx_listening_s {
unsigned open:1;
unsigned remain:1;
unsigned ignore:1;
+ unsigned per_worker:1;
unsigned bound:1; /* already bound */
unsigned inherited:1; /* inherited from previous process */
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index c3ac726..3672b7a 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1817,6 +1817,8 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
ls->fastopen = addr->opt.fastopen;
#endif
+ ls->per_worker = addr->opt.per_worker;
+
return ls;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 74a448a..e447f86 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -4026,6 +4026,11 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strcmp(value[n].data, "per_worker") == 0) {
+ lsopt.per_worker = 1;
+ continue;
+ }
+
#if (NGX_HAVE_SETFIB)
if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 220c94e..76a4e98 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -72,6 +72,7 @@ typedef struct {
unsigned default_server:1;
unsigned bind:1;
unsigned wildcard:1;
+ unsigned per_worker:1;
#if (NGX_HTTP_SSL)
unsigned ssl:1;
#endif
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index 6f3f385..a421c09 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -34,6 +34,7 @@ ngx_int_t ngx_process_slot;
ngx_socket_t ngx_channel;
ngx_int_t ngx_last_process;
ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
+ngx_int_t ngx_worker_slot;
ngx_signal_t signals[] = {
diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h
index 7b5e8c0..26eccf5 100644
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -83,6 +83,7 @@ extern ngx_socket_t ngx_channel;
extern ngx_int_t ngx_process_slot;
extern ngx_int_t ngx_last_process;
extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
+extern ngx_int_t ngx_worker_slot;
#endif /* _NGX_PROCESS_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 499039a..c54b4d5 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -737,6 +737,8 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
ngx_process = NGX_PROCESS_WORKER;
+ ngx_worker_slot = worker;
+
ngx_worker_process_init(cycle, worker);
ngx_setproctitle("worker process");
@@ -970,6 +972,12 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
ls[i].previous = NULL;
}
+ if (ngx_open_listening_sockets(cycle) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "failed to init worker listeners");
+ exit(2);
+ }
+
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_process) {
if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {