Make slight SSL performance improvements

This commit is contained in:
Justine Tunney 2021-07-08 21:54:21 -07:00
parent 4178896aa0
commit fe881982b5
6 changed files with 100 additions and 19 deletions

View file

@ -9,6 +9,7 @@
#endif
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/dns/dns.h"
#include "libc/errno.h"
@ -91,14 +92,32 @@ static int Socket(int family, int type, int protocol) {
static int TlsSend(void *c, const unsigned char *p, size_t n) {
int rc;
VERBOSEF("begin send %zu", n);
CHECK_NE(-1, (rc = write(*(int *)c, p, n)));
VERBOSEF("end send %zu", n);
return rc;
}
static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t t) {
int rc;
CHECK_NE(-1, (rc = read(*(int *)c, p, n)));
return rc;
static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
int r;
struct iovec v[2];
static unsigned a, b;
static unsigned char t[4096];
if (a < b) {
r = MIN(n, b - a);
memcpy(p, t + a, r);
if ((a += r) == b) a = b = 0;
return r;
}
v[0].iov_base = p;
v[0].iov_len = n;
v[1].iov_base = t;
v[1].iov_len = sizeof(t);
VERBOSEF("begin recv %zu", n + sizeof(t) - b);
CHECK_NE(-1, (r = readv(*(int *)c, v, 2)));
VERBOSEF("end recv %zu", r);
if (r > n) b = r - n;
return MIN(n, r);
}
static void TlsDebug(void *c, int v, const char *f, int l, const char *s) {
@ -137,14 +156,14 @@ static int AppendFmt(struct Buffer *b, const char *fmt, ...) {
va_start(va, fmt);
va_copy(vb, va);
n = vsnprintf(b->p + b->i, b->n - b->i, fmt, va);
if (n >= b->n - b->i) {
if (b->i + n + 1 > b->n) {
do {
if (b->n) {
b->n += b->n >> 1;
} else {
b->n = 16;
}
} while (b->i + n > b->n);
} while (b->i + n + 1 > b->n);
b->p = realloc(b->p, b->n);
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
}
@ -174,6 +193,7 @@ int main(int argc, char *argv[]) {
case 'q':
break;
case 'v':
++__log_level;
break;
case 'I':
method = kHttpHead;
@ -262,6 +282,7 @@ int main(int argc, char *argv[]) {
"Connection: close\r\n"
"User-Agent: %s\r\n",
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
fprintf(stderr, "%`'.*s\n", request.i, request.p);
for (int i = 0; i < headers.n; ++i) {
AppendFmt(&request, "%s\r\n", headers.p[i]);
}

View file

@ -33,7 +33,7 @@ int AppendFmt(struct Buffer *b, const char *fmt, ...) {
} else {
b->n = 16;
}
} while (b->i + n > b->n);
} while (b->i + n + 1 > b->n);
b->p = realloc(b->p, b->n);
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
}

View file

@ -277,6 +277,32 @@ TEST(fmt, p) {
gc(xasprintf("% 10p", 0xffff800000031337)));
}
TEST(fmt, regress) {
char buf[512];
const char *meth = "GET";
const char *path = "/";
const char *host = "10.10.10.124";
const char *port = "8080";
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
ASSERT_EQ(
strlen("GET / HTTP/1.1\r\n"
"Host: 10.10.10.124:8080\r\n"
"Connection: close\r\n"
"User-Agent: hurl/1.o (https://github.com/jart/cosmopolitan)\r\n"),
sprintf(buf,
"%s %s HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Connection: close\r\n"
"User-Agent: %s\r\n",
meth, path, host, port, agent));
ASSERT_STREQ(
"GET / HTTP/1.1\r\n"
"Host: 10.10.10.124:8080\r\n"
"Connection: close\r\n"
"User-Agent: hurl/1.o (https://github.com/jart/cosmopolitan)\r\n",
buf);
}
/* TEST(fmt, funchar) { */
/* /\* TODO(jart): fix this *\/ */
/* ASSERT_STREQ("'\\200'", gc(xasprintf("%`'c", 0200))); */

View file

@ -136,15 +136,20 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
if( X->n < nblimbs )
{
if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
if( ( p = (mbedtls_mpi_uint*)malloc( nblimbs*ciL ) ) == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
if( X->p != NULL )
{
memcpy( p, X->p, X->n * ciL );
memset( p + X->n, 0, ( nblimbs - X->n ) * ciL );
mbedtls_mpi_zeroize( X->p, X->n );
mbedtls_free( X->p );
}
else
{
memset( p, 0, nblimbs * ciL );
}
X->n = nblimbs;
X->p = p;

View file

@ -68,14 +68,14 @@ int AppendFmt(struct Buffer *b, const char *fmt, ...) {
va_start(va, fmt);
va_copy(vb, va);
n = vsnprintf(b->p + b->i, b->n - b->i, fmt, va);
if (n >= b->n - b->i) {
if (b->i + n + 1 > b->n) {
do {
if (b->n) {
b->n += b->n >> 1; /* the proper way to grow w/ amortization */
b->n += b->n >> 1;
} else {
b->n = 16;
}
} while (b->i + n > b->n);
} while (b->i + n + 1 > b->n);
b->p = realloc(b->p, b->n);
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
}

View file

@ -177,6 +177,12 @@ struct Buffer {
char *p;
};
struct TlsBio {
int fd;
unsigned a, b;
unsigned char t[4000];
};
struct Strings {
size_t n, c;
struct String {
@ -374,6 +380,7 @@ static mbedtls_ssl_config confcli;
static mbedtls_ssl_context sslcli;
static mbedtls_ctr_drbg_context rngcli;
static struct TlsBio g_bio;
static char slashpath[PATH_MAX];
static char *Route(const char *, size_t, const char *, size_t);
@ -1241,10 +1248,22 @@ static ssize_t WritevAll(int fd, struct iovec *iov, int iovlen) {
return 0;
}
static int TlsRecvImpl(void *ctx, unsigned char *buf, size_t len,
uint32_t tmo) {
int rc;
while ((rc = read(*(int *)ctx, buf, len)) == -1) {
static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
int r;
ssize_t s;
struct iovec v[2];
struct TlsBio *bio = ctx;
if (bio->a < bio->b) {
r = MIN(n, bio->b - bio->a);
memcpy(p, bio->t + bio->a, r);
if ((bio->a += r) == bio->b) bio->a = bio->b = 0;
return r;
}
v[0].iov_base = p;
v[0].iov_len = n;
v[1].iov_base = bio->t;
v[1].iov_len = sizeof(bio->t);
while ((r = readv(bio->fd, v, 2)) == -1) {
if (errno == EINTR) {
return MBEDTLS_ERR_SSL_WANT_READ;
} else if (errno == EAGAIN) {
@ -1256,7 +1275,8 @@ static int TlsRecvImpl(void *ctx, unsigned char *buf, size_t len,
return MBEDTLS_ERR_NET_RECV_FAILED;
}
}
return rc;
if (r > n) bio->b = r - n;
return MIN(n, r);
}
static int TlsRecv(void *ctx, unsigned char *buf, size_t len, uint32_t tmo) {
@ -1278,7 +1298,8 @@ static void TlsDebug(void *ctx, int level, const char *file, int line,
static int TlsSend(void *ctx, const unsigned char *buf, size_t len) {
int rc;
while ((rc = write(*(int *)ctx, buf, len)) == -1) {
struct TlsBio *bio = ctx;
while ((rc = write(bio->fd, buf, len)) == -1) {
if (errno == EINTR) {
LockInc(&shared->c.writeinterruputs);
if (killed || (meltdown && nowl() - startread > 2)) {
@ -1360,6 +1381,9 @@ static bool TlsSetup(void) {
inbuf.n -= amtread;
inbuf.c = amtread;
amtread = 0;
g_bio.fd = client;
g_bio.a = 0;
g_bio.b = 0;
for (;;) {
if (!(r = mbedtls_ssl_handshake(&ssl))) {
LockInc(&shared->c.sslhandshakes);
@ -3414,6 +3438,7 @@ static int LuaFetch(lua_State *L) {
struct Url url;
int t, ret, sock;
char *host, *port;
struct TlsBio *bio;
struct Buffer inbuf;
struct addrinfo *addr;
struct HttpMessage msg;
@ -3520,7 +3545,11 @@ static int LuaFetch(lua_State *L) {
sslcliused = true;
DEBUGF("client handshaking %`'s", host);
mbedtls_ssl_set_hostname(&sslcli, host);
mbedtls_ssl_set_bio(&sslcli, &sock, TlsSend, 0, TlsRecvImpl);
bio = gc(malloc(sizeof(struct TlsBio)));
bio->fd = sock;
bio->a = 0;
bio->b = 0;
mbedtls_ssl_set_bio(&sslcli, bio, TlsSend, 0, TlsRecvImpl);
while ((ret = mbedtls_ssl_handshake(&ssl))) {
switch (ret) {
case MBEDTLS_ERR_SSL_WANT_READ:
@ -6081,9 +6110,9 @@ void RedBean(int argc, char *argv[]) {
? MBEDTLS_SSL_VERIFY_REQUIRED
: MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_ca_chain(&confcli, GetSslRoots(), 0);
mbedtls_ssl_set_bio(&ssl, &g_bio, TlsSend, 0, TlsRecv);
mbedtls_ssl_setup(&ssl, &conf);
mbedtls_ssl_setup(&sslcli, &confcli);
mbedtls_ssl_set_bio(&ssl, &client, TlsSend, 0, TlsRecv);
#endif
if (launchbrowser) {
LaunchBrowser(launchbrowser);