tls_ct_wrq.c

Go to the documentation of this file.
00001 /* 
00002  * Copyright (C) 2010 iptelorg GmbH
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00026 /*
00027  * History:
00028  * --------
00029  *  2010-03-31  initial version (andrei)
00030 */
00031 
00032 #include "tls_ct_wrq.h"
00033 #include "tls_cfg.h"
00034 #include "tls_server.h"
00035 #include "../../atomic_ops.h"
00036 #include "../../mem/shm_mem.h"
00037 #include <openssl/err.h>
00038 #include <openssl/ssl.h>
00039 
00040 
00041 atomic_t* tls_total_ct_wq; /* total clear text bytes queued for a future
00042                                                           SSL_write() (due to renegotiations/
00043                                                           SSL_WRITE_WANTS_READ ).*/
00044 
00045 
00046 
00051 int tls_ct_wq_init()
00052 {
00053         tls_total_ct_wq = shm_malloc(sizeof(*tls_total_ct_wq));
00054         if (unlikely(tls_total_ct_wq == 0))
00055                 return -1;
00056         atomic_set(tls_total_ct_wq, 0);
00057         return 0;
00058 }
00059 
00060 
00061 
00065 void tls_ct_wq_destroy()
00066 {
00067         if (tls_total_ct_wq) {
00068                 shm_free(tls_total_ct_wq);
00069                 tls_total_ct_wq = 0;
00070         }
00071 }
00072 
00073 
00074 
00079 unsigned int tls_ct_wq_total_bytes()
00080 {
00081         return (unsigned)atomic_get(tls_total_ct_wq);
00082 }
00083 
00084 
00085 
00097 static int ssl_flush(void* tcp_c, void* error, const void* buf, unsigned size)
00098 {
00099         int n;
00100         int ssl_error;
00101         struct tls_extra_data* tls_c;
00102         SSL* ssl;
00103         
00104         tls_c = ((struct tcp_connection*)tcp_c)->extra_data;
00105         ssl = tls_c->ssl;
00106         ssl_error = SSL_ERROR_NONE;
00107         if (unlikely(tls_c->state == S_TLS_CONNECTING)) {
00108                 n = tls_connect(tcp_c, &ssl_error);
00109                 if (unlikely(n>=1)) {
00110                         n = SSL_write(ssl, buf, size);
00111                         if (unlikely(n <= 0))
00112                                 ssl_error = SSL_get_error(ssl, n);
00113                 }
00114         } else if (unlikely(tls_c->state == S_TLS_ACCEPTING)) {
00115                 n = tls_accept(tcp_c, &ssl_error);
00116                 if (unlikely(n>=1)) {
00117                         n = SSL_write(ssl, buf, size);
00118                         if (unlikely(n <= 0))
00119                                 ssl_error = SSL_get_error(ssl, n);
00120                 }
00121         } else {
00122                 n = SSL_write(ssl, buf, size);
00123                 if (unlikely(n <= 0))
00124                         ssl_error = SSL_get_error(ssl, n);
00125         }
00126         
00127         *(long*)error = ssl_error;
00128         return n;
00129 }
00130 
00131 
00132 
00145 int tls_ct_wq_flush(struct tcp_connection* c, tls_ct_q** ct_q,
00146                                         int* flags, int* ssl_err)
00147 {
00148         int ret;
00149         long error;
00150         
00151         error = SSL_ERROR_NONE;
00152         ret = tls_ct_q_flush(ct_q,  flags, ssl_flush, c, &error);
00153         *ssl_err = (int)error;
00154         if (likely(ret > 0))
00155                 atomic_add(tls_total_ct_wq, -ret);
00156         return ret;
00157 }
00158 
00159 
00160 
00173 int tls_ct_wq_add(tls_ct_q** ct_q, const void* data, unsigned int size)
00174 {
00175         int ret;
00176         
00177         if (unlikely( (*ct_q && (((*ct_q)->queued + size) >
00178                                                 cfg_get(tls, tls_cfg, con_ct_wq_max))) ||
00179                                 (atomic_get(tls_total_ct_wq) + size) >
00180                                                 cfg_get(tls, tls_cfg, ct_wq_max))) {
00181                 return -2;
00182         }
00183         ret = tls_ct_q_add(ct_q, data, size,
00184                                                 cfg_get(tls, tls_cfg, ct_wq_blk_size));
00185         if (likely(ret >= 0))
00186                 atomic_add(tls_total_ct_wq, size);
00187         return ret;
00188 }
00189 
00190 
00191 
00199 unsigned int tls_ct_wq_free(tls_ct_q** ct_q)
00200 {
00201         unsigned int ret;
00202         
00203         if (likely((ret = tls_ct_q_destroy(ct_q)) > 0))
00204                 atomic_add(tls_total_ct_wq, -ret);
00205         return ret;
00206 }
00207 
00208 
00209 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */