summaryrefslogtreecommitdiff
path: root/src/plugins/relay
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/relay')
-rw-r--r--src/plugins/relay/CMakeLists.txt7
-rw-r--r--src/plugins/relay/Makefile.am4
-rw-r--r--src/plugins/relay/relay-config.c17
-rw-r--r--src/plugins/relay/relay-config.h2
-rw-r--r--src/plugins/relay/weechat/relay-weechat-msg.c196
-rw-r--r--src/plugins/relay/weechat/relay-weechat-protocol.c38
-rw-r--r--src/plugins/relay/weechat/relay-weechat.c4
-rw-r--r--src/plugins/relay/weechat/relay-weechat.h1
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,
};