canl_io_read with ssl support
authorMarcel Poul <marcel.poul@cern.ch>
Mon, 28 Nov 2011 17:07:08 +0000 (17:07 +0000)
committerMarcel Poul <marcel.poul@cern.ch>
Mon, 28 Nov 2011 17:07:08 +0000 (17:07 +0000)
emi.canl.canl-c/src/canl.c
emi.canl.canl-c/src/canl_locl.h
emi.canl.canl-c/src/canl_sample_client.c
emi.canl.canl-c/src/canl_ssl.c

index de1fd44..deb9c99 100644 (file)
@@ -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
index 597d3ea..e0a6572 100644 (file)
@@ -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);
index 2bd1cdf..479e2c7 100644 (file)
@@ -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);
index d479336..9cb8f4c 100644 (file)
@@ -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;
+}