diff options
Diffstat (limited to 'src/plugins/relay')
-rw-r--r-- | src/plugins/relay/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/plugins/relay/Makefile.am | 4 | ||||
-rw-r--r-- | src/plugins/relay/relay-config.c | 17 | ||||
-rw-r--r-- | src/plugins/relay/relay-config.h | 2 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-msg.c | 196 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-protocol.c | 38 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat.c | 4 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat.h | 1 |
8 files changed, 198 insertions, 71 deletions
diff --git a/src/plugins/relay/CMakeLists.txt b/src/plugins/relay/CMakeLists.txt index 451a54030..57e123074 100644 --- a/src/plugins/relay/CMakeLists.txt +++ b/src/plugins/relay/CMakeLists.txt @@ -43,13 +43,16 @@ set_target_properties(relay PROPERTIES PREFIX "") set(LINK_LIBS) -list(APPEND LINK_LIBS ${ZLIB_LIBRARY}) - include_directories(${GNUTLS_INCLUDE_PATH}) list(APPEND LINK_LIBS ${GNUTLS_LIBRARY}) list(APPEND LINK_LIBS ${GCRYPT_LDFLAGS}) +list(APPEND LINK_LIBS ${ZLIB_LIBRARY}) + +include_directories(${ZSTD_INCLUDE_DIRS}) +list(APPEND LINK_LIBS ${LIBZSTD_LDFLAGS}) + target_link_libraries(relay ${LINK_LIBS} coverage_config) install(TARGETS relay LIBRARY DESTINATION ${WEECHAT_LIBDIR}/plugins) diff --git a/src/plugins/relay/Makefile.am b/src/plugins/relay/Makefile.am index 1fcee124f..c84d09569 100644 --- a/src/plugins/relay/Makefile.am +++ b/src/plugins/relay/Makefile.am @@ -17,7 +17,7 @@ # along with WeeChat. If not, see <https://www.gnu.org/licenses/>. # -AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" $(ZLIB_CFLAGS) $(GCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" $(GCRYPT_CFLAGS) $(GNUTLS_CFLAGS) $(ZLIB_CFLAGS) $(ZSTD_CFLAGS) libdir = ${weechat_libdir}/plugins @@ -61,6 +61,6 @@ relay_la_SOURCES = relay.c \ weechat/relay-weechat-protocol.h relay_la_LDFLAGS = -module -no-undefined -relay_la_LIBADD = $(RELAY_LFLAGS) $(ZLIB_LFLAGS) $(GCRYPT_LFLAGS) $(GNUTLS_LFLAGS) +relay_la_LIBADD = $(RELAY_LFLAGS) $(GCRYPT_LFLAGS) $(GNUTLS_LFLAGS) $(ZLIB_LFLAGS) $(ZSTD_LFLAGS) EXTRA_DIST = CMakeLists.txt diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c index 790a38a53..3e85e182e 100644 --- a/src/plugins/relay/relay-config.c +++ b/src/plugins/relay/relay-config.c @@ -63,7 +63,7 @@ struct t_config_option *relay_config_network_allowed_ips; struct t_config_option *relay_config_network_auth_timeout; struct t_config_option *relay_config_network_bind_address; struct t_config_option *relay_config_network_clients_purge_delay; -struct t_config_option *relay_config_network_compression_level; +struct t_config_option *relay_config_network_compression; struct t_config_option *relay_config_network_ipv6; struct t_config_option *relay_config_network_max_clients; struct t_config_option *relay_config_network_nonce_size; @@ -1070,13 +1070,16 @@ relay_config_init () "clients immediately, -1 = never purge)"), NULL, -1, 60 * 24 * 30, "0", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - relay_config_network_compression_level = weechat_config_new_option ( + relay_config_network_compression = weechat_config_new_option ( relay_config_file, ptr_section, - "compression_level", "integer", - N_("compression level for packets sent to client with WeeChat protocol " - "(0 = disable compression, 1 = low compression ... 9 = best " - "compression)"), - NULL, 0, 9, "6", NULL, 0, + "compression", "integer", + N_("compression for packets sent to client with WeeChat " + "protocol: 0 = disable compression, 1 = low compression, fast " + "... 100 = best compression, slow; the value is a percentage " + "converted to 1-9 for zlib and 1-19 for zstd; " + "default value is 20 which is a sane default and offers good " + "compression and speed"), + NULL, 0, 100, "20", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); relay_config_network_ipv6 = weechat_config_new_option ( relay_config_file, ptr_section, diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h index d5b9c9372..41d970bf3 100644 --- a/src/plugins/relay/relay-config.h +++ b/src/plugins/relay/relay-config.h @@ -42,7 +42,7 @@ extern struct t_config_option *relay_config_network_allowed_ips; extern struct t_config_option *relay_config_network_auth_timeout; extern struct t_config_option *relay_config_network_bind_address; extern struct t_config_option *relay_config_network_clients_purge_delay; -extern struct t_config_option *relay_config_network_compression_level; +extern struct t_config_option *relay_config_network_compression; extern struct t_config_option *relay_config_network_ipv6; extern struct t_config_option *relay_config_network_max_clients; extern struct t_config_option *relay_config_network_nonce_size; diff --git a/src/plugins/relay/weechat/relay-weechat-msg.c b/src/plugins/relay/weechat/relay-weechat-msg.c index 7703604d1..b11c68b88 100644 --- a/src/plugins/relay/weechat/relay-weechat-msg.c +++ b/src/plugins/relay/weechat/relay-weechat-msg.c @@ -29,6 +29,7 @@ #include <errno.h> #include <arpa/inet.h> #include <zlib.h> +#include <zstd.h> #include "../../weechat-plugin.h" #include "../relay.h" @@ -1027,62 +1028,171 @@ relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg, } /* - * Sends a message. + * Compresses the message with zlib. + * + * Returns: + * 1: OK, message compressed and sent + * 0: error, no message sent */ -void -relay_weechat_msg_send (struct t_relay_client *client, - struct t_relay_weechat_msg *msg) +int +relay_weechat_msg_compress_zlib (struct t_relay_client *client, + struct t_relay_weechat_msg *msg) { + char raw_message[1024]; uint32_t size32; - char compression, raw_message[1024]; - int rc; Bytef *dest; uLongf dest_size; struct timeval tv1, tv2; long long time_diff; + int rc, rc_compress, compression, compression_level; + + rc = 0; + dest = NULL; + + dest_size = compressBound (msg->data_size - 5); + dest = malloc (dest_size + 5); + if (!dest) + goto error; + + /* convert % to zlib compression level (1-9) */ + compression = weechat_config_integer (relay_config_network_compression); + compression_level = (((compression - 1) * 9) / 100) + 1; + + gettimeofday (&tv1, NULL); + rc_compress = compress2 ( + dest + 5, + &dest_size, + (Bytef *)(msg->data + 5), + msg->data_size - 5, + compression_level); + gettimeofday (&tv2, NULL); + time_diff = weechat_util_timeval_diff (&tv1, &tv2); + if ((rc_compress != Z_OK) || ((int)dest_size + 5 >= msg->data_size)) + goto error; + + /* set size and compression flag */ + size32 = htonl ((uint32_t)(dest_size + 5)); + memcpy (dest, &size32, 4); + dest[4] = RELAY_WEECHAT_COMPRESSION_ZLIB; + + /* display message in raw buffer */ + snprintf (raw_message, sizeof (raw_message), + "obj: %d/%d bytes (zlib: %d%%, %.2fms), id: %s", + (int)dest_size + 5, + msg->data_size, + 100 - ((((int)dest_size + 5) * 100) / msg->data_size), + ((float)time_diff) / 1000, + msg->id); + + /* send compressed data */ + relay_client_send (client, RELAY_CLIENT_MSG_STANDARD, + (const char *)dest, dest_size + 5, + raw_message); + + rc = 1; + +error: + if (dest) + free (dest); + + return rc; +} + +/* + * Compresses the message with zstd. + * + * Returns: + * 1: OK, message compressed and sent + * 0: error, no message sent + */ + +int +relay_weechat_msg_compress_zstd (struct t_relay_client *client, + struct t_relay_weechat_msg *msg) +{ + char raw_message[1024]; + uint32_t size32; + Bytef *dest; + size_t dest_size, comp_size; + struct timeval tv1, tv2; + long long time_diff; + int rc, compression, compression_level; + + rc = 0; + dest = NULL; + + dest_size = ZSTD_compressBound (msg->data_size - 5); + dest = malloc (dest_size + 5); + if (!dest) + goto error; + + /* convert % to zstd compression level (1-19) */ + compression = weechat_config_integer (relay_config_network_compression); + compression_level = (((compression - 1) * 19) / 100) + 1; + + gettimeofday (&tv1, NULL); + comp_size = ZSTD_compress( + dest + 5, + dest_size, + (void *)(msg->data + 5), + msg->data_size - 5, + compression_level); + gettimeofday (&tv2, NULL); + time_diff = weechat_util_timeval_diff (&tv1, &tv2); + if ((comp_size == 0) || ((int)comp_size + 5 >= msg->data_size)) + goto error; + + /* set size and compression flag */ + size32 = htonl ((uint32_t)(comp_size + 5)); + memcpy (dest, &size32, 4); + dest[4] = RELAY_WEECHAT_COMPRESSION_ZSTD; + + /* display message in raw buffer */ + snprintf (raw_message, sizeof (raw_message), + "obj: %d/%d bytes (zstd: %d%%, %.2fms), id: %s", + (int)comp_size + 5, + msg->data_size, + 100 - ((((int)comp_size + 5) * 100) / msg->data_size), + ((float)time_diff) / 1000, + msg->id); + + /* send compressed data */ + relay_client_send (client, RELAY_CLIENT_MSG_STANDARD, + (const char *)dest, comp_size + 5, + raw_message); + + rc = 1; + +error: + if (dest) + free (dest); - if (weechat_config_integer (relay_config_network_compression_level) > 0) + return rc; +} + +/* + * Sends a message. + */ + +void +relay_weechat_msg_send (struct t_relay_client *client, + struct t_relay_weechat_msg *msg) +{ + char compression, raw_message[1024]; + uint32_t size32; + + if (weechat_config_integer (relay_config_network_compression) > 0) { switch (RELAY_WEECHAT_DATA(client, compression)) { case RELAY_WEECHAT_COMPRESSION_ZLIB: - dest_size = compressBound (msg->data_size - 5); - dest = malloc (dest_size + 5); - if (dest) - { - gettimeofday (&tv1, NULL); - rc = compress2 (dest + 5, &dest_size, - (Bytef *)(msg->data + 5), msg->data_size - 5, - weechat_config_integer (relay_config_network_compression_level)); - gettimeofday (&tv2, NULL); - time_diff = weechat_util_timeval_diff (&tv1, &tv2); - if ((rc == Z_OK) && ((int)dest_size + 5 < msg->data_size)) - { - /* set size and compression flag */ - size32 = htonl ((uint32_t)(dest_size + 5)); - memcpy (dest, &size32, 4); - dest[4] = RELAY_WEECHAT_COMPRESSION_ZLIB; - - /* display message in raw buffer */ - snprintf (raw_message, sizeof (raw_message), - "obj: %d/%d bytes (%d%%, %.2fms), id: %s", - (int)dest_size + 5, - msg->data_size, - 100 - ((((int)dest_size + 5) * 100) / msg->data_size), - ((float)time_diff) / 1000, - msg->id); - - /* send compressed data */ - relay_client_send (client, RELAY_CLIENT_MSG_STANDARD, - (const char *)dest, dest_size + 5, - raw_message); - - free (dest); - return; - } - free (dest); - } + if (relay_weechat_msg_compress_zlib (client, msg)) + return; + break; + case RELAY_WEECHAT_COMPRESSION_ZSTD: + if (relay_weechat_msg_compress_zstd (client, msg)) + return; break; default: break; diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.c b/src/plugins/relay/weechat/relay-weechat-protocol.c index d8f1bf212..49188decb 100644 --- a/src/plugins/relay/weechat/relay-weechat-protocol.c +++ b/src/plugins/relay/weechat/relay-weechat-protocol.c @@ -229,7 +229,7 @@ relay_weechat_protocol_handshake_reply (struct t_relay_client *client, RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake) { - char **options, **auths, *pos; + char **options, **auths, **compressions, *pos; int i, j, index_hash_algo, hash_algo_found, auth_allowed, compression; int password_received, plain_text_password; @@ -292,9 +292,28 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake) } else if (strcmp (options[i], "compression") == 0) { - compression = relay_weechat_compression_search (pos); - if (compression >= 0) - RELAY_WEECHAT_DATA(client, compression) = compression; + compressions = weechat_string_split ( + pos, + ":", + NULL, + WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_STRIP_RIGHT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, + 0, + NULL); + if (compressions) + { + for (j = 0; compressions[j]; j++) + { + compression = relay_weechat_compression_search (compressions[j]); + if (compression >= 0) + { + RELAY_WEECHAT_DATA(client, compression) = compression; + break; + } + } + weechat_string_free_split (compressions); + } } } } @@ -337,12 +356,9 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake) * hash is given in hexadecimal * totp time-based one time password used as secondary * authentication factor - * compression zlib (default) or off * * Message looks like: * init password=mypass - * init password=mypass,compression=zlib - * init password=mypass,compression=off * init password_hash=sha256:71c480df93d6ae2f1efad1447c66c9…,totp=123456 * init password_hash=pbkdf2:sha256:414232…:100000:01757d53157c…,totp=123456 */ @@ -350,7 +366,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake) RELAY_WEECHAT_PROTOCOL_CALLBACK(init) { char **options, *pos, *relay_password, *totp_secret, *info_totp_args, *info_totp; - int i, compression, length, password_received, totp_received; + int i, length, password_received, totp_received; RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0); @@ -411,12 +427,6 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(init) } } } - else if (strcmp (options[i], "compression") == 0) - { - compression = relay_weechat_compression_search (pos); - if (compression >= 0) - RELAY_WEECHAT_DATA(client, compression) = compression; - } } } weechat_string_free_split_command (options); diff --git a/src/plugins/relay/weechat/relay-weechat.c b/src/plugins/relay/weechat/relay-weechat.c index c12bf1cf2..8bdbb28ed 100644 --- a/src/plugins/relay/weechat/relay-weechat.c +++ b/src/plugins/relay/weechat/relay-weechat.c @@ -41,7 +41,7 @@ char *relay_weechat_compression_string[] = /* strings for compression */ -{ "off", "zlib" }; +{ "off", "zlib", "zstd" }; /* @@ -173,7 +173,7 @@ relay_weechat_alloc (struct t_relay_client *client) RELAY_WEECHAT_DATA(client, handshake_done) = 0; RELAY_WEECHAT_DATA(client, password_ok) = 0; RELAY_WEECHAT_DATA(client, totp_ok) = 0; - RELAY_WEECHAT_DATA(client, compression) = RELAY_WEECHAT_COMPRESSION_ZLIB; + RELAY_WEECHAT_DATA(client, compression) = RELAY_WEECHAT_COMPRESSION_OFF; RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, diff --git a/src/plugins/relay/weechat/relay-weechat.h b/src/plugins/relay/weechat/relay-weechat.h index c8339398b..1229ce8da 100644 --- a/src/plugins/relay/weechat/relay-weechat.h +++ b/src/plugins/relay/weechat/relay-weechat.h @@ -34,6 +34,7 @@ enum t_relay_weechat_compression { RELAY_WEECHAT_COMPRESSION_OFF = 0, /* no compression of binary objects */ RELAY_WEECHAT_COMPRESSION_ZLIB, /* zlib compression */ + RELAY_WEECHAT_COMPRESSION_ZSTD, /* Zstandard compression */ /* number of compressions */ RELAY_WEECHAT_NUM_COMPRESSIONS, }; |