]> git.meshlink.io Git - meshlink/commitdiff
Add meshlink_channel_abort().
authorGuus Sliepen <guus@meshlink.io>
Fri, 23 Apr 2021 07:30:18 +0000 (09:30 +0200)
committerGuus Sliepen <guus@meshlink.io>
Fri, 23 Apr 2021 07:30:18 +0000 (09:30 +0200)
This is similar to meshlink_channel_close(), but resets the UTCP channel
instead of doing a normal FIN shutdown. It will also drop the send and
receive buffers.

src/meshlink++.h
src/meshlink.c
src/meshlink.h
src/meshlink.sym
src/utcp.c

index baf08ae1ef15405aa238360bfbb69a1f2309c5a0..25fd34f3f2c1530c14ad99db328e646d8c81a2ed 100644 (file)
@@ -1012,12 +1012,30 @@ public:
         *  It also causes the local node to stop accepting incoming data from the remote node.
         *  Afterwards, the channel handle is invalid and must not be used any more.
         *
+        *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
+        *  If called with a valid handle, this function always succeeds, otherwise the result is undefined.
+        *
         *  @param channel      A handle for the channel.
         */
        void channel_close(meshlink_channel_t *channel) {
                return meshlink_channel_close(handle, channel);
        }
 
+       /// Abort a reliable stream channel.
+       /** This aborts a channel.
+        *  Data that was in the send and receive buffers is dropped, so potentially there is some data that
+        *  was sent on this channel that will not be received by the peer.
+        *  Afterwards, the channel handle is invalid and must not be used any more.
+        *
+        *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
+        *  If called with a valid handle, this function always succeeds, otherwise the result is undefined.
+        *
+        *  @param channel      A handle for the channel.
+        */
+       void channel_abort(meshlink_channel_t *channel) {
+               return meshlink_channel_abort(handle, channel);
+       }
+
        /// Transmit data on a channel
        /** This queues data to send to the remote node.
         *
index 63feee2c88420b6670251eb697e3fe0aac1f6ce5..4280c4f13797c27919f1790ac5be59ce442a12d8 100644 (file)
@@ -4252,6 +4252,32 @@ void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_channel_abort(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+       if(!mesh || !channel) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       if(pthread_mutex_lock(&mesh->mutex) != 0) {
+               abort();
+       }
+
+       if(channel->c) {
+               utcp_abort(channel->c);
+               channel->c = NULL;
+
+               /* Clean up any outstanding AIO buffers. */
+               aio_abort(mesh, channel, &channel->aio_send);
+               aio_abort(mesh, channel, &channel->aio_receive);
+       }
+
+       if(!channel->in_callback) {
+               free(channel);
+       }
+
+       pthread_mutex_unlock(&mesh->mutex);
+}
+
 ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
        if(!mesh || !channel) {
                meshlink_errno = MESHLINK_EINVAL;
index 3e3728652143e356f253f1bcde6a1acc16190aeb..a6c5b4b9401a2233808b34914f8d692aa59bb71c 100644 (file)
@@ -1531,7 +1531,6 @@ void meshlink_channel_shutdown(struct meshlink_handle *mesh, struct meshlink_cha
 /// Close a reliable stream channel.
 /** This informs the remote node that the local node has finished sending all data on the channel.
  *  It also causes the local node to stop accepting incoming data from the remote node.
- *  It will free the struct meshlink_channel and all associated resources.
  *  Afterwards, the channel handle is invalid and must not be used any more.
  *
  *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
@@ -1543,6 +1542,21 @@ void meshlink_channel_shutdown(struct meshlink_handle *mesh, struct meshlink_cha
  */
 void meshlink_channel_close(struct meshlink_handle *mesh, struct meshlink_channel *channel);
 
+/// Abort a reliable stream channel.
+/** This aborts a channel.
+ *  Data that was in the send and receive buffers is dropped, so potentially there is some data that
+ *  was sent on this channel that will not be received by the peer.
+ *  Afterwards, the channel handle is invalid and must not be used any more.
+ *
+ *  It is allowed to call this function at any time on a valid handle, even inside callback functions.
+ *  If called with a valid handle, this function always succeeds, otherwise the result is undefined.
+ *
+ *  \memberof meshlink_channel
+ *  @param mesh         A handle which represents an instance of MeshLink.
+ *  @param channel      A handle for the channel.
+ */
+void meshlink_channel_abort(struct meshlink_handle *mesh, struct meshlink_channel *channel);
+
 /// Transmit data on a channel
 /** This queues data to send to the remote node.
  *
index ce78f112003715982d95e30036f1ff7511345cf0..7c4de629c7f21b9531da14e6c90a348a64a4b9bf 100644 (file)
@@ -13,6 +13,7 @@ meshlink_add_external_address
 meshlink_add_invitation_address
 meshlink_blacklist
 meshlink_blacklist_by_name
+meshlink_channel_abort
 meshlink_channel_aio_fd_receive
 meshlink_channel_aio_fd_send
 meshlink_channel_aio_receive
index 8b3509ef0f5c376ee7b37640cb3c82dba1819df4..e3070b890ebedc754a50260c2c5c8169a8b47b89 100644 (file)
@@ -2072,6 +2072,9 @@ static bool reset_connection(struct utcp_connection *c) {
                return false;
        }
 
+       buffer_clear(&c->sndbuf);
+       buffer_clear(&c->rcvbuf);
+
        c->recv = NULL;
        c->poll = NULL;