Browse code

tls: async support (major tls core rewrite)

The new tls hook interface (exported by the tcp code) is now used.
All the IO operations are made through a custom SSL BIO, that
reads and writes in some memory buffers (see tls_bio.h), while
externally emulating a socket. This BIO provides in fact some
functions that will be called by the openssl code on IO.
In the case of a read event, the data is first read in memory
(using tcp_read_data()), then assigned to the BIO and after that
one of SSL_read(), SSL_connect/accept (if the connection is not
yet established) or SSL_write (if the last write wanted to read
some data due to re-keying) are called. They will all read from
the custom BIO. A SSL_read() might not use all the data (in some
very unlikely situations), so in this case the encrypted data is
queued and the tcp code is signaled (via some flags) that it
should repeat the read call when more space is available.
Writes are split in 2: 1st write on a new connection in async mode
and other writes (they need to be handled slightly differently).
The encrypted data will end up in a memory buffer (via SSL_write()
and the custom BIO). From there it will be either sent directly if
possible or queued (tcp_async). In the case when the SSL_write()
needs to read some data (e.g. re-keying), the whole clear text
data will be queued and the SSL_write() will be retried on the
first read event.

There is no separate async mode for tls, if tcp is in async mode,
then tls will be too and vice versa.
Runtime tunning (queue sizes a.s.o) and statistics are missing for
now.

(C) and license changes:
- moved tls_dump_verification_failure into a separate file
(tls_dump_vf.c), out of tls_server.c.
- the remaining tcp_server.[ch] code is either re-written (most of it,
the entire read & write part) or comes from old iptel code =>
changed the (c) to iptelorg only and the license to BSD-like
(only for tcp_server.[ch]).

Andrei Pelinescu-Onciul authored on 20/05/2010 16:24:38
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,144 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2006 enum.at
5
+ *
6
+ * This file is part of SIP-router, a free SIP server.
7
+ *
8
+ * SIP-router is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * SIP-router is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License 
19
+ * along with this program; if not, write to the Free Software 
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
+ */
22
+/** log the verification failure reason.
23
+ * @file tls_dump_vf.c
24
+ * @ingroup: tls
25
+ * Module: @ref tls
26
+ */
27
+/*
28
+ * History:
29
+ * --------
30
+ *  2010-05-20  split from tls_server.c
31
+*/
32
+
33
+#include "tls_dump_vf.h"
34
+
35
+#include <openssl/ssl.h>
36
+#include "../../dprint.h"
37
+#include "tls_mod.h"
38
+
39
+/** log the verification failure reason.
40
+ */
41
+void tls_dump_verification_failure(long verification_result)
42
+{
43
+	switch(verification_result) {
44
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
45
+		LOG(tls_log, "verification failure: unable to get issuer certificate\n");
46
+		break;
47
+	case X509_V_ERR_UNABLE_TO_GET_CRL:
48
+		LOG(tls_log, "verification failure: unable to get certificate CRL\n");
49
+		break;
50
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
51
+		LOG(tls_log, "verification failure: unable to decrypt certificate's signature\n");
52
+		break;
53
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
54
+		LOG(tls_log, "verification failure: unable to decrypt CRL's signature\n");
55
+		break;
56
+	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
57
+		LOG(tls_log, "verification failure: unable to decode issuer public key\n");
58
+		break;
59
+	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
60
+		LOG(tls_log, "verification failure: certificate signature failure\n");
61
+		break;
62
+	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
63
+		LOG(tls_log, "verification failure: CRL signature failure\n");
64
+		break;
65
+	case X509_V_ERR_CERT_NOT_YET_VALID:
66
+		LOG(tls_log, "verification failure: certificate is not yet valid\n");
67
+		break;
68
+	case X509_V_ERR_CERT_HAS_EXPIRED:
69
+		LOG(tls_log, "verification failure: certificate has expired\n");
70
+		break;
71
+	case X509_V_ERR_CRL_NOT_YET_VALID:
72
+		LOG(tls_log, "verification failure: CRL is not yet valid\n");
73
+		break;
74
+	case X509_V_ERR_CRL_HAS_EXPIRED:
75
+		LOG(tls_log, "verification failure: CRL has expired\n");
76
+		break;
77
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
78
+		LOG(tls_log, "verification failure: format error in certificate's notBefore field\n");
79
+		break;
80
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
81
+		LOG(tls_log, "verification failure: format error in certificate's notAfter field\n");
82
+		break;
83
+	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
84
+		LOG(tls_log, "verification failure: format error in CRL's lastUpdate field\n");
85
+		break;
86
+	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
87
+		LOG(tls_log, "verification failure: format error in CRL's nextUpdate field\n");
88
+		break;
89
+	case X509_V_ERR_OUT_OF_MEM:
90
+		LOG(tls_log, "verification failure: out of memory\n");
91
+		break;
92
+	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
93
+		LOG(tls_log, "verification failure: self signed certificate\n");
94
+		break;
95
+	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
96
+		LOG(tls_log, "verification failure: self signed certificate in certificate chain\n");
97
+		break;
98
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
99
+		LOG(tls_log, "verification failure: unable to get local issuer certificate\n");
100
+		break;
101
+	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
102
+		LOG(tls_log, "verification failure: unable to verify the first certificate\n");
103
+		break;
104
+	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
105
+		LOG(tls_log, "verification failure: certificate chain too long\n");
106
+		break;
107
+	case X509_V_ERR_CERT_REVOKED:
108
+		LOG(tls_log, "verification failure: certificate revoked\n");
109
+		break;
110
+	case X509_V_ERR_INVALID_CA:
111
+		LOG(tls_log, "verification failure: invalid CA certificate\n");
112
+		break;
113
+	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
114
+		LOG(tls_log, "verification failure: path length constraint exceeded\n");
115
+		break;
116
+	case X509_V_ERR_INVALID_PURPOSE:
117
+		LOG(tls_log, "verification failure: unsupported certificate purpose\n");
118
+		break;
119
+	case X509_V_ERR_CERT_UNTRUSTED:
120
+		LOG(tls_log, "verification failure: certificate not trusted\n");
121
+		break;
122
+	case X509_V_ERR_CERT_REJECTED:
123
+		LOG(tls_log, "verification failure: certificate rejected\n");
124
+		break;
125
+	case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
126
+		LOG(tls_log, "verification failure: subject issuer mismatch\n");
127
+		break;
128
+	case X509_V_ERR_AKID_SKID_MISMATCH:
129
+		LOG(tls_log, "verification failure: authority and subject key identifier mismatch\n");
130
+		break;
131
+	case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
132
+		LOG(tls_log, "verification failure: authority and issuer serial number mismatch\n");
133
+		break;
134
+	case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
135
+		LOG(tls_log, "verification failure: key usage does not include certificate signing\n");
136
+		break;
137
+	case X509_V_ERR_APPLICATION_VERIFICATION:
138
+		LOG(tls_log, "verification failure: application verification failure\n");
139
+		break;
140
+	}
141
+}
142
+
143
+
144
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
0 145
new file mode 100644
... ...
@@ -0,0 +1,41 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2006 enum.at
5
+ *
6
+ * This file is part of SIP-router, a free SIP server.
7
+ *
8
+ * SIP-router is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * SIP-router is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License 
19
+ * along with this program; if not, write to the Free Software 
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
+ */
22
+/** log the verification failure reason.
23
+ * @file tls_dump_vf.h
24
+ * @ingroup: tls
25
+ * Module: @ref tls
26
+ */
27
+/*
28
+ * History:
29
+ * --------
30
+ *  2010-05-20  split from tls_server.c
31
+*/
32
+
33
+#ifndef __tls_dump_vf_h
34
+#define __tls_dump_vf_h
35
+
36
+
37
+void tls_dump_verification_failure(long verification_result);
38
+
39
+#endif /*__tls_dump_vf_h*/
40
+
41
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
... ...
@@ -69,6 +69,7 @@
69 69
 #include "tls_mod.h"
70 70
 #include "tls_init.h"
71 71
 #include "tls_locking.h"
72
+#include "tls_ct_wrq.h"
72 73
 
73 74
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
74 75
 #    warning ""
... ...
@@ -645,4 +646,5 @@ void destroy_tls_h(void)
645 646
 	/* TODO: free all the ctx'es */
646 647
 	tls_destroy_cfg();
647 648
 	tls_destroy_locks();
649
+	tls_ct_wq_destroy();
648 650
 }
... ...
@@ -278,12 +278,12 @@ struct module_exports exports = {
278 278
 
279 279
 
280 280
 static struct tls_hooks tls_h = {
281
-	tls_h_read,
282
-	tls_h_blocking_write,
281
+	tls_read_f,
282
+	tls_do_send_f,
283
+	tls_1st_send_f,
283 284
 	tls_h_tcpconn_init,
284 285
 	tls_h_tcpconn_clean,
285 286
 	tls_h_close,
286
-	tls_h_fix_read_conn,
287 287
 	tls_h_init_si,
288 288
 	init_tls_h,
289 289
 	destroy_tls_h
... ...
@@ -346,11 +346,13 @@ static int mod_init(void)
346 346
 		return 0;
347 347
 	}
348 348
 
349
+/*
349 350
 	if (cfg_get(tcp, tcp_cfg, async) && !tls_force_run){
350 351
 		ERR("tls does not support tcp in async mode, please use"
351 352
 				" tcp_async=no in the config file\n");
352 353
 		return -1;
353 354
 	}
355
+*/
354 356
 	     /* Convert tls_method parameter to integer */
355 357
 	method = tls_parse_method(&tls_method);
356 358
 	if (method < 0) {
... ...
@@ -368,7 +370,7 @@ static int mod_init(void)
368 370
 	tls_cfg = (tls_cfg_t**)shm_malloc(sizeof(tls_cfg_t*));
369 371
 	if (!tls_cfg) {
370 372
 		ERR("Not enough shared memory left\n");
371
-		return -1;
373
+		goto error;
372 374
 	}
373 375
 	*tls_cfg = NULL;
374 376
 
... ...
@@ -380,23 +382,27 @@ static int mod_init(void)
380 382
 	tls_cfg_lock = lock_alloc();
381 383
 	if (tls_cfg_lock == 0) {
382 384
 		ERR("Unable to create TLS configuration lock\n");
383
-		return -1;
385
+		goto error;
384 386
 	}
385 387
 	if (lock_init(tls_cfg_lock) == 0) {
386 388
 		lock_dealloc(tls_cfg_lock);
387 389
 		ERR("Unable to initialize TLS configuration lock\n");
388
-		return -1;
390
+		goto error;
391
+	}
392
+	if (tls_ct_wq_init() < 0) {
393
+		ERR("Unable to initialize TLS buffering\n");
394
+		goto error;
389 395
 	}
390
-
391 396
 	if (tls_cfg_file.s) {
392 397
 		*tls_cfg = tls_load_config(&tls_cfg_file);
393
-		if (!(*tls_cfg)) return -1;
398
+		if (!(*tls_cfg)) goto error;
394 399
 	} else {
395 400
 		*tls_cfg = tls_new_cfg();
396
-		if (!(*tls_cfg)) return -1;
401
+		if (!(*tls_cfg)) goto error;
397 402
 	}
398 403
 
399
-	if (tls_check_sockets(*tls_cfg) < 0) return -1;
404
+	if (tls_check_sockets(*tls_cfg) < 0)
405
+		goto error;
400 406
 
401 407
 	/* fix the timeouts from s to ticks */
402 408
 	if (tls_con_lifetime<0){
... ...
@@ -413,10 +419,10 @@ static int mod_init(void)
413 419
 			tls_con_lifetime=S_TO_TICKS(tls_con_lifetime);
414 420
 		}
415 421
 	}
416
-	
417
-
418
-
419 422
 	return 0;
423
+error:
424
+	destroy_tls_h();
425
+	return -1;
420 426
 }
421 427
 
422 428
 
... ...
@@ -441,6 +447,8 @@ static int mod_child(int rank)
441 447
 
442 448
 static void destroy(void)
443 449
 {
450
+	/* tls is destroyed via the registered destroy_tls_h callback
451
+	   => nothing to do here */
444 452
 }
445 453
 
446 454
 
... ...
@@ -4,24 +4,21 @@
4 4
  * TLS module - main server part
5 5
  * 
6 6
  * Copyright (C) 2001-2003 FhG FOKUS
7
- * Copyright (C) 2004,2005 Free Software Foundation, Inc.
8
- * Copyright (C) 2005,2006 iptelorg GmbH
7
+ * Copyright (C) 2005-2010 iptelorg GmbH
9 8
  *
10 9
  * This file is part of SIP-router, a free SIP server.
11 10
  *
12
- * SIP-router is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2 of the License, or
15
- * (at your option) any later version
11
+ * Permission to use, copy, modify, and distribute this software for any
12
+ * purpose with or without fee is hereby granted, provided that the above
13
+ * copyright notice and this permission notice appear in all copies.
16 14
  *
17
- * SIP-router is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License 
23
- * along with this program; if not, write to the Free Software 
24
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 22
  */
26 23
 /*
27 24
  * History:
... ...
@@ -31,11 +28,10 @@
31 28
  *  2009-09-21  tls connection state is now kept in c->extra_data (no
32 29
  *               longer shared with tcp state) (andrei)
33 30
  */
34
-/*!
35
- * \file
36
- * \brief SIP-router TLS support :: Main server part
37
- * \ingroup tls
38
- * Module: \ref tls
31
+/** main tls part (implements the tls hooks that are called from the tcp code).
32
+ * @file tls_server.c
33
+ * @ingroup tls
34
+ * Module: @ref tls
39 35
  */
40 36
 
41 37
 
... ...
@@ -49,12 +45,16 @@
49 45
 #include "../../timer.h"
50 46
 #include "../../globals.h"
51 47
 #include "../../pt.h"
48
+#include "../../tcp_int_send.h"
49
+#include "../../tcp_read.h"
52 50
 
53 51
 #include "tls_init.h"
54 52
 #include "tls_domain.h"
55 53
 #include "tls_util.h"
56 54
 #include "tls_mod.h"
57 55
 #include "tls_server.h"
56
+#include "tls_bio.h"
57
+#include "tls_dump_vf.h"
58 58
 
59 59
 /* low memory treshold for openssl bug #1491 workaround */
60 60
 #define LOW_MEM_NEW_CONNECTION_TEST() \
... ...
@@ -62,10 +62,15 @@
62 62
 #define LOW_MEM_CONNECTED_TEST() \
63 63
 	((openssl_mem_threshold2) && (shm_available()<openssl_mem_threshold2))
64 64
 
65
-/* 
66
- * finish the ssl init (creates the SSL and set extra_data to it)
67
- * separated from tls_tcpconn_init to allow delayed ssl context
65
+#define TLS_RD_MBUF_SZ	65536
66
+#define TLS_WR_MBUF_SZ	65536
67
+
68
+/** finish the ssl init.
69
+ * Creates the SSL and set extra_data to it.
70
+ * Separated from tls_tcpconn_init to allow delayed ssl context
68 71
  * init. (from the "child" process and not from the main one 
72
+ * WARNING: the connection should be already locked.
73
+ * @return 0 on success, -1 on errror.
69 74
  */
70 75
 static int tls_complete_init(struct tcp_connection* c)
71 76
 {
... ...
@@ -142,37 +147,59 @@ static int tls_complete_init(struct tcp_connection* c)
142 147
 }
143 148
 
144 149
 
145
-/*
146
- * Update ssl structure with new fd 
150
+
151
+/** completes tls init if needed and checks if tls can be used.
152
+ *  It will check for low memory.
153
+ *  WARNING: must be called with c->write_lock held.
154
+ *  @return 0 on success, < 0 on error (complete init failed or out of memory).
147 155
  */
148
-static int tls_update_fd(struct tcp_connection *c, int fd)
156
+static int tls_fix_connection(struct tcp_connection* c)
149 157
 {
150
-	SSL *ssl;
151
-	BIO *rbio;
152
-	BIO *wbio;
153
-	
154
-	if (!c->extra_data && tls_complete_init(c) < 0) {
155
-		ERR("Delayed init failed\n");
156
-		return -1;
157
-	}else if (LOW_MEM_CONNECTED_TEST()){
158
+	if (unlikely(!c->extra_data)) {
159
+		if (unlikely(tls_complete_init(c) < 0)) {
160
+			ERR("Delayed init failed\n");
161
+			return -1;
162
+		}
163
+	}else if (unlikely(LOW_MEM_CONNECTED_TEST())){
158 164
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
159 165
 				" operation: %lu\n", shm_available());
160 166
 		return -1;
161 167
 	}
162
-	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
168
+	return 0;
169
+}
170
+
171
+
172
+
173
+/** sets an mbuf pair for the bio used by the tls connection.
174
+ * WARNING: must be called with c->write_lock held.
175
+ * @return 0 on success, -1 on error.
176
+ */
177
+static int tls_set_mbufs(struct tcp_connection *c,
178
+							struct tls_mbuf* rd,
179
+							struct tls_mbuf* wr)
180
+{
181
+	SSL *ssl;
182
+	BIO *rwbio;
183
+	
184
+	/* if (unlikely(tls_fix_connection(c) < 0))
185
+		return -1;
186
+	*/
163 187
 	
164
-	if (((rbio=SSL_get_rbio(ssl))==0) || ((wbio=SSL_get_wbio(ssl))==0)){
165
-		/* no BIO connected */
166
-		if (SSL_set_fd(ssl, fd) != 1) {
167
-			TLS_ERR("tls_update_fd:");
188
+	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
189
+	if (unlikely(((rwbio=SSL_get_rbio(ssl))==0) ||
190
+					((rwbio=SSL_get_wbio(ssl))==0))) {
191
+		rwbio = tls_BIO_new_mbuf(rd, wr);
192
+		if (unlikely(rwbio == 0)) {
193
+			ERR("new mbuf BIO creation failure\n");
168 194
 			return -1;
169 195
 		}
196
+		/* use the same bio for both read & write */
197
+		SSL_set_bio(ssl, rwbio, rwbio);
170 198
 		return 0;
171 199
 	}
172
-	if ((BIO_set_fd(rbio, fd, BIO_NOCLOSE)!=1) ||
173
-		(BIO_set_fd(wbio, fd, BIO_NOCLOSE)!=1)) {
200
+	if (unlikely(tls_BIO_mbuf_set(rwbio, rd, wr)<=0)) {
174 201
 		/* it should be always 1 */
175
-		TLS_ERR("tls_update_fd:");
202
+		ERR("failed to set mbufs");
176 203
 		return -1;
177 204
 	}
178 205
 	return 0;
... ...
@@ -199,115 +226,20 @@ static void tls_dump_cert_info(char* s, X509* cert)
199 226
 }
200 227
 
201 228
 
202
-static void tls_dump_verification_failure(long verification_result)
203
-{
204
-	switch(verification_result) {
205
-	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
206
-		LOG(tls_log, "verification failure: unable to get issuer certificate\n");
207
-		break;
208
-	case X509_V_ERR_UNABLE_TO_GET_CRL:
209
-		LOG(tls_log, "verification failure: unable to get certificate CRL\n");
210
-		break;
211
-	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
212
-		LOG(tls_log, "verification failure: unable to decrypt certificate's signature\n");
213
-		break;
214
-	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
215
-		LOG(tls_log, "verification failure: unable to decrypt CRL's signature\n");
216
-		break;
217
-	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
218
-		LOG(tls_log, "verification failure: unable to decode issuer public key\n");
219
-		break;
220
-	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
221
-		LOG(tls_log, "verification failure: certificate signature failure\n");
222
-		break;
223
-	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
224
-		LOG(tls_log, "verification failure: CRL signature failure\n");
225
-		break;
226
-	case X509_V_ERR_CERT_NOT_YET_VALID:
227
-		LOG(tls_log, "verification failure: certificate is not yet valid\n");
228
-		break;
229
-	case X509_V_ERR_CERT_HAS_EXPIRED:
230
-		LOG(tls_log, "verification failure: certificate has expired\n");
231
-		break;
232
-	case X509_V_ERR_CRL_NOT_YET_VALID:
233
-		LOG(tls_log, "verification failure: CRL is not yet valid\n");
234
-		break;
235
-	case X509_V_ERR_CRL_HAS_EXPIRED:
236
-		LOG(tls_log, "verification failure: CRL has expired\n");
237
-		break;
238
-	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
239
-		LOG(tls_log, "verification failure: format error in certificate's notBefore field\n");
240
-		break;
241
-	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
242
-		LOG(tls_log, "verification failure: format error in certificate's notAfter field\n");
243
-		break;
244
-	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
245
-		LOG(tls_log, "verification failure: format error in CRL's lastUpdate field\n");
246
-		break;
247
-	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
248
-		LOG(tls_log, "verification failure: format error in CRL's nextUpdate field\n");
249
-		break;
250
-	case X509_V_ERR_OUT_OF_MEM:
251
-		LOG(tls_log, "verification failure: out of memory\n");
252
-		break;
253
-	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
254
-		LOG(tls_log, "verification failure: self signed certificate\n");
255
-		break;
256
-	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
257
-		LOG(tls_log, "verification failure: self signed certificate in certificate chain\n");
258
-		break;
259
-	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
260
-		LOG(tls_log, "verification failure: unable to get local issuer certificate\n");
261
-		break;
262
-	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
263
-		LOG(tls_log, "verification failure: unable to verify the first certificate\n");
264
-		break;
265
-	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
266
-		LOG(tls_log, "verification failure: certificate chain too long\n");
267
-		break;
268
-	case X509_V_ERR_CERT_REVOKED:
269
-		LOG(tls_log, "verification failure: certificate revoked\n");
270
-		break;
271
-	case X509_V_ERR_INVALID_CA:
272
-		LOG(tls_log, "verification failure: invalid CA certificate\n");
273
-		break;
274
-	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
275
-		LOG(tls_log, "verification failure: path length constraint exceeded\n");
276
-		break;
277
-	case X509_V_ERR_INVALID_PURPOSE:
278
-		LOG(tls_log, "verification failure: unsupported certificate purpose\n");
279
-		break;
280
-	case X509_V_ERR_CERT_UNTRUSTED:
281
-		LOG(tls_log, "verification failure: certificate not trusted\n");
282
-		break;
283
-	case X509_V_ERR_CERT_REJECTED:
284
-		LOG(tls_log, "verification failure: certificate rejected\n");
285
-		break;
286
-	case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
287
-		LOG(tls_log, "verification failure: subject issuer mismatch\n");
288
-		break;
289
-	case X509_V_ERR_AKID_SKID_MISMATCH:
290
-		LOG(tls_log, "verification failure: authority and subject key identifier mismatch\n");
291
-		break;
292
-	case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
293
-		LOG(tls_log, "verification failure: authority and issuer serial number mismatch\n");
294
-		break;
295
-	case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
296
-		LOG(tls_log, "verification failure: key usage does not include certificate signing\n");
297
-		break;
298
-	case X509_V_ERR_APPLICATION_VERIFICATION:
299
-		LOG(tls_log, "verification failure: application verification failure\n");
300
-		break;
301
-	}
302
-}
303
-
304 229
 
305
-/*
306
- * Wrapper around SSL_accept, returns -1 on error, 0 on success 
230
+/** wrapper around SSL_accept, usin SSL return convention.
231
+ * It will also log critical errors and certificate debugging info.
232
+ * @param c - tcp connection with tls (extra_data must be a filled
233
+ *            tcp_extra_data structure). The state must be S_TLS_ACCEPTING.
234
+ * @param error  set to the error reason (SSL_ERROR_*).
235
+ * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL
236
+ *           connection was closed/shutdown. < 0 is also returned for
237
+ *           WANT_READ or WANT_WRITE 
238
+ *
307 239
  */
308 240
 static int tls_accept(struct tcp_connection *c, int* error)
309 241
 {
310
-	int ret, err, ssl_err;
242
+	int ret, ssl_err;
311 243
 	SSL *ssl;
312 244
 	X509* cert;
313 245
 	struct tls_extra_data* tls_c;
... ...
@@ -321,13 +253,13 @@ static int tls_accept(struct tcp_connection *c, int* error)
321 253
 	tls_c=(struct tls_extra_data*)c->extra_data;
322 254
 	ssl=tls_c->ssl;
323 255
 	
324
-	if (tls_c->state != S_TLS_ACCEPTING) {
256
+	if (unlikely(tls_c->state != S_TLS_ACCEPTING)) {
325 257
 		BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state);
326 258
 		/* Not critical */
327
-		return 0;
259
+		goto err;
328 260
 	}
329 261
 	ret = SSL_accept(ssl);
330
-	if (ret == 1) {
262
+	if (unlikely(ret == 1)) {
331 263
 		DBG("TLS accept successful\n");
332 264
 		tls_c->state = S_TLS_ESTABLISHED;
333 265
 		LOG(tls_log, "tls_accept: new connection from %s:%d using %s %s %d\n",
... ...
@@ -350,10 +282,9 @@ static int tls_accept(struct tcp_connection *c, int* error)
350 282
 		} else {
351 283
 			LOG(tls_log, "tls_accept: client did not present a certificate\n");
352 284
 		}
353
-	} else {
354
-		err = SSL_get_error(ssl, ret);
355
-		if (error) *error = err;
356
-		switch (err) {
285
+	} else { /* ret == 0 or < 0 */
286
+		*error = SSL_get_error(ssl, ret);
287
+		switch (*error) {
357 288
 		case SSL_ERROR_ZERO_RETURN:
358 289
 			DBG("TLS handshake failed cleanly\n");
359 290
 			goto err;
... ...
@@ -383,7 +314,8 @@ static int tls_accept(struct tcp_connection *c, int* error)
383 314
 			TLS_ERR_RET(ssl_err, "TLS accept:");
384 315
 			if (!ssl_err) {
385 316
 				if (ret == 0) {
386
-					WARN("Unexpected EOF occurred while performing TLS accept\n");
317
+					WARN("Unexpected EOF occurred while performing"
318
+							" TLS accept\n");
387 319
 				} else {
388 320
 					ERR("IO error: (%d) %s\n", errno, strerror(errno));
389 321
 				}
... ...
@@ -395,19 +327,26 @@ static int tls_accept(struct tcp_connection *c, int* error)
395 327
 			goto err;
396 328
 		}
397 329
 	}
398
-	return 0;
330
+	return ret;
399 331
 err:
400 332
 	return -1;
401 333
 }
402 334
 
403 335
 
404
-/*
405
- * wrapper around SSL_connect, returns 0 on success, -1 on error 
336
+/** wrapper around SSL_connect, usin SSL return convention.
337
+ * It will also log critical errors and certificate debugging info.
338
+ * @param c - tcp connection with tls (extra_data must be a filled
339
+ *            tcp_extra_data structure). The state must be S_TLS_CONNECTING.
340
+ * @param error  set to the error reason (SSL_ERROR_*).
341
+ * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL
342
+ *           connection was closed/shutdown. < 0 is also returned for
343
+ *           WANT_READ or WANT_WRITE 
344
+ *
406 345
  */
407 346
 static int tls_connect(struct tcp_connection *c, int* error)
408 347
 {
409 348
 	SSL *ssl;
410
-	int ret, err, ssl_err;
349
+	int ret, ssl_err;
411 350
 	X509* cert;
412 351
 	struct tls_extra_data* tls_c;
413 352
 
... ...
@@ -420,14 +359,15 @@ static int tls_connect(struct tcp_connection *c, int* error)
420 359
 	tls_c=(struct tls_extra_data*)c->extra_data;
421 360
 	ssl=tls_c->ssl;
422 361
 	
423
-	if (tls_c->state != S_TLS_CONNECTING) {
362
+	*error = SSL_ERROR_NONE;
363
+	if (unlikely(tls_c->state != S_TLS_CONNECTING)) {
424 364
 		BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state);
425 365
 		/* Not critical */
426
-		return 0;
366
+		goto err;
427 367
 	}
428 368
 	ret = SSL_connect(ssl);
429
-	if (ret == 1) {
430
-		DBG("TLS connect successuful\n");
369
+	if (unlikely(ret == 1)) {
370
+		DBG("TLS connect successful\n");
431 371
 		tls_c->state = S_TLS_ESTABLISHED;
432 372
 		LOG(tls_log, "tls_connect: new connection to %s:%d using %s %s %d\n", 
433 373
 		    ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
... ...
@@ -447,13 +387,13 @@ static int tls_connect(struct tcp_connection *c, int* error)
447 387
 			}
448 388
 			X509_free(cert);
449 389
 		} else {
450
-			     /* this should not happen, servers always present a cert */
451
-			LOG(tls_log, "tls_connect: server did not present a certificate\n");
390
+			/* this should not happen, servers always present a cert */
391
+			LOG(tls_log, "tls_connect: server did not "
392
+							"present a certificate\n");
452 393
 		}
453
-	} else {
454
-		err = SSL_get_error(ssl, ret);
455
-		if (error) *error = err;
456
-		switch (err) {
394
+	} else { /* 0 or < 0 */
395
+		*error = SSL_get_error(ssl, ret);
396
+		switch (*error) {
457 397
 		case SSL_ERROR_ZERO_RETURN:
458 398
 			DBG("TLS handshake failed cleanly\n");
459 399
 			goto err;
... ...
@@ -495,7 +435,7 @@ static int tls_connect(struct tcp_connection *c, int* error)
495 435
 			goto err;
496 436
 		}
497 437
 	}
498
-	return 0;
438
+	return ret;
499 439
 err:
500 440
 	return -1;
501 441
 }
... ...
@@ -578,86 +518,12 @@ static int tls_shutdown(struct tcp_connection *c)
578 518
 }
579 519
 
580 520
 
581
-/* "normal", return number of bytes written,  -1 on error/EOF & sets error
582
- * & c->state on EOF; 0 on want READ/WRITE
583
- * 
584
- * expects a set fd */
585
-static int tls_write(struct tcp_connection *c, const void *buf, size_t len, int* error)
586
-{
587
-	int ret, err, ssl_err;
588
-	SSL *ssl;
589
-	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
590
-
591
-	err = 0;
592
-	if (LOW_MEM_CONNECTED_TEST()){
593
-		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
594
-				" operation: %lu\n", shm_available());
595
-		ret=-1;
596
-		goto err;
597
-	}
598
-	ret = SSL_write(ssl, buf, len);
599
-	if (ret <= 0) {
600
-		err = SSL_get_error(ssl, ret);
601
-		switch (err) {
602
-		case SSL_ERROR_ZERO_RETURN:
603
-			DBG("TLS connection has been closed\n");
604
-			c->state = S_CONN_EOF;
605
-			ret = -1;
606
-			break;
607
-			
608
-		case SSL_ERROR_WANT_READ:
609
-			DBG("Need to get more data to finish TLS write\n");
610
-			ret = 0;
611
-			break;
612
-
613
-		case SSL_ERROR_WANT_WRITE:
614
-			DBG("Need to send more data to finish TLS write\n");
615
-			ret = 0;
616
-			break;
617
-			
618
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L /*0.9.7*/
619
-		case SSL_ERROR_WANT_CONNECT:
620
-		case SSL_ERROR_WANT_ACCEPT:
621
-			DBG("TLS not connected\n");
622
-			ret = -1;
623
-			break;
624
-#endif
625
-		case SSL_ERROR_WANT_X509_LOOKUP:
626
-			DBG("Application callback asked to be called again\n");
627
-			ret = 0;
628
-			break;
629
-			
630
-		case SSL_ERROR_SYSCALL:
631
-			TLS_ERR_RET(ssl_err, "tls_write:");
632
-			if (!ssl_err) {
633
-				if (ret == 0) {
634
-					WARN("Unexpected EOF occurred while performing TLS shutdown\n");
635
-					c->state = S_CONN_EOF;
636
-					ret = -1;
637
-				} else {
638
-					ERR("IO error: (%d) %s\n", errno, strerror(errno));
639
-				}
640
-			}
641
-			break;
642
-			
643
-		default:
644
-			TLS_ERR("SSL error:");
645
-			break;
646
-		}
647
-	}
648
-
649
-err:
650
-	if (error) *error = err;
651
-	return ret;
652
-}
653
-
654 521
 
655 522
 /*
656
- * Called when new tcp connection is accepted or connected, create ssl
657
- * data structures here, there is no need to acquire any lock, because the 
658
- * connection is being created by a new process and on other process has
659
- * access to it yet, this is called before adding the tcp_connection
660
- * structure into the hash 
523
+ * Called when new tcp connection is accepted or connected. It creates the ssl
524
+ * data structures. There is no need to acquire any lock, because when the
525
+ * connection is being created no other process has access to it yet
526
+ * (this is called before adding the tcp_connection structure into the hash) 
661 527
  */
662 528
 int tls_h_tcpconn_init(struct tcp_connection *c, int sock)
663 529
 {
... ...
@@ -686,6 +552,12 @@ void tls_h_tcpconn_clean(struct tcp_connection *c)
686 552
 		extra = (struct tls_extra_data*)c->extra_data;
687 553
 		SSL_free(extra->ssl);
688 554
 		extra->cfg->ref_count--;
555
+		if (extra->ct_wq)
556
+			tls_ct_wq_free(&extra->ct_wq);
557
+		if (extra->enc_rd_buf) {
558
+			shm_free(extra->enc_rd_buf);
559
+			extra->enc_rd_buf = 0;
560
+		}
689 561
 		shm_free(c->extra_data);
690 562
 		c->extra_data = 0;
691 563
 	}
... ...
@@ -697,333 +569,516 @@ void tls_h_tcpconn_clean(struct tcp_connection *c)
697 569
  */
698 570
 void tls_h_close(struct tcp_connection *c, int fd)
699 571
 {
700
-	     /*
701
-	      * runs within global tcp lock 
702
-	      */
703
-	DBG("Closing SSL connection\n");
704
-	if (c->extra_data) {
705
-		if (tls_update_fd(c, fd)==0)
706
-			tls_shutdown(c); /* shudown only on succesfull set fd */
572
+	unsigned char rd_buf[TLS_RD_MBUF_SZ];
573
+	unsigned char wr_buf[TLS_WR_MBUF_SZ];
574
+	struct tls_mbuf rd, wr;
575
+	
576
+	/*
577
+	 * runs either within global tcp lock or after the connection has 
578
+	 * been "detached" and is unreachable from any other process.
579
+	 * Unfortunately when called via
580
+	 * tcpconn_put_destroy()+tcpconn_close_main_fd() the connection might
581
+	 * still be in a writer, so in this case locking is needed.
582
+	 */
583
+	DBG("Closing SSL connection %p\n", c->extra_data);
584
+	if (likely(c->extra_data)) {
585
+		lock_get(&c->write_lock);
586
+			if (unlikely(c->extra_data == 0)) {
587
+				/* changed in the meanwhile */
588
+				lock_release(&c->write_lock);
589
+				return;
590
+			}
591
+			tls_mbuf_init(&rd, rd_buf, sizeof(rd_buf));
592
+			tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf));
593
+			if (tls_set_mbufs(c, &rd, &wr)==0) {
594
+				tls_shutdown(c); /* shudown only on succesfull set fd */
595
+				/* write as much as possible and update wr.
596
+				 * Since this is a close, we don't want to queue the write
597
+				 * (if it can't write immediately, just fail silently)
598
+				 */
599
+				if (wr.used)
600
+					_tcpconn_write_nb(fd, c, (char*)wr.buf, wr.used);
601
+				/* we don't bother reading anything (we don't want to wait
602
+				on close) */
603
+			}
604
+		lock_release(&c->write_lock);
707 605
 	}
708 606
 }
709 607
 
710 608
 
711 609
 
712
-/*
713
- * This is shamelessly stolen tsend_stream from tsend.c 
714
- */
715
-/*
716
- * fixme: probably does not work correctly 
610
+/* generic tcpconn_{do,1st}_send() function pointer type */
611
+typedef int (*tcp_low_level_send_t)(int fd, struct tcp_connection *c,
612
+									char* buf, unsigned len,
613
+									snd_flags_t send_flags,
614
+									long* resp, int locked);
615
+
616
+
617
+
618
+/** tls generic send function.
619
+ * It is used by tls_do_send_f and tls_1st_send_f (which are wrappers
620
+ * arround it).
621
+ * WARNING: it must be called with c->write_lock held!
622
+ * @param c - tcp connection
623
+ * @param fd - valid file descriptor for the tcp connection
624
+ * @param buf - data
625
+ * @param len - data size
626
+ * @param send_flags
627
+ * @param resp - filled with a cmd. for tcp_main (@see tcpconn_do_send() for
628
+ *               more details)
629
+ * 
630
+ * @return >=0 on success, < 0 on error && * resp == CON_ERROR.
717 631
  */
718
-int tls_h_blocking_write(struct tcp_connection *c, int fd, const char *buf,
719
-			  unsigned int len)
632
+static int tls_generic_send(int fd, struct tcp_connection *c,
633
+						const char *buf, unsigned int len,
634
+						snd_flags_t send_flags, long* resp,
635
+						tcp_low_level_send_t tcp_do_send_f)
720 636
 {
721
-	int err, n, ticks, tout;
722
-	fd_set sel_set;
723
-	struct timeval timeout;
637
+	int n, offs;
638
+	SSL* ssl;
724 639
 	struct tls_extra_data* tls_c;
640
+	unsigned char wr_buf[TLS_WR_MBUF_SZ];
641
+	struct tls_mbuf rd, wr;
642
+	int ssl_error;
725 643
 	
644
+	*resp = CONN_NOP;
726 645
 	n = 0;
727
-	if (tls_update_fd(c, fd) < 0) goto error;
728
-	tls_c=(struct tls_extra_data*)c->extra_data;
729
-again:
730
-	err = 0;
731
-	     /* first try  a "fast" write -- avoid the extra select call,
732
-	      * we might get lucky and not need it */
733
-	if (tls_c->state == S_TLS_CONNECTING) {
734
-		if (tls_connect(c, &err) < 0) goto error;
735
-		tout = tls_handshake_timeout;
736
-	} else if (tls_c->state == S_TLS_ACCEPTING) {
737
-		if (tls_accept(c, &err) < 0) goto error;
738
-		tout = tls_handshake_timeout;
646
+	offs = 0;
647
+	ssl_error = SSL_ERROR_NONE;
648
+	lock_get(&c->write_lock);
649
+	if (unlikely(tls_fix_connection(c) < 0))
650
+		goto error;
651
+	tls_c = (struct tls_extra_data*)c->extra_data;
652
+	ssl = tls_c->ssl;
653
+	/* clear text already queued (WANTS_READ) queue directly*/
654
+	if (unlikely(tls_write_wants_read(tls_c))) {
655
+		if (unlikely(tls_ct_wq_add(&tls_c->ct_wq, buf+offs, len -offs) < 0))
656
+				goto error_wq_full;
657
+		goto end;
658
+	}
659
+	tls_mbuf_init(&rd, 0, 0); /* no read */
660
+redo_wr:
661
+	tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf));
662
+	if (tls_set_mbufs(c, &rd, &wr) < 0)
663
+		goto error;
664
+	if (unlikely(tls_c->state == S_TLS_CONNECTING)) {
665
+		n = tls_connect(c, &ssl_error);
666
+		if (unlikely(n>=1)) {
667
+			n = SSL_write(ssl, buf + offs, len - offs);
668
+			if (unlikely(n <= 0))
669
+				ssl_error = SSL_get_error(ssl, n);
670
+		}
671
+	} else if (unlikely(tls_c->state == S_TLS_ACCEPTING)) {
672
+		n = tls_accept(c, &ssl_error);
673
+		if (unlikely(n>=1)) {
674
+			n = SSL_write(ssl, buf + offs, len - offs);
675
+			if (unlikely(n <= 0))
676
+				ssl_error = SSL_get_error(ssl, n);
677
+		}
739 678
 	} else {
740
-		n = tls_write(c, buf, len, &err);
741
-		if (n < 0) {
742
-			DBG("tls_write error %d (ssl %d)\n", n, err);
743
-			goto error;
744
-		} else if (n < len) {
745
-			     /* not all the contents was written => try again w/ the rest
746
-			      * (possible when SSL_MODE_ENABLE_PARTIAL_WRITE is set)
747
-			      */
748
-			DBG("%ld bytes still need to be written\n", 
749
-				(long)(len - n));
750
-			buf += n; 
751
-			len -= n;
752
-		} else {
753
-			     /* succesfull write */
754
-			DBG("write finished, %d bytes written\n", n);
755
-			goto end;
679
+		n = SSL_write(ssl, buf + offs, len - offs);
680
+		if (unlikely(n <= 0))
681
+			ssl_error = SSL_get_error(ssl, n);
682
+	}
683
+	if (wr.used ) {
684
+		/* something was written */
685
+		if (unlikely( n < (len -offs)  && n >= 0)) {
686
+			/* if partial tls write, don't force close the tcp connection */
687
+			tcpconn_set_send_flags(c, send_flags); /* set the original flags */
688
+			send_flags.f &= ~SND_F_CON_CLOSE;
689
+		}
690
+		if (unlikely(tcp_do_send_f(fd, c, (char*)wr.buf, wr.used,
691
+											send_flags, resp, 1) < 0)){
692
+			tls_set_mbufs(c, 0, 0);
693
+			goto error_send;
756 694
 		}
757
-		tout = tls_send_timeout;
758 695
 	}
759
-
760
-	while(1) {
761
-		FD_ZERO(&sel_set);
762
-		FD_SET(fd, &sel_set);
763
-		timeout.tv_sec = tout;
764
-		timeout.tv_usec = 0;
765
-		ticks = get_ticks();
766
-
767
-		     /* blocking part, wait until we can write again on the fd */
768
-		switch(err){
769
-			case 0:
770
-			case SSL_ERROR_WANT_WRITE:
771
-				n = select(fd + 1, 0, &sel_set ,0 , &timeout);
696
+	/* check for possible ssl errors */
697
+	if (unlikely(n <= 0)){
698
+		switch(ssl_error) {
699
+			case SSL_ERROR_NONE:
772 700
 				break;
773
-
701
+			case SSL_ERROR_ZERO_RETURN:
702
+				/* SSL EOF */
703
+				goto ssl_eof;
774 704
 			case SSL_ERROR_WANT_READ:
775
-				n = select(fd + 1, &sel_set, 0 ,0 , &timeout);
776
-				break;
777
-
778
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L /*0.9.7*/
779
-			case SSL_ERROR_WANT_ACCEPT:
780
-#endif
781
-			case SSL_ERROR_WANT_CONNECT:
782
-				DBG("re-trying accept/connect\n");
783
-				goto again;
784
-
705
+				/* queue write buffer */
706
+				if (unlikely(tls_ct_wq_add(&tls_c->ct_wq, buf+offs, len -offs)
707
+								< 0))
708
+					goto error_wq_full;
709
+				tls_c->flags |= F_TLS_CON_WR_WANTS_RD;
710
+				break; /* or goto end */
711
+			case SSL_ERROR_WANT_WRITE:
712
+				/*  error, no record fits in the buffer */
713
+				BUG("write buffer too small (%d/%d bytes)\n",
714
+						wr.used, wr.size);
715
+				goto bug;
716
+			case SSL_ERROR_SYSCALL:
785 717
 			default:
786
-				BUG("Unhandled SSL error %d\n", err);
787
-				goto error;
788
-		}
789
-		if (n < 0) {
790
-			if (errno == EINTR) continue;/* just a signal */
791
-			ERR("Select failed:"
792
-			    " (%d) %s\n", errno, strerror(errno));
793
-			goto error;
794
-		}
795
-		if (n == 0) {
796
-			     /* timeout, make sure the interval really expired */
797
-			if ((get_ticks() - ticks) >= tout) {
798
-				ERR("Peer not "
799
-				    " responding after %d s=> timeout (state %d) \n",
800
-				    tout, c->state);
801
-				goto error;
802
-			}
803
-		}
804
-		if (FD_ISSET(fd, &sel_set)) {
805
-			     /* we can write again */
806
-			DBG("Ready to read/write again\n");
807
-			goto again;
718
+				BUG("unexpected SSL error %d\n", ssl_error);
719
+				goto bug;
808 720
 		}
721
+	} else if (unlikely(n < (len - offs))) {
722
+		/* partial ssl write => retry with the rest */
723
+		offs += n;
724
+		goto redo_wr;
809 725
 	}
810
-	
811
- error:
726
+	tls_set_mbufs(c, 0, 0);
727
+end:
728
+	lock_release(&c->write_lock);
729
+	return len;
730
+error:
731
+error_send:
732
+error_wq_full:
733
+bug:
734
+	tls_set_mbufs(c, 0, 0);
735
+	lock_release(&c->write_lock);
736
+	*resp = CONN_ERROR;
737
+	return -1;
738
+ssl_eof:
739
+	c->state = S_CONN_EOF;
740
+	lock_release(&c->write_lock);
741
+	DBG("TLS connection has been closed\n");
742
+	*resp = CONN_EOF;
812 743
 	return -1;
813
- end:
814
-	return n;
815 744
 }
816 745
 
817 746
 
818 747
 
819
-#if 0  /* not used for now */
820
-/* nonblocking version */
821
-int tls_h_nonblocking_write(struct tcp_connection *c, int fd, const char *buf,
822
-			  unsigned int len)
748
+/** tls do_send callback.
749
+ * It is called for all sends (by the tcp send code), except the first send
750
+ * on an async connection (@see tls_1st_send).
751
+ * WARNING: it must be called with c->write_lock held!
752
+ * @param c - tcp connection
753
+ * @param fd - valid file descriptor for the tcp connection
754
+ * @param buf - data
755
+ * @param len - data size
756
+ * @param send_flags
757
+ * @param resp - filled with a cmd. for tcp_main (@see tcpconn_do_send() for
758
+ *               more details)
759
+ * 
760
+ * @return >=0 on success, < 0 on error && * resp == CON_ERROR.
761
+ */
762
+int tls_do_send_f(int fd, struct tcp_connection *c,
763
+						const char *buf, unsigned int len,
764
+						snd_flags_t send_flags, long* resp)
823 765
 {
824
-	int err, n;
825
-	struct tls_extra_data* tls_c;
826
-	
827
-	n = 0;
828
-	if (tls_update_fd(c, fd) < 0) goto error;
829
-	tls_c=(struct tls_extra_data*)c->extra_data;
830
-again:
831
-	err = 0;
832
-	if (tls_c->state == S_TLS_CONNECTING) {
833
-		if (tls_connect(c, &err) < 0) goto error;
834
-	} else if (tls_c->state == S_TLS_ACCEPTING) {
835
-		if (tls_accept(c, &err) < 0) goto error;
836
-	}
837
-	if (tls_c->state!=S_TLS_CONNECTING && tls_c->state!=S_TLS_ACCEPTING){
838
-		n = tls_write(c, buf, len, &err);
839
-		if (n < 0) {
840
-			DBG("tls_write error %d (ssl %d)\n", n, err);
841
-			goto error;
842
-		} else if (n==len){
843
-			goto end;
844
-		}else{
845
-			DBG("%ld bytes still need to be written\n", 
846
-				(long)(len - n));
847
-		}
848
-	}else
849
-		n=0; /* no bytes written */
766
+	return tls_generic_send(fd, c, buf, len, send_flags, resp,
767
+							tcpconn_do_send);
768
+}
850 769
 
851
-		switch(err){
852
-			/* TODO: set some flag: WANT_READ, WANT_WRITE */
853
-			case 0:
854
-			case SSL_ERROR_WANT_WRITE:
855
-				break;
856
-			case SSL_ERROR_WANT_READ:
857
-				break;
858
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L /*0.9.7*/
859
-			case SSL_ERROR_WANT_ACCEPT:
860
-#endif
861
-			case SSL_ERROR_WANT_CONNECT:
862
-				DBG("re-trying accept/connect\n");
863
-				break;
864
-			default:
865
-				BUG("Unhandled SSL error %d\n", err);
866
-				goto error;
867
-		}
868
-	
869
-error:
870
-	return -1;
871
-end:
872
-	return n;
770
+
771
+
772
+/** tls 1st_send callback.
773
+ * It is called for the first send on an async tcp connection
774
+ * (should be non-blocking).
775
+ * WARNING: it must be called with c->write_lock held!
776
+ * @param c - tcp connection
777
+ * @param fd - valid file descriptor for the tcp connection
778
+ * @param buf - data
779
+ * @param len - data size
780
+ * @param send_flags
781
+ * @param resp - filled with a cmd. for tcp_main (@see tcpconn_1st_send() for
782
+ *               more details)
783
+ * 
784
+ * @return >=0 on success, < 0 on error && * resp == CON_ERROR.
785
+ */
786
+int tls_1st_send_f(int fd, struct tcp_connection *c,
787
+						const char *buf, unsigned int len,
788
+						snd_flags_t send_flags, long* resp)
789
+{
790
+	return tls_generic_send(fd, c, buf, len, send_flags, resp,
791
+							tcpconn_1st_send);
873 792
 }
874
-#endif
875 793
 
876 794
 
877
-/*
878
- * called only when a connection is in S_TLS_ESTABLISHED, we do not have to
879
- * care about accepting or connecting here. Each modification of ssl data
880
- * structures has to be protected, another process might ask for the same
881
- * connection and attempt write to it which would result in updating the
882
- * ssl structures 
795
+
796
+/** tls read.
797
+ * Each modification of ssl data structures has to be protected, another process * might ask for the same connection and attempt write to it which would
798
+ * result in updating the ssl structures 
799
+ * WARNING: must be called whic c->write_lock _unlocked_.
800
+ * @param c - tcp connection pointer. The following flags might be set:
801
+ * @param flags - value/result:
802
+ *                     input: RD_CONN_FORCE_EOF  - force EOF after the first
803
+ *                            successful read (bytes_read >=0 )
804
+ *                     output: RD_CONN_SHORT_READ if the read exhausted
805
+ *                              all the bytes in the socket read buffer.
806
+ *                             RD_CONN_EOF if EOF detected (0 bytes read)
807
+ *                              or forced via RD_CONN_FORCE_EOF.
808
+ *                             RD_CONN_RETRY_READ  if this function should
809
+ *                              be called again (e.g. has some data
810
+ *                              buffered internally that didn't fit in
811
+ *                              tcp_req).
812
+ *                     Note: RD_CONN_SHORT_READ & RD_CONN_EOF must be cleared
813
+ *                           before calling this function.
814
+ * used to signal a seen or "forced" EOF on the
815
+ *     connection (when it is known that no more data will come after the
816
+ *     current socket buffer is emptied )=> return/signal EOF on the first
817
+ *     short read (=> don't use it on POLLPRI, as OOB data will cause short
818
+ *      reads even if there are still remaining bytes in the socket buffer)
819
+ * return number of bytes read, 0 on EOF or -1 on error,
820
+ * on EOF it also sets c->state to S_CONN_EOF.
821
+ * sets also r->error.
822
+ * @return bytes decrypted on success, -1 on error (it also sets some
823
+ *         tcp connection flags)
883 824
  */
884
-int tls_h_read(struct tcp_connection * c)
825
+int tls_read_f(struct tcp_connection* c, int* flags)
885 826
 {
886 827
 	struct tcp_req* r;
887
-	int bytes_free, bytes_read, err, ssl_err;
828
+	int bytes_free, bytes_read, read_size, ssl_error, ssl_read;
888 829
 	SSL* ssl;
889
-
830
+	unsigned char rd_buf[TLS_RD_MBUF_SZ];
831
+	unsigned char wr_buf[TLS_WR_MBUF_SZ];
832
+	struct tls_mbuf rd, wr;
833
+	struct tls_extra_data* tls_c;
834
+	struct tls_rd_buf* enc_rd_buf;
835
+	int n, flush_flags;
836
+	
837
+	ssl_read = 0;
890 838
 	r = &c->req;
839
+	enc_rd_buf = 0;
840
+	*flags &= ~RD_CONN_REPEAT_READ;
841
+	if (unlikely(c->extra_data == 0)) {
842
+		/* not yet fully init => lock & intialize */
843
+		lock_get(&c->write_lock);
844
+			if (tls_fix_connection(c) < 0) {
845
+				lock_release(&c->write_lock);
846
+				return -1;
847
+			}
848
+		lock_release(&c->write_lock);
849
+	} else if (unlikely(LOW_MEM_CONNECTED_TEST())){
850
+		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
851
+			" operation: %lu\n", shm_available());
852
+		return -1;
853
+	}
854
+	/* here it's safe to use c->extra_data in read-only mode.
855
+	   If it's != 0 is changed only on destroy. It's not possible to have
856
+	   parallel reads.*/
857
+	tls_c = c->extra_data;
858
+redo_read:
891 859
 	bytes_free = c->req.b_size - (int)(r->pos - r->buf);
892
-	
893
-	if (bytes_free == 0) {
860
+	if (unlikely(bytes_free == 0)) {
894 861
 		ERR("Buffer overrun, dropping\n");
895 862
 		r->error = TCP_REQ_OVERRUN;
896 863
 		return -1;
897 864
 	}
898
-	if (LOW_MEM_CONNECTED_TEST()){
899
-		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
900
-				" operation: %lu\n", shm_available());
901
-		return -1;
865
+	/* if data queued from a previous read(), use it (don't perform
866
+	 * a real read()).
867
+	*/
868
+	if (unlikely(tls_c->enc_rd_buf)) {
869
+		/* use queued data */
870
+		/* safe to use without locks, because only read changes it and 
871
+		   there can't be parallel reads on the same connection */
872
+		enc_rd_buf = tls_c->enc_rd_buf;
873
+		tls_c->enc_rd_buf = 0;
874
+		tls_mbuf_init(&rd, enc_rd_buf->buf + enc_rd_buf->pos,
875
+						enc_rd_buf->size - enc_rd_buf->pos);
876
+		rd.used = enc_rd_buf->size - enc_rd_buf->pos;
877
+	} else {
878
+		/* if we were using using queued data before, free & reset the
879
+			the queued read data before performing the real read() */
880
+		if (unlikely(enc_rd_buf)) {
881
+			shm_free(enc_rd_buf);
882
+			enc_rd_buf = 0;
883
+		}
884
+		/* real read() */
885
+		tls_mbuf_init(&rd, rd_buf, sizeof(rd_buf));
886
+		/* read() only if no SSL_PENDING (bytes available for immediate
887
+		   read inside the SSL context */
888
+		if (likely(!(tls_c->flags & F_TLS_CON_SSL_PENDING))) {
889
+			/* don't read more then the free bytes in the tcp req buffer */
890
+			read_size = MIN_unsigned(rd.size, bytes_free);
891
+			bytes_read = tcp_read_data(c->fd, c, (char*)rd.buf, read_size,
892
+										flags);
893
+			if (unlikely(bytes_read <= 0)) {
894
+				if (likely(bytes_read == 0))
895
+					goto end;
896
+				else
897
+					goto error;
898
+			}
899
+			rd.used = bytes_read;
900
+		}
902 901
 	}
903
-	     /* we have to avoid to run in the same time 
904
-	      * with a tls_write because of the 
905
-	      * update_fd stuff  (we don't want a write
906
-	      * stealing the fd under us or vice versa)
907
-	      * => lock on con->write_lock (ugly hack) */
902
+	
903
+	tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf));
904
+	ssl_error = SSL_ERROR_NONE;
905
+	
906
+	/* we have to avoid to run in the same time 
907
+	 * with a tls_write because of the
908
+	 * update bio stuff  (we don't want a write
909
+	 * stealing the wbio or rbio under us or vice versa)
910
+	 * => lock on con->write_lock (ugly hack) */
908 911
 	lock_get(&c->write_lock);
909
-	if (tls_update_fd(c, c->fd) != 0) {
910
-		     /* error */
911
-		lock_release(&c->write_lock);
912
-		return -1;
913
-	}
914
-	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
915
-	bytes_read = SSL_read(ssl, r->pos, bytes_free);
912
+		tls_set_mbufs(c, &rd, &wr);
913
+		ssl = tls_c->ssl;
914
+		n = 0;
915
+		if (unlikely(tls_write_wants_read(tls_c) &&
916
+						!(*flags & RD_CONN_EOF))) {
917
+			DBG("tls write on read (WRITE_WANTS_READ)\n");
918
+			n = tls_ct_wq_flush(ssl, &tls_c->ct_wq, &flush_flags,
919
+								&ssl_error);
920
+			if (unlikely(n < 0 )) {
921
+				tls_set_mbufs(c, 0, 0);
922
+				lock_release(&c->write_lock);
923
+				ERR("write flush error (%d)\n", n);
924
+				goto error;
925
+			}
926
+			if (likely(flush_flags & F_BUFQ_EMPTY))
927
+				tls_c->flags &= ~F_TLS_CON_WR_WANTS_RD;
928
+		}
929
+		if (likely((rd.pos != rd.used ||
930
+						(tls_c->flags & F_TLS_CON_SSL_PENDING)) &&
931
+					ssl_error == SSL_ERROR_NONE)) {
932
+			/* reset the SSL_PENDING flag */
933
+			tls_c->flags &= ~F_TLS_CON_SSL_PENDING;
934
+			if (unlikely(tls_c->state == S_TLS_CONNECTING)) {
935
+				n = tls_connect(c, &ssl_error);
936
+				if (unlikely(n>=1)) {
937
+					n = SSL_read(ssl, r->pos, bytes_free);
938
+				} else
939
+					goto ssl_read_skipped;
940
+			} else if (unlikely(tls_c->state == S_TLS_ACCEPTING)) {
941
+				n = tls_accept(c, &ssl_error);
942
+				if (unlikely(n>=1)) {
943
+					n = SSL_read(ssl, r->pos, bytes_free);
944
+				} else
945
+					goto ssl_read_skipped;
946
+			} else {
947
+				/* if bytes in then decrypt read buffer into tcpconn req.
948
+				   buffer */
949
+				n = SSL_read(ssl, r->pos, bytes_free);
950
+			}
951
+			if (unlikely(n <= 0)) {
952
+				ssl_error = SSL_get_error(ssl, n);
953
+				/*  errors handled below, outside the lock */
954
+			} else {
955
+				ssl_error = SSL_ERROR_NONE;
956
+				r->pos += n;
957
+				ssl_read += n;
958
+				if (unlikely(SSL_pending(ssl)>0)) {
959
+					tls_c->flags |= F_TLS_CON_SSL_PENDING;
960
+					*flags |= RD_CONN_REPEAT_READ;
961
+				}
962
+			}
963
+ssl_read_skipped:
964
+			;
965
+		}
966
+		if (unlikely(wr.used != 0 && ssl_error != SSL_ERROR_ZERO_RETURN)) {
967
+			/* something was written and it's not ssl EOF*/
968
+			if (unlikely(tcpconn_send_unsafe(c->fd, c, (char*)wr.buf,
969
+											wr.used, c->send_flags) < 0)) {
970
+				tls_set_mbufs(c, 0, 0);
971
+				lock_release(&c->write_lock);
972
+				goto error_send;
973
+			}
974
+		}
975
+		/* quickly catch bugs: segfault if accessed and not set */
976
+		tls_set_mbufs(c, 0, 0);
916 977
 	lock_release(&c->write_lock);
917
-	
918
-	if (bytes_read <= 0) {
919
-		err = SSL_get_error(ssl, bytes_read);
920
-		switch(err){
978
+	switch(ssl_error) {
979
+		case SSL_ERROR_NONE:
980
+			break;
921 981
 		case SSL_ERROR_ZERO_RETURN:
922
-			     /* tls connection has been closed */
923
-			DBG("tls_read: eof\n");
924