r->in_payload->iov_len = ret;
knot_quic_conn_t *hconn = NULL;
- (void)knot_quic_handle(conn->quic_table, r, timeout_ms * 1000L, &hconn);
+ ret = knot_quic_handle(conn->quic_table, r, timeout_ms * 1000L, &hconn);
if (hconn == NULL) {
return KNOT_EOK;
} else if (hconn != conn) {
return KNOT_ESEMCHECK;
} else {
- return KNOT_EOK;
+ return ret;
}
}
(void)r;
}
-struct knot_quic_reply *knot_qreq_connect(int fd,
- struct sockaddr_storage *remote,
- struct sockaddr_storage *local,
- const struct knot_quic_creds *local_creds,
- const uint8_t *peer_pin,
- uint8_t peer_pin_len,
- int timeout_ms)
+int knot_qreq_connect(struct knot_quic_reply **out,
+ int fd,
+ struct sockaddr_storage *remote,
+ struct sockaddr_storage *local,
+ const struct knot_quic_creds *local_creds,
+ const uint8_t *peer_pin,
+ uint8_t peer_pin_len,
+ int timeout_ms)
{
- knot_quic_reply_t *r = calloc(1, sizeof(*r) + 2 * sizeof(struct iovec) +
- 2 * QUIC_BUF_SIZE);
+ struct knot_quic_reply *r = calloc(1, sizeof(*r) + 2 * sizeof(struct iovec) +
+ 2 * QUIC_BUF_SIZE);
if (r == NULL) {
- return NULL;
+ return KNOT_ENOMEM;
}
r->ip_rem = remote;
peer_pin, peer_pin_len);
if (creds == NULL) {
free(r);
- return NULL;
+ return KNOT_ENOMEM;
}
// NOTE the limits on conns and buffers do not do anything since we do not sweep
if (table == NULL) {
knot_quic_free_creds(creds);
free(r);
- return NULL;
+ return KNOT_ENOMEM;
}
knot_quic_conn_t *conn = NULL;
r->in_ctx = conn;
if (ret != KNOT_EOK) {
knot_qreq_close(r);
- return NULL;
+ return ret;
}
struct timespec t_start = time_now(), t_cur;
while (!conn->handshake_done) {
t_cur = time_now();
if (time_diff_ms(&t_start, &t_cur) > timeout_ms ||
- quic_exchange(conn, r, timeout_ms) != KNOT_EOK) {
+ (ret = quic_exchange(conn, r, timeout_ms)) != KNOT_EOK) {
knot_qreq_close(r);
- return NULL;
+ return ret;
}
}
r->in_ctx = conn;
- return r;
+ *out = r;
+
+ return KNOT_EOK;
}
int knot_qreq_send(struct knot_quic_reply *r, const struct iovec *data)
struct knot_quic_creds;
struct knot_quic_reply;
-struct knot_quic_reply *knot_qreq_connect(int fd,
- struct sockaddr_storage *remote,
- struct sockaddr_storage *local,
- const struct knot_quic_creds *local_creds,
- const uint8_t *peer_pin,
- uint8_t peer_pin_len,
- int timeout_ms);
+int knot_qreq_connect(struct knot_quic_reply **out,
+ int fd,
+ struct sockaddr_storage *remote,
+ struct sockaddr_storage *local,
+ const struct knot_quic_creds *local_creds,
+ const uint8_t *peer_pin,
+ uint8_t peer_pin_len,
+ int timeout_ms);
int knot_qreq_send(struct knot_quic_reply *r, const struct iovec *data);
&local_len);
}
#ifdef ENABLE_QUIC
- request->quic_ctx = knot_qreq_connect(request->fd, &request->remote,
- &request->source, request->creds,
- request->pin, request->pin_len,
- timeout_ms);
- if (request->quic_ctx == NULL) {
+ int ret = knot_qreq_connect(&request->quic_ctx,
+ request->fd, &request->remote,
+ &request->source, request->creds,
+ request->pin, request->pin_len,
+ timeout_ms);
+ if (ret != KNOT_EOK) {
close(request->fd);
- return KNOT_ECONN;
+ return ret;
}
#else
assert(0);
-/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
KNOT_EEMPTYZONE,
KNOT_ENODB,
KNOT_EUNREACH,
+ KNOT_EBADCERTKEY,
KNOT_GENERAL_ERROR = -900,
-/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
{ KNOT_EEMPTYZONE, "zone is empty" },
{ KNOT_ENODB, "database does not exist" },
{ KNOT_EUNREACH, "remote known to be unreachable" },
+ { KNOT_EBADCERTKEY, "unknown certificate key" },
{ KNOT_GENERAL_ERROR, "unknown general error" },
knot_quic_table_rem(conn, table);
ret = KNOT_EOK;
goto finish;
- } else if(ngtcp2_err_is_fatal(ret)) { // connection doomed
+ } else if (ngtcp2_err_is_fatal(ret)) { // connection doomed
+ if (ret == NGTCP2_ERR_CALLBACK_FAILURE) {
+ ret = KNOT_EBADCERTKEY;
+ } else {
+ ret = KNOT_ECONN;
+ }
knot_quic_table_rem(conn, table);
- ret = KNOT_ECONN;
goto finish;
} else if (ret != NGTCP2_NO_ERROR) { // non-fatal error, discard packet
ret = KNOT_EOK;