]> git.meshlink.io Git - meshlink/blob - test/channels-failure.c
Allow the mesh to detect when a node has completely restarted.
[meshlink] / test / channels-failure.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/time.h>
6 #include <assert.h>
7
8 #include "../src/meshlink.h"
9 #include "utils.h"
10
11 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
12         (void)mesh;
13         (void)channel;
14         (void)port;
15         (void)data;
16         (void)len;
17
18         return true;
19 }
20
21 static struct sync_flag poll_flag;
22 static size_t poll_len;
23
24 static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
25         meshlink_set_channel_poll_cb(mesh, channel, NULL);
26         poll_len = len;
27         set_sync_flag(&poll_flag, true);
28 }
29
30 static struct sync_flag receive_flag;
31 static size_t receive_len;
32
33 static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
34         (void)mesh;
35         (void)channel;
36         (void)data;
37
38         receive_len = len;
39         set_sync_flag(&receive_flag, true);
40 }
41
42 int main() {
43         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
44
45         // Open two meshlink instances.
46
47         meshlink_handle_t *mesh_a, *mesh_b;
48         open_meshlink_pair(&mesh_a, &mesh_b, "channels_failure");
49
50         // Set the callbacks.
51
52         meshlink_set_channel_accept_cb(mesh_b, accept_cb);
53
54         // Open a channel from a to b
55
56         meshlink_node_t *b = meshlink_get_node(mesh_a, "b");
57         assert(b);
58
59         meshlink_channel_t *channel = meshlink_channel_open(mesh_a, b, 7, receive_cb, NULL, 0);
60         assert(channel);
61
62         meshlink_set_channel_poll_cb(mesh_a, channel, poll_cb);
63
64         // Start both instances
65
66         start_meshlink_pair(mesh_a, mesh_b);
67
68         // Wait for the channel to be established
69
70         assert(wait_sync_flag(&poll_flag, 10));
71         assert(poll_len != 0);
72
73         sleep(1);
74
75         // Set a very small timeout for channels to b.
76
77         meshlink_set_node_channel_timeout(mesh_a, b, 1);
78
79         // Stop mesh_b. We should get a notification that the channel has closed after a while.
80
81         meshlink_stop(mesh_b);
82
83         assert(wait_sync_flag(&receive_flag, 5));
84         assert(receive_len == 0);
85
86         meshlink_channel_close(mesh_a, channel);
87
88         // Try setting up a new channel while b is still down.
89
90         set_sync_flag(&poll_flag, false);
91         set_sync_flag(&receive_flag, false);
92
93         channel = meshlink_channel_open(mesh_a, b, 7, NULL, NULL, 0);
94         assert(channel);
95
96         meshlink_set_channel_poll_cb(mesh_a, channel, poll_cb);
97
98         assert(wait_sync_flag(&poll_flag, 5));
99         assert(poll_len == 0);
100
101         meshlink_channel_close(mesh_a, channel);
102
103         // Restart b and create a new channel
104
105         set_sync_flag(&poll_flag, false);
106         set_sync_flag(&receive_flag, false);
107
108         meshlink_set_node_channel_timeout(mesh_a, b, 60);
109
110         assert(meshlink_start(mesh_b));
111
112         channel = meshlink_channel_open(mesh_a, b, 7, receive_cb, NULL, 0);
113         meshlink_set_channel_poll_cb(mesh_a, channel, poll_cb);
114         assert(channel);
115         assert(wait_sync_flag(&poll_flag, 10));
116         assert(poll_len != 0);
117
118         // Close and reopen b, we should get a fast notification that the channel has been closed.
119
120         meshlink_close(mesh_b);
121         mesh_b = meshlink_open("channels_failure_conf.2", "b", "channels_failure", DEV_CLASS_BACKBONE);
122         assert(mesh_b);
123         assert(meshlink_start(mesh_b));
124
125         assert(wait_sync_flag(&receive_flag, 10));
126         assert(receive_len == 0);
127
128         // Clean up.
129
130         close_meshlink_pair(mesh_a, mesh_b);
131 }