mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-26 11:10:58 +00:00 
			
		
		
		
	Make slight SSL performance improvements
This commit is contained in:
		
							parent
							
								
									4178896aa0
								
							
						
					
					
						commit
						fe881982b5
					
				
					 6 changed files with 100 additions and 19 deletions
				
			
		|  | @ -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]); | ||||
|   } | ||||
|  |  | |||
|  | @ -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); | ||||
|   } | ||||
|  |  | |||
|  | @ -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))); */ | ||||
|  |  | |||
							
								
								
									
										7
									
								
								third_party/mbedtls/bignum.c
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								third_party/mbedtls/bignum.c
									
										
									
									
										vendored
									
									
								
							|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
|   } | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue