quic_send_datagram (session_t *udp_session, struct iovec *packet,
quicly_address_t *dest, quicly_address_t *src)
{
- u32 max_enqueue;
+ u32 max_enqueue, len;
session_dgram_hdr_t hdr;
- u32 len, ret;
svm_fifo_t *f;
transport_connection_t *tc;
+ int ret;
len = packet->iov_len;
f = udp_session->tx_fifo;
QUIC_ASSERT (dest->sa.sa_family == AF_INET6);
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &dest->sa;
hdr.rmt_port = sa6->sin6_port;
- clib_memcpy (&hdr.rmt_ip.ip6, &sa6->sin6_addr, 16);
+ clib_memcpy_fast (&hdr.rmt_ip.ip6, &sa6->sin6_addr, 16);
}
- ret = svm_fifo_enqueue (f, sizeof (hdr), (u8 *) & hdr);
- if (ret != sizeof (hdr))
- {
- QUIC_ERR ("Not enough space to enqueue header");
- return QUIC_ERROR_FULL_FIFO;
- }
- ret = svm_fifo_enqueue (f, len, packet->iov_base);
- if (ret != len)
+ svm_fifo_seg_t segs[2] = { { (u8 *) &hdr, sizeof (hdr) },
+ { packet->iov_base, len } };
+
+ ret = svm_fifo_enqueue_segments (f, segs, 2, 0 /* allow partial */);
+ if (PREDICT_FALSE (ret < 0))
{
- QUIC_ERR ("Not enough space to enqueue payload");
+ QUIC_ERR ("Not enough space to enqueue dgram");
return QUIC_ERROR_FULL_FIFO;
}
quicly_conn_t *conn;
size_t num_packets, i, max_packets;
quicly_address_t dest, src;
-
- num_packets = QUIC_SEND_PACKET_VEC_SIZE;
-
+ u32 n_sent = 0;
int err = 0;
/* We have sctx, get qctx */
goto quicly_error;
conn = ctx->conn;
-
if (!conn)
return 0;
- /* TODO : quicly can assert it can send min_packets up to 2 */
- if (quic_sendable_packet_count (udp_session) < 2)
- goto stop_sending;
-
do
{
+ /* TODO : quicly can assert it can send min_packets up to 2 */
max_packets = quic_sendable_packet_count (udp_session);
if (max_packets < 2)
break;
+
num_packets = max_packets;
if ((err = quicly_send (conn, &dest, &src, packets, &num_packets, buf,
sizeof (buf))))
goto quicly_error;
}
+ n_sent += num_packets;
}
while (num_packets > 0 && num_packets == max_packets);
-stop_sending:
quic_set_udp_tx_evt (udp_session);
QUIC_DBG (3, "%u[TX] %u[RX]", svm_fifo_max_dequeue (udp_session->tx_fifo),
svm_fifo_max_dequeue (udp_session->rx_fifo));
quic_update_timer (ctx);
- return 0;
+ return n_sent;
quicly_error:
if (err && err != QUICLY_ERROR_PACKET_IGNORED
&& err != QUICLY_ERROR_FREE_CONNECTION)
clib_warning ("Quic error '%U'.", quic_format_err, err);
quic_connection_closed (ctx);
- return 1;
+ return 0;
}
/* Quicly callbacks */
if (!quicly_sendstate_is_open (&stream->sendstate))
{
QUIC_ERR ("Warning: tried to send on closed stream");
- return -1;
+ return 0;
}
stream_data = (quic_stream_data_t *) stream->data;
QUIC_ASSERT (!rv);
tx_end:
- quic_send_packets (ctx);
- return 0;
+ return quic_send_packets (ctx);
}
/*