Skip to content

Commit

Permalink
[tests] fix some error handling
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Jul 23, 2021
1 parent e7a739b commit d9c796e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 15 deletions.
70 changes: 57 additions & 13 deletions libknet/tests/fun_acl_check.c
Expand Up @@ -14,15 +14,27 @@
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>

#include "libknet.h"

#include "internals.h"
#include "netutils.h"
#include "test-common.h"


/*
* Keep track of how many messages got through:
* clean + 3xACLs + QUIT
*/
#define CORRECT_NUM_MSGS 5
static int msgs_recvd = 0;

static pthread_mutex_t msg_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t msg_cond = PTHREAD_COND_INITIALIZER;

#define FAIL_ON_ERR(fn) \
if ((res = fn) < 0) { \
if ((res = fn) != 0) { \
int savederrno = errno; \
knet_link_set_enable(knet_h[1], 2, 0, 0); \
knet_link_set_enable(knet_h[2], 1, 0, 0); \
Expand All @@ -38,7 +50,7 @@
if (res == -2) { \
exit(SKIP); \
} else { \
printf("*** on line %d %s failed: %s\n", __LINE__ , #fn, strerror(savederrno)); \
printf("*** FAIL on line %d %s failed: %s\n", __LINE__ , #fn, strerror(savederrno)); \
exit(FAIL); \
} \
} else { \
Expand Down Expand Up @@ -113,14 +125,16 @@ static void *recv_messages(void *handle)
while ( (len = knet_recv(knet_h, buf, sizeof(buf), 0)) ) {
if (len > 0) {
printf("recv: (%ld) %s\n", (long)len, buf);
msgs_recvd++;
if (strcmp("QUIT", buf) == 0) {
break;
}
if (buf[0] == '0') { /* We should not have received this! */
printf(" *** received packet that should have been blocked\n");
printf(" *** FAIL received packet that should have been blocked\n");
err = 1;
return &err;
}
pthread_cond_signal(&msg_cond);
}
if (len < 0 && errno != EAGAIN) {
break;
Expand All @@ -143,10 +157,24 @@ static void notify_fn(void *private_data,
}


static void wait_for_cond(knet_handle_t *knet_h, int *logfds)
{
int res;
struct timespec ts;

clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 60;

FAIL_ON_ERR(pthread_mutex_lock(&msg_mutex));
/* This one needs checking for ETIMEDOUT */
pthread_cond_timedwait(&msg_cond, &msg_mutex, &ts);
FAIL_ON_ERR(pthread_mutex_unlock(&msg_mutex));
}

#define TESTNODES 2
static void test(int transport)
{
knet_handle_t knet_h[3];
knet_handle_t knet_h[TESTNODES+1];
int logfds[2];
struct sockaddr_storage lo0, lo1;
struct sockaddr_storage ss1, ss2;
Expand All @@ -157,6 +185,7 @@ static void test(int transport)
int8_t channel;

// Initial setup gubbins
msgs_recvd = 0;
setup_logpipes(logfds);
start_logthread(logfds[1], stdout);
knet_handle_start_nodes(knet_h, TESTNODES, logfds, KNET_LOG_DEBUG);
Expand Down Expand Up @@ -192,7 +221,7 @@ static void test(int transport)
FAIL_ON_ERR(pthread_create(&recv_thread, NULL, recv_messages, (void *)knet_h[1]));

// Let everything settle down
wait_for_nodes_state(knet_h[1], 2, 1, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, 60, logfds[0], stdout));
flush_logs(logfds[0], stdout);

/*
Expand All @@ -203,6 +232,7 @@ static void test(int transport)

// No ACL
FAIL_ON_ERR(knet_send_str(knet_h[2], "1No ACL - this should get through"));
wait_for_cond(knet_h, logfds);

// Block traffic from this address.
memset(&ss1, 0, sizeof(ss1));
Expand All @@ -214,42 +244,51 @@ static void test(int transport)

// This needs to go after the first ACLs are added
FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 1));

FAIL_ON_ERR(knet_send_str(knet_h[2], "0Address blocked - this should NOT get through"));

// Unblock and check again
wait_for_nodes_state(knet_h[1], 2, 0, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, 60, logfds[0], stdout));
FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
wait_for_nodes_state(knet_h[1], 2, 1, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, 60, logfds[0], stdout));

FAIL_ON_ERR(knet_send_str(knet_h[2], "1Address unblocked - this should get through"));
wait_for_cond(knet_h, logfds);

// Block traffic using a netmask
knet_strtoaddr("127.0.0.1","0", &ss1, sizeof(ss1));
knet_strtoaddr("255.0.0.1","0", &ss2, sizeof(ss2));
FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));

FAIL_ON_ERR(knet_send_str(knet_h[2], "0Netmask blocked - this should NOT get through"));

// Unblock and check again
wait_for_nodes_state(knet_h[1], 2, 0, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, 60, logfds[0], stdout));
FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
wait_for_nodes_state(knet_h[1], 2, 1, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, 60, logfds[0], stdout));

FAIL_ON_ERR(knet_send_str(knet_h[2], "1Netmask unblocked - this should get through"));
wait_for_cond(knet_h, logfds);

// Block traffic from a range
knet_strtoaddr("127.0.0.0","0", &ss1, sizeof(ss1));
knet_strtoaddr("127.0.0.9","0", &ss2, sizeof(ss2));
knet_strtoaddr("127.0.0.0", "0", &ss1, sizeof(ss1));
knet_strtoaddr("127.0.0.9", "0", &ss2, sizeof(ss2));
FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));

FAIL_ON_ERR(knet_send_str(knet_h[2], "0Range blocked - this should NOT get through"));

// Unblock and check again
wait_for_nodes_state(knet_h[1], 2, 0, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, 60, logfds[0], stdout));
FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
wait_for_nodes_state(knet_h[1], 2, 1, 60, logfds[0], stdout);
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, 60, logfds[0], stdout));

FAIL_ON_ERR(knet_send_str(knet_h[2], "1Range unblocked - this should get through"));
wait_for_cond(knet_h, logfds);

// Finish up - disable ACLS to make sure the QUIT message gets through
FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 0));
FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, 60, logfds[0], stdout));

FAIL_ON_ERR(knet_send_str(knet_h[2], "QUIT"));

// Check return from the receiving thread
Expand All @@ -276,6 +315,11 @@ static void test(int transport)
stop_logthread();
flush_logs(logfds[0], stdout);
close_logpipes(logfds);

if (msgs_recvd != CORRECT_NUM_MSGS) {
printf("*** FAIL Recv thread got %d messages, expected %d\n", msgs_recvd, CORRECT_NUM_MSGS);
exit(FAIL);
}
}

int main(int argc, char *argv[])
Expand Down
13 changes: 11 additions & 2 deletions libknet/tests/test-common.c
Expand Up @@ -883,7 +883,7 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
int logfd, FILE *std)
{
struct timespec ts;
int res;
int res, savederrno = 0;

if (state) {
target = numnodes-1; /* exclude us */
Expand All @@ -910,14 +910,23 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
return -1;
}

res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
if (res == -1 && errno == ETIMEDOUT) {
if (res != 0 && res != ETIMEDOUT) {
fprintf(stderr, "pthread_cond_timedwait fatal error\n");
errno = res;
return -1;
}
if (res == ETIMEDOUT) {
fprintf(stderr, "Timed-out\n");
savederrno = ETIMEDOUT;
res = -1;
}
pthread_mutex_unlock(&wait_mutex);

knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
flush_logs(logfd, std);
errno = savederrno;
return res;
}

Expand Down

0 comments on commit d9c796e

Please sign in to comment.