Skip to content

Commit

Permalink
Merge pull request #191 from jelu/dohdbg
Browse files Browse the repository at this point in the history
DoH response handling
  • Loading branch information
jelu authored Oct 28, 2021
2 parents 38303f9 + 6a452b0 commit abf8f0e
Showing 1 changed file with 49 additions and 32 deletions.
81 changes: 49 additions & 32 deletions src/net_doh.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ struct perf__doh_socket {
bool http2_is_dns;

struct _doh_stats stats;

char recvbuf[TCP_RECV_BUF_SIZE];
size_t recv_at;
};

static pthread_mutex_t _nghttp2_lock = PTHREAD_MUTEX_INITIALIZER;
Expand Down Expand Up @@ -291,50 +294,62 @@ static ssize_t perf__doh_recv(struct perf_net_socket* sock, void* buf, size_t le
return -1;
}

uint8_t recvbuf[TCP_RECV_BUF_SIZE];
ssize_t n = SSL_read(self->ssl, recvbuf, TCP_RECV_BUF_SIZE);
if (!n) {
perf__doh_reconnect(sock);
PERF_UNLOCK(&self->lock);
errno = EAGAIN;
return -1;
}
if (n < 0) {
int err = SSL_get_error(self->ssl, n);
switch (err) {
case SSL_ERROR_WANT_READ:
if (self->recv_at < sizeof(self->recvbuf)) {
// try to recv more if we can
ssize_t n = SSL_read(self->ssl, self->recvbuf + self->recv_at, sizeof(self->recvbuf) - self->recv_at);
if (!n) {
perf__doh_reconnect(sock);
PERF_UNLOCK(&self->lock);
errno = EAGAIN;
break;
case SSL_ERROR_SYSCALL:
switch (errno) {
case ECONNREFUSED:
case ECONNRESET:
case ENOTCONN:
perf__doh_reconnect(sock);
return -1;
}
if (n < 0) {
int err = SSL_get_error(self->ssl, n);
switch (err) {
case SSL_ERROR_WANT_READ:
if (self->recv_at) {
// did not recv but we got something in buffer
break;
}
errno = EAGAIN;
break;
PERF_UNLOCK(&self->lock);
return -1;
case SSL_ERROR_SYSCALL:
switch (errno) {
case ECONNREFUSED:
case ECONNRESET:
case ENOTCONN:
perf__doh_reconnect(sock);
errno = EAGAIN;
break;
default:
break;
}
PERF_UNLOCK(&self->lock);
return -1;
default:
break;
errno = EBADF;
PERF_UNLOCK(&self->lock);
return -1;
}
break;
default:
errno = EBADF;
break;
} else {
self->recv_at += n;
}
PERF_UNLOCK(&self->lock);
return -1;
}

// this will be processed by nghttp2 callbacks
int ret = nghttp2_session_mem_recv(self->http2.session, recvbuf, n);
ssize_t ret = nghttp2_session_mem_recv(self->http2.session, (uint8_t*)self->recvbuf, self->recv_at);
if (ret < 0) {
perf_log_warning("nghttp2_session_mem_recv failed: %s", nghttp2_strerror(ret));
PERF_UNLOCK(&self->lock);
return -1;
}
// TODO: handle partial mem_recv
if (ret != n) {
perf_log_fatal("perf__doh_recv() mem_recv did not take all");
if (ret != self->recv_at) {
// only process one response per call
memmove(self->recvbuf, self->recvbuf + ret, self->recv_at - ret);
self->recv_at -= ret;
} else {
self->recv_at = 0;
}

// TODO: is this faster then mem_recv?
Expand Down Expand Up @@ -850,7 +865,9 @@ static int _http2_data_chunk_recv_cb(nghttp2_session* session,
}

if (self->http2.dnsmsg_completed) {
perf_log_fatal("_http2_data_chunk_recv_cb: chunk received when already having a dns msg");
// pause for now and don't process this chunk
// can only do one response at a time in perf__doh_recv()
return NGHTTP2_ERR_PAUSE;
}

// TODO: point of nghttp2_session_get_stream_user_data() code?
Expand Down

0 comments on commit abf8f0e

Please sign in to comment.