return ret;
}
+/* Flush txbuf for <qc> connection. This must be called prior to a packet
+ * preparation when txbuf contains older data. A send will be conducted for
+ * these data.
+ *
+ * Returns 1 on success : buffer is empty and can be use for packet
+ * preparation. On error 0 is returned.
+ */
+static int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf)
+{
+ TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
+
+ /* This operation can only be conducted if txbuf is not empty. This
+ * case only happens for connection with their owned socket due to an
+ * older transient sendto() error.
+ */
+ BUG_ON(!qc_test_fd(qc));
+
+ if (b_data(buf) && !qc_send_ppkts(buf, qc->xprt_ctx)) {
+ if (qc->flags & QUIC_FL_CONN_TO_KILL)
+ qc_txb_release(qc);
+ TRACE_DEVEL("leaving in error", QUIC_EV_CONN_TXPKT, qc);
+ return 0;
+ }
+
+ TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
+ return 1;
+}
+
/* Try to send application frames from list <frms> on connection <qc>.
*
* Use qc_send_app_probing wrapper when probing with old data.
goto err;
}
+ if (b_data(buf) && !qc_purge_txbuf(qc, buf))
+ goto err;
+
/* Prepare and send packets until we could not further prepare packets. */
while (1) {
int ret;
goto leave;
}
+ if (b_data(buf) && !qc_purge_txbuf(qc, buf))
+ goto out;
+
/* Currently buf cannot be non-empty at this stage. Even if a previous
* sendto() has failed it is emptied to simulate packet emission and
* rely on QUIC lost detection to try to emit it.
if (!buf)
goto out;
+ if (b_data(buf) && !qc_purge_txbuf(qc, buf))
+ goto skip_send;
+
/* Currently buf cannot be non-empty at this stage. Even if a previous
* sendto() has failed it is emptied to simulate packet emission and
* rely on QUIC lost detection to try to emit it.