udp: refuse to add the same target twice
authorGerrit Renker <grenker@cscs.ch>
Sun, 13 Jun 2010 09:30:47 +0000 (11:30 +0200)
committerAndre Noll <maan@systemlinux.org>
Tue, 22 Jun 2010 23:16:43 +0000 (01:16 +0200)
Based on the preceding patches, this turns the UDP targets list into a set.

error.h
udp_send.c

diff --git a/error.h b/error.h
index 3190306..f687a4c 100644 (file)
--- a/error.h
+++ b/error.h
@@ -16,7 +16,6 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define TIME_ERRORS
 #define CLOSE_ON_FORK_ERRORS
 #define DAEMON_ERRORS
-#define UDP_SEND_ERRORS
 #define GUI_ERRORS
 #define RINGBUFFER_ERRORS
 #define SCORE_ERRORS
@@ -235,6 +234,11 @@ extern const char **para_errlist[];
        PARA_ERROR(UDP_OVERRUN, "output buffer overrun"), \
 
 
+#define UDP_SEND_ERRORS \
+       PARA_ERROR(TARGET_EXISTS, "requested target is already present"),\
+       PARA_ERROR(TARGET_NOT_FOUND, "requested target not found")
+
+
 #define HTTP_RECV_ERRORS \
        PARA_ERROR(HTTP_RECV_OVERRUN, "http_recv: output buffer overrun"), \
 
index 8baf15e..71e85b7 100644 (file)
@@ -213,14 +213,13 @@ static int udp_com_off(__a_unused struct sender_command_data *scd)
        return 1;
 }
 
-static int udp_com_delete(struct sender_command_data *scd)
+static struct sender_client *udp_lookup_target(struct sender_command_data *scd)
 {
        struct sender_client *sc, *tmp;
        char host[MAX_HOSTLEN];
        int32_t port;
 
        list_for_each_entry_safe(sc, tmp, &targets, node) {
-               struct udp_target *ut = sc->private_data;
                parse_url(sc->name, host, sizeof(host), &port);
 
                /* Unspecified port means wildcard port match */
@@ -228,9 +227,22 @@ static int udp_com_delete(struct sender_command_data *scd)
                        continue;
                if (strcmp(host, scd->host))
                        continue;
+               return sc;
+       }
+       return NULL;
+}
+
+static int udp_com_delete(struct sender_command_data *scd)
+{
+       struct udp_target *ut = sc->private_data;
+       struct sender_client *sc = udp_lookup_target(scd);
+
+       if (sc) {
                udp_delete_target(ut, "com_delete");
+               return 1;
        }
-       return 1;
+       PARA_NOTICE_LOG("not deleting non-existing target '%s'\n", scd->host);
+       return -E_TARGET_NOT_FOUND;
 }
 
 /** Initialize UDP session and set maximum payload size. */
@@ -316,18 +328,25 @@ fail:
        return ret;
 }
 
-static void udp_add_target(struct sender_command_data *scd)
+static int udp_com_add(struct sender_command_data *scd)
 {
        int ret;
-       struct udp_target *ut = para_calloc(sizeof(*ut));
+       struct udp_target *ut;
+       struct sender_client *sc = udp_lookup_target(scd);
 
+       if (sc) {
+               PARA_NOTICE_LOG("target %s already exists - not adding it\n",
+                               sc->name);
+               return -E_TARGET_EXISTS;
+       }
+       ut = para_calloc(sizeof(*ut));
+       sc = ut->sc = para_calloc(sizeof(*sc));
        ut->fcp.slices_per_group      = scd->slices_per_group;
        ut->fcp.data_slices_per_group = scd->data_slices_per_group;
        ut->fcp.max_slice_bytes       = scd->max_slice_bytes;
        ut->fcp.init_fec              = udp_init_fec;
        ut->fcp.send_fec              = udp_send_fec;
 
-       ut->sc = para_calloc(sizeof(*ut->sc));
        ut->sc->private_data = ut;
        ut->sc->fd = -1;
        ret = para_connect_simple(IPPROTO_UDP, scd->host, scd->port);
@@ -345,7 +364,7 @@ static void udp_add_target(struct sender_command_data *scd)
        PARA_INFO_LOG("adding to target list (%s)\n", ut->sc->name);
        ut->fc = vss_add_fec_client(ut->sc, &ut->fcp);
        para_list_add(&ut->sc->node, &targets);
-       return;
+       return 1;
 err:
        if (ut->sc->fd >= 0)
                close(ut->sc->fd);
@@ -353,12 +372,7 @@ err:
                        scd->host, scd->port, para_strerror(-ret));
        free(ut->sc);
        free(ut);
-}
-
-static int udp_com_add(struct sender_command_data *scd)
-{
-       udp_add_target(scd);
-       return 1;
+       return ret;
 }
 
 static char *udp_info(void)
@@ -401,7 +415,7 @@ static void udp_init_target_list(void)
                        PARA_CRIT_LOG("not adding requested target '%s'\n",
                                        conf.udp_target_arg[i]);
                else
-                       udp_add_target(&scd);
+                       udp_com_add(&scd);
        }
 }