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 {