#include "quic_common.h"
#include "libdnssec/random.h"
#include "session2.h"
+#include <ngtcp2/ngtcp2.h>
uint64_t quic_timestamp(void)
{
session2_event(session, PROTOLAYER_EVENT_DISCONNECT, conn);
}
+ssize_t send_version_negotiation(struct wire_buf *dest, ngtcp2_version_cid dec_cids,
+ ngtcp2_cid dcid, ngtcp2_cid scid)
+{
+ uint8_t rnd = 0;
+ dnssec_random_buffer(&rnd, sizeof(rnd));
+ uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
+ int ret = ngtcp2_pkt_write_version_negotiation(
+ wire_buf_free_space(dest),
+ wire_buf_free_space_length(dest),
+ rnd, dec_cids.scid, dec_cids.scidlen,
+ dec_cids.dcid, dec_cids.dcidlen, supported_quic,
+ sizeof(supported_quic) / sizeof(*supported_quic)
+ );
+
+ return ret;
+}
void init_random_cid(ngtcp2_cid *cid, size_t len);
void quic_event_close_connection(struct pl_quic_conn_sess_data *conn,
struct session2 *session);
+ssize_t send_version_negotiation(struct wire_buf *dest, ngtcp2_version_cid dec_cids,
+ ngtcp2_cid dcid, ngtcp2_cid scid);
uint64_t now = quic_timestamp();
- uint8_t rnd = 0;
- dnssec_random_buffer(&rnd, sizeof(rnd));
- uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
ngtcp2_cid new_dcid;
uint8_t retry_token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
uint8_t stateless_reset_token[NGTCP2_STATELESS_RESET_TOKENLEN];
int ret = 0;
switch (action) {
case QUIC_SEND_VERSION_NEGOTIATION:
- ret = ngtcp2_pkt_write_version_negotiation(
- wire_buf_free_space(ctx->payload.wire_buf),
- wire_buf_free_space_length(ctx->payload.wire_buf),
- rnd, conn->dec_cids.scid, conn->dec_cids.scidlen,
- conn->dec_cids.dcid, conn->dec_cids.dcidlen, supported_quic,
- sizeof(supported_quic) / sizeof(*supported_quic)
- );
+ ret = send_version_negotiation(ctx->payload.wire_buf,
+ conn->dec_cids,
+ conn->dcid,
+ conn->scid);
break;
case QUIC_SEND_RETRY:
ngtcp2_cid_init(&scid, dec_cids.scid, dec_cids.scidlen);
if (ret == NGTCP2_ERR_VERSION_NEGOTIATION) {
- /* version negotiation packet should be sent */
+ wire_buf_reset(ctx->payload.wire_buf);
+ send_version_negotiation(ctx->payload.wire_buf,
+ dec_cids, dcid, scid);
+ if (ret >= 0) {
+ session2_wrap(demux->h.session, ctx->payload, ctx->comm,
+ ctx->req, ctx->finished_cb,
+ ctx->finished_cb_baton);
+ }
+
+ return protolayer_break(ctx, kr_ok());
}
qconn = kr_quic_table_lookup(&dcid, demux->conn_table);