Skip to content

Commit

Permalink
Optimize nghttp3_read_varint
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsuhiro-t committed Sep 11, 2024
1 parent 31a1543 commit c75f960
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 55 deletions.
24 changes: 12 additions & 12 deletions lib/nghttp3_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ static nghttp3_ssize conn_read_type(nghttp3_conn *conn, nghttp3_stream *stream,

assert(srclen);

nread = nghttp3_read_varint(rvint, src, srclen, fin);
nread = nghttp3_read_varint(rvint, src, src + srclen, fin);
if (nread < 0) {
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
}
Expand Down Expand Up @@ -650,7 +650,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
switch (rstate->state) {
case NGHTTP3_CTRL_STREAM_STATE_FRAME_TYPE:
assert(end - p > 0);
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), /* fin = */ 0);
nread = nghttp3_read_varint(rvint, p, end, /* fin = */ 0);
if (nread < 0) {
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
}
Expand All @@ -670,7 +670,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
/* Fall through */
case NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH:
assert(end - p > 0);
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), /* fin = */ 0);
nread = nghttp3_read_varint(rvint, p, end, /* fin = */ 0);
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand Down Expand Up @@ -769,7 +769,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
/* Read Identifier */
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand All @@ -795,7 +795,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
break;
}

nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand All @@ -820,7 +820,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
case NGHTTP3_CTRL_STREAM_STATE_SETTINGS_ID:
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand All @@ -847,7 +847,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
case NGHTTP3_CTRL_STREAM_STATE_SETTINGS_VALUE:
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand Down Expand Up @@ -881,7 +881,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
case NGHTTP3_CTRL_STREAM_STATE_GOAWAY:
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand Down Expand Up @@ -918,7 +918,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
/* server side only */
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand All @@ -943,7 +943,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
/* server side only */
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
assert(len > 0);
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand Down Expand Up @@ -1240,7 +1240,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
switch (rstate->state) {
case NGHTTP3_REQ_STREAM_STATE_FRAME_TYPE:
assert(end - p > 0);
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), fin);
nread = nghttp3_read_varint(rvint, p, end, fin);
if (nread < 0) {
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
}
Expand All @@ -1260,7 +1260,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
/* Fall through */
case NGHTTP3_REQ_STREAM_STATE_FRAME_LENGTH:
assert(end - p > 0);
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), fin);
nread = nghttp3_read_varint(rvint, p, end, fin);
if (nread < 0) {
return NGHTTP3_ERR_H3_FRAME_ERROR;
}
Expand Down
39 changes: 22 additions & 17 deletions lib/nghttp3_conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,39 @@
#include "nghttp3_str.h"
#include "nghttp3_unreachable.h"

int64_t nghttp3_get_varint(size_t *plen, const uint8_t *p) {
const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p) {
union {
char b[8];
uint8_t n8;
uint16_t n16;
uint32_t n32;
uint64_t n64;
} n;

*plen = (size_t)(1u << (*p >> 6));

switch (*plen) {
switch (*p >> 6) {
case 0:
*dest = *p++;
return p;
case 1:
return (int64_t)*p;
case 2:
memcpy(&n, p, 2);
n.b[0] &= 0x3f;
return (int64_t)ntohs(n.n16);
case 4:
n.n8 &= 0x3f;
*dest = ntohs(n.n16);

return p + 2;
case 2:
memcpy(&n, p, 4);
n.b[0] &= 0x3f;
return (int64_t)ntohl(n.n32);
case 8:
n.n8 &= 0x3f;
*dest = ntohl(n.n32);

return p + 4;
case 3:
memcpy(&n, p, 8);
n.b[0] &= 0x3f;
return (int64_t)nghttp3_ntohl64(n.n64);
}
n.n8 &= 0x3f;
*dest = (int64_t)nghttp3_ntohl64(n.n64);

nghttp3_unreachable();
return p + 8;
default:
nghttp3_unreachable();
}
}

int64_t nghttp3_get_varint_fb(const uint8_t *p) { return *p & 0x3f; }
Expand Down
8 changes: 4 additions & 4 deletions lib/nghttp3_conv.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ STIN uint16_t ntohs(uint16_t netshort) {
#endif /* WIN32 */

/*
* nghttp3_get_varint reads variable-length integer from |p|, and
* returns it in host byte order. The number of bytes read is stored
* in |*plen|.
* nghttp3_get_varint reads variable-length unsigned integer from |p|,
* and stores it in the buffer pointed by |dest| in host byte order.
* It returns |p| plus the number of bytes read from |p|.
*/
int64_t nghttp3_get_varint(size_t *plen, const uint8_t *p);
const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p);

/*
* nghttp3_get_varint_fb reads first byte of encoded variable-length
Expand Down
38 changes: 17 additions & 21 deletions lib/nghttp3_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,48 +179,44 @@ void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate) {
}

nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
const uint8_t *src, size_t srclen, int fin) {
size_t nread = 0;
size_t n;
size_t i;
const uint8_t *begin, const uint8_t *end,
int fin) {
const uint8_t *orig_begin = begin;
size_t len;

assert(srclen > 0);
assert(begin != end);

if (rvint->left == 0) {
assert(rvint->acc == 0);

rvint->left = nghttp3_get_varintlen(src);
if (rvint->left <= srclen) {
rvint->acc = nghttp3_get_varint(&nread, src);
rvint->left = 0;
return (nghttp3_ssize)nread;
len = nghttp3_get_varintlen(begin);
if (len <= (size_t)(end - begin)) {
nghttp3_get_varint(&rvint->acc, begin);
return (nghttp3_ssize)len;
}

if (fin) {
return NGHTTP3_ERR_INVALID_ARGUMENT;
}

rvint->acc = nghttp3_get_varint_fb(src);
nread = 1;
++src;
--srclen;
--rvint->left;
rvint->acc = nghttp3_get_varint_fb(begin++);
rvint->left = len - 1;
}

n = nghttp3_min_size(rvint->left, srclen);
len = nghttp3_min_size(rvint->left, (size_t)(end - begin));
end = begin + len;

for (i = 0; i < n; ++i) {
rvint->acc = (rvint->acc << 8) + src[i];
for (; begin != end;) {
rvint->acc = (rvint->acc << 8) + *begin++;
}

rvint->left -= n;
nread += n;
rvint->left -= len;

if (fin && rvint->left) {
return NGHTTP3_ERR_INVALID_ARGUMENT;
}

return (nghttp3_ssize)nread;
return (nghttp3_ssize)(begin - orig_begin);
}

int nghttp3_stream_frq_add(nghttp3_stream *stream,
Expand Down
3 changes: 2 additions & 1 deletion lib/nghttp3_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ void nghttp3_varint_read_state_reset(nghttp3_varint_read_state *rvint);
void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate);

nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
const uint8_t *src, size_t srclen, int fin);
const uint8_t *begin, const uint8_t *end,
int fin);

int nghttp3_stream_frq_add(nghttp3_stream *stream,
const nghttp3_frame_entry *frent);
Expand Down

0 comments on commit c75f960

Please sign in to comment.