Changeset: 1b5481acefab for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1b5481acefab
Modified Files:
        clients/mapilib/mapi.c
        common/utils/mcrypt.c
        monetdb5/modules/mal/mal_mapi.c
Branch: protocol
Log Message:

Allow both client/server to support both protocol 9 and 10, and add some 
pseudocode for future implementation.


diffs (212 lines):

diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c
--- a/clients/mapilib/mapi.c
+++ b/clients/mapilib/mapi.c
@@ -2193,6 +2193,12 @@ mapi_destroy(Mapi mid)
        return MOK;
 }
 
+typedef enum {
+       prot9 = 1,
+       prot10 = 2,
+       prot10compressed = 3,
+} protocol_version;
+
 /* (Re-)establish a connection with the server. */
 MapiMsg
 mapi_reconnect(Mapi mid)
@@ -2207,6 +2213,7 @@ mapi_reconnect(Mapi mid)
        char *server;
        char *protover;
        char *rest;
+       protocol_version prot_version = prot9;
 
        if (mid->connected)
                close_connection(mid);
@@ -2595,7 +2602,7 @@ mapi_reconnect(Mapi mid)
                char **algs = algsv;
                char *p;
 
-               /* rBuCQ9WTn3:mserver:9:RIPEMD160,SHA256,SHA1,MD5:LIT:SHA1: */
+               /* 
rBuCQ9WTn3:mserver:9:RIPEMD160,SHA256,SHA1,MD5,PROT10,PROT10COMPRESSED:LIT:SHA1:
 */
 
                if (mid->username == NULL || mid->password == NULL) {
                        mapi_setError(mid, "username and password must be set",
@@ -2620,6 +2627,21 @@ mapi_reconnect(Mapi mid)
                        *hash = '\0';
                        rest = hash + 1;
                }
+
+#ifdef HAVE_LIBSNAPPY
+               if (strstr(hashes, "PROT10COMPRESSED")) {
+                       // both server and client support compressed protocol 
10; use compressed version 
+                       prot_version = prot10compressed;
+               } else
+#endif
+               if (strstr(hashes, "PROT10")) {
+                       // both server and client support protocol 10; use 
protocol 10
+                       prot_version = prot10;
+               } else {
+                       // connecting to old server; use protocol 9
+                       prot_version = prot9;
+               }
+
                /* in rest now should be the byte order of the server */
                byteo = rest;
                hash = strchr(byteo, ':');
@@ -2705,20 +2727,37 @@ mapi_reconnect(Mapi mid)
 
                /* note: if we make the database field an empty string, it
                 * means we want the default.  However, it *should* be there. */
-               if (snprintf(buf, BLOCK, "%s:%s:%s:%s:%s:\n",
-#ifdef WORDS_BIGENDIAN
-                            "BIG",
-#else
-                            "LIT",
-#endif
-                            mid->username, hash, mid->language,
-                            mid->database == NULL ? "" : mid->database) >= 
BLOCK) {;
-                       mapi_setError(mid, "combination of database name and 
user name too long", "mapi_reconnect", MERROR);
-                       free(hash);
-                       close_connection(mid);
-                       return mid->error;
+               {
+                       int retval;
+                       if (prot_version == prot10 || prot_version == 
prot10compressed) {
+                               // if we are using protocol 10, we have to send 
either PROT10/PROT10COMPRESSED to the server
+                               // so the server knows which protocol to use
+                               retval = snprintf(buf, BLOCK, 
"%s:%s:%s:%s:%s:%s:\n",
+       #ifdef WORDS_BIGENDIAN
+                                    "BIG",
+       #else
+                                    "LIT",
+       #endif
+                                    mid->username, hash, mid->language,
+                                    mid->database == NULL ? "" : mid->database,
+                                    prot_version == prot10 ? "PROT10" : 
"PROT10COMPRESSED");
+                       } else {
+                               retval = snprintf(buf, BLOCK, 
"%s:%s:%s:%s:%s:\n",
+       #ifdef WORDS_BIGENDIAN
+                                    "BIG",
+       #else
+                                    "LIT",
+       #endif
+                                    mid->username, hash, mid->language,
+                                    mid->database == NULL ? "" : 
mid->database);
+                       }
+                       if (retval >= BLOCK) {;
+                               mapi_setError(mid, "combination of database 
name and user name too long", "mapi_reconnect", MERROR);
+                               free(hash);
+                               close_connection(mid);
+                               return mid->error;
+                       }
                }
-
                free(hash);
        } else {
                /* because the headers changed, and because it makes no sense to
@@ -2741,6 +2780,33 @@ mapi_reconnect(Mapi mid)
        mnstr_flush(mid->to);
        check_stream(mid, mid->to, "Could not send initial byte sequence", 
"mapi_reconnect", mid->error);
 
+       if (prot_version == prot10 || prot_version == prot10compressed) {
+               printf("Using protocol version %s.\n", prot_version == prot10  
? "PROT10" : "PROT10COMPRESSED");
+               // FIXME: destroy block streams and replace with appropriate 
streams
+#if 0
+               assert(isa_block_stream(mid->to));
+               assert(isa_block_stream(mid->from));
+
+               bs *bs_to = (bs*) mid->to;
+               bs *bs_from = (bs*) mid->from;
+
+               if (prot_version == prot10compressed) {
+#ifdef HAVE_LIBSNAPPY
+                       mid->to = compressed_stream(bs_to->s, 
COMPRESSION_SNAPPY);
+                       mid->from = compressed_stream(bs_from->s, 
COMPRESSION_SNAPPY);
+#else
+                       assert(0);
+#endif
+               } else {
+                       mid->to = byte_stream((bs_to->s);
+                       mid->from = byte_stream(bs_from->s);
+               }
+
+               close_stream(bs_to);
+               close_stream(bs_from);
+#endif
+       }
+
        /* consume the welcome message from the server */
        hdl = mapi_new_handle(mid);
        if (hdl == NULL) {
diff --git a/common/utils/mcrypt.c b/common/utils/mcrypt.c
--- a/common/utils/mcrypt.c
+++ b/common/utils/mcrypt.c
@@ -34,7 +34,13 @@ mcrypt_getHashAlgorithms(void)
         * Better/stronger/faster algorithms can be added in the future upon
         * desire.
         */
-       return strdup("RIPEMD160,SHA256,SHA1,MD5");
+#ifdef HAVE_LIBSNAPPY
+       // the server supports protocol 10 + compression
+       return strdup("RIPEMD160,SHA256,SHA1,MD5,PROT10,PROT10COMPR");
+#else
+       // the server only supports protocol 10
+       return strdup("RIPEMD160,SHA256,SHA1,MD5,PROT10");
+#endif
 }
 
 /**
diff --git a/monetdb5/modules/mal/mal_mapi.c b/monetdb5/modules/mal/mal_mapi.c
--- a/monetdb5/modules/mal/mal_mapi.c
+++ b/monetdb5/modules/mal/mal_mapi.c
@@ -146,8 +146,8 @@ doChallenge(void *data)
        algos = mcrypt_getHashAlgorithms();
        // FIXME: add the newproto flag to algos and rename to 'capabilities' 
to hide the crime
 
-       /* note that we claim to speak proto 9 here for hashed passwords */
-       mnstr_printf(fdout, "%s:mserver:10:%s:%s:%s:",
+       // send the challenge over the block stream
+       mnstr_printf(fdout, "%s:mserver:9:%s:%s:%s:",
                        challenge,
                        algos,
 #ifdef WORDS_BIGENDIAN
@@ -168,6 +168,39 @@ doChallenge(void *data)
                return;
        }
        buf[len] = 0;
+
+       if (strstr(buf, "PROT10")) {
+               // client requests switch to protocol 10
+               printf("Serving client with PROT10.\n");
+#if 0
+               // FIXME: destroy existing bstream and replace with byte or 
compressed stream stream
+               stream *client_in = NULL, *client_out = NULL;
+
+               close_stream(fdin);
+               close_stream(fdout);
+
+               if (!strstr(buf, "PROT10COMPRESSED")) {
+                       // uncompressed protocol 10
+                       client_in = byte_stream(((struct challengedata *) 
data)->in);
+                       client_out = byte_stream(((struct challengedata *) 
data)->out);
+               } else {
+#ifdef HAVE_LIBSNAPPY
+                       // compressed protocol 10
+                       client_in = compressed_stream(((struct challengedata *) 
data)->in, COMPRESSION_SNAPPY);
+                       client_out = compressed_stream(((struct challengedata 
*) data)->out, COMPRESSION_SNAPPY);
+#else
+                       // client requested compressed protocol, but server 
does not support it
+                       GDKsyserror("SERVERlisten:server does not support 
compressed protocol");
+#endif
+               }
+
+               if (client_null == NULL || client_out == NULL) {
+                       GDKsyserror("SERVERlisten:"MAL_MALLOC_FAIL);
+                       return;
+               }
+#endif
+       }
+
 #ifdef DEBUG_SERVER
        printf("mal_mapi:Client accepted %s\n", buf);
        fflush(stdout);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to