From 7ece2b2350630584a2268b6b028d545ea69053a3 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 23 Feb 2021 19:56:31 +0100 Subject: [PATCH] Add meshlink_set_channel_flags(). This allows changing some of the flags of a channel. Currently it can be used to change MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE. --- src/meshlink++.h | 13 +++++++++++++ src/meshlink.c | 14 ++++++++++++++ src/meshlink.h | 13 +++++++++++++ src/meshlink.sym | 1 + src/utcp.c | 5 +++++ src/utcp.h | 3 +++ test/channels-no-partial.c | 13 +++++++++++++ 7 files changed, 62 insertions(+) diff --git a/src/meshlink++.h b/src/meshlink++.h index 551913d4..b7ba5b91 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -885,6 +885,19 @@ public: meshlink_set_channel_rcvbuf(handle, channel, size); } + /// Set the flags of a channel. + /** This function allows changing some of the channel flags. + * Currently only MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE are supported, other flags are ignored. + * These flags only affect the local side of the channel with the peer. + * The changes take effect immediately. + * + * @param channel A handle for the channel. + * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. + */ + void set_channel_flags(channel *channel, uint32_t flags) { + meshlink_set_channel_flags(handle, channel, flags); + } + /// Set the connection timeout used for channels to the given node. /** This sets the timeout after which unresponsive channels will be reported as closed. * The timeout is set for all current and future channels to the given node. diff --git a/src/meshlink.c b/src/meshlink.c index 31fc205a..fd8e2f98 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -4082,6 +4082,20 @@ void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch pthread_mutex_unlock(&mesh->mutex); } +void meshlink_set_channel_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint32_t flags) { + if(!mesh || !channel) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + utcp_set_flags(channel->c, flags); + pthread_mutex_unlock(&mesh->mutex); +} + meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) { if(data && len) { abort(); // TODO: handle non-NULL data diff --git a/src/meshlink.h b/src/meshlink.h index 1acd99b0..b3ccf8f0 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -1381,6 +1381,19 @@ void meshlink_set_channel_sndbuf(struct meshlink_handle *mesh, struct meshlink_c */ void meshlink_set_channel_rcvbuf(struct meshlink_handle *mesh, struct meshlink_channel *channel, size_t size); +/// Set the flags of a channel. +/** This function allows changing some of the channel flags. + * Currently only MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE are supported, other flags are ignored. + * These flags only affect the local side of the channel with the peer. + * The changes take effect immediately. + * + * \memberof meshlink_channel + * @param mesh A handle which represents an instance of MeshLink. + * @param channel A handle for the channel. + * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. + */ +void meshlink_set_channel_flags(struct meshlink_handle *mesh, struct meshlink_channel *channel, uint32_t flags); + /// Open a reliable stream channel to another node. /** This function is called whenever a remote node wants to open a channel to the local node. * The application then has to decide whether to accept or reject this channel. diff --git a/src/meshlink.sym b/src/meshlink.sym index 51511ee9..faa3517d 100644 --- a/src/meshlink.sym +++ b/src/meshlink.sym @@ -72,6 +72,7 @@ meshlink_send meshlink_set_blacklisted_cb meshlink_set_canonical_address meshlink_set_channel_accept_cb +meshlink_set_channel_flags meshlink_set_channel_listen_cb meshlink_set_channel_poll_cb meshlink_set_channel_rcvbuf diff --git a/src/utcp.c b/src/utcp.c index 20dd0aba..f237270f 100644 --- a/src/utcp.c +++ b/src/utcp.c @@ -2428,6 +2428,11 @@ void utcp_expect_data(struct utcp_connection *c, bool expect) { } } +void utcp_set_flags(struct utcp_connection *c, uint32_t flags) { + c->flags &= ~UTCP_CHANGEABLE_FLAGS; + c->flags |= flags & UTCP_CHANGEABLE_FLAGS; +} + void utcp_offline(struct utcp *utcp, bool offline) { struct timespec now; clock_gettime(UTCP_CLOCK, &now); diff --git a/src/utcp.h b/src/utcp.h index 2c537014..9921a375 100644 --- a/src/utcp.h +++ b/src/utcp.h @@ -53,6 +53,7 @@ struct utcp_connection; #define UTCP_TCP 3 #define UTCP_UDP 0 +#define UTCP_CHANGEABLE_FLAGS 0x18U typedef bool (*utcp_listen_t)(struct utcp *utcp, uint16_t port); typedef void (*utcp_accept_t)(struct utcp_connection *utcp_connection, uint16_t port); @@ -118,6 +119,8 @@ size_t utcp_get_outq(struct utcp_connection *connection); void utcp_expect_data(struct utcp_connection *connection, bool expect); +void utcp_set_flags(struct utcp_connection *connection, uint32_t flags); + // Completely global options void utcp_set_clock_granularity(long granularity); diff --git a/test/channels-no-partial.c b/test/channels-no-partial.c index c765456a..43792be3 100644 --- a/test/channels-no-partial.c +++ b/test/channels-no-partial.c @@ -73,6 +73,19 @@ int main(int argc, char *argv[]) { assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30); assert(meshlink_channel_send(mesh_a, channel, buf, 512) == 512); + // Check that we can change the NO_PARTIAL flag + + assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30); + meshlink_set_channel_sndbuf(mesh_a, channel, 256); + assert(meshlink_channel_send(mesh_a, channel, buf, 257) == -1); + meshlink_set_channel_flags(mesh_a, channel, 0); + assert(meshlink_channel_send(mesh_a, channel, buf, 257) == 256); + + assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30); + meshlink_set_channel_flags(mesh_a, channel, MESHLINK_CHANNEL_NO_PARTIAL); + assert(meshlink_channel_send(mesh_a, channel, buf, 257) == -1); + assert(meshlink_channel_send(mesh_a, channel, buf, 256) == 256); + // Clean up. close_meshlink_pair(mesh_a, mesh_b); -- 2.39.2