]> git.proxmox.com Git - mirror_kronosnet.git/commitdiff
loopback: Only allow 1 link to localhost if loopback is used.
authorChristine Caulfield <ccaulfie@redhat.com>
Thu, 3 Aug 2017 15:16:09 +0000 (16:16 +0100)
committerChristine Caulfield <ccaulfie@redhat.com>
Thu, 3 Aug 2017 15:16:09 +0000 (16:16 +0100)
If loopback is configured as a link transport to localhost then
no other transport makes sense and could actually cause
duplicate packets to be received. So now it's enforced and tested.

Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
libknet/libknet.h
libknet/link.c
libknet/tests/api_knet_send_loopback.c

index e1f0fb323bee0a222aed051eb8d3df0a7d70134a..9b5a8973beaeeb7305ed707af856dd04892af995 100644 (file)
@@ -941,7 +941,8 @@ int knet_addrtostr(const struct sockaddr_storage *ss, socklen_t sslen,
  * type is allowed. Data sent down a LOOPBACK link will be copied directly from
  * the knet send datafd to the knet receive datafd so the application must be set
  * up to take data from that socket at least as often as it is sent or deadlocks
- * could occur.
+ * could occur. If used, a LOOPBACK link must be the only link configured to the
+ * local host.
  */
 
 struct transport_info {
index 0fafe572e14f89adb410b12583c923e436935dec..c6bd4f5c354c19c1da3260d327c8083b741a4e25 100644 (file)
@@ -60,7 +60,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
                         struct sockaddr_storage *dst_addr,
                         uint64_t flags)
 {
-       int savederrno = 0, err = 0;
+       int savederrno = 0, err = 0, i;
        struct knet_host *host;
        struct knet_link *link;
 
@@ -99,12 +99,14 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
 
        if (transport == KNET_TRANSPORT_LOOPBACK && knet_h->host_id != host_id) {
                log_err(knet_h, KNET_SUB_LINK, "Cannot create loopback link to remote node");
+               err = -1;
                errno = EINVAL;
                goto exit_unlock;
        }
 
-       if (transport == KNET_TRANSPORT_LOOPBACK && knet_h->host_id != host_id && knet_h->has_loop_link) {
-               log_err(knet_h, KNET_SUB_LINK, "Cannot create more than 1 loopback link");
+       if (knet_h->host_id == host_id && knet_h->has_loop_link) {
+               log_err(knet_h, KNET_SUB_LINK, "Cannot create more than 1 link when loopback is active");
+               err = -1;
                errno = EINVAL;
                goto exit_unlock;
        }
@@ -118,6 +120,17 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
                goto exit_unlock;
        }
 
+       if (transport == KNET_TRANSPORT_LOOPBACK && knet_h->host_id == host_id) {
+               for (i=0; i<KNET_MAX_LINK; i++) {
+                       if (host->link[i].configured) {
+                               log_err(knet_h, KNET_SUB_LINK, "Cannot add loopback link when other links are already configured.");
+                               err = -1;
+                               errno = EINVAL;
+                               goto exit_unlock;
+                       }
+               }
+       }
+
        link = &host->link[link_id];
 
        if (link->configured != 0) {
index c36d9fd2eafed0647726495d74688af50490c6a1..1f91c0fb96f7ef326ed6af093910d9bd970d8116 100644 (file)
@@ -65,22 +65,49 @@ static void test(void)
                exit(FAIL);
        }
 
-       printf("Test knet_send with no send_buff\n");
+       flush_logs(logfds[0], stdout);
+
+       printf("Test configuring multiple links with loopback\n");
 
-       if ((!knet_send(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
-               printf("knet_send accepted invalid send_buff or returned incorrect error: %s\n", strerror(errno));
+       if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+               printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+               knet_handle_free(knet_h);
+               flush_logs(logfds[0], stdout);
+               close_logpipes(logfds);
+               exit(FAIL);
+        }
+
+       datafd = 0;
+       channel = -1;
+
+       if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+               printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
                exit(FAIL);
        }
 
-       flush_logs(logfds[0], stdout);
+       if (knet_host_add(knet_h, 1) < 0) {
+               printf("knet_host_add failed: %s\n", strerror(errno));
+               knet_handle_free(knet_h);
+               flush_logs(logfds[0], stdout);
+               close_logpipes(logfds);
+               exit(FAIL);
+       }
 
-       printf("Test knet_send with invalid send_buff len (0)\n");
+       if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) < 0) {
+               printf("Unable to configure link: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
+               knet_handle_free(knet_h);
+               flush_logs(logfds[0], stdout);
+               close_logpipes(logfds);
+               exit(FAIL);
+       }
 
-       if ((!knet_send(knet_h, send_buff, 0, channel)) || (errno != EINVAL)) {
-               printf("knet_send accepted invalid send_buff len (0) or returned incorrect error: %s\n", strerror(errno));
+       if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) == 0) {
+               printf("Managed to configure two LOOPBACK links - this is wrong\n");
+               knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
@@ -88,11 +115,11 @@ static void test(void)
        }
 
        flush_logs(logfds[0], stdout);
+       printf("Test configuring UDP link after loopback\n");
 
-       printf("Test knet_send with invalid send_buff len (> KNET_MAX_PACKET_SIZE)\n");
-
-       if ((!knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE + 1, channel)) || (errno != EINVAL)) {
-               printf("knet_send accepted invalid send_buff len (> KNET_MAX_PACKET_SIZE) or returned incorrect error: %s\n", strerror(errno));
+       if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, &lo, &lo, 0) == 0) {
+               printf("Managed to configure UDP and LOOPBACK links together: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
@@ -100,30 +127,41 @@ static void test(void)
        }
 
        flush_logs(logfds[0], stdout);
+       printf("Test configuring UDP link before loopback\n");
 
-       printf("Test knet_send with valid data\n");
-
-       if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
-               printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+       if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+               printf("Failed to clear existing LOOPBACK link: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
                exit(FAIL);
-        }
+       }
 
-       datafd = 0;
-       channel = -1;
+       if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
+               printf("Failed to configure UDP link for testing: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
+               knet_handle_free(knet_h);
+               flush_logs(logfds[0], stdout);
+               close_logpipes(logfds);
+               exit(FAIL);
+       }
 
-       if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
-               printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+       if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) == 0) {
+               printf("Managed to configure LOOPBACK link after UDP: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
                exit(FAIL);
        }
 
-       if (knet_host_add(knet_h, 1) < 0) {
-               printf("knet_host_add failed: %s\n", strerror(errno));
+       flush_logs(logfds[0], stdout);
+       printf("Test knet_send with valid data\n");
+
+       if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+               printf("Failed to clear existing UDP link: %s\n", strerror(errno));
+               knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);
                close_logpipes(logfds);
@@ -131,7 +169,7 @@ static void test(void)
        }
 
        if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) < 0) {
-               printf("Unable to configure link: %s\n", strerror(errno));
+               printf("Failed configure LOOPBACK link for sending: %s\n", strerror(errno));
                knet_host_remove(knet_h, 1);
                knet_handle_free(knet_h);
                flush_logs(logfds[0], stdout);