Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 397:de797f3b4c27
nginx-0.0.7-2004-07-23-09:37:29 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 23 Jul 2004 05:37:29 +0000 |
parents | 6f3b20c1ac50 |
children | 201b5f68b59f |
comparison
equal
deleted
inserted
replaced
396:6f3b20c1ac50 | 397:de797f3b4c27 |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_event.h> | 4 #include <ngx_event.h> |
5 | |
6 | |
7 static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size); | |
5 | 8 |
6 | 9 |
7 ngx_int_t ngx_ssl_init(ngx_log_t *log) | 10 ngx_int_t ngx_ssl_init(ngx_log_t *log) |
8 { | 11 { |
9 SSL_library_init(); | 12 SSL_library_init(); |
20 | 23 |
21 if (!(ssl = ngx_pcalloc(c->pool, sizeof(ngx_ssl_t)))) { | 24 if (!(ssl = ngx_pcalloc(c->pool, sizeof(ngx_ssl_t)))) { |
22 return NGX_ERROR; | 25 return NGX_ERROR; |
23 } | 26 } |
24 | 27 |
28 if (!(ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE))) { | |
29 return NGX_ERROR; | |
30 } | |
31 | |
25 if (flags & NGX_SSL_BUFFER) { | 32 if (flags & NGX_SSL_BUFFER) { |
26 if (!(ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE))) { | 33 ssl->buffer = 1; |
27 return NGX_ERROR; | |
28 } | |
29 } | 34 } |
30 | 35 |
31 ssl->ssl = SSL_new(ssl_ctx); | 36 ssl->ssl = SSL_new(ssl_ctx); |
32 | 37 |
33 if (ssl->ssl == NULL) { | 38 if (ssl->ssl == NULL) { |
102 | 107 |
103 | 108 |
104 ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, | 109 ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, |
105 off_t limit) | 110 off_t limit) |
106 { | 111 { |
107 int n, sslerr; | 112 int n; |
108 ngx_err_t err; | 113 ngx_uint_t flush; |
109 ssize_t send, size; | 114 ssize_t send, size; |
110 ngx_buf_t *buf; | 115 ngx_buf_t *buf; |
116 | |
117 buf = c->ssl->buf; | |
118 | |
119 if (in && in->next == NULL && !c->ssl->buffer && buf->pos == buf->last) { | |
120 | |
121 /* | |
122 * the optimized path without a copy if there is the single incoming | |
123 * buf, we do not need to buffer output and our buffer is empty | |
124 */ | |
125 | |
126 n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos); | |
127 | |
128 if (n < 0) { | |
129 return (ngx_chain_t *) n; | |
130 } | |
131 | |
132 in->buf->pos += n; | |
133 | |
134 return in; | |
135 } | |
111 | 136 |
112 send = 0; | 137 send = 0; |
113 | 138 flush = (in == NULL) ? 1 : 0; |
114 buf = c->ssl->buf; | 139 |
115 | 140 for ( ;; ) { |
116 #if 0 | 141 |
117 | 142 while (in && buf->last < buf->end) { |
118 if (buf) { | 143 if (in->buf->last_buf) { |
119 | 144 flush = 1; |
120 for ( ;; ) { | 145 } |
121 | 146 |
122 for ( /* void */ ; in && buf->last < buf->end; in = in->next) { | 147 if (ngx_buf_special(in->buf)) { |
123 if (ngx_buf_special(in->buf)) { | 148 continue; |
124 continue; | 149 } |
125 } | 150 |
126 | 151 size = in->buf->last - in->buf->pos; |
127 size = in->buf->last - in->buf->pos; | 152 |
128 | 153 if (size > buf->end - buf->last) { |
129 if (size > buf->end - buf->last) { | 154 size = buf->end - buf->last; |
130 size = buf->end - buf->last; | 155 } |
131 } | 156 |
132 | 157 /* |
133 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 158 * TODO: the taking in->buf->flush into account can be |
134 "SSL buf copy: %d", size); | 159 * implemented using the limit |
135 | 160 */ |
136 ngx_memcpy(buf->last, in->buf->pos, size); | |
137 | |
138 buf->last += size; | |
139 in->buf->pos += size; | |
140 } | |
141 | |
142 size = buf->last - buf->pos; | |
143 | 161 |
144 if (send + size > limit) { | 162 if (send + size > limit) { |
145 size = limit - send; | 163 size = limit - send; |
164 flush = 1; | |
146 } | 165 } |
147 | 166 |
148 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 167 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
149 "SSL to write: %d", size); | 168 "SSL buf copy: %d", size); |
150 | 169 |
151 n = SSL_write(c->ssl->ssl, buf->pos, size); | 170 ngx_memcpy(buf->last, in->buf->pos, size); |
152 | 171 |
153 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 172 buf->last += size; |
154 "SSL_write: %d", n); | 173 |
155 | 174 in->buf->pos += size; |
156 if (n > 0) { | 175 if (in->buf->pos == in->buf->last) { |
157 buf->pos += n; | 176 in = in->next; |
158 send += n; | 177 } |
159 c->sent += n; | 178 } |
160 | 179 |
161 if (n < size) { | 180 size = buf->last - buf->pos; |
162 break; | 181 |
163 } | 182 if (flush || buf->last == buf->end || !c->ssl->buffer) { |
164 | 183 n = ngx_ssl_write(c, buf->pos, size); |
165 if (send < limit) { | 184 |
166 if (buf->pos == buf->last) { | 185 } else { |
167 buf->pos = buf->start; | 186 return NGX_CHAIN_AGAIN; |
168 buf->last = buf->start; | 187 } |
169 } | 188 |
170 | 189 if (n < 0) { |
171 if (in == NULL) { | 190 return (ngx_chain_t *) n; |
172 break; | 191 } |
173 } | 192 |
174 | 193 buf->pos += n; |
175 continue; | 194 send += n; |
176 } | 195 c->sent += n; |
177 } | 196 |
178 | 197 if (n < size) { |
179 n = SSL_get_error(c->ssl->ssl, n); | 198 break; |
180 | 199 } |
181 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 200 |
182 "SSL_get_error: %d", n); | 201 if (buf->pos == buf->last) { |
183 | 202 buf->pos = buf->start; |
184 if (n == SSL_ERROR_WANT_WRITE) { | 203 buf->last = buf->start; |
185 break; | 204 } |
186 } | 205 |
206 if (in == NULL || send == limit) { | |
207 break; | |
208 } | |
209 } | |
210 | |
211 if (in) { | |
212 return in; | |
213 } | |
214 | |
215 if (buf->pos == buf->last) { | |
216 return NULL; | |
217 } | |
218 | |
219 return NGX_CHAIN_AGAIN; | |
220 } | |
221 | |
222 | |
223 static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) | |
224 { | |
225 int n, sslerr; | |
226 ngx_err_t err; | |
227 | |
228 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); | |
229 | |
230 n = SSL_write(c->ssl->ssl, data, size); | |
231 | |
232 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); | |
233 | |
234 if (n > 0) { | |
235 return n; | |
236 } | |
237 | |
238 sslerr = SSL_get_error(c->ssl->ssl, n); | |
239 | |
240 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; | |
241 | |
242 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); | |
243 | |
244 if (sslerr == SSL_ERROR_WANT_WRITE) { | |
245 c->write->ready = 0; | |
246 return NGX_AGAIN; | |
247 } | |
187 | 248 |
188 #if 0 | 249 #if 0 |
189 if (n == SSL_ERROR_WANT_READ) { | 250 if (sslerr == SSL_ERROR_WANT_READ) { |
190 break; | 251 return NGX_AGAIN; |
191 } | 252 } |
192 #endif | 253 #endif |
193 | 254 |
194 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed"); | 255 c->ssl->no_rcv_shut = 1; |
195 | 256 |
196 return NGX_CHAIN_ERROR; | 257 ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed"); |
197 } | 258 |
198 | 259 return NGX_ERROR; |
199 if (in) { | |
200 c->write->ready = 0; | |
201 return in; | |
202 } | |
203 | |
204 if (buf->pos == buf->last) { | |
205 return NULL; | |
206 | |
207 } else { | |
208 c->write->ready = 0; | |
209 return NGX_CHAIN_AGAIN; | |
210 } | |
211 } | |
212 | |
213 #endif | |
214 | |
215 for (/* void */; in; in = in->next) { | |
216 if (ngx_buf_special(in->buf)) { | |
217 continue; | |
218 } | |
219 | |
220 size = in->buf->last - in->buf->pos; | |
221 | |
222 if (send + size > limit) { | |
223 size = limit - send; | |
224 } | |
225 | |
226 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
227 "SSL to write: %d", size); | |
228 | |
229 n = SSL_write(c->ssl->ssl, in->buf->pos, size); | |
230 | |
231 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); | |
232 | |
233 if (n > 0) { | |
234 in->buf->pos += n; | |
235 send += n; | |
236 c->sent += n; | |
237 | |
238 if (n == size) { | |
239 if (send < limit) { | |
240 continue; | |
241 } | |
242 | |
243 return in; | |
244 } | |
245 | |
246 c->write->ready = 0; | |
247 return in; | |
248 } | |
249 | |
250 sslerr = SSL_get_error(c->ssl->ssl, n); | |
251 | |
252 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; | |
253 | |
254 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
255 "SSL_get_error: %d", sslerr); | |
256 | |
257 if (sslerr == SSL_ERROR_WANT_WRITE) { | |
258 c->write->ready = 0; | |
259 return in; | |
260 } | |
261 | |
262 #if 0 | |
263 if (sslerr == SSL_ERROR_WANT_READ) { | |
264 return NGX_AGAIN; | |
265 } | |
266 #endif | |
267 | |
268 c->ssl->no_rcv_shut = 1; | |
269 | |
270 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_write() failed"); | |
271 | |
272 return NGX_CHAIN_ERROR; | |
273 } | |
274 | |
275 return in; | |
276 } | 260 } |
277 | 261 |
278 | 262 |
279 ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) | 263 ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) |
280 { | 264 { |