Changeset: d7ad96722fc6 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d7ad96722fc6
Modified Files:
        clients/mapilib/connect.c
        clients/mapilib/connect_openssl.c
        clients/mapilib/mapi_intern.h
        common/stream/openssl_stream.c
        common/stream/stream.h
Branch: monetdburl
Log Message:

It almost works


diffs (192 lines):

diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -469,7 +469,7 @@ mapi_handshake(Mapi mid)
        /* consume server challenge */
        len = mnstr_read_block(mid->from, buf, 1, sizeof(buf));
 
-       check_stream(mid, mid->from, "Connection terminated while starting", 
(mid->blk.eos = true, mid->error));
+       check_stream(mid, mid->from, "Connection terminated while starting 
handshake", (mid->blk.eos = true, mid->error));
 
        assert(len < sizeof(buf));
        buf[len] = 0;
diff --git a/clients/mapilib/connect_openssl.c 
b/clients/mapilib/connect_openssl.c
--- a/clients/mapilib/connect_openssl.c
+++ b/clients/mapilib/connect_openssl.c
@@ -181,18 +181,18 @@ wrap_tls(Mapi mid, SOCKET sock)
                return croak(mid, __func__, "BIO_up_ref bio");
        }
        // On error: free 'bio' twice
-       stream *rstream = openssl_stream(hostcolonport, bio);
+       stream *rstream = openssl_rstream(hostcolonport, bio);
        if (rstream == NULL || mnstr_errnr(rstream) != MNSTR_NO__ERROR) {
                BIO_free_all(bio); // drops first ref
                BIO_free_all(bio); // drops second ref
-               return croak(mid, __func__, "openssl_stream: %s", 
mnstr_peek_error(rstream));
+               return croak(mid, __func__, "openssl_rstream: %s", 
mnstr_peek_error(rstream));
        }
        // On error: free 'bio' and close 'rstream'.
-       stream *wstream = openssl_stream(hostcolonport, bio);
+       stream *wstream = openssl_wstream(hostcolonport, bio);
        if (wstream == NULL || mnstr_errnr(wstream) != MNSTR_NO__ERROR) {
                BIO_free_all(bio);
                mnstr_close(rstream);
-               return croak(mid, __func__, "openssl_stream: %s", 
mnstr_peek_error(wstream));
+               return croak(mid, __func__, "openssl_wstream: %s", 
mnstr_peek_error(wstream));
        }
        // On error: free 'rstream' and 'wstream'.
        msg = mapi_set_streams(mid, rstream, wstream);
diff --git a/clients/mapilib/mapi_intern.h b/clients/mapilib/mapi_intern.h
--- a/clients/mapilib/mapi_intern.h
+++ b/clients/mapilib/mapi_intern.h
@@ -271,8 +271,11 @@ void mapi_log_record(Mapi mid, const cha
                        if (msg != NULL) mapi_log_record(mid, msg);     \
                        mapi_log_record(mid, mnstr_peek_error(s));      \
                        mapi_log_record(mid, __func__);                 \
+                       if (mnstr_peek_error(s))                        \
+                               mapi_printError((mid), __func__, MTIMEOUT, "%s: 
%s", (msg), mnstr_peek_error(s)); \
+                       else                                            \
+                               mapi_printError((mid), __func__, MTIMEOUT, 
"%s", (msg)); \
                        close_connection(mid);                          \
-                       mapi_setError((mid), (msg), __func__, MTIMEOUT); \
                        return (e);                                     \
                }                                                       \
        } while (0)
diff --git a/common/stream/openssl_stream.c b/common/stream/openssl_stream.c
--- a/common/stream/openssl_stream.c
+++ b/common/stream/openssl_stream.c
@@ -13,11 +13,117 @@
 #include "stream_internal.h"
 
 #include <openssl/ssl.h>
+#include <openssl/err.h>
+
+static ssize_t ostream_read(stream *restrict s, void *restrict buf, size_t 
elmsize, size_t cnt);
+static ssize_t ostream_write(stream *restrict s, const void *restrict buf, 
size_t elmsize, size_t cnt);
+static void ostream_close(stream *s);
+static int ostream_flush(stream *s, mnstr_flush_level flush_level);
 
 stream *
-openssl_stream(const char *hostname, BIO *bio)
+openssl_rstream(const char *host_colon_port, BIO *bio)
+{
+       stream *s = openssl_wstream(host_colon_port, bio);
+       if (s != NULL)
+               s->readonly = true;
+       return s;
+}
+stream *
+openssl_wstream(const char *host_colon_port, BIO *bio)
+{
+       assert(bio);
+
+       stream *s = create_stream(host_colon_port);
+       if (s == NULL)
+               return NULL;
+
+       s->stream_data.p = bio;
+       s->readonly = false;
+       s->binary = true;
+       s->read = ostream_read;
+       s->write = ostream_write;
+       s->close = ostream_close;
+       s->flush = ostream_flush;
+
+       return s;
+}
+
+static ssize_t
+ostream_error(stream *s, mnstr_error_kind kind)
+{
+       unsigned long err = ERR_get_error();
+       const char *msg = ERR_reason_error_string(err);
+       mnstr_set_error(s, kind, "%s", msg);
+       return -1;
+}
+
+
+ssize_t
+ostream_read(stream *restrict s, void *restrict buf, size_t elmsize, size_t 
cnt)
 {
-       (void)bio;
-       mnstr_set_open_error(hostname, 0, "not implemented yet");
-       return NULL;
+       BIO *bio = (BIO*)s->stream_data.p;
+
+       char *start = (char*)buf;
+       size_t size = elmsize * cnt;
+       if (size == 0)
+               return 0;
+
+       // iterate in order to read a complete number of items
+       size_t pos = 0;
+       do {
+               size_t nread;
+               if (!BIO_read_ex(bio, start + pos, size - pos, &nread))
+                       return ostream_error(s, MNSTR_READ_ERROR);
+               if (nread == 0) {
+                       s->eof = 0;
+                       break;
+               }
+               pos += nread;
+
+               // adjust pos to the smallest multiple of elmsize.
+               // example 1: size=4 pos=7 (-7)%4=1, newsize=8
+               size_t delta = (-pos) % size;
+               if (size - pos > delta)
+                       size = pos + delta;
+       } while (pos < size);
+
+       return (ssize_t) (pos / elmsize);
 }
+
+ssize_t
+ostream_write(stream *restrict s, const void *restrict buf, size_t elmsize, 
size_t cnt)
+{
+       BIO *bio = (BIO*)s->stream_data.p;
+
+       char *start = (char*)buf;
+       size_t size = elmsize * cnt;
+       size_t pos = 0;
+       while (pos < size) {
+               size_t nwritten;
+               if (!BIO_write_ex(bio, start + pos, size - pos, &nwritten))
+                       return ostream_error(s, MNSTR_WRITE_ERROR);
+               if (nwritten == 0 && !BIO_should_retry(bio))
+                       break;
+               pos += nwritten;
+       }
+
+       return (ssize_t) (pos / elmsize);
+}
+
+void
+ostream_close(stream *s)
+{
+       BIO *bio = (BIO*) s->stream_data.p;
+       BIO_free(bio);
+       s->stream_data.p = NULL;
+}
+
+int
+ostream_flush(stream *s, mnstr_flush_level flush_level)
+{
+       (void)s;
+       (void)flush_level;
+       mnstr_set_error(s, MNSTR_WRITE_ERROR, "flush not implemented");
+       return -1;
+}
+
diff --git a/common/stream/stream.h b/common/stream/stream.h
--- a/common/stream/stream.h
+++ b/common/stream/stream.h
@@ -278,7 +278,8 @@ stream_export stream *mapi_request_downl
 stream_export stream *byte_counting_stream(stream *wrapped, uint64_t *counter);
 
 #ifdef HAVE_OPENSSL
-stream_export stream *openssl_stream(const char *hostname, BIO *bio);
+stream_export stream *openssl_rstream(const char *hostname, BIO *bio);
+stream_export stream *openssl_wstream(const char *hostname, BIO *bio);
 #endif
 
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to