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