From 876f26819024fbb66a06afc2f6bdcf04c21316ea Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Mon, 28 Nov 2011 17:07:08 +0000 Subject: [PATCH] canl_io_read with ssl support --- emi.canl.canl-c/src/canl.c | 25 +++++++-- emi.canl.canl-c/src/canl_locl.h | 11 ++-- emi.canl.canl-c/src/canl_sample_client.c | 4 +- emi.canl.canl-c/src/canl_ssl.c | 92 ++++++++++++++++++++++++++++---- 4 files changed, 111 insertions(+), 21 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index de1fd44..deb9c99 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -432,6 +432,7 @@ size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; int b_recvd = 0; + errno = 0; if (!cc) { return -1; @@ -442,11 +443,19 @@ size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, err = EINVAL; goto end; } + + if (!buffer || !size) { + err = EINVAL; + update_error(glb_cc, err, "no memory to write into (canl_io_read)"); + return -1; + } - //TODO testing: read something without using openssl - b_recvd = recv(io_cc->sock, buffer, size, 0); - if (b_recvd == -1) + //read something using openssl + b_recvd = ssl_read(glb_cc, io_cc, buffer, size, timeout); + if (b_recvd == -1) { err = errno; //TODO check again + goto end; + } end: if (err) update_error(glb_cc, err, "can't read from connection" @@ -461,7 +470,7 @@ size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, int b_written = 0; int err = 0; errno = 0; - + if (!cc) { return -1; } @@ -471,7 +480,13 @@ size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, goto end; } - //read something using openssl + if (!buffer || !size) { + err = EINVAL; + update_error(glb_cc, err, "nothing to write (canl_io_write)"); + return -1; + } + + //write something using openssl b_written = ssl_write(glb_cc, io_cc, buffer, size, timeout); if (b_written == -1) { err = errno; //TODO check again diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 597d3ea..e0a6572 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -41,9 +41,14 @@ typedef struct _io_handler void reset_error (glb_ctx *cc, CANL_ERROR err_code); void set_error (glb_ctx *cc, CANL_ERROR err_code, const char *err_format, ...); -void update_error (glb_ctx *cc, CANL_ERROR err_code, const char *err_format, ...); +void update_error (glb_ctx *cc, CANL_ERROR err_code, + const char *err_format, ...); void free_hostent(struct hostent *h); //TODO is there some standard funcion to free hostent? -int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, - struct timeval *timeout); +int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, + struct timeval *timeout); int ssl_init(glb_ctx *cc, io_handler *io); int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout); +int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, + struct timeval *tout); +int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, + struct timeval *tout); diff --git a/emi.canl.canl-c/src/canl_sample_client.c b/emi.canl.canl-c/src/canl_sample_client.c index 2bd1cdf..479e2c7 100644 --- a/emi.canl.canl-c/src/canl_sample_client.c +++ b/emi.canl.canl-c/src/canl_sample_client.c @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) buf_len = strlen(buf) + 1; printf("Trying to send sth to the server\n"); - err = canl_io_write (my_ctx, my_io_h, buf, buf_len, NULL); + err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); if (err <= 0) { printf("can't write using ssl\n"); goto end; @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) printf("message \"%s\" sent successfully\n", buf); } - err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); + err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); if (err > 0) { buf[err] = '\0'; printf ("received: %s\n", buf); diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index d479336..9cb8f4c 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -57,21 +57,20 @@ int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout) io->s_ctx->bio_conn = NULL; //TODO ???? if ((err = do_ssl_connect(cc, io, timeout))) { - update_error(cc, err, ""); //TODO update error goto end; } /* if (post_connection_check(io->s_ctx->ssl_io)) { - opened = true; + opened = 1; (void)Send("0"); - return true; + return 1; } */ end: if (err) - update_error(cc, err, ""); //TODO update error + update_error(cc, err, "(ssl_connect)"); //TODO update error return err; } @@ -183,12 +182,13 @@ int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct tim int err = 0; int ret = 0, nwritten=0; const char *str; - int fd; + int fd = -1; time_t starttime, curtime; int do_continue = 0; int expected = 0; int locl_timeout; - int tout = 0; + int touted = 0; + int to = 0; // bool if (!io->s_ctx->ssl_io) { err = EINVAL; @@ -216,9 +216,12 @@ int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct tim curtime = starttime = time(NULL); if (timeout) { locl_timeout = timeout->tv_sec; + to = 1; } - else + else { + to = 0; locl_timeout = -1; + } do { ret = do_select(fd, starttime, locl_timeout, expected); @@ -251,9 +254,10 @@ int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct tim } } curtime = time(NULL); - locl_timeout = locl_timeout - (curtime - starttime); - if (locl_timeout != -1 && locl_timeout <= 0){ - tout = 1; + if (to) + locl_timeout = locl_timeout - (curtime - starttime); + if (to && locl_timeout <= 0){ + touted = 1; goto end; } } while (ret <= 0 && do_continue); @@ -264,7 +268,7 @@ end: update_error (cc, err, "Error during SSL write (ssl_write)"); return -1; } - if (tout){ + if (touted){ errno = err = ETIMEDOUT; update_error(cc, err, "Connection stuck during write: timeout reached (ssl_write)"); return -1; @@ -275,3 +279,69 @@ end: } return ret; } + +int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *tout) +{ + int err = 0; + int ret = 0, nwritten=0, ret2 = 0; + char *str; + int fd = -1; + time_t starttime, curtime; + int expected = 0, error = 0; + int timeout; + + if (!io->s_ctx->ssl_io) { + err = EINVAL; + goto end; + } + + if (!cc) { + return -1; + } + if (!io) { + err = EINVAL; + goto end; + } + + if (!buffer) { + err = EINVAL; //TODO really? + update_error(cc, err, "Not enough memory to read to (ssl_read)"); + errno = err; + return -1; + } + + fd = BIO_get_fd(SSL_get_rbio(io->s_ctx->ssl_io), NULL); + str = buffer;//TODO !!!!!! text.c_str(); + + curtime = starttime = time(NULL); + if (tout) { + timeout = tout->tv_sec; + } + else + timeout = -1; + do { + ret = do_select(fd, starttime, timeout, expected); + curtime = time(NULL); + + if (ret > 0) { + ret2 = SSL_read(io->s_ctx->ssl_io, str + nwritten, strlen(str) - nwritten); + + if (ret2 <= 0) { + expected = error = SSL_get_error(io->s_ctx->ssl_io, ret2); + } + } + } while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error)); + +end: + if (ret <= 0 || ret2 <= 0) { //TODO ret2 < 0 originally + err = -1; //TODO what to assign + if (timeout != -1 && (curtime - starttime >= timeout)){ + update_error(cc, ETIMEDOUT, "Connection stuck during read: timeout reached. (ssl_read)"); + } + else + update_error(cc, err, "Error during SSL read: (ssl_read)"); + } + else + err = ret2; + return err; +} -- 1.8.2.3