Skip to content

Commit

Permalink
Make improvements to redbean
Browse files Browse the repository at this point in the history
The following Lua APIs have been added:

  - IsDaemon() → bool
  - ProgramPidPath(str)

The following Lua hooks have been added:

  - OnClientConnection(ip:int,port:int,serverip:int,serverport:int) → bool
  - OnProcessCreate(pid:int,ip:int,port:int,serverip:int,serverport:int)
  - OnProcessDestroy(pid:int)
  - OnServerStart()
  - OnServerStop()
  - OnWorkerStart()
  - OnWorkerStop()

redbean now does a better job at applying gzip on the fly from the local
filesystem, using a streaming chunked api with constant memory, which is
useful for doing things like serving a 4gb text file off NFS, and having
it start transmitting in milliseconds. redbean will also compute entropy
on the beginnings of files to determine if compression is profitable.

This change pays off technical debts relating to memory, such as relying
on exit() to free() allocations. That's now mostly fixed so it should be
easier now to spot memory leaks in malloc traces.

This change also fixes bugs and makes improvements to our SSL support.
Uniprocess mode failed handshakes are no longer an issue. Token Alpn is
offered so curl -v looks less weird. Hybrid SSL certificate loading is
now smarter about naming conflicts. Self-signed CA root anchors will no
longer be delivered to the client during the handshake.
  • Loading branch information
jart committed Jul 10, 2021
1 parent 98c674d commit 8c4cce0
Show file tree
Hide file tree
Showing 25 changed files with 22,317 additions and 350 deletions.
4 changes: 3 additions & 1 deletion examples/curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
Expand Down Expand Up @@ -175,6 +176,7 @@ static int AppendFmt(struct Buffer *b, const char *fmt, ...) {

int main(int argc, char *argv[]) {
if (!NoDebug()) showcrashreports();
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);

/*
* Read flags.
Expand Down Expand Up @@ -282,7 +284,6 @@ 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]);
}
Expand Down Expand Up @@ -459,6 +460,7 @@ int main(int argc, char *argv[]) {
mbedtls_ssl_free(&ssl);
mbedtls_ctr_drbg_free(&drbg);
mbedtls_ssl_config_free(&conf);
mbedtls_ctr_drbg_free(&drbg);
}

return 0;
Expand Down
2 changes: 1 addition & 1 deletion libc/intrin/asan.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct AsanGlobal {

struct AsanMorgue {
unsigned i;
void *p[16];
void *p[32];
};

static struct AsanMorgue __asan_morgue;
Expand Down
1 change: 0 additions & 1 deletion libc/log/backtrace3.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ int PrintBacktraceUsingSymbols(int fd, const struct StackFrame *bp,
} else {
p = stpcpy(p, "UNKNOWN");
}
*p++ = '\r';
*p++ = '\n';
if (write(fd, buf, p - buf) == -1) {
return -1;
Expand Down
2 changes: 1 addition & 1 deletion libc/log/oncrash.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static const char kGregNames[17][4] forcealign(1) = {
static const char kCpuFlags[12] forcealign(1) = "CVPRAKZSTIDO";
static const char kFpuExceptions[6] forcealign(1) = "IDZOUP";
static const char kCrashSigNames[8][5] forcealign(1) = {
"QUIT", "FPE", "ILL", "SEGV", "TRAP", "ABRT", "BUS"};
"QUIT", "FPE", "ILL", "SEGV", "TRAP", "ABRT", "BUS", "PIPE"};

hidden int kCrashSigs[8];
hidden struct sigaction g_oldcrashacts[8];
Expand Down
7 changes: 7 additions & 0 deletions libc/mem/putenv.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,20 @@

static bool once;

static void PutEnvDestroy(void) {
char **a;
for (a = environ; *a; ++a) free(*a);
free(environ);
}

static void PutEnvInit(void) {
char **pin, **pout;
pin = environ;
pout = malloc(sizeof(char *) * MAX_VARS);
environ = pout;
while (*pin) *pout++ = strdup(*pin++);
*pout = NULL;
atexit(PutEnvDestroy);
}

int PutEnvImpl(char *s, bool overwrite) {
Expand Down
64 changes: 31 additions & 33 deletions third_party/dlmalloc/mtrace.c → libc/rand/measureentropy.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
Expand All @@ -16,39 +16,37 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/fmt/itoa.h"
#include "libc/runtime/runtime.h"
#include "libc/math.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "third_party/dlmalloc/dlmalloc.internal.h"

static uintptr_t lastfree_;

void *AddressBirthAction(void *addr) {
char buf[64], *p;
p = buf;
p = stpcpy(p, __FUNCTION__);
p = stpcpy(p, ": 0x");
p += uint64toarray_radix16((uintptr_t)addr, p);
*p++ = '\n';
__print(buf, p - buf);
if (lastfree_ == (uintptr_t)addr) {
lastfree_ = 0;
}
return addr;
}

void *AddressDeathAction(void *addr) {
char buf[64], *p;
p = buf;
p = stpcpy(p, __FUNCTION__);
p = stpcpy(p, ": 0x");
p += uint64toarray_radix16((uintptr_t)addr, p);
if (lastfree_ != (uintptr_t)addr) {
lastfree_ = (uintptr_t)addr;
} else {
p = stpcpy(p, " [OBVIOUS DOUBLE FREE]");
/**
* Returns number between 0 and 8.
*
* This gives you an idea of the density of information. Cryptographic
* random should be in the ballpark of 7.9 whereas plaintext will be
* more like 4.5.
*
* @param p is treated as binary octets
* @param n should be at least 1000
*/
double MeasureEntropy(const char *p, size_t n) {
size_t i;
double e, x;
long h[256];
e = 0;
if (n) {
memset(h, 0, sizeof(h));
for (i = 0; i < n; ++i) {
++h[p[i] & 255];
}
for (i = 0; i < 256; i++) {
if (h[i]) {
x = h[i];
x /= n;
e += x * log2(1 / x);
}
}
}
*p++ = '\n';
__print(buf, p - buf);
return addr;
return e;
}
1 change: 1 addition & 0 deletions libc/rand/rand.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ char *initstate(unsigned, char *, size_t);
char *setstate(char *);
long random(void);
void srandom(unsigned);
double MeasureEntropy(const char *, size_t);

COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
Expand Down
21 changes: 10 additions & 11 deletions libc/str/memccpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ static inline noasan uint64_t UncheckedAlignedRead64(unsigned char *p) {
void *memccpy(void *dst, const void *src, int c, size_t n) {
size_t i;
uint64_t v, w;
unsigned char *d;
unsigned char *pd;
unsigned char *d, *q;
const unsigned char *s;
i = 0;
d = dst;
Expand All @@ -72,15 +71,15 @@ void *memccpy(void *dst, const void *src, int c, size_t n) {
if (~(w ^ v) & ((w ^ v) - 0x0101010101010101) & 0x8080808080808080) {
break;
} else {
pd = d + i;
pd[0] = (w >> 000) & 255;
pd[1] = (w >> 010) & 255;
pd[2] = (w >> 020) & 255;
pd[3] = (w >> 030) & 255;
pd[4] = (w >> 040) & 255;
pd[5] = (w >> 050) & 255;
pd[6] = (w >> 060) & 255;
pd[7] = (w >> 070) & 255;
q = d + i;
q[0] = (w & 0x00000000000000ff) >> 000;
q[1] = (w & 0x000000000000ff00) >> 010;
q[2] = (w & 0x0000000000ff0000) >> 020;
q[3] = (w & 0x00000000ff000000) >> 030;
q[4] = (w & 0x000000ff00000000) >> 040;
q[5] = (w & 0x0000ff0000000000) >> 050;
q[6] = (w & 0x00ff000000000000) >> 060;
q[7] = (w & 0xff00000000000000) >> 070;
}
}
for (; i < n; ++i) {
Expand Down
29 changes: 29 additions & 0 deletions libc/str/strncpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,35 @@
* data from modifying memory without authorization; the memccpy()
* function can be used for that purpose.
*
* Here's an example of the only use case we know of for strncpy:
*
* static const struct People {
* char name[8];
* int age;
* } kPeople[] = {
* {"alice", 29}, //
* {"bob", 42}, //
* };
*
* int GetAge(const char *name) {
* char k[8];
* int m, l, r;
* l = 0;
* r = ARRAYLEN(kPeople) - 1;
* strncpy(k, name, 8);
* while (l <= r) {
* m = (l + r) >> 1;
* if (READ64BE(kPeople[m].name) < READ64BE(k)) {
* l = m + 1;
* } else if (READ64BE(kPeople[m].name) > READ64BE(k)) {
* r = m - 1;
* } else {
* return kPeople[m].age;
* }
* }
* return -1;
* }
*
* @return dest
* @see stpncpy(), memccpy()
* @asyncsignalsafe
Expand Down
4 changes: 4 additions & 0 deletions libc/testlib/hyperion.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ extern size_t kHyperionSize;
extern char kHyperion[];
extern uint8_t kHyperionZip[];

extern size_t kMobySize;
extern char kMoby[];
extern uint8_t kMobyZip[];

COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_TESTLIB_HYPERION_H_ */
32 changes: 32 additions & 0 deletions libc/testlib/moby.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
.rodata

// Nontrivial NUL-terminated string test vector.
.align 1
kMoby:
0: .incbin "libc/testlib/moby.txt"
1: .byte 0
.endobj kMoby,globl

.align 8
kMobySize:
.quad 1b-0b
.endobj kMobySize,globl
12 changes: 12 additions & 0 deletions libc/testlib/moby.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef COSMOPOLITAN_LIBC_TESTLIB_MOBY_H_
#define COSMOPOLITAN_LIBC_TESTLIB_MOBY_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_

extern size_t kMobySize;
extern char kMoby[];
extern uint8_t kMobyZip[];

COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_TESTLIB_MOBY_H_ */
Loading

0 comments on commit 8c4cce0

Please sign in to comment.