+static void udp_send_buf(char *buf, size_t len)
+{
+ struct udp_target *ut, *tmp;
+ int ret;
+
+ list_for_each_entry_safe(ut, tmp, &targets, node) {
+ ret = udp_init_session(ut);
+ if (ret < 0) {
+ udp_delete_target(ut, para_strerror(-ret));
+ continue;
+ }
+ ret = send_queued_chunks(ut->fd, ut->cq, 0);
+ if (ret < 0) {
+ udp_delete_target(ut, para_strerror(-ret));
+ continue;
+ }
+ if (!len)
+ continue;
+ if (!ret) { /* still data left in the queue */
+ ret = cq_enqueue(ut->cq, buf, len);
+ if (ret < 0) {
+ udp_delete_target(ut, para_strerror(-ret));
+ continue;
+ }
+ }
+ ret = write_nonblock(ut->fd, buf, len, 0);
+ if (ret < 0) {
+ udp_delete_target(ut, para_strerror(-ret));
+ continue;
+ }
+ if (ret != len) {
+ ret = cq_enqueue(ut->cq, buf + ret, len - ret);
+ if (ret < 0) {
+ udp_delete_target(ut, para_strerror(-ret));
+ continue;
+ }
+ }
+ }
+}
+