#define QUICLY_PACKET_TYPE_BITMASK 0xf0
#define QUIC_FIFO_SIZE (64 << 10)
+#define QUIC_ERROR_FULL_FIFO 0xff10
+
+static char *
+quic_format_err (u64 code)
+{
+ switch (code)
+ {
+ case QUIC_ERROR_FULL_FIFO:
+ return "full fifo";
+ case QUICLY_ERROR_PACKET_IGNORED:
+ return "QUICLY_ERROR_PACKET_IGNORED";
+ case QUICLY_ERROR_SENDBUF_FULL:
+ return "QUICLY_ERROR_SENDBUF_FULL";
+ case QUICLY_ERROR_FREE_CONNECTION:
+ return "no open stream on connection";
+ case QUICLY_ERROR_RECEIVED_STATELESS_RESET:
+ return "QUICLY_ERROR_RECEIVED_STATELESS_RESET";
+ case QUICLY_TRANSPORT_ERROR_NONE:
+ return "QUICLY_TRANSPORT_ERROR_NONE";
+ case QUICLY_TRANSPORT_ERROR_INTERNAL:
+ return "QUICLY_TRANSPORT_ERROR_INTERNAL";
+ case QUICLY_TRANSPORT_ERROR_SERVER_BUSY:
+ return "QUICLY_TRANSPORT_ERROR_SERVER_BUSY";
+ case QUICLY_TRANSPORT_ERROR_FLOW_CONTROL:
+ return "QUICLY_TRANSPORT_ERROR_FLOW_CONTROL";
+ case QUICLY_TRANSPORT_ERROR_STREAM_ID:
+ return "QUICLY_TRANSPORT_ERROR_STREAM_ID";
+ case QUICLY_TRANSPORT_ERROR_STREAM_STATE:
+ return "QUICLY_TRANSPORT_ERROR_STREAM_STATE";
+ case QUICLY_TRANSPORT_ERROR_FINAL_OFFSET:
+ return "QUICLY_TRANSPORT_ERROR_FINAL_OFFSET";
+ case QUICLY_TRANSPORT_ERROR_FRAME_ENCODING:
+ return "QUICLY_TRANSPORT_ERROR_FRAME_ENCODING";
+ case QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER:
+ return "QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER";
+ case QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION:
+ return "QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION";
+ case QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION:
+ return "QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION";
+ case QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION:
+ return "QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION";
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE:
+ return "QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE";
+ default:
+ return "unknown error";
+ }
+}
static u32
quic_ctx_alloc (u32 thread_index)
if (max_enqueue <= sizeof (session_dgram_hdr_t))
{
QUIC_DBG (1, "Not enough space to enqueue header");
- return 1;
+ return QUIC_ERROR_FULL_FIFO;
}
max_enqueue -= sizeof (session_dgram_hdr_t);
{
QUIC_DBG (1, "Too much data to send, max_enqueue %u, len %u",
max_enqueue, len);
- return 1;
+ return QUIC_ERROR_FULL_FIFO;
}
/* Build packet header for fifo */
if (ret != sizeof (hdr))
{
QUIC_DBG (1, "Not enough space to enqueue header");
- return 1;
+ return QUIC_ERROR_FULL_FIFO;
}
ret = svm_fifo_enqueue (f, len, packet->data.base);
if (ret != len)
{
QUIC_DBG (1, "Not enough space to enqueue payload");
- return 1;
+ return QUIC_ERROR_FULL_FIFO;
}
return 0;
}
quicly_context_t *quicly_context;
app_worker_t *app_wrk;
application_t *app;
+ int err;
/* We have sctx, get qctx */
if (ctx->c_quic_ctx_id.is_stream)
if (max_packets < 2)
break;
num_packets = max_packets;
- if (quicly_send (conn, packets, &num_packets))
+ if ((err = quicly_send (conn, packets, &num_packets)))
goto quicly_error;
for (i = 0; i != num_packets; ++i)
{
- if (quic_send_datagram (udp_session, packets[i]))
+ if ((err = quic_send_datagram (udp_session, packets[i])))
goto quicly_error;
quicly_context->packet_allocator->
return 0;
quicly_error:
- QUIC_DBG (1, "Error sending packets closing connection");
+ if (err != QUICLY_ERROR_PACKET_IGNORED)
+ clib_warning ("Quic error '%s'.", quic_format_err (err));
quic_connection_closed (ctx->c_c_index, ctx->c_thread_index);
return 1;
}
return &ctx->connection;
}
+static u8 *
+format_quic_ctx (u8 * s, va_list * args)
+{
+ quic_ctx_t *ctx = va_arg (*args, quic_ctx_t *);
+ u32 verbose = va_arg (*args, u32);
+
+ if (!ctx)
+ return s;
+ s = format (s, "[#%d][%s] ", ctx->c_thread_index, "Q");
+
+ if (ctx->is_listener)
+ {
+ s = format (s, "%s Listener: ", ctx->c_quic_ctx_id.is_stream ?
+ "Stream" : "QSession");
+ if (verbose)
+ s = format (s, "app %d wrk %d", ctx->c_quic_ctx_id.parent_app_id,
+ ctx->c_quic_ctx_id.parent_app_wrk_id);
+ }
+ else
+ {
+ if (ctx->c_is_ip4)
+ s = format (s, "%U:%d->%U:%d", format_ip4_address, &ctx->c_lcl_ip4,
+ clib_net_to_host_u16 (ctx->c_lcl_port),
+ format_ip4_address, &ctx->c_rmt_ip4,
+ clib_net_to_host_u16 (ctx->c_rmt_port));
+ else
+ s = format (s, "%U:%d->%U:%d", format_ip6_address, &ctx->c_lcl_ip6,
+ clib_net_to_host_u16 (ctx->c_lcl_port),
+ format_ip6_address, &ctx->c_rmt_ip6,
+ clib_net_to_host_u16 (ctx->c_rmt_port));
+ }
+ return s;
+}
+
static u8 *
format_quic_connection (u8 * s, va_list * args)
{
- s = format (s, "[QUIC] connection"); /* TODO */
+ u32 qc_index = va_arg (*args, u32);
+ u32 thread_index = va_arg (*args, u32);
+ u32 verbose = va_arg (*args, u32);
+ quic_ctx_t *ctx = quic_ctx_get (qc_index, thread_index);
+ if (ctx)
+ s = format (s, "%-50U", format_quic_ctx, ctx, verbose);
return s;
}
static u8 *
format_quic_listener (u8 * s, va_list * args)
{
- s = format (s, "[QUIC] listener"); /* TODO */
+ u32 tci = va_arg (*args, u32);
+ u32 verbose = va_arg (*args, u32);
+ quic_ctx_t *ctx = quic_ctx_get (tci, vlib_get_thread_index ());
+ if (ctx)
+ {
+ ASSERT (ctx->is_listener);
+ s = format (s, "%-50U", format_quic_ctx, ctx, verbose);
+ }
return s;
}