udp: Also send the EOF packet when a target is removed.
[paraslash.git] / udp_send.c
index 0343feb633c8d34319c70320e0081c701d18d0fe..9092985725b5289ee7391eba3df2c12ae4e62844 100644 (file)
@@ -43,8 +43,6 @@
 struct udp_target {
        /** Track time (seconds) of last ICMP Port Unreachable error */
        time_t last_unreachable;
-       /** Common sender client data */
-       struct sender_client *sc;
        /** The opaque structure returned by vss_add_fec_client(). */
        struct fec_client *fc;
        /** The FEC parameters for this target. */
@@ -56,8 +54,12 @@ static int sender_status;
 
 static void udp_close_target(struct sender_client *sc)
 {
+       const char *buf;
+       size_t len = vss_get_fec_eof_packet(&buf);
+
        if (sc->cq != NULL) {
-               del_close_on_fork_list(sc->fd);
+               /* ignore return value, closing the target anyway. */
+               (void)write(sc->fd, buf, len);
                cq_destroy(sc->cq);
                sc->cq = NULL;
        }
@@ -69,6 +71,8 @@ static void udp_delete_target(struct sender_client *sc, const char *msg)
 
        PARA_NOTICE_LOG("deleting %s (%s) from list\n", sc->name, msg);
        udp_close_target(sc);
+       close(sc->fd);
+       del_close_on_fork_list(sc->fd);
        vss_del_fec_client(ut->fc);
        list_del(&sc->node);
        free(sc->name);
@@ -159,7 +163,6 @@ static void udp_init_session(struct sender_client *sc)
 {
        if (sc->cq == NULL) {
                sc->cq = cq_new(UDP_CQ_BYTES);
-               add_close_on_fork_list(sc->fd);
                PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
        }
 }
@@ -167,15 +170,8 @@ static void udp_init_session(struct sender_client *sc)
 static void udp_shutdown_targets(void)
 {
        struct sender_client *sc, *tmp;
-       const char *buf;
-       size_t len = vss_get_fec_eof_packet(&buf);
-
        list_for_each_entry_safe(sc, tmp, &targets, node)
-               if (sc->cq != NULL) {
-                       /* ignore return value, closing the target anyway. */
-                       (void)write(sc->fd, buf, len);
-                       udp_close_target(sc);
-               }
+               udp_close_target(sc);
 }
 
 static int udp_resolve_target(const char *url, struct sender_command_data *scd)
@@ -339,7 +335,7 @@ static int udp_com_add(struct sender_command_data *scd)
                return -E_TARGET_EXISTS;
        }
        ut = para_calloc(sizeof(*ut));
-       sc = ut->sc = para_calloc(sizeof(*sc));
+       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.init_fec              = udp_init_fec;
@@ -362,6 +358,7 @@ static int udp_com_add(struct sender_command_data *scd)
        PARA_INFO_LOG("adding to target list (%s)\n", sc->name);
        ut->fc = vss_add_fec_client(sc, &ut->fcp);
        para_list_add(&sc->node, &targets);
+       add_close_on_fork_list(sc->fd);
        return 1;
 err:
        if (sc->fd >= 0)