]> git.meshlink.io Git - meshlink/blob - test/blackbox/common/common_handlers.c
Add the blackbox channel connection tests.
[meshlink] / test / blackbox / common / common_handlers.c
1 /*
2     common_handlers.c -- Implementation of common callback handling and signal handling
3                             functions for black box tests
4     Copyright (C) 2018  Guus Sliepen <guus@meshlink.io>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 #include <stdio.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <sys/ioctl.h>
27 #include <net/if.h>
28 #include <arpa/inet.h>
29 #include <sys/socket.h>
30 #include <netdb.h>
31 #include <ifaddrs.h>
32 #include <ctype.h>
33 #include "test_step.h"
34 #include "common_handlers.h"
35
36 #define GET_IP_FAMILY AF_INET
37
38 char *lxc_bridge = NULL;
39 black_box_state_t *state_ptr = NULL;
40
41 bool meta_conn_status[10];
42 bool node_reachable_status[10];
43
44 bool test_running;
45
46 void mesh_close_signal_handler(int a) {
47         test_running = false;
48
49         exit(EXIT_SUCCESS);
50 }
51
52 void mesh_stop_start_signal_handler(int a) {
53         /* Stop the Mesh if it is running, otherwise start it again */
54         (mesh_started) ? execute_stop() : execute_start();
55 }
56
57 void setup_signals(void) {
58         test_running = true;
59         signal(SIGTERM, mesh_close_signal_handler);
60         signal(SIGINT, mesh_stop_start_signal_handler);
61 }
62
63 /* Return the IP Address of the Interface 'if_name'
64     The caller is responsible for freeing the dynamically allocated string that is returned */
65 char *get_ip(const char *if_name) {
66         struct ifaddrs *ifaddr, *ifa;
67         char *ip;
68         int family;
69
70         ip = malloc(NI_MAXHOST);
71         assert(ip);
72         assert(getifaddrs(&ifaddr) != -1);
73
74         for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
75                 if(ifa->ifa_addr == NULL) {
76                         continue;
77                 }
78
79                 family = ifa->ifa_addr->sa_family;
80
81                 if(family == GET_IP_FAMILY && !strcmp(ifa->ifa_name, if_name)) {
82                         assert(!getnameinfo(ifa->ifa_addr, (family == GET_IP_FAMILY) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST));
83                         break;
84                 }
85         }
86
87         return ip;
88 }
89
90 /* Return the IP Address of the Interface 'if_name'
91     The caller is responsible for freeing the dynamically allocated string that is returned */
92 char *get_netmask(const char *if_name) {
93         struct ifaddrs *ifaddr, *ifa;
94         char *ip;
95         int family;
96
97         ip = malloc(NI_MAXHOST);
98         assert(ip);
99         assert(getifaddrs(&ifaddr) != -1);
100
101         for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
102                 if(ifa->ifa_addr == NULL) {
103                         continue;
104                 }
105
106                 family = ifa->ifa_addr->sa_family;
107
108                 if(family == GET_IP_FAMILY && !strcmp(ifa->ifa_name, if_name)) {
109                         assert(!getnameinfo(ifa->ifa_netmask, (family == GET_IP_FAMILY) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST));
110                         break;
111                 }
112         }
113
114         return ip;
115 }
116
117 /* Change the IP Address of an interface */
118 void set_ip(const char *if_name, const char *new_ip) {
119         char set_ip_cmd[100];
120         assert(snprintf(set_ip_cmd, sizeof(set_ip_cmd), "ifconfig %s %s", if_name, new_ip) >= 0);
121         assert(system(set_ip_cmd) == 0);
122 }
123
124 /* Change the Netmask of an interface */
125 void set_netmask(const char *if_name, const char *new_netmask) {
126         char set_mask_cmd[100];
127         assert(snprintf(set_mask_cmd, sizeof(set_mask_cmd), "ifconfig %s netmask %s", if_name, new_netmask) >= 0);
128         assert(system(set_mask_cmd) == 0);
129 }
130
131 /* Bring a network interface down (before making changes such as the IP Address) */
132 void stop_nw_intf(const char *if_name) {
133         char nw_down_cmd[100];
134         assert(snprintf(nw_down_cmd, sizeof(nw_down_cmd), "ifconfig %s down", if_name) >= 0);
135         assert(system(nw_down_cmd) == 0);
136 }
137
138 /* Bring a network interface up (after bringing it down and making changes such as
139     the IP Address) */
140 void start_nw_intf(const char *if_name) {
141         char nw_up_cmd[100];
142         assert(snprintf(nw_up_cmd, sizeof(nw_up_cmd), "ifconfig %s up", if_name) >= 0);
143         assert(system(nw_up_cmd) == 0);
144 }
145
146 void meshlink_callback_node_status(meshlink_handle_t *mesh, meshlink_node_t *node,
147                                    bool reachable) {
148         int i;
149
150         (void)mesh;
151         fprintf(stderr, "Node %s became %s\n", node->name, (reachable) ? "reachable" : "unreachable");
152
153         if(state_ptr)
154                 for(i = 0; i < state_ptr->num_nodes; i++)
155                         if(strcmp(node->name, state_ptr->node_names[i]) == 0) {
156                                 node_reachable_status[i] = reachable;
157                         }
158 }
159
160 void meshlink_callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
161                               const char *text) {
162         int i;
163         char connection_match_msg[100];
164         (void)mesh;
165         (void)level;
166
167         fprintf(stderr, "meshlink>> %s\n", text);
168
169         if(state_ptr && (strstr(text, "Connection") || strstr(text, "connection"))) {
170                 for(i = 0; i < state_ptr->num_nodes; i++) {
171                         assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
172                                         "Connection with %s", state_ptr->node_names[i]) >= 0);
173
174                         if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
175                                 meta_conn_status[i] = true;
176                                 continue;
177                         }
178
179                         assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
180                                         "Already connected to %s", state_ptr->node_names[i]) >= 0);
181
182                         if(strstr(text, connection_match_msg)) {
183                                 meta_conn_status[i] = true;
184                                 continue;
185                         }
186
187                         assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
188                                         "Connection closed by %s", state_ptr->node_names[i]) >= 0);
189
190                         if(strstr(text, connection_match_msg)) {
191                                 meta_conn_status[i] = false;
192                                 continue;
193                         }
194
195                         assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
196                                         "Closing connection with %s", state_ptr->node_names[i]) >= 0);
197
198                         if(strstr(text, connection_match_msg)) {
199                                 meta_conn_status[i] = false;
200                                 continue;
201                         }
202                 }
203         }
204 }