mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Add SSL to redbean
Your redbean can now interoperate with clients that require TLS crypto. This is accomplished using a protocol polyglot that lets us distinguish between HTTP and HTTPS regardless of the port number. Certificates will be generated automatically, if none are supplied by the user. Footprint increases by only a few hundred kb so redbean in MODY=tiny is now 1.0mb - Add lseek() polyfills for ZIP executable - Automatically polyfill /tmp/FOO paths on NT - Fix readdir() / ftw() / nftw() bugs on Windows - Introduce -B flag for slower SSL that's stronger - Remove mbedtls features Cosmopolitan doesn't need - Have base64 decoder support the uri-safe alternative - Remove Truncated HMAC because it's forbidden by the IETF - Add all the mbedtls test suites and make them go 3x faster - Support opendir() / readdir() / closedir() on ZIP executable - Use Everest for ECDHE-ECDSA because it's so good it's so good - Add tinier implementation of sha1 since it's not worth the rom - Add chi-square monte-carlo mean correlation tests for getrandom() - Source entropy on Windows from the proper interface everyone uses We're continuing to outperform NGINX and other servers on raw message throughput. Using SSL means that instead of 1,000,000 qps you can get around 300,000 qps. However redbean isn't as fast as NGINX yet at SSL handshakes, since redbean can do 2,627 per second and NGINX does 4.3k Right now, the SSL UX story works best if you give your redbean a key signing key since that can be easily generated by openssl using a one liner then redbean will do all the things that are impossibly hard to do like signing ecdsa and rsa certificates that'll work in chrome. We should integrate the let's encrypt acme protocol in the future. Live Demo: https://redbean.justine.lol/ Root Cert: https://redbean.justine.lol/redbean1.crt
This commit is contained in:
parent
1beeb7a829
commit
cc1920749e
1032 changed files with 152673 additions and 69310 deletions
9
Makefile
9
Makefile
|
@ -129,15 +129,15 @@ include libc/libc.mk #─┘
|
||||||
include libc/sock/sock.mk #─┐
|
include libc/sock/sock.mk #─┐
|
||||||
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
||||||
include libc/dns/dns.mk # │ You can communicate with the network
|
include libc/dns/dns.mk # │ You can communicate with the network
|
||||||
include libc/crypto/crypto.mk # │
|
include net/http/http.mk # │
|
||||||
include net/http/http.mk #─┘
|
include third_party/regex/regex.mk #─┘
|
||||||
include third_party/regex/regex.mk
|
|
||||||
include third_party/third_party.mk
|
include third_party/third_party.mk
|
||||||
include libc/testlib/testlib.mk
|
include libc/testlib/testlib.mk
|
||||||
include tool/viz/lib/vizlib.mk
|
include tool/viz/lib/vizlib.mk
|
||||||
include third_party/lua/lua.mk
|
include third_party/lua/lua.mk
|
||||||
include third_party/sqlite3/sqlite3.mk
|
include third_party/sqlite3/sqlite3.mk
|
||||||
include third_party/mbedtls/mbedtls.mk
|
include third_party/mbedtls/mbedtls.mk
|
||||||
|
include third_party/mbedtls/test/test.mk
|
||||||
include third_party/quickjs/quickjs.mk
|
include third_party/quickjs/quickjs.mk
|
||||||
include third_party/lz4cli/lz4cli.mk
|
include third_party/lz4cli/lz4cli.mk
|
||||||
include third_party/infozip/infozip.mk
|
include third_party/infozip/infozip.mk
|
||||||
|
@ -162,7 +162,6 @@ include test/libc/nexgen32e/test.mk
|
||||||
include test/libc/runtime/test.mk
|
include test/libc/runtime/test.mk
|
||||||
include test/libc/sock/test.mk
|
include test/libc/sock/test.mk
|
||||||
include test/libc/bits/test.mk
|
include test/libc/bits/test.mk
|
||||||
include test/libc/crypto/test.mk
|
|
||||||
include test/libc/str/test.mk
|
include test/libc/str/test.mk
|
||||||
include test/libc/unicode/test.mk
|
include test/libc/unicode/test.mk
|
||||||
include test/libc/calls/test.mk
|
include test/libc/calls/test.mk
|
||||||
|
@ -237,7 +236,6 @@ loc: o/$(MODE)/tool/build/summy.com
|
||||||
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
|
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
|
||||||
|
|
||||||
COSMOPOLITAN_OBJECTS = \
|
COSMOPOLITAN_OBJECTS = \
|
||||||
LIBC_CRYPTO \
|
|
||||||
LIBC_DNS \
|
LIBC_DNS \
|
||||||
LIBC_SOCK \
|
LIBC_SOCK \
|
||||||
LIBC_NT_WS2_32 \
|
LIBC_NT_WS2_32 \
|
||||||
|
@ -287,7 +285,6 @@ COSMOPOLITAN_HEADERS = \
|
||||||
LIBC_ALG \
|
LIBC_ALG \
|
||||||
LIBC_BITS \
|
LIBC_BITS \
|
||||||
LIBC_CALLS \
|
LIBC_CALLS \
|
||||||
LIBC_CRYPTO \
|
|
||||||
LIBC_DNS \
|
LIBC_DNS \
|
||||||
LIBC_ELF \
|
LIBC_ELF \
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
|
|
|
@ -45,6 +45,7 @@ EXAMPLES_DIRECTDEPS = \
|
||||||
LIBC_LOG \
|
LIBC_LOG \
|
||||||
LIBC_MEM \
|
LIBC_MEM \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
|
LIBC_NT_IPHLPAPI \
|
||||||
LIBC_NT_KERNEL32 \
|
LIBC_NT_KERNEL32 \
|
||||||
LIBC_NT_NTDLL \
|
LIBC_NT_NTDLL \
|
||||||
LIBC_NT_USER32 \
|
LIBC_NT_USER32 \
|
||||||
|
@ -69,8 +70,8 @@ EXAMPLES_DIRECTDEPS = \
|
||||||
THIRD_PARTY_DLMALLOC \
|
THIRD_PARTY_DLMALLOC \
|
||||||
THIRD_PARTY_GDTOA \
|
THIRD_PARTY_GDTOA \
|
||||||
THIRD_PARTY_GETOPT \
|
THIRD_PARTY_GETOPT \
|
||||||
THIRD_PARTY_MBEDTLS \
|
|
||||||
THIRD_PARTY_LUA \
|
THIRD_PARTY_LUA \
|
||||||
|
THIRD_PARTY_MBEDTLS \
|
||||||
THIRD_PARTY_MUSL \
|
THIRD_PARTY_MUSL \
|
||||||
THIRD_PARTY_STB \
|
THIRD_PARTY_STB \
|
||||||
THIRD_PARTY_XED \
|
THIRD_PARTY_XED \
|
||||||
|
|
|
@ -8,58 +8,116 @@
|
||||||
╚─────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
#endif
|
#endif
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/struct/rusage.h"
|
#include "libc/calls/struct/rusage.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
|
#include "libc/runtime/clktck.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/fileno.h"
|
#include "libc/sysv/consts/fileno.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
void Show(const char *name, long measurement, const char *unit) {
|
#define PREFIX "\e[1mRL\e[0m: "
|
||||||
fprintf(stderr, "%-*s%,*d %s\n", 32, name, 32, measurement, unit);
|
|
||||||
|
static void PrintResourceReport(struct rusage *ru) {
|
||||||
|
long utime, stime;
|
||||||
|
long double ticks;
|
||||||
|
if (ru->ru_maxrss) {
|
||||||
|
fprintf(stderr, "%sballooned to %,ldkb in size\n", PREFIX, ru->ru_maxrss);
|
||||||
|
}
|
||||||
|
if ((utime = ru->ru_utime.tv_sec * 1000000 + ru->ru_utime.tv_usec) |
|
||||||
|
(stime = ru->ru_stime.tv_sec * 1000000 + ru->ru_stime.tv_usec)) {
|
||||||
|
ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK));
|
||||||
|
fprintf(stderr, "%sneeded %,ldµs cpu (%d%% kernel)\n", PREFIX,
|
||||||
|
utime + stime, (int)((long double)stime / (utime + stime) * 100));
|
||||||
|
if (ru->ru_idrss) {
|
||||||
|
fprintf(stderr, "%sneeded %,ldkb memory on average\n", PREFIX,
|
||||||
|
lroundl(ru->ru_idrss / ticks));
|
||||||
|
}
|
||||||
|
if (ru->ru_isrss) {
|
||||||
|
fprintf(stderr, "%sneeded %,ldkb stack on average\n", PREFIX,
|
||||||
|
lroundl(ru->ru_isrss / ticks));
|
||||||
|
}
|
||||||
|
if (ru->ru_ixrss) {
|
||||||
|
fprintf(stderr, "%smapped %,ldkb shared on average\n", PREFIX,
|
||||||
|
lroundl(ru->ru_ixrss / ticks));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ru->ru_minflt || ru->ru_majflt) {
|
||||||
|
fprintf(stderr, "%scaused %,ld page faults (%d%% memcpy)\n", PREFIX,
|
||||||
|
ru->ru_minflt + ru->ru_majflt,
|
||||||
|
(int)((long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) *
|
||||||
|
100));
|
||||||
|
}
|
||||||
|
if (ru->ru_nvcsw + ru->ru_nivcsw > 1) {
|
||||||
|
fprintf(stderr, "%s%,ld context switches (%d%% consensual)\n", PREFIX,
|
||||||
|
ru->ru_nvcsw + ru->ru_nivcsw,
|
||||||
|
(int)((long double)ru->ru_nvcsw / (ru->ru_nvcsw + ru->ru_nivcsw) *
|
||||||
|
100));
|
||||||
|
}
|
||||||
|
if (ru->ru_msgrcv || ru->ru_msgsnd) {
|
||||||
|
fprintf(stderr, "%sreceived %,ld message%s and sent %,ld\n", PREFIX,
|
||||||
|
ru->ru_msgrcv, ru->ru_msgrcv == 1 ? "" : "s", ru->ru_msgsnd);
|
||||||
|
}
|
||||||
|
if (ru->ru_inblock || ru->ru_oublock) {
|
||||||
|
fprintf(stderr, "%sperformed %,ld read%s and %,ld write i/o operations\n",
|
||||||
|
PREFIX, ru->ru_inblock, ru->ru_inblock == 1 ? "" : "s",
|
||||||
|
ru->ru_oublock);
|
||||||
|
}
|
||||||
|
if (ru->ru_nsignals) {
|
||||||
|
fprintf(stderr, "%sreceived %,ld signals\n", PREFIX, ru->ru_nsignals);
|
||||||
|
}
|
||||||
|
if (ru->ru_nswap) {
|
||||||
|
fprintf(stderr, "%sgot swapped %,ld times\n", PREFIX, ru->ru_nswap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long TvToNs(struct timeval tv) {
|
struct rusage rusage;
|
||||||
return tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int pid, wstatus;
|
int pid, wstatus;
|
||||||
long double ts1, ts2;
|
long double ts1, ts2;
|
||||||
struct rusage rusage;
|
sigset_t chldmask, savemask;
|
||||||
|
struct sigaction dflt, ignore, saveint, savequit;
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "Usage: %s PROG [ARGS...]\n", argv[0]);
|
fprintf(stderr, "Usage: %s PROG [ARGS...]\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memset(&rusage, -1, sizeof(rusage));
|
dflt.sa_flags = 0;
|
||||||
CHECK_GT(argc, 1);
|
dflt.sa_handler = SIG_DFL;
|
||||||
|
sigemptyset(&dflt.sa_mask);
|
||||||
|
ignore.sa_flags = 0;
|
||||||
|
ignore.sa_handler = SIG_IGN;
|
||||||
|
sigemptyset(&ignore.sa_mask);
|
||||||
|
sigaction(SIGINT, &ignore, &saveint);
|
||||||
|
sigaction(SIGQUIT, &ignore, &savequit);
|
||||||
|
sigemptyset(&chldmask);
|
||||||
|
sigaddset(&chldmask, SIGCHLD);
|
||||||
|
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||||
ts1 = nowl();
|
ts1 = nowl();
|
||||||
if (!(pid = vfork())) {
|
CHECK_NE(-1, (pid = vfork()));
|
||||||
|
if (!pid) {
|
||||||
|
sigaction(SIGINT, &dflt, 0);
|
||||||
|
sigaction(SIGQUIT, &dflt, 0);
|
||||||
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
execvp(argv[1], argv + 1);
|
execvp(argv[1], argv + 1);
|
||||||
abort();
|
_Exit(127);
|
||||||
|
}
|
||||||
|
while (wait4(pid, &wstatus, 0, &rusage) == -1) {
|
||||||
|
CHECK_EQ(EINTR, errno);
|
||||||
}
|
}
|
||||||
CHECK_NE(-1, wait4(pid, &wstatus, 0, &rusage));
|
|
||||||
ts2 = nowl();
|
ts2 = nowl();
|
||||||
Show("wall time", lroundl((ts2 - ts1) * 1e9l), "ns");
|
sigaction(SIGINT, &saveint, 0);
|
||||||
Show("user time", TvToNs(rusage.ru_utime), "ns");
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
Show("sys time", TvToNs(rusage.ru_stime), "ns");
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
Show("maximum resident set size", rusage.ru_maxrss, "");
|
fprintf(stderr, "%stook %,ldµs wall time\n", PREFIX,
|
||||||
Show("integral shared memory size", rusage.ru_ixrss, "");
|
(int64_t)((ts2 - ts1) * 1e6));
|
||||||
Show("integral unshared data size", rusage.ru_idrss, "");
|
PrintResourceReport(&rusage);
|
||||||
Show("integral unshared stack size", rusage.ru_isrss, "");
|
|
||||||
Show("minor page faults", rusage.ru_minflt, "");
|
|
||||||
Show("major page faults", rusage.ru_majflt, "");
|
|
||||||
Show("swaps", rusage.ru_nswap, "");
|
|
||||||
Show("block input ops", rusage.ru_inblock, "");
|
|
||||||
Show("block output ops", rusage.ru_oublock, "");
|
|
||||||
Show("ipc messages sent", rusage.ru_msgsnd, "");
|
|
||||||
Show("ipc messages received", rusage.ru_msgrcv, "");
|
|
||||||
Show("signals received", rusage.ru_nsignals, "");
|
|
||||||
Show("voluntary context switches", rusage.ru_nvcsw, "");
|
|
||||||
Show("involuntary context switches", rusage.ru_nivcsw, "");
|
|
||||||
if (WIFEXITED(wstatus)) {
|
if (WIFEXITED(wstatus)) {
|
||||||
return WEXITSTATUS(wstatus);
|
return WEXITSTATUS(wstatus);
|
||||||
} else {
|
} else {
|
||||||
|
|
55
examples/stringbuffer.c
Normal file
55
examples/stringbuffer.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#if 0
|
||||||
|
/*─────────────────────────────────────────────────────────────────╗
|
||||||
|
│ To the extent possible under law, Justine Tunney has waived │
|
||||||
|
│ all copyright and related or neighboring rights to this file, │
|
||||||
|
│ as it is written in the following disclaimers: │
|
||||||
|
│ • http://unlicense.org/ │
|
||||||
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
|
#endif
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/fmt/fmt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview Fast Growable Strings Tutorial
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Buffer {
|
||||||
|
size_t i, n;
|
||||||
|
char *p;
|
||||||
|
};
|
||||||
|
|
||||||
|
int AppendFmt(struct Buffer *b, const char *fmt, ...) {
|
||||||
|
int n;
|
||||||
|
char *p;
|
||||||
|
va_list va, vb;
|
||||||
|
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) {
|
||||||
|
do {
|
||||||
|
if (b->n) {
|
||||||
|
b->n += b->n >> 1; /* this is the important line */
|
||||||
|
} else {
|
||||||
|
b->n = 16;
|
||||||
|
}
|
||||||
|
} while (b->i + n > b->n);
|
||||||
|
b->p = realloc(b->p, b->n);
|
||||||
|
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
|
||||||
|
}
|
||||||
|
va_end(vb);
|
||||||
|
va_end(va);
|
||||||
|
b->i += n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct Buffer b = {0};
|
||||||
|
AppendFmt(&b, "hello ");
|
||||||
|
AppendFmt(&b, " world\n");
|
||||||
|
AppendFmt(&b, "%d arg%s\n", argc, argc == 1 ? "" : "s");
|
||||||
|
AppendFmt(&b, "%s\n", "have a nice day");
|
||||||
|
write(1, b.p, b.i);
|
||||||
|
free(b.p);
|
||||||
|
return 0;
|
||||||
|
}
|
153
examples/tls.c
153
examples/tls.c
|
@ -1,153 +0,0 @@
|
||||||
#if 0
|
|
||||||
/*─────────────────────────────────────────────────────────────────╗
|
|
||||||
│ To the extent possible under law, Justine Tunney has waived │
|
|
||||||
│ all copyright and related or neighboring rights to this file, │
|
|
||||||
│ as it is written in the following disclaimers: │
|
|
||||||
│ • http://unlicense.org/ │
|
|
||||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────*/
|
|
||||||
#endif
|
|
||||||
#include "libc/log/check.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/mbedtls/ctr_drbg.h"
|
|
||||||
#include "third_party/mbedtls/dhm.h"
|
|
||||||
#include "third_party/mbedtls/entropy.h"
|
|
||||||
#include "third_party/mbedtls/error.h"
|
|
||||||
#include "third_party/mbedtls/net_sockets.h"
|
|
||||||
#include "third_party/mbedtls/pk.h"
|
|
||||||
#include "third_party/mbedtls/platform.h"
|
|
||||||
#include "third_party/mbedtls/ssl.h"
|
|
||||||
#include "third_party/mbedtls/ssl_cache.h"
|
|
||||||
#include "third_party/mbedtls/x509_crt.h"
|
|
||||||
|
|
||||||
#define R(e) \
|
|
||||||
if ((r = e)) goto Die
|
|
||||||
|
|
||||||
char buf[1024], ebuf[100];
|
|
||||||
mbedtls_net_context server, client;
|
|
||||||
mbedtls_x509_crt cert;
|
|
||||||
mbedtls_x509_crt cacert;
|
|
||||||
mbedtls_entropy_context entropy;
|
|
||||||
mbedtls_ssl_cache_context cache;
|
|
||||||
mbedtls_ctr_drbg_context ctrdrbg;
|
|
||||||
mbedtls_pk_context pkey;
|
|
||||||
mbedtls_ssl_config conf;
|
|
||||||
mbedtls_ssl_context ssl;
|
|
||||||
|
|
||||||
void OnDebug(void *ctx, int lev, const char *file, int line, const char *str) {
|
|
||||||
fprintf(stderr, "%s:%04d: %s", file, line, str);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
int r, len;
|
|
||||||
|
|
||||||
system("openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem "
|
|
||||||
"-days 3650 -nodes -subj '/CN=localhost'");
|
|
||||||
|
|
||||||
mbedtls_net_init(&server);
|
|
||||||
mbedtls_net_init(&client);
|
|
||||||
mbedtls_ssl_init(&ssl);
|
|
||||||
mbedtls_ssl_config_init(&conf);
|
|
||||||
mbedtls_ssl_cache_init(&cache);
|
|
||||||
mbedtls_entropy_init(&entropy);
|
|
||||||
mbedtls_x509_crt_init(&cert);
|
|
||||||
mbedtls_pk_init(&pkey);
|
|
||||||
mbedtls_ctr_drbg_init(&ctrdrbg);
|
|
||||||
|
|
||||||
R(mbedtls_pk_parse_keyfile(&pkey, "key.pem", 0));
|
|
||||||
R(mbedtls_x509_crt_parse_file(&cert, "cert.pem"));
|
|
||||||
R(mbedtls_net_bind(&server, "0.0.0.0", "8080", MBEDTLS_NET_PROTO_TCP));
|
|
||||||
R(mbedtls_ctr_drbg_seed(&ctrdrbg, mbedtls_entropy_func, &entropy,
|
|
||||||
(const unsigned char *)"redbean", 7));
|
|
||||||
R(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER,
|
|
||||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
|
||||||
MBEDTLS_SSL_PRESET_DEFAULT));
|
|
||||||
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctrdrbg);
|
|
||||||
mbedtls_ssl_conf_dbg(&conf, OnDebug, 0);
|
|
||||||
mbedtls_ssl_conf_session_cache(&conf, &cache, mbedtls_ssl_cache_get,
|
|
||||||
mbedtls_ssl_cache_set);
|
|
||||||
R(mbedtls_ssl_conf_own_cert(&conf, &cert, &pkey));
|
|
||||||
R(mbedtls_ssl_setup(&ssl, &conf));
|
|
||||||
|
|
||||||
Reset:
|
|
||||||
mbedtls_net_free(&client);
|
|
||||||
R(mbedtls_ssl_session_reset(&ssl));
|
|
||||||
R(mbedtls_net_accept(&server, &client, 0, 0, 0));
|
|
||||||
mbedtls_ssl_set_bio(&ssl, &client, mbedtls_net_send, mbedtls_net_recv, 0);
|
|
||||||
|
|
||||||
while ((r = mbedtls_ssl_handshake(&ssl)) != 0) {
|
|
||||||
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
|
||||||
printf(" failed\n ! mbedtls_ssl_handshake returned %d\n", r);
|
|
||||||
goto Reset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
len = sizeof(buf) - 1;
|
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
r = mbedtls_ssl_read(&ssl, (void *)buf, len);
|
|
||||||
if (r == MBEDTLS_ERR_SSL_WANT_READ || r == MBEDTLS_ERR_SSL_WANT_WRITE)
|
|
||||||
continue;
|
|
||||||
if (r <= 0) {
|
|
||||||
switch (r) {
|
|
||||||
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
|
|
||||||
printf("connection was closed gracefully\n");
|
|
||||||
break;
|
|
||||||
case MBEDTLS_ERR_NET_CONN_RESET:
|
|
||||||
printf("connection was reset by peer\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("mbedtls_ssl_read returned -0x%x\n", -r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
len = r;
|
|
||||||
printf("%d bytes read\n%s", len, buf);
|
|
||||||
if (r > 0) break;
|
|
||||||
} while (1);
|
|
||||||
|
|
||||||
len = sprintf(buf,
|
|
||||||
"HTTP/1.0 200 OK\r\n"
|
|
||||||
"Content-Type: text/html\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"<h2>Mbed TLS Test Server</h2>\r\n"
|
|
||||||
"<p>Successful connection using: %s\r\n",
|
|
||||||
mbedtls_ssl_get_ciphersuite(&ssl));
|
|
||||||
|
|
||||||
while ((r = mbedtls_ssl_write(&ssl, (void *)buf, len)) <= 0) {
|
|
||||||
if (r == MBEDTLS_ERR_NET_CONN_RESET) {
|
|
||||||
printf("failed\n ! peer closed the connection\n");
|
|
||||||
goto Reset;
|
|
||||||
}
|
|
||||||
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
|
||||||
printf("failed\n ! mbedtls_ssl_write returned %d\n", r);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((r = mbedtls_ssl_close_notify(&ssl)) < 0) {
|
|
||||||
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
|
||||||
printf("error: mbedtls_ssl_close_notify returned %d\n", r);
|
|
||||||
goto Reset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ok\n");
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
goto Reset;
|
|
||||||
|
|
||||||
mbedtls_net_free(&client);
|
|
||||||
mbedtls_net_free(&server);
|
|
||||||
mbedtls_x509_crt_free(&cert);
|
|
||||||
mbedtls_pk_free(&pkey);
|
|
||||||
mbedtls_ssl_cache_free(&cache);
|
|
||||||
return 0;
|
|
||||||
Die:
|
|
||||||
mbedtls_strerror(r, ebuf, 100);
|
|
||||||
printf("last error was: %d - %s\n", r, ebuf);
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -9,9 +9,13 @@
|
||||||
#endif
|
#endif
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/runtime/gc.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/exit.h"
|
#include "libc/sysv/consts/exit.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
#include "third_party/musl/ftw.h"
|
#include "third_party/musl/ftw.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,10 +46,12 @@ static int display_info(const char *fpath, const struct stat *sb, int tflag,
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
const char *dir;
|
||||||
if (argc > 2 && strchr(argv[2], 'd') != NULL) flags |= FTW_DEPTH;
|
if (argc > 2 && strchr(argv[2], 'd') != NULL) flags |= FTW_DEPTH;
|
||||||
if (argc > 2 && strchr(argv[2], 'p') != NULL) flags |= FTW_PHYS;
|
if (argc > 2 && strchr(argv[2], 'p') != NULL) flags |= FTW_PHYS;
|
||||||
if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags) == -1) {
|
dir = argc < 2 ? "." : argv[1];
|
||||||
perror("nftw");
|
if (nftw(dir, display_info, 20, flags) == -1) {
|
||||||
|
fprintf(stderr, "nftw() failed: %s: %s\n", strerror(errno), dir);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|
|
@ -117,7 +117,7 @@ i32 __sys_openat(i32, const char *, i32, u32) hidden;
|
||||||
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||||
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
||||||
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
||||||
i32 getdents(i32, char *, u32, i64 *) hidden;
|
i32 getdents(i32, void *, u32, i64 *) hidden;
|
||||||
i32 sys_chdir(const char *) hidden;
|
i32 sys_chdir(const char *) hidden;
|
||||||
i32 sys_clock_gettime(i32, struct timespec *) hidden;
|
i32 sys_clock_gettime(i32, struct timespec *) hidden;
|
||||||
i32 sys_close(i32) hidden;
|
i32 sys_close(i32) hidden;
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/zipos/zipos.internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes current position of file descriptor/handle.
|
* Changes current position of file descriptor/handle.
|
||||||
|
@ -30,7 +32,10 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int64_t lseek(int fd, int64_t offset, unsigned whence) {
|
int64_t lseek(int fd, int64_t offset, unsigned whence) {
|
||||||
if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) {
|
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||||
|
return weaken(__zipos_lseek)(
|
||||||
|
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, offset, whence);
|
||||||
|
} else if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) {
|
||||||
return sys_lseek(fd, offset, whence, 0);
|
return sys_lseek(fd, offset, whence, 0);
|
||||||
} else if (IsOpenbsd() || IsNetbsd()) {
|
} else if (IsOpenbsd() || IsNetbsd()) {
|
||||||
return sys_lseek(fd, offset, offset, whence);
|
return sys_lseek(fd, offset, offset, whence);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntmagicpaths.internal.h"
|
#include "libc/calls/ntmagicpaths.internal.h"
|
||||||
|
#include "libc/nt/systeminfo.h"
|
||||||
#include "libc/str/oldutf16.internal.h"
|
#include "libc/str/oldutf16.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/str/tpdecode.internal.h"
|
#include "libc/str/tpdecode.internal.h"
|
||||||
|
@ -70,15 +71,30 @@ textwindows int __mkntpath2(const char *path,
|
||||||
* 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement
|
* 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement
|
||||||
* 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
* 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||||
*/
|
*/
|
||||||
size_t i, n;
|
char *q;
|
||||||
|
char16_t *p;
|
||||||
|
size_t i, n, m, z;
|
||||||
if (!path) return efault();
|
if (!path) return efault();
|
||||||
path = FixNtMagicPath(path, flags);
|
path = FixNtMagicPath(path, flags);
|
||||||
n = tprecode8to16(path16, PATH_MAX - 16, path).ax;
|
p = path16;
|
||||||
if (n == PATH_MAX - 16 - 1) return enametoolong();
|
q = path;
|
||||||
|
z = PATH_MAX - 16;
|
||||||
|
if (q[0] == '/' && q[1] == 't' && q[2] == 'm' && q[3] == 'p' &&
|
||||||
|
(q[4] == '/' || !q[4])) {
|
||||||
|
m = GetTempPath(z, p);
|
||||||
|
if (!q[4]) return m;
|
||||||
|
q += 5;
|
||||||
|
p += m;
|
||||||
|
z -= m;
|
||||||
|
} else {
|
||||||
|
m = 0;
|
||||||
|
}
|
||||||
|
n = tprecode8to16(p, z, q).ax;
|
||||||
|
if (n == z - 1) return enametoolong();
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
if (path16[i] == '/') {
|
if (p[i] == '/') {
|
||||||
path16[i] = '\\';
|
p[i] = '\\';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return m + n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,9 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) {
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
if (fd == -1 || offset < 0) return einval();
|
if (fd == -1 || offset < 0) return einval();
|
||||||
if (__isfdkind(fd, kFdZip)) {
|
if (__isfdkind(fd, kFdZip)) {
|
||||||
rc = weaken(__zipos_read)(
|
rc =
|
||||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, buf, size, offset);
|
weaken(__zipos_read)((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle,
|
||||||
|
(struct iovec[]){{buf, size}}, 1, offset);
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
rc = sys_pread(fd, buf, size, offset, offset);
|
rc = sys_pread(fd, buf, size, offset, offset);
|
||||||
} else if (__isfdkind(fd, kFdFile)) {
|
} else if (__isfdkind(fd, kFdFile)) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct dirent { /* linux getdents64 abi */
|
||||||
uint64_t d_ino; /* inode number */
|
uint64_t d_ino; /* inode number */
|
||||||
int64_t d_off; /* implementation-dependent location number */
|
int64_t d_off; /* implementation-dependent location number */
|
||||||
uint16_t d_reclen; /* byte length of this whole struct and string */
|
uint16_t d_reclen; /* byte length of this whole struct and string */
|
||||||
uint8_t d_type; /* DT_UNKNOWN, DT_BLK, DT_DIR, etc. */
|
uint8_t d_type; /* DT_REG, DT_DIR, DT_UNKNOWN, DT_BLK, etc. */
|
||||||
char d_name[256]; /* NUL-terminated basename */
|
char d_name[256]; /* NUL-terminated basename */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,11 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int64_t time(int64_t *opt_out_ret) {
|
int64_t time(int64_t *opt_out_ret) {
|
||||||
int64_t rc;
|
int64_t secs;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
if (gettimeofday(&tv, NULL) == -1) {
|
secs = nowl();
|
||||||
rc = -1;
|
|
||||||
} else {
|
|
||||||
rc = tv.tv_sec;
|
|
||||||
}
|
|
||||||
if (opt_out_ret) {
|
if (opt_out_ret) {
|
||||||
*opt_out_ret = rc;
|
*opt_out_ret = secs;
|
||||||
}
|
}
|
||||||
return rc;
|
return secs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
|
||||||
|
|
||||||
PKGS += LIBC_CRYPTO
|
|
||||||
|
|
||||||
LIBC_CRYPTO_ARTIFACTS += LIBC_CRYPTO_A
|
|
||||||
LIBC_CRYPTO = $(LIBC_CRYPTO_A_DEPS) $(LIBC_CRYPTO_A)
|
|
||||||
LIBC_CRYPTO_A = o/$(MODE)/libc/crypto/crypto.a
|
|
||||||
LIBC_CRYPTO_A_FILES := $(wildcard libc/crypto/*)
|
|
||||||
LIBC_CRYPTO_A_HDRS = $(filter %.h,$(LIBC_CRYPTO_A_FILES))
|
|
||||||
LIBC_CRYPTO_A_SRCS_A = $(filter %.s,$(LIBC_CRYPTO_A_FILES))
|
|
||||||
LIBC_CRYPTO_A_SRCS_S = $(filter %.S,$(LIBC_CRYPTO_A_FILES))
|
|
||||||
LIBC_CRYPTO_A_SRCS_C = $(filter %.c,$(LIBC_CRYPTO_A_FILES))
|
|
||||||
|
|
||||||
LIBC_CRYPTO_A_SRCS = \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_A) \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_S) \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_C)
|
|
||||||
|
|
||||||
LIBC_CRYPTO_A_OBJS = \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_A:%.s=o/$(MODE)/%.o) \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
|
||||||
$(LIBC_CRYPTO_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
|
||||||
|
|
||||||
LIBC_CRYPTO_A_CHECKS = \
|
|
||||||
$(LIBC_CRYPTO_A).pkg \
|
|
||||||
$(LIBC_CRYPTO_A_HDRS:%=o/$(MODE)/%.ok)
|
|
||||||
|
|
||||||
LIBC_CRYPTO_A_DIRECTDEPS = \
|
|
||||||
LIBC_INTRIN \
|
|
||||||
LIBC_STUBS \
|
|
||||||
LIBC_NEXGEN32E
|
|
||||||
|
|
||||||
LIBC_CRYPTO_A_DEPS := \
|
|
||||||
$(call uniq,$(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x))))
|
|
||||||
|
|
||||||
$(LIBC_CRYPTO_A): \
|
|
||||||
libc/crypto/ \
|
|
||||||
$(LIBC_CRYPTO_A).pkg \
|
|
||||||
$(LIBC_CRYPTO_A_OBJS)
|
|
||||||
|
|
||||||
$(LIBC_CRYPTO_A).pkg: \
|
|
||||||
$(LIBC_CRYPTO_A_OBJS) \
|
|
||||||
$(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x)_A).pkg)
|
|
||||||
|
|
||||||
LIBC_CRYPTO_LIBS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)))
|
|
||||||
LIBC_CRYPTO_SRCS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_SRCS))
|
|
||||||
LIBC_CRYPTO_HDRS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_HDRS))
|
|
||||||
LIBC_CRYPTO_BINS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_BINS))
|
|
||||||
LIBC_CRYPTO_CHECKS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_CHECKS))
|
|
||||||
LIBC_CRYPTO_OBJS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_OBJS))
|
|
||||||
LIBC_CRYPTO_TESTS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_TESTS))
|
|
||||||
$(LIBC_CRYPTO_OBJS): $(BUILD_FILES) libc/crypto/crypto.mk
|
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/libc/crypto
|
|
||||||
o/$(MODE)/libc/crypto: $(LIBC_CRYPTO_CHECKS)
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*-*- 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
|
|
||||||
.align 64 # for cacheline yoinking
|
|
||||||
kAesSbox:
|
|
||||||
.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
|
|
||||||
.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
|
|
||||||
.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
|
|
||||||
.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
|
|
||||||
.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
|
|
||||||
.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
|
|
||||||
.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
|
|
||||||
.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
|
|
||||||
.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
|
|
||||||
.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
|
|
||||||
.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
|
|
||||||
.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
|
|
||||||
.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
|
|
||||||
.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
|
|
||||||
.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
|
|
||||||
.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
|
|
||||||
.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
|
|
||||||
.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
|
|
||||||
.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
|
|
||||||
.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
|
|
||||||
.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
|
|
||||||
.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
|
|
||||||
.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
|
|
||||||
.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
|
|
||||||
.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
|
|
||||||
.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
|
|
||||||
.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
|
|
||||||
.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
|
|
||||||
.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
|
|
||||||
.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
|
|
||||||
.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
|
|
||||||
.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
|
|
||||||
.endfn kAesSbox,globl,hidden
|
|
||||||
.previous
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*-*- 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
|
|
||||||
.align 64 # for cacheline yoinking
|
|
||||||
kAesSboxInverse:
|
|
||||||
.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
|
|
||||||
.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
|
|
||||||
.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
|
|
||||||
.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
|
|
||||||
.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
|
|
||||||
.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
|
|
||||||
.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
|
|
||||||
.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
|
|
||||||
.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
|
|
||||||
.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
|
|
||||||
.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
|
|
||||||
.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
|
|
||||||
.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
|
|
||||||
.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
|
|
||||||
.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
|
|
||||||
.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
|
|
||||||
.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
|
|
||||||
.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
|
|
||||||
.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
|
|
||||||
.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
|
|
||||||
.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
|
|
||||||
.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
|
|
||||||
.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
|
|
||||||
.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
|
|
||||||
.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
|
|
||||||
.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
|
|
||||||
.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
|
|
||||||
.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
|
|
||||||
.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
|
|
||||||
.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
|
|
||||||
.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
|
|
||||||
.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
|
|
||||||
.endfn kAesSboxInverse,globl,hidden
|
|
||||||
.previous
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/bits/emmintrin.internal.h"
|
|
||||||
#include "libc/crypto/rijndael.h"
|
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
|
||||||
|
|
||||||
forceinline aes_block_t rijndael_westmere(uint32_t n, aes_block_t x,
|
|
||||||
const struct Rijndael *ctx) {
|
|
||||||
uint32_t i;
|
|
||||||
x ^= ctx->rk[0].xmm;
|
|
||||||
for (i = 1; i < n; ++i) {
|
|
||||||
asm("aesenc\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm));
|
|
||||||
}
|
|
||||||
asm("aesenclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static noinline aes_block_t rijndael_pure(uint32_t n, aes_block_t x,
|
|
||||||
const struct Rijndael *ctx) {
|
|
||||||
uint32_t i, j;
|
|
||||||
__v16qu b1, b2;
|
|
||||||
aes_block_t u1, u2, u3, u4;
|
|
||||||
x ^= ctx->rk[0].xmm;
|
|
||||||
for (i = 1; i < n + 1; ++i) {
|
|
||||||
b2 = b1 = (__v16qu)x;
|
|
||||||
for (j = 0; j < 16; ++j) {
|
|
||||||
b2[j % 4 + 13 * j / 4 % 4 * 4] = kAesSbox[b1[j]];
|
|
||||||
}
|
|
||||||
u1 = (aes_block_t)b2;
|
|
||||||
if (i != n) {
|
|
||||||
u2 = u1 >> 010 | u1 << 030;
|
|
||||||
u3 = u1 ^ u2;
|
|
||||||
u4 = u3 & 0x80808080;
|
|
||||||
u3 = ((u3 ^ u4) << 1) ^ ((u4 >> 7) * 0x1b);
|
|
||||||
u1 = u3 ^ u2 ^ (u1 >> 020 | u1 << 020) ^ (u1 >> 030 | u1 << 010);
|
|
||||||
}
|
|
||||||
x = ctx->rk[i].xmm ^ u1;
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypts paragraph w/ AES.
|
|
||||||
*
|
|
||||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
|
||||||
* @param x is 128-bit chunk of plaintext to encrypt
|
|
||||||
* @param ctx was initialized by rijndaelinit()
|
|
||||||
* @return result of transformation
|
|
||||||
*/
|
|
||||||
aes_block_t rijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) {
|
|
||||||
if (X86_HAVE(AES)) {
|
|
||||||
return rijndael_westmere(n, x, ctx);
|
|
||||||
} else {
|
|
||||||
return rijndael_pure(n, x, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_
|
|
||||||
#ifndef __STRICT_ANSI__
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
||||||
│ cosmopolitan § cryptography » advanced encryption standard ─╬─│┼
|
|
||||||
╚────────────────────────────────────────────────────────────────────────────│─┘
|
|
||||||
AES-256 Latency x86 2010+ SSE2
|
|
||||||
─────────────── ───────── ──────
|
|
||||||
rijndael(14, block, &ctx) 23 ns 218 ns
|
|
||||||
unrijndael(14, block, &ctx) 23 ns 690 ns
|
|
||||||
rijndaelinit(&ctx, 14, k1, k2) 136 ns 135 ns
|
|
||||||
unrijndaelinit(&ctx, 14, k1, k2) 186 ns 639 ns
|
|
||||||
|
|
||||||
Untrustworthy System Viability x86 2010+ SSE2
|
|
||||||
────────────────────────────── ───────── ──────
|
|
||||||
rijndael(14, block, &ctx) A C
|
|
||||||
unrijndael(14, block, &ctx) A C
|
|
||||||
rijndaelinit(&ctx, 14, k1, k2) B B
|
|
||||||
unrijndaelinit(&ctx, 14, k1, k2) B C
|
|
||||||
|
|
||||||
Comparison Cosmo Rijndael Tiny-AES
|
|
||||||
────────────────────────────── ─────── ──────── ────────
|
|
||||||
Generalized Math Yes Yes No
|
|
||||||
Footprint 1,782 b 9,258 b 903 b
|
|
||||||
Performance (New Hardware) ~20 ns ~40 ns ~400 ns
|
|
||||||
Performance (Old Hardware) ~400 ns ~40 ns ~400 ns */
|
|
||||||
|
|
||||||
typedef uint32_t aes_block_t _Vector_size(16) forcealign(16);
|
|
||||||
|
|
||||||
struct Rijndael {
|
|
||||||
union {
|
|
||||||
aes_block_t xmm;
|
|
||||||
uint32_t u32[4];
|
|
||||||
uint8_t u8[16];
|
|
||||||
} rk[15];
|
|
||||||
};
|
|
||||||
|
|
||||||
void rijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t);
|
|
||||||
aes_block_t rijndael(uint32_t, aes_block_t, const struct Rijndael *);
|
|
||||||
void unrijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t);
|
|
||||||
aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *);
|
|
||||||
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
||||||
│ cosmopolitan § cryptography » implementation details ─╬─│┼
|
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
||||||
|
|
||||||
extern const uint8_t kAesSbox[256] forcealign(64);
|
|
||||||
extern const uint8_t kAesSboxInverse[256] forcealign(64);
|
|
||||||
|
|
||||||
aes_block_t InvMixColumns(aes_block_t) hidden;
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* !ANSI */
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_ */
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/assert.h"
|
|
||||||
#include "libc/bits/bits.h"
|
|
||||||
#include "libc/bits/xmmintrin.internal.h"
|
|
||||||
#include "libc/crypto/rijndael.h"
|
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/str/internal.h"
|
|
||||||
|
|
||||||
#define ROR(w, k) (CheckUnsigned(w) >> (k) | (w) << (sizeof(w) * 8 - (k)))
|
|
||||||
|
|
||||||
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
|
|
||||||
0x20, 0x40, 0x80, 0x1b, 0x36};
|
|
||||||
|
|
||||||
forceinline uint32_t SubRot(uint32_t t) {
|
|
||||||
uint32_t j;
|
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
t = (t & -256) | kAesSbox[t & 255];
|
|
||||||
t = ROR(t, 8);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes key schedule for rijndael().
|
|
||||||
*
|
|
||||||
* @param ctx receives round keys
|
|
||||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
|
||||||
* @param k1/k2 holds the master key
|
|
||||||
*/
|
|
||||||
void rijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1,
|
|
||||||
aes_block_t k2) {
|
|
||||||
#define Nk (n - 6)
|
|
||||||
#define W(i) (ctx->rk[(i) / 4].u32[(i) % 4])
|
|
||||||
#define K(i) ((i) < 4 ? k1[i] : k2[(i)-4])
|
|
||||||
uint32_t i, t;
|
|
||||||
ctx->rk[0].xmm = k1;
|
|
||||||
ctx->rk[1].xmm = k2;
|
|
||||||
for (i = Nk; i < 4 * (n + 1); ++i) {
|
|
||||||
t = W(i - 1);
|
|
||||||
if (i % Nk == 0) {
|
|
||||||
t = ROR(t, 8);
|
|
||||||
t = SubRot(t);
|
|
||||||
t ^= Rcon[i / Nk];
|
|
||||||
} else if (Nk > 6 && i % Nk == 4) {
|
|
||||||
t = SubRot(t);
|
|
||||||
}
|
|
||||||
W(i) = W(i - Nk) ^ t;
|
|
||||||
}
|
|
||||||
XMM_DESTROY(k1);
|
|
||||||
XMM_DESTROY(k2);
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/bits/emmintrin.internal.h"
|
|
||||||
#include "libc/crypto/rijndael.h"
|
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
|
||||||
|
|
||||||
forceinline aes_block_t unrijndael_westmere(uint32_t n, aes_block_t x,
|
|
||||||
const struct Rijndael *ctx) {
|
|
||||||
x ^= ctx->rk[n--].xmm;
|
|
||||||
do {
|
|
||||||
asm("aesdec\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm));
|
|
||||||
} while (--n);
|
|
||||||
asm("aesdeclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static noinline aes_block_t unrijndael_pure(uint32_t n, aes_block_t x,
|
|
||||||
const struct Rijndael *ctx) {
|
|
||||||
uint32_t j;
|
|
||||||
__v16qu b1, b2;
|
|
||||||
x ^= ctx->rk[n--].xmm;
|
|
||||||
do {
|
|
||||||
b2 = b1 = (__v16qu)x;
|
|
||||||
for (j = 0; j < 16; ++j) {
|
|
||||||
b2[j] = kAesSboxInverse[b1[j % 4 + j * 13 / 4 % 4 * 4]];
|
|
||||||
}
|
|
||||||
x = (aes_block_t)b2;
|
|
||||||
if (n) x = InvMixColumns(x);
|
|
||||||
x ^= ctx->rk[n].xmm;
|
|
||||||
} while (n--);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypts paragraph w/ AES.
|
|
||||||
*
|
|
||||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
|
||||||
* @param x is 128-bit chunk of ciphertext to decrypt
|
|
||||||
* @param ctx was initialized by unrijndaelinit()
|
|
||||||
* @return result of transformation
|
|
||||||
*/
|
|
||||||
aes_block_t unrijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) {
|
|
||||||
if (X86_HAVE(AES)) {
|
|
||||||
return unrijndael_westmere(n, x, ctx);
|
|
||||||
} else {
|
|
||||||
return unrijndael_pure(n, x, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/assert.h"
|
|
||||||
#include "libc/bits/xmmintrin.internal.h"
|
|
||||||
#include "libc/crypto/rijndael.h"
|
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
|
||||||
|
|
||||||
static void unrijndaelinit_westmere(struct Rijndael *ctx, uint32_t n,
|
|
||||||
aes_block_t k1, aes_block_t k2) {
|
|
||||||
uint32_t i;
|
|
||||||
aes_block_t x;
|
|
||||||
assert(n > 1);
|
|
||||||
rijndaelinit(ctx, n, k1, k2);
|
|
||||||
i = 1;
|
|
||||||
do {
|
|
||||||
x = ctx->rk[i].xmm;
|
|
||||||
asm("aesimc\t%1,%0" : "=x"(x) : "0"(x));
|
|
||||||
ctx->rk[i].xmm = x;
|
|
||||||
} while (++i < n);
|
|
||||||
XMM_DESTROY(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static relegated noinline void unrijndaelinit_pure(struct Rijndael *ctx,
|
|
||||||
uint32_t n, aes_block_t k1,
|
|
||||||
aes_block_t k2) {
|
|
||||||
uint32_t i;
|
|
||||||
aes_block_t x;
|
|
||||||
assert(n > 1);
|
|
||||||
rijndaelinit(ctx, n, k1, k2);
|
|
||||||
i = 1;
|
|
||||||
do {
|
|
||||||
x = ctx->rk[i].xmm;
|
|
||||||
x = InvMixColumns(x);
|
|
||||||
ctx->rk[i].xmm = x;
|
|
||||||
} while (++i < n);
|
|
||||||
XMM_DESTROY(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes key schedule for unrijndael().
|
|
||||||
*
|
|
||||||
* @param rk receives round keys
|
|
||||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
|
||||||
* @param k1/k2 holds the master key
|
|
||||||
*/
|
|
||||||
void unrijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1,
|
|
||||||
aes_block_t k2) {
|
|
||||||
if (X86_HAVE(AES)) {
|
|
||||||
return unrijndaelinit_westmere(ctx, n, k1, k2);
|
|
||||||
} else {
|
|
||||||
return unrijndaelinit_pure(ctx, n, k1, k2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,7 +35,7 @@ static struct HostsTxtInitialStaticMemory {
|
||||||
char strings[64];
|
char strings[64];
|
||||||
} g_hoststxt_init;
|
} g_hoststxt_init;
|
||||||
|
|
||||||
static textwindows noinline char *getnthoststxtpath(char *pathbuf,
|
static textwindows noinline char *GetNtHostsTxtPath(char *pathbuf,
|
||||||
uint32_t size) {
|
uint32_t size) {
|
||||||
const char *const kWinHostsPath = "\\drivers\\etc\\hosts";
|
const char *const kWinHostsPath = "\\drivers\\etc\\hosts";
|
||||||
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
||||||
|
@ -49,7 +49,7 @@ static textwindows noinline char *getnthoststxtpath(char *pathbuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns parsed sorted singleton hardcoded hostname→ip4 map.
|
* Returns hosts.txt map.
|
||||||
*
|
*
|
||||||
* @note yoinking realloc() ensures there's no size limits
|
* @note yoinking realloc() ensures there's no size limits
|
||||||
*/
|
*/
|
||||||
|
@ -68,13 +68,12 @@ const struct HostsTxt *GetHostsTxt(void) {
|
||||||
__cxa_atexit(FreeHostsTxt, &g_hoststxt, NULL);
|
__cxa_atexit(FreeHostsTxt, &g_hoststxt, NULL);
|
||||||
path = "/etc/hosts";
|
path = "/etc/hosts";
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
path = firstnonnull(getnthoststxtpath(pathbuf, ARRAYLEN(pathbuf)), path);
|
path = firstnonnull(GetNtHostsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||||
}
|
}
|
||||||
if (!(f = fopen(path, "r")) || ParseHostsTxt(g_hoststxt, f) == -1) {
|
if (!(f = fopen(path, "r")) || ParseHostsTxt(g_hoststxt, f) == -1) {
|
||||||
/* TODO(jart): Elevate robustness. */
|
/* TODO(jart): Elevate robustness. */
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
SortHostsTxt(g_hoststxt);
|
|
||||||
}
|
}
|
||||||
return g_hoststxt;
|
return g_hoststxt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ struct HostsTxt {
|
||||||
const struct HostsTxt *GetHostsTxt(void) returnsnonnull;
|
const struct HostsTxt *GetHostsTxt(void) returnsnonnull;
|
||||||
void FreeHostsTxt(struct HostsTxt **) paramsnonnull();
|
void FreeHostsTxt(struct HostsTxt **) paramsnonnull();
|
||||||
int ParseHostsTxt(struct HostsTxt *, FILE *) paramsnonnull();
|
int ParseHostsTxt(struct HostsTxt *, FILE *) paramsnonnull();
|
||||||
void SortHostsTxt(struct HostsTxt *) paramsnonnull();
|
|
||||||
int ResolveHostsTxt(const struct HostsTxt *, int, const char *,
|
int ResolveHostsTxt(const struct HostsTxt *, int, const char *,
|
||||||
struct sockaddr *, uint32_t, const char **)
|
struct sockaddr *, uint32_t, const char **)
|
||||||
paramsnonnull((1, 3));
|
paramsnonnull((1, 3));
|
||||||
|
|
|
@ -59,7 +59,7 @@ int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
||||||
if (!resolvconf->nameservers.i) return 0;
|
if (!resolvconf->nameservers.i) return 0;
|
||||||
memset(&h, 0, sizeof(h));
|
memset(&h, 0, sizeof(h));
|
||||||
rc = ebadmsg();
|
rc = ebadmsg();
|
||||||
h.id = rand32();
|
h.id = rand64();
|
||||||
h.bf1 = 1; /* recursion desired */
|
h.bf1 = 1; /* recursion desired */
|
||||||
h.qdcount = 1;
|
h.qdcount = 1;
|
||||||
q.qname = name;
|
q.qname = name;
|
||||||
|
|
|
@ -68,7 +68,7 @@ int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
|
||||||
if (!resolvconf->nameservers.i) return 0;
|
if (!resolvconf->nameservers.i) return 0;
|
||||||
memset(&h, 0, sizeof(h));
|
memset(&h, 0, sizeof(h));
|
||||||
rc = ebadmsg();
|
rc = ebadmsg();
|
||||||
h.id = rand32();
|
h.id = rand64();
|
||||||
h.bf1 = 1; /* recursion desired */
|
h.bf1 = 1; /* recursion desired */
|
||||||
h.qdcount = 1;
|
h.qdcount = 1;
|
||||||
q.qname = name;
|
q.qname = name;
|
||||||
|
|
|
@ -1,8 +1,27 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/alg/alg.h"
|
#include "libc/alg/alg.h"
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/dns/consts.h"
|
#include "libc/dns/consts.h"
|
||||||
#include "libc/dns/dns.h"
|
#include "libc/dns/dns.h"
|
||||||
#include "libc/dns/hoststxt.h"
|
#include "libc/dns/hoststxt.h"
|
||||||
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
|
@ -16,30 +35,18 @@
|
||||||
* @param ip is IP address in binary (sin_addr)
|
* @param ip is IP address in binary (sin_addr)
|
||||||
* @param buf is buffer to store the name
|
* @param buf is buffer to store the name
|
||||||
* @param bufsize is length of buf
|
* @param bufsize is length of buf
|
||||||
*
|
|
||||||
* @return 1 if found, 0 if not found, or -1 w/ errno
|
* @return 1 if found, 0 if not found, or -1 w/ errno
|
||||||
* @error EAFNOSUPPORT
|
* @error EAFNOSUPPORT
|
||||||
*/
|
*/
|
||||||
int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip,
|
int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip,
|
||||||
char *buf, size_t bufsize) {
|
char *buf, size_t bufsize) {
|
||||||
struct HostsTxtEntry *entry = NULL;
|
size_t i;
|
||||||
uint32_t v1, v2;
|
|
||||||
|
|
||||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||||
if (!ht->entries.p || !buf || bufsize == 0) return -1;
|
for (i = 0; i < ht->entries.i; ++i) {
|
||||||
|
if (READ32LE(ip) == READ32LE(ht->entries.p[i].ip)) {
|
||||||
v1 = *((uint32_t *)ip);
|
snprintf(buf, bufsize, "%s", ht->strings.p + ht->entries.p[i].name);
|
||||||
for (size_t j = 0; j < ht->entries.i; j++) {
|
return 1;
|
||||||
v2 = *((uint32_t *)ht->entries.p[j].ip);
|
|
||||||
if (v1 == v2) {
|
|
||||||
entry = &(ht->entries.p[j]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
strncpy(buf, &ht->strings.p[entry->name], bufsize);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,17 +25,9 @@
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
static int hoststxtgetcmp(const char *node, const struct HostsTxtEntry *entry,
|
|
||||||
const char *strings) {
|
|
||||||
return CompareDnsNames(node, &strings[entry->name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds address associated with name in HOSTS.TXT table.
|
* Finds address associated with name in HOSTS.TXT table.
|
||||||
*
|
*
|
||||||
* This function performs binary search, so SortHostsTxt() must be
|
|
||||||
* called on the table beforehand.
|
|
||||||
*
|
|
||||||
* @param ht can be GetHostsTxt()
|
* @param ht can be GetHostsTxt()
|
||||||
* @param af can be AF_INET, AF_UNSPEC
|
* @param af can be AF_INET, AF_UNSPEC
|
||||||
* @param name can be a local or fully-qualified hostname
|
* @param name can be a local or fully-qualified hostname
|
||||||
|
@ -49,21 +41,22 @@ static int hoststxtgetcmp(const char *node, const struct HostsTxtEntry *entry,
|
||||||
int ResolveHostsTxt(const struct HostsTxt *ht, int af, const char *name,
|
int ResolveHostsTxt(const struct HostsTxt *ht, int af, const char *name,
|
||||||
struct sockaddr *addr, uint32_t addrsize,
|
struct sockaddr *addr, uint32_t addrsize,
|
||||||
const char **canon) {
|
const char **canon) {
|
||||||
|
size_t i;
|
||||||
struct sockaddr_in *addr4;
|
struct sockaddr_in *addr4;
|
||||||
struct HostsTxtEntry *entry;
|
|
||||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||||
if ((entry = bsearch_r(name, ht->entries.p, ht->entries.i,
|
for (i = 0; i < ht->entries.i; ++i) {
|
||||||
sizeof(struct HostsTxtEntry), (void *)hoststxtgetcmp,
|
if (!CompareDnsNames(name, ht->strings.p + ht->entries.p[i].name)) {
|
||||||
ht->strings.p))) {
|
if (addr) {
|
||||||
if (addr) {
|
if (addrsize < kMinSockaddr4Size) return einval();
|
||||||
if (addrsize < kMinSockaddr4Size) return einval();
|
addr4 = (struct sockaddr_in *)addr;
|
||||||
addr4 = (struct sockaddr_in *)addr;
|
addr4->sin_family = AF_INET;
|
||||||
addr4->sin_family = AF_INET;
|
memcpy(&addr4->sin_addr.s_addr, &ht->entries.p[i].ip[0], 4);
|
||||||
memcpy(&addr4->sin_addr.s_addr, &entry->ip[0], 4);
|
}
|
||||||
|
if (canon) {
|
||||||
|
*canon = ht->strings.p + ht->entries.p[i].canon;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (canon) *canon = &ht->strings.p[entry->canon];
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/alg/alg.h"
|
|
||||||
#include "libc/dns/dns.h"
|
|
||||||
#include "libc/dns/hoststxt.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares hostnames in HOSTS.TXT table.
|
|
||||||
* @see CompareDnsNames(), ParseHostsTxt()
|
|
||||||
*/
|
|
||||||
static int cmphoststxt(const struct HostsTxtEntry *e1,
|
|
||||||
const struct HostsTxtEntry *e2, const char *strings) {
|
|
||||||
if (e1 == e2) return 0;
|
|
||||||
return CompareDnsNames(&strings[e1->name], &strings[e2->name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts entries in HOSTS.TXT table.
|
|
||||||
*
|
|
||||||
* This function enables ResolveHostsTxt() to be called so hard-coded
|
|
||||||
* hostname lookups take logarithmic time; you can blackhole all the
|
|
||||||
* spam you want, in your /etc/hosts file.
|
|
||||||
*
|
|
||||||
* The sorted order, defined by CompareDnsNames(), also makes it
|
|
||||||
* possible to efficiently search for subdomains, once the initial sort
|
|
||||||
* is done.
|
|
||||||
*/
|
|
||||||
void SortHostsTxt(struct HostsTxt *ht) {
|
|
||||||
if (ht->entries.p) {
|
|
||||||
qsort_r(ht->entries.p, ht->entries.i, sizeof(*ht->entries.p),
|
|
||||||
(void *)cmphoststxt, ht->strings.p);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,8 @@
|
||||||
* format strings are constexprs that only contain directives.
|
* format strings are constexprs that only contain directives.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PFLINK(FMT) \
|
#define PFLINK(...) _PFLINK(__VA_ARGS__)
|
||||||
|
#define _PFLINK(FMT, ...) \
|
||||||
({ \
|
({ \
|
||||||
if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \
|
if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \
|
||||||
if (___PFLINK(FMT, strpbrk, "cmrqs")) { \
|
if (___PFLINK(FMT, strpbrk, "cmrqs")) { \
|
||||||
|
@ -34,7 +35,8 @@
|
||||||
FMT; \
|
FMT; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SFLINK(FMT) \
|
#define SFLINK(...) _SFLINK(__VA_ARGS__)
|
||||||
|
#define _SFLINK(FMT) \
|
||||||
({ \
|
({ \
|
||||||
if (___PFLINK(FMT, strchr, 'm')) { \
|
if (___PFLINK(FMT, strchr, 'm')) { \
|
||||||
STATIC_YOINK("malloc"); \
|
STATIC_YOINK("malloc"); \
|
||||||
|
|
|
@ -246,6 +246,30 @@
|
||||||
#define HUMPD int64_t
|
#define HUMPD int64_t
|
||||||
#define HWND int64_t
|
#define HWND int64_t
|
||||||
|
|
||||||
|
#define ADDRESS_FAMILY uint16_t
|
||||||
|
#define TUNNEL_TYPE uint32_t
|
||||||
|
#define NET_IF_CONNECTION_TYPE uint32_t
|
||||||
|
#define NET_IF_COMPARTMENT_ID uint32_t
|
||||||
|
#define IFTYPE uint32_t
|
||||||
|
#define NL_PREFIX_ORIGIN uint32_t
|
||||||
|
#define NL_SUFFIX_ORIGIN uint32_t
|
||||||
|
#define NL_DAD_STATE uint32_t
|
||||||
|
#define NET_IF_NETWORK_GUID struct NtGuid
|
||||||
|
#define IP_PREFIX_ORIGIN NL_PREFIX_ORIGIN
|
||||||
|
#define IP_SUFFIX_ORIGIN NL_SUFFIX_ORIGIN
|
||||||
|
#define IP_DAD_STATE NL_DAD_STATE
|
||||||
|
#define IP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses
|
||||||
|
#define PIP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses*
|
||||||
|
#define IP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh
|
||||||
|
#define PIP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh*
|
||||||
|
#define IP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp
|
||||||
|
#define PIP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp*
|
||||||
|
#define IP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp
|
||||||
|
#define PIP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp*
|
||||||
|
#define IP_ADAPTER_DNS_SERVER_ADDRESS struct NtIpAdapterDnsServerAddressXp
|
||||||
|
#define IP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp
|
||||||
|
#define PIP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp*
|
||||||
|
|
||||||
#define _GENERIC_MAPPING NtGenericMapping
|
#define _GENERIC_MAPPING NtGenericMapping
|
||||||
#define GENERIC_MAPPING struct NtGenericMapping
|
#define GENERIC_MAPPING struct NtGenericMapping
|
||||||
#define PGENERIC_MAPPING struct NtGenericMapping*
|
#define PGENERIC_MAPPING struct NtGenericMapping*
|
||||||
|
|
|
@ -88,4 +88,13 @@ __oncrash_sigbus:
|
||||||
ret
|
ret
|
||||||
.endfn __oncrash_sigbus,globl
|
.endfn __oncrash_sigbus,globl
|
||||||
|
|
||||||
|
.org 11*7
|
||||||
|
__oncrash_sigpipe:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
call __oncrash
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
|
.endfn __oncrash_sigpipe,globl
|
||||||
|
|
||||||
.endobj __oncrash_thunks,globl
|
.endobj __oncrash_thunks,globl
|
||||||
|
|
|
@ -16,15 +16,18 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/typedef/sigaction_f.h"
|
#include "libc/calls/typedef/sigaction_f.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/internal.h"
|
#include "libc/log/internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/signals.h"
|
#include "libc/nt/signals.h"
|
||||||
|
#include "libc/runtime/symbols.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
|
@ -61,6 +64,7 @@ void showcrashreports(void) {
|
||||||
kCrashSigs[4] = SIGTRAP; /* bad system call */
|
kCrashSigs[4] = SIGTRAP; /* bad system call */
|
||||||
kCrashSigs[5] = SIGABRT; /* abort() called */
|
kCrashSigs[5] = SIGABRT; /* abort() called */
|
||||||
kCrashSigs[6] = SIGBUS; /* misaligned, noncanonical ptr, etc. */
|
kCrashSigs[6] = SIGBUS; /* misaligned, noncanonical ptr, etc. */
|
||||||
|
kCrashSigs[7] = SIGPIPE; /* write to closed thing */
|
||||||
/* </SYNC-LIST>: oncrashthunks.S */
|
/* </SYNC-LIST>: oncrashthunks.S */
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_flags = SA_RESETHAND;
|
sa.sa_flags = SA_RESETHAND;
|
||||||
|
|
|
@ -40,20 +40,7 @@
|
||||||
static struct timespec vflogf_ts;
|
static struct timespec vflogf_ts;
|
||||||
|
|
||||||
static int vflogf_loglevel2char(unsigned level) {
|
static int vflogf_loglevel2char(unsigned level) {
|
||||||
switch (level) {
|
return "FEWIVDYZ"[level & 7];
|
||||||
case kLogInfo:
|
|
||||||
return 'I';
|
|
||||||
case kLogDebug:
|
|
||||||
return 'D';
|
|
||||||
case kLogWarn:
|
|
||||||
return 'W';
|
|
||||||
case kLogFatal:
|
|
||||||
return 'F';
|
|
||||||
case kLogVerbose:
|
|
||||||
return 'V';
|
|
||||||
default:
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,63 +3,20 @@
|
||||||
#include "libc/nexgen32e/kcpuids.h"
|
#include "libc/nexgen32e/kcpuids.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
|
||||||
/*
|
#define IsAuthenticAMD() \
|
||||||
* Known 80x86 Vendors (CPUID.0 EBX+EDX+ECX)
|
(kCpuids[KCPUIDS_0H][KCPUIDS_EBX] == 0x68747541 /* Auth */ && \
|
||||||
*
|
kCpuids[KCPUIDS_0H][KCPUIDS_EDX] == 0x69746e65 /* enti */ && \
|
||||||
* ╤ ╤
|
kCpuids[KCPUIDS_0H][KCPUIDS_ECX] == 0x444d4163 /* cAMD */)
|
||||||
* GenuineIntel
|
|
||||||
* AuthenticAMD
|
|
||||||
* GenuineCosmo
|
|
||||||
* NexGenDriven
|
|
||||||
* AMDisbetter!
|
|
||||||
* CentaurHauls
|
|
||||||
* TransmetaCPU
|
|
||||||
* GenuineTMx86
|
|
||||||
* CyrixInstead
|
|
||||||
* UMC UMC UMC
|
|
||||||
* SiS SiS SiS
|
|
||||||
* Geode by NSC
|
|
||||||
* RiseRiseRise
|
|
||||||
* Vortex86 SoC
|
|
||||||
* VIA VIA VIA
|
|
||||||
* VMwareVMware
|
|
||||||
* XenVMMXenVMM
|
|
||||||
* Microsoft Hv
|
|
||||||
* └────┐ │
|
|
||||||
* G ⊕ t = 0x33 Intel
|
|
||||||
* A ⊕ A = 0x00 AMD
|
|
||||||
* G ⊕ s = 0x34 Cosmopolitan
|
|
||||||
* N ⊕ v = 0x38 NexGen (Modern x86)
|
|
||||||
* A ⊕ e = 0x24 AMD (Rank & File)
|
|
||||||
* C ⊕ u = 0x36 Via (DBA Centaur)
|
|
||||||
* T ⊕ C = 0x17 Transmeta (Historical)
|
|
||||||
* G ⊕ x = 0x3f Transmeta (Historical)
|
|
||||||
* C ⊕ e = 0x26 Cyrix (Historical)
|
|
||||||
* U ⊕ M = 0x18 UMC (Taiwan)
|
|
||||||
* S ⊕ i = 0x3a SiS (Historical)
|
|
||||||
* G ⊕ N = 0x09 National Semiconductors (OLPC)
|
|
||||||
* R ⊕ i = 0x3b Rise Technology (Historical)
|
|
||||||
* V ⊕ S = 0x05 DM&P (Vortex86)
|
|
||||||
* V ⊕ I = 0x1f Via
|
|
||||||
* V ⊕ a = 0x37 VMware
|
|
||||||
* X ⊕ V = 0x0e Xen
|
|
||||||
* M ⊕ = 0x6d Microsoft (Win10 Hyper-V)
|
|
||||||
* │ │
|
|
||||||
* │ │ perfect
|
|
||||||
* │ │ (𝑠)=𝑠₀⊕𝑠₉
|
|
||||||
* ╧ ╧
|
|
||||||
*
|
|
||||||
* @note Parallels Desktop CPU brand string is " lrpepyh vr " since even
|
|
||||||
* folks designing microprocessor emulators apparently struggle w/
|
|
||||||
* endianness lool.
|
|
||||||
*/
|
|
||||||
#define IsAuthenticAMD() (_KCPUIDS_VENDOR() == 0x00)
|
|
||||||
#define IsGenuineIntel() (_KCPUIDS_VENDOR() == 0x33)
|
|
||||||
#define IsGenuineCosmo() (_KCPUIDS_VENDOR() == 0x34)
|
|
||||||
|
|
||||||
#define _KCPUIDS_VENDOR() \
|
#define IsGenuineIntel() \
|
||||||
(((kCpuids[KCPUIDS_0H][KCPUIDS_EBX] >> 000) & 0xff) ^ \
|
(kCpuids[KCPUIDS_0H][KCPUIDS_EBX] == 0x756e6547 /* Genu */ && \
|
||||||
((kCpuids[KCPUIDS_0H][KCPUIDS_ECX] >> 010) & 0xff))
|
kCpuids[KCPUIDS_0H][KCPUIDS_EDX] == 0x49656e69 /* ineI */ && \
|
||||||
|
kCpuids[KCPUIDS_0H][KCPUIDS_ECX] == 0x6c65746e /* ntel */)
|
||||||
|
|
||||||
|
#define IsGenuineCosmo() \
|
||||||
|
(kCpuids[KCPUIDS_0H][KCPUIDS_EBX] == 0x756e6547 /* Genu */ && \
|
||||||
|
kCpuids[KCPUIDS_0H][KCPUIDS_EDX] == 0x43656e69 /* ineC */ && \
|
||||||
|
kCpuids[KCPUIDS_0H][KCPUIDS_ECX] == 0x6f6d736f /* osmo */)
|
||||||
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ */
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#define kX86CpuExtfamilyid ((KCPUIDS(1H, EAX) >> 20) & 255)
|
#define kX86CpuExtfamilyid ((KCPUIDS(1H, EAX) >> 20) & 255)
|
||||||
|
|
||||||
#define kX86CpuFamily \
|
#define kX86CpuFamily \
|
||||||
(kX86CpuFamilyid + (kX86CpuFamily == 15 ? kX86CpuExtfamilyid : 0))
|
(kX86CpuFamilyid + (kX86CpuFamilyid == 15 ? kX86CpuExtfamilyid : 0))
|
||||||
|
|
||||||
#define kX86CpuModel \
|
#define kX86CpuModel \
|
||||||
(kX86CpuModelid | \
|
(kX86CpuModelid | \
|
||||||
(kX86CpuFamily == 6 || kX86CpuFamily == 15 ? kX86CpuExtmodelid : 0) << 4)
|
(kX86CpuFamilyid == 6 || kX86CpuFamilyid == 15 ? kX86CpuExtmodelid : 0) \
|
||||||
|
<< 4)
|
||||||
|
|
||||||
#define kX86ProcessorModelKey \
|
#define kX86ProcessorModelKey \
|
||||||
(kX86CpuExtfamilyid << 12 | kX86CpuFamilyid << 8 | kX86CpuExtmodelid << 4 | \
|
(kX86CpuExtfamilyid << 12 | kX86CpuFamilyid << 8 | kX86CpuExtmodelid << 4 | \
|
||||||
|
|
12
libc/nt/advapi32/SystemFunction036.s
Normal file
12
libc/nt/advapi32/SystemFunction036.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp advapi32,__imp_SystemFunction036,SystemFunction036,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
RtlGenRandom:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_SystemFunction036(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn RtlGenRandom,globl
|
||||||
|
.previous
|
392
libc/nt/enum/lang.h
Normal file
392
libc/nt/enum/lang.h
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_LANG_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_NT_ENUM_LANG_H_
|
||||||
|
|
||||||
|
#define MAKELANGID(p, s) ((((uint16_t)(s)) << 10) | (uint16_t)(p))
|
||||||
|
|
||||||
|
#define kNtLangNeutral 0x00
|
||||||
|
#define kNtLangInvariant 0x7f
|
||||||
|
#define kNtLangAfrikaans 0x36
|
||||||
|
#define kNtLangAlbanian 0x1c
|
||||||
|
#define kNtLangAlsatian 0x84
|
||||||
|
#define kNtLangAmharic 0x5e
|
||||||
|
#define kNtLangArabic 0x01
|
||||||
|
#define kNtLangArmenian 0x2b
|
||||||
|
#define kNtLangAssamese 0x4d
|
||||||
|
#define kNtLangAzeri 0x2c
|
||||||
|
#define kNtLangAzerbaijani 0x2c
|
||||||
|
#define kNtLangBangla 0x45
|
||||||
|
#define kNtLangBashkir 0x6d
|
||||||
|
#define kNtLangBasque 0x2d
|
||||||
|
#define kNtLangBelarusian 0x23
|
||||||
|
#define kNtLangBengali 0x45
|
||||||
|
#define kNtLangBreton 0x7e
|
||||||
|
#define kNtLangBosnian 0x1a
|
||||||
|
#define kNtLangBosnianNeutral 0x781a
|
||||||
|
#define kNtLangBulgarian 0x02
|
||||||
|
#define kNtLangCatalan 0x03
|
||||||
|
#define kNtLangCentralKurdish 0x92
|
||||||
|
#define kNtLangCherokee 0x5c
|
||||||
|
#define kNtLangChinese 0x04
|
||||||
|
#define kNtLangChineseSimplified 0x04
|
||||||
|
#define kNtLangChineseTraditional 0x7c04
|
||||||
|
#define kNtLangCorsican 0x83
|
||||||
|
#define kNtLangCroatian 0x1a
|
||||||
|
#define kNtLangCzech 0x05
|
||||||
|
#define kNtLangDanish 0x06
|
||||||
|
#define kNtLangDari 0x8c
|
||||||
|
#define kNtLangDivehi 0x65
|
||||||
|
#define kNtLangDutch 0x13
|
||||||
|
#define kNtLangEnglish 0x09
|
||||||
|
#define kNtLangEstonian 0x25
|
||||||
|
#define kNtLangFaeroese 0x38
|
||||||
|
#define kNtLangFarsi 0x29
|
||||||
|
#define kNtLangFilipino 0x64
|
||||||
|
#define kNtLangFinnish 0x0b
|
||||||
|
#define kNtLangFrench 0x0c
|
||||||
|
#define kNtLangFrisian 0x62
|
||||||
|
#define kNtLangFulah 0x67
|
||||||
|
#define kNtLangGalician 0x56
|
||||||
|
#define kNtLangGeorgian 0x37
|
||||||
|
#define kNtLangGerman 0x07
|
||||||
|
#define kNtLangGreek 0x08
|
||||||
|
#define kNtLangGreenlandic 0x6f
|
||||||
|
#define kNtLangGujarati 0x47
|
||||||
|
#define kNtLangHausa 0x68
|
||||||
|
#define kNtLangHawaiian 0x75
|
||||||
|
#define kNtLangHebrew 0x0d
|
||||||
|
#define kNtLangHindi 0x39
|
||||||
|
#define kNtLangHungarian 0x0e
|
||||||
|
#define kNtLangIcelandic 0x0f
|
||||||
|
#define kNtLangIgbo 0x70
|
||||||
|
#define kNtLangIndonesian 0x21
|
||||||
|
#define kNtLangInuktitut 0x5d
|
||||||
|
#define kNtLangIrish 0x3c
|
||||||
|
#define kNtLangItalian 0x10
|
||||||
|
#define kNtLangJapanese 0x11
|
||||||
|
#define kNtLangKannada 0x4b
|
||||||
|
#define kNtLangKashmiri 0x60
|
||||||
|
#define kNtLangKazak 0x3f
|
||||||
|
#define kNtLangKhmer 0x53
|
||||||
|
#define kNtLangKiche 0x86
|
||||||
|
#define kNtLangKinyarwanda 0x87
|
||||||
|
#define kNtLangKonkani 0x57
|
||||||
|
#define kNtLangKorean 0x12
|
||||||
|
#define kNtLangKyrgyz 0x40
|
||||||
|
#define kNtLangLao 0x54
|
||||||
|
#define kNtLangLatvian 0x26
|
||||||
|
#define kNtLangLithuanian 0x27
|
||||||
|
#define kNtLangLowerSorbian 0x2e
|
||||||
|
#define kNtLangLuxembourgish 0x6e
|
||||||
|
#define kNtLangMacedonian 0x2f
|
||||||
|
#define kNtLangMalay 0x3e
|
||||||
|
#define kNtLangMalayalam 0x4c
|
||||||
|
#define kNtLangMaltese 0x3a
|
||||||
|
#define kNtLangManipuri 0x58
|
||||||
|
#define kNtLangMaori 0x81
|
||||||
|
#define kNtLangMapudungun 0x7a
|
||||||
|
#define kNtLangMarathi 0x4e
|
||||||
|
#define kNtLangMohawk 0x7c
|
||||||
|
#define kNtLangMongolian 0x50
|
||||||
|
#define kNtLangNepali 0x61
|
||||||
|
#define kNtLangNorwegian 0x14
|
||||||
|
#define kNtLangOccitan 0x82
|
||||||
|
#define kNtLangOdia 0x48
|
||||||
|
#define kNtLangOriya 0x48
|
||||||
|
#define kNtLangPashto 0x63
|
||||||
|
#define kNtLangPersian 0x29
|
||||||
|
#define kNtLangPolish 0x15
|
||||||
|
#define kNtLangPortuguese 0x16
|
||||||
|
#define kNtLangPular 0x67
|
||||||
|
#define kNtLangPunjabi 0x46
|
||||||
|
#define kNtLangQuechua 0x6b
|
||||||
|
#define kNtLangRomanian 0x18
|
||||||
|
#define kNtLangRomansh 0x17
|
||||||
|
#define kNtLangRussian 0x19
|
||||||
|
#define kNtLangSakha 0x85
|
||||||
|
#define kNtLangSami 0x3b
|
||||||
|
#define kNtLangSanskrit 0x4f
|
||||||
|
#define kNtLangScottishGaelic 0x91
|
||||||
|
#define kNtLangSerbian 0x1a
|
||||||
|
#define kNtLangSerbianNeutral 0x7c1a
|
||||||
|
#define kNtLangSindhi 0x59
|
||||||
|
#define kNtLangSinhalese 0x5b
|
||||||
|
#define kNtLangSlovak 0x1b
|
||||||
|
#define kNtLangSlovenian 0x24
|
||||||
|
#define kNtLangSotho 0x6c
|
||||||
|
#define kNtLangSpanish 0x0a
|
||||||
|
#define kNtLangSwahili 0x41
|
||||||
|
#define kNtLangSwedish 0x1d
|
||||||
|
#define kNtLangSyriac 0x5a
|
||||||
|
#define kNtLangTajik 0x28
|
||||||
|
#define kNtLangTamazight 0x5f
|
||||||
|
#define kNtLangTamil 0x49
|
||||||
|
#define kNtLangTatar 0x44
|
||||||
|
#define kNtLangTelugu 0x4a
|
||||||
|
#define kNtLangThai 0x1e
|
||||||
|
#define kNtLangTibetan 0x51
|
||||||
|
#define kNtLangTigrigna 0x73
|
||||||
|
#define kNtLangTigrinya 0x73
|
||||||
|
#define kNtLangTswana 0x32
|
||||||
|
#define kNtLangTurkish 0x1f
|
||||||
|
#define kNtLangTurkmen 0x42
|
||||||
|
#define kNtLangUighur 0x80
|
||||||
|
#define kNtLangUkrainian 0x22
|
||||||
|
#define kNtLangUpperSorbian 0x2e
|
||||||
|
#define kNtLangUrdu 0x20
|
||||||
|
#define kNtLangUzbek 0x43
|
||||||
|
#define kNtLangValencian 0x03
|
||||||
|
#define kNtLangVietnamese 0x2a
|
||||||
|
#define kNtLangWelsh 0x52
|
||||||
|
#define kNtLangWolof 0x88
|
||||||
|
#define kNtLangXhosa 0x34
|
||||||
|
#define kNtLangYakut 0x85
|
||||||
|
#define kNtLangYi 0x78
|
||||||
|
#define kNtLangYoruba 0x6a
|
||||||
|
#define kNtLangZulu 0x35
|
||||||
|
|
||||||
|
#define kNtSublangNeutral 0x00
|
||||||
|
#define kNtSublangDefault 0x01
|
||||||
|
#define kNtSublangSysDefault 0x02
|
||||||
|
#define kNtSublangCustomDefault 0x03
|
||||||
|
#define kNtSublangCustomUnspecified 0x04
|
||||||
|
#define kNtSublangUiCustomDefault 0x05
|
||||||
|
#define kNtSublangAfrikaansSouthAfrica 0x01
|
||||||
|
#define kNtSublangAlbanianAlbania 0x01
|
||||||
|
#define kNtSublangAlsatianFrance 0x01
|
||||||
|
#define kNtSublangAmharicEthiopia 0x01
|
||||||
|
#define kNtSublangArabicSaudiArabia 0x01
|
||||||
|
#define kNtSublangArabicIraq 0x02
|
||||||
|
#define kNtSublangArabicEgypt 0x03
|
||||||
|
#define kNtSublangArabicLibya 0x04
|
||||||
|
#define kNtSublangArabicAlgeria 0x05
|
||||||
|
#define kNtSublangArabicMorocco 0x06
|
||||||
|
#define kNtSublangArabicTunisia 0x07
|
||||||
|
#define kNtSublangArabicOman 0x08
|
||||||
|
#define kNtSublangArabicYemen 0x09
|
||||||
|
#define kNtSublangArabicSyria 0x0a
|
||||||
|
#define kNtSublangArabicJordan 0x0b
|
||||||
|
#define kNtSublangArabicLebanon 0x0c
|
||||||
|
#define kNtSublangArabicKuwait 0x0d
|
||||||
|
#define kNtSublangArabicUae 0x0e
|
||||||
|
#define kNtSublangArabicBahrain 0x0f
|
||||||
|
#define kNtSublangArabicQatar 0x10
|
||||||
|
#define kNtSublangArmenianArmenia 0x01
|
||||||
|
#define kNtSublangAssameseIndia 0x01
|
||||||
|
#define kNtSublangAzeriLatin 0x01
|
||||||
|
#define kNtSublangAzeriCyrillic 0x02
|
||||||
|
#define kNtSublangAzerbaijaniAzerbaijanLatin 0x01
|
||||||
|
#define kNtSublangAzerbaijaniAzerbaijanCyrillic 0x02
|
||||||
|
#define kNtSublangBanglaIndia 0x01
|
||||||
|
#define kNtSublangBanglaBangladesh 0x02
|
||||||
|
#define kNtSublangBashkirRussia 0x01
|
||||||
|
#define kNtSublangBasqueBasque 0x01
|
||||||
|
#define kNtSublangBelarusianBelarus 0x01
|
||||||
|
#define kNtSublangBengaliIndia 0x01
|
||||||
|
#define kNtSublangBengaliBangladesh 0x02
|
||||||
|
#define kNtSublangBosnianBosniaHerzegovinaLatin 0x05
|
||||||
|
#define kNtSublangBosnianBosniaHerzegovinaCyrillic 0x08
|
||||||
|
#define kNtSublangBretonFrance 0x01
|
||||||
|
#define kNtSublangBulgarianBulgaria 0x01
|
||||||
|
#define kNtSublangCatalanCatalan 0x01
|
||||||
|
#define kNtSublangCentralKurdishIraq 0x01
|
||||||
|
#define kNtSublangCherokeeCherokee 0x01
|
||||||
|
#define kNtSublangChineseTraditional 0x01
|
||||||
|
#define kNtSublangChineseSimplified 0x02
|
||||||
|
#define kNtSublangChineseHongkong 0x03
|
||||||
|
#define kNtSublangChineseSingapore 0x04
|
||||||
|
#define kNtSublangChineseMacau 0x05
|
||||||
|
#define kNtSublangCorsicanFrance 0x01
|
||||||
|
#define kNtSublangCzechCzechRepublic 0x01
|
||||||
|
#define kNtSublangCroatianCroatia 0x01
|
||||||
|
#define kNtSublangCroatianBosniaHerzegovinaLatin 0x04
|
||||||
|
#define kNtSublangDanishDenmark 0x01
|
||||||
|
#define kNtSublangDariAfghanistan 0x01
|
||||||
|
#define kNtSublangDivehiMaldives 0x01
|
||||||
|
#define kNtSublangDutch 0x01
|
||||||
|
#define kNtSublangDutchBelgian 0x02
|
||||||
|
#define kNtSublangEnglishUs 0x01
|
||||||
|
#define kNtSublangEnglishUk 0x02
|
||||||
|
#define kNtSublangEnglishAus 0x03
|
||||||
|
#define kNtSublangEnglishCan 0x04
|
||||||
|
#define kNtSublangEnglishNz 0x05
|
||||||
|
#define kNtSublangEnglishEire 0x06
|
||||||
|
#define kNtSublangEnglishSouthAfrica 0x07
|
||||||
|
#define kNtSublangEnglishJamaica 0x08
|
||||||
|
#define kNtSublangEnglishCaribbean 0x09
|
||||||
|
#define kNtSublangEnglishBelize 0x0a
|
||||||
|
#define kNtSublangEnglishTrinidad 0x0b
|
||||||
|
#define kNtSublangEnglishZimbabwe 0x0c
|
||||||
|
#define kNtSublangEnglishPhilippines 0x0d
|
||||||
|
#define kNtSublangEnglishIndia 0x10
|
||||||
|
#define kNtSublangEnglishMalaysia 0x11
|
||||||
|
#define kNtSublangEnglishSingapore 0x12
|
||||||
|
#define kNtSublangEstonianEstonia 0x01
|
||||||
|
#define kNtSublangFaeroeseFaroeIslands 0x01
|
||||||
|
#define kNtSublangFilipinoPhilippines 0x01
|
||||||
|
#define kNtSublangFinnishFinland 0x01
|
||||||
|
#define kNtSublangFrench 0x01
|
||||||
|
#define kNtSublangFrenchBelgian 0x02
|
||||||
|
#define kNtSublangFrenchCanadian 0x03
|
||||||
|
#define kNtSublangFrenchSwiss 0x04
|
||||||
|
#define kNtSublangFrenchLuxembourg 0x05
|
||||||
|
#define kNtSublangFrenchMonaco 0x06
|
||||||
|
#define kNtSublangFrisianNetherlands 0x01
|
||||||
|
#define kNtSublangFulahSenegal 0x02
|
||||||
|
#define kNtSublangGalicianGalician 0x01
|
||||||
|
#define kNtSublangGeorgianGeorgia 0x01
|
||||||
|
#define kNtSublangGerman 0x01
|
||||||
|
#define kNtSublangGermanSwiss 0x02
|
||||||
|
#define kNtSublangGermanAustrian 0x03
|
||||||
|
#define kNtSublangGermanLuxembourg 0x04
|
||||||
|
#define kNtSublangGermanLiechtenstein 0x05
|
||||||
|
#define kNtSublangGreekGreece 0x01
|
||||||
|
#define kNtSublangGreenlandicGreenland 0x01
|
||||||
|
#define kNtSublangGujaratiIndia 0x01
|
||||||
|
#define kNtSublangHausaNigeriaLatin 0x01
|
||||||
|
#define kNtSublangHawaiianUs 0x01
|
||||||
|
#define kNtSublangHebrewIsrael 0x01
|
||||||
|
#define kNtSublangHindiIndia 0x01
|
||||||
|
#define kNtSublangHungarianHungary 0x01
|
||||||
|
#define kNtSublangIcelandicIceland 0x01
|
||||||
|
#define kNtSublangIgboNigeria 0x01
|
||||||
|
#define kNtSublangIndonesianIndonesia 0x01
|
||||||
|
#define kNtSublangInuktitutCanada 0x01
|
||||||
|
#define kNtSublangInuktitutCanadaLatin 0x02
|
||||||
|
#define kNtSublangIrishIreland 0x02
|
||||||
|
#define kNtSublangItalian 0x01
|
||||||
|
#define kNtSublangItalianSwiss 0x02
|
||||||
|
#define kNtSublangJapaneseJapan 0x01
|
||||||
|
#define kNtSublangKannadaIndia 0x01
|
||||||
|
#define kNtSublangKashmiriSasia 0x02
|
||||||
|
#define kNtSublangKashmiriIndia 0x02
|
||||||
|
#define kNtSublangKazakKazakhstan 0x01
|
||||||
|
#define kNtSublangKhmerCambodia 0x01
|
||||||
|
#define kNtSublangKicheGuatemala 0x01
|
||||||
|
#define kNtSublangKinyarwandaRwanda 0x01
|
||||||
|
#define kNtSublangKonkaniIndia 0x01
|
||||||
|
#define kNtSublangKorean 0x01
|
||||||
|
#define kNtSublangKyrgyzKyrgyzstan 0x01
|
||||||
|
#define kNtSublangLaoLao 0x01
|
||||||
|
#define kNtSublangLatvianLatvia 0x01
|
||||||
|
#define kNtSublangLithuanian 0x01
|
||||||
|
#define kNtSublangLowerSorbianGermany 0x02
|
||||||
|
#define kNtSublangLuxembourgishLuxembourg 0x01
|
||||||
|
#define kNtSublangMacedonianMacedonia 0x01
|
||||||
|
#define kNtSublangMalayMalaysia 0x01
|
||||||
|
#define kNtSublangMalayBruneiDarussalam 0x02
|
||||||
|
#define kNtSublangMalayalamIndia 0x01
|
||||||
|
#define kNtSublangMalteseMalta 0x01
|
||||||
|
#define kNtSublangMaoriNewZealand 0x01
|
||||||
|
#define kNtSublangMapudungunChile 0x01
|
||||||
|
#define kNtSublangMarathiIndia 0x01
|
||||||
|
#define kNtSublangMohawkMohawk 0x01
|
||||||
|
#define kNtSublangMongolianCyrillicMongolia 0x01
|
||||||
|
#define kNtSublangMongolianPrc 0x02
|
||||||
|
#define kNtSublangNepaliIndia 0x02
|
||||||
|
#define kNtSublangNepaliNepal 0x01
|
||||||
|
#define kNtSublangNorwegianBokmal 0x01
|
||||||
|
#define kNtSublangNorwegianNynorsk 0x02
|
||||||
|
#define kNtSublangOccitanFrance 0x01
|
||||||
|
#define kNtSublangOdiaIndia 0x01
|
||||||
|
#define kNtSublangOriyaIndia 0x01
|
||||||
|
#define kNtSublangPashtoAfghanistan 0x01
|
||||||
|
#define kNtSublangPersianIran 0x01
|
||||||
|
#define kNtSublangPolishPoland 0x01
|
||||||
|
#define kNtSublangPortuguese 0x02
|
||||||
|
#define kNtSublangPortugueseBrazilian 0x01
|
||||||
|
#define kNtSublangPularSenegal 0x02
|
||||||
|
#define kNtSublangPunjabiIndia 0x01
|
||||||
|
#define kNtSublangPunjabiPakistan 0x02
|
||||||
|
#define kNtSublangQuechuaBolivia 0x01
|
||||||
|
#define kNtSublangQuechuaEcuador 0x02
|
||||||
|
#define kNtSublangQuechuaPeru 0x03
|
||||||
|
#define kNtSublangRomanianRomania 0x01
|
||||||
|
#define kNtSublangRomanshSwitzerland 0x01
|
||||||
|
#define kNtSublangRussianRussia 0x01
|
||||||
|
#define kNtSublangSakhaRussia 0x01
|
||||||
|
#define kNtSublangSamiNorthernNorway 0x01
|
||||||
|
#define kNtSublangSamiNorthernSweden 0x02
|
||||||
|
#define kNtSublangSamiNorthernFinland 0x03
|
||||||
|
#define kNtSublangSamiLuleNorway 0x04
|
||||||
|
#define kNtSublangSamiLuleSweden 0x05
|
||||||
|
#define kNtSublangSamiSouthernNorway 0x06
|
||||||
|
#define kNtSublangSamiSouthernSweden 0x07
|
||||||
|
#define kNtSublangSamiSkoltFinland 0x08
|
||||||
|
#define kNtSublangSamiInariFinland 0x09
|
||||||
|
#define kNtSublangSanskritIndia 0x01
|
||||||
|
#define kNtSublangScottishGaelic 0x01
|
||||||
|
#define kNtSublangSerbianBosniaHerzegovinaLatin 0x06
|
||||||
|
#define kNtSublangSerbianBosniaHerzegovinaCyrillic 0x07
|
||||||
|
#define kNtSublangSerbianMontenegroLatin 0x0b
|
||||||
|
#define kNtSublangSerbianMontenegroCyrillic 0x0c
|
||||||
|
#define kNtSublangSerbianSerbiaLatin 0x09
|
||||||
|
#define kNtSublangSerbianSerbiaCyrillic 0x0a
|
||||||
|
#define kNtSublangSerbianCroatia 0x01
|
||||||
|
#define kNtSublangSerbianLatin 0x02
|
||||||
|
#define kNtSublangSerbianCyrillic 0x03
|
||||||
|
#define kNtSublangSindhiIndia 0x01
|
||||||
|
#define kNtSublangSindhiPakistan 0x02
|
||||||
|
#define kNtSublangSindhiAfghanistan 0x02
|
||||||
|
#define kNtSublangSinhaleseSriLanka 0x01
|
||||||
|
#define kNtSublangSothoNorthernSouthAfrica 0x01
|
||||||
|
#define kNtSublangSlovakSlovakia 0x01
|
||||||
|
#define kNtSublangSlovenianSlovenia 0x01
|
||||||
|
#define kNtSublangSpanish 0x01
|
||||||
|
#define kNtSublangSpanishMexican 0x02
|
||||||
|
#define kNtSublangSpanishModern 0x03
|
||||||
|
#define kNtSublangSpanishGuatemala 0x04
|
||||||
|
#define kNtSublangSpanishCostaRica 0x05
|
||||||
|
#define kNtSublangSpanishPanama 0x06
|
||||||
|
#define kNtSublangSpanishDominicanRepublic 0x07
|
||||||
|
#define kNtSublangSpanishVenezuela 0x08
|
||||||
|
#define kNtSublangSpanishColombia 0x09
|
||||||
|
#define kNtSublangSpanishPeru 0x0a
|
||||||
|
#define kNtSublangSpanishArgentina 0x0b
|
||||||
|
#define kNtSublangSpanishEcuador 0x0c
|
||||||
|
#define kNtSublangSpanishChile 0x0d
|
||||||
|
#define kNtSublangSpanishUruguay 0x0e
|
||||||
|
#define kNtSublangSpanishParaguay 0x0f
|
||||||
|
#define kNtSublangSpanishBolivia 0x10
|
||||||
|
#define kNtSublangSpanishElSalvador 0x11
|
||||||
|
#define kNtSublangSpanishHonduras 0x12
|
||||||
|
#define kNtSublangSpanishNicaragua 0x13
|
||||||
|
#define kNtSublangSpanishPuertoRico 0x14
|
||||||
|
#define kNtSublangSpanishUs 0x15
|
||||||
|
#define kNtSublangSwahiliKenya 0x01
|
||||||
|
#define kNtSublangSwedish 0x01
|
||||||
|
#define kNtSublangSwedishFinland 0x02
|
||||||
|
#define kNtSublangSyriacSyria 0x01
|
||||||
|
#define kNtSublangTajikTajikistan 0x01
|
||||||
|
#define kNtSublangTamazightAlgeriaLatin 0x02
|
||||||
|
#define kNtSublangTamazightMoroccoTifinagh 0x04
|
||||||
|
#define kNtSublangTamilIndia 0x01
|
||||||
|
#define kNtSublangTamilSriLanka 0x02
|
||||||
|
#define kNtSublangTatarRussia 0x01
|
||||||
|
#define kNtSublangTeluguIndia 0x01
|
||||||
|
#define kNtSublangThaiThailand 0x01
|
||||||
|
#define kNtSublangTibetanPrc 0x01
|
||||||
|
#define kNtSublangTigrignaEritrea 0x02
|
||||||
|
#define kNtSublangTigrinyaEritrea 0x02
|
||||||
|
#define kNtSublangTigrinyaEthiopia 0x01
|
||||||
|
#define kNtSublangTswanaBotswana 0x02
|
||||||
|
#define kNtSublangTswanaSouthAfrica 0x01
|
||||||
|
#define kNtSublangTurkishTurkey 0x01
|
||||||
|
#define kNtSublangTurkmenTurkmenistan 0x01
|
||||||
|
#define kNtSublangUighurPrc 0x01
|
||||||
|
#define kNtSublangUkrainianUkraine 0x01
|
||||||
|
#define kNtSublangUpperSorbianGermany 0x01
|
||||||
|
#define kNtSublangUrduPakistan 0x01
|
||||||
|
#define kNtSublangUrduIndia 0x02
|
||||||
|
#define kNtSublangUzbekLatin 0x01
|
||||||
|
#define kNtSublangUzbekCyrillic 0x02
|
||||||
|
#define kNtSublangValencianValencia 0x02
|
||||||
|
#define kNtSublangVietnameseVietnam 0x01
|
||||||
|
#define kNtSublangWelshUnitedKingdom 0x01
|
||||||
|
#define kNtSublangWolofSenegal 0x01
|
||||||
|
#define kNtSublangXhosaSouthAfrica 0x01
|
||||||
|
#define kNtSublangYakutRussia 0x01
|
||||||
|
#define kNtSublangYiPrc 0x01
|
||||||
|
#define kNtSublangYorubaNigeria 0x01
|
||||||
|
#define kNtSublangZuluSouthAfrica 0x01
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_LANG_H_ */
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef COSMOPOLITAN_NT_ERRORS_H_
|
#ifndef COSMOPOLITAN_NT_ERRORS_H_
|
||||||
#define COSMOPOLITAN_NT_ERRORS_H_
|
#define COSMOPOLITAN_NT_ERRORS_H_
|
||||||
|
|
||||||
|
#define kNtNoError 0
|
||||||
|
|
||||||
#define kNtErrorInsufficientBuffer 122
|
#define kNtErrorInsufficientBuffer 122
|
||||||
|
|
||||||
#define kNtErrorSuccess 0
|
#define kNtErrorSuccess 0
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_
|
#ifndef COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_
|
||||||
#define COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_
|
#define COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_
|
||||||
|
|
||||||
#include "libc/nt/struct/ipadapteraddresses.h"
|
#include "libc/nt/struct/ipadapteraddresses.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
@ -26,17 +25,13 @@ COSMOPOLITAN_C_START_
|
||||||
▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███
|
▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███
|
||||||
░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██
|
░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██
|
||||||
╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗
|
╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗
|
||||||
│ cosmopolitan § new technology » ip helper API ─╬─│┼
|
│ cosmopolitan § new technology » ip helper api ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
||||||
uint32_t GetAdaptersAddresses(
|
uint32_t GetAdaptersAddresses(uint32_t Family, uint32_t Flags, void *Reserved,
|
||||||
uint32_t Family,
|
NtIpAdapterAddresses *AdapterAddresses,
|
||||||
uint32_t Flags,
|
uint32_t *SizePointer);
|
||||||
void * Reserved,
|
|
||||||
NtIpAdapterAddresses *AdapterAddresses,
|
|
||||||
uint32_t *SizePointer);
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_IPHLPAPI_H_ */
|
||||||
|
|
|
@ -1,2 +1,15 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_LocalFree,LocalFree,0
|
.imp kernel32,__imp_LocalFree,LocalFree,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
LocalFree:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov %rdi,%rcx
|
||||||
|
sub $32,%rsp
|
||||||
|
call *__imp_LocalFree(%rip)
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.endfn LocalFree,globl
|
||||||
|
.previous
|
||||||
|
|
|
@ -3223,7 +3223,7 @@ imp 'LocalAlloc' LocalAlloc kernel32 0 # KernelBase
|
||||||
imp 'LocalCompact' LocalCompact kernel32 970
|
imp 'LocalCompact' LocalCompact kernel32 970
|
||||||
imp 'LocalFileTimeToFileTime' LocalFileTimeToFileTime kernel32 0 # KernelBase
|
imp 'LocalFileTimeToFileTime' LocalFileTimeToFileTime kernel32 0 # KernelBase
|
||||||
imp 'LocalFlags' LocalFlags kernel32 972
|
imp 'LocalFlags' LocalFlags kernel32 972
|
||||||
imp 'LocalFree' LocalFree kernel32 0 # KernelBase
|
imp 'LocalFree' LocalFree kernel32 0 1 # KernelBase
|
||||||
imp 'LocalHandle' LocalHandle kernel32 974
|
imp 'LocalHandle' LocalHandle kernel32 974
|
||||||
imp 'LocalLock' LocalLock kernel32 0 # KernelBase
|
imp 'LocalLock' LocalLock kernel32 0 # KernelBase
|
||||||
imp 'LocalReAlloc' LocalReAlloc kernel32 0 # KernelBase
|
imp 'LocalReAlloc' LocalReAlloc kernel32 0 # KernelBase
|
||||||
|
@ -5087,6 +5087,7 @@ imp 'RtlFreeThreadActivationContextStack' RtlFreeThreadActivationContextStack
|
||||||
imp 'RtlFreeUnicodeString' RtlFreeUnicodeString ntdll 1000 1
|
imp 'RtlFreeUnicodeString' RtlFreeUnicodeString ntdll 1000 1
|
||||||
imp 'RtlFreeUserStack' RtlFreeUserStack ntdll 1001
|
imp 'RtlFreeUserStack' RtlFreeUserStack ntdll 1001
|
||||||
imp 'RtlGUIDFromString' RtlGUIDFromString ntdll 1002
|
imp 'RtlGUIDFromString' RtlGUIDFromString ntdll 1002
|
||||||
|
imp 'RtlGenRandom' SystemFunction036 advapi32 0 2
|
||||||
imp 'RtlGenerate8dot3Name' RtlGenerate8dot3Name ntdll 1003
|
imp 'RtlGenerate8dot3Name' RtlGenerate8dot3Name ntdll 1003
|
||||||
imp 'RtlGetAce' RtlGetAce ntdll 1004
|
imp 'RtlGetAce' RtlGetAce ntdll 1004
|
||||||
imp 'RtlGetActiveActivationContext' RtlGetActiveActivationContext ntdll 1005
|
imp 'RtlGetActiveActivationContext' RtlGetActiveActivationContext ntdll 1005
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
void *LocalFree(void *hMem);
|
||||||
|
|
||||||
int64_t CreateFileMappingNuma(
|
int64_t CreateFileMappingNuma(
|
||||||
int64_t opt_hFile /* -1ul is MAP_ANONYMOUS */,
|
int64_t opt_hFile /* -1ul is MAP_ANONYMOUS */,
|
||||||
const struct NtSecurityAttributes *opt_lpFileMappingAttributes,
|
const struct NtSecurityAttributes *opt_lpFileMappingAttributes,
|
||||||
|
|
|
@ -313,6 +313,25 @@ $(LIBC_NT_SHELL32_A).pkg: \
|
||||||
|
|
||||||
#───────────────────────────────────────────────────────────────────────────────
|
#───────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
LIBC_NT_ARTIFACTS += LIBC_NT_IPHLPAPI_A
|
||||||
|
LIBC_NT_IPHLPAPI = $(LIBC_NT_IPHLPAPI_A_DEPS) $(LIBC_NT_IPHLPAPI_A)
|
||||||
|
LIBC_NT_IPHLPAPI_A = o/$(MODE)/libc/nt/iphlpapi.a
|
||||||
|
LIBC_NT_IPHLPAPI_A_SRCS := $(wildcard libc/nt/iphlpapi/*.s)
|
||||||
|
LIBC_NT_IPHLPAPI_A_OBJS = $(LIBC_NT_IPHLPAPI_A_SRCS:%.s=o/$(MODE)/%.o)
|
||||||
|
LIBC_NT_IPHLPAPI_A_CHECKS = $(LIBC_NT_IPHLPAPI_A).pkg
|
||||||
|
LIBC_NT_IPHLPAPI_A_DIRECTDEPS = LIBC_NT_KERNEL32
|
||||||
|
LIBC_NT_IPHLPAPI_A_DEPS := \
|
||||||
|
$(call uniq,$(foreach x,$(LIBC_NT_IPHLPAPI_A_DIRECTDEPS),$($(x))))
|
||||||
|
$(LIBC_NT_IPHLPAPI_A): \
|
||||||
|
libc/nt/iphlpapi/ \
|
||||||
|
$(LIBC_NT_IPHLPAPI_A).pkg \
|
||||||
|
$(LIBC_NT_IPHLPAPI_A_OBJS)
|
||||||
|
$(LIBC_NT_IPHLPAPI_A).pkg: \
|
||||||
|
$(LIBC_NT_IPHLPAPI_A_OBJS) \
|
||||||
|
$(foreach x,$(LIBC_NT_IPHLPAPI_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
|
#───────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
$(LIBC_NT_OBJS): o/libc/nt/codegen.inc
|
$(LIBC_NT_OBJS): o/libc/nt/codegen.inc
|
||||||
|
|
||||||
o/libc/nt/codegen.inc: \
|
o/libc/nt/codegen.inc: \
|
||||||
|
|
|
@ -39,6 +39,7 @@ bool32 CloseHandle(int64_t hObject) nothrow nocallback;
|
||||||
intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect;
|
intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect;
|
||||||
bool32 SetStdHandle(int64_t nStdHandle, int64_t hHandle);
|
bool32 SetStdHandle(int64_t nStdHandle, int64_t hHandle);
|
||||||
bool32 SetDefaultDllDirectories(unsigned dirflags);
|
bool32 SetDefaultDllDirectories(unsigned dirflags);
|
||||||
|
bool32 RtlGenRandom(void *RandomBuffer, uint32_t RandomBufferLength);
|
||||||
|
|
||||||
#if ShouldUseMsabiAttribute()
|
#if ShouldUseMsabiAttribute()
|
||||||
#include "libc/nt/thunk/runtime.inc"
|
#include "libc/nt/thunk/runtime.inc"
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_
|
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_
|
||||||
#define COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_
|
#define COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_
|
||||||
|
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
/* Constants ----------------------------------------------------------- */
|
/* Constants ----------------------------------------------------------- */
|
||||||
#define kNtMaxAdapterAddressLength 8
|
#define kNtMaxAdapterAddressLength 8
|
||||||
#define kNtMaxDnsSuffixStringLength 256
|
#define kNtMaxDnsSuffixStringLength 256
|
||||||
#define kNtMaxDhcpv6DuidLength 130
|
#define kNtMaxDhcpv6DuidLength 130
|
||||||
|
|
||||||
/* Values for the 'Flags' parameter of GetAdaptersAddresses */
|
/* Values for the 'Flags' parameter of GetAdaptersAddresses */
|
||||||
#define kNtGaaFlagSkipUnicast 0x0001
|
#define kNtGaaFlagSkipUnicast 0x0001
|
||||||
|
@ -26,7 +24,8 @@ COSMOPOLITAN_C_START_
|
||||||
#define kNtGaaFlagSkipDnsInfo 0x0800
|
#define kNtGaaFlagSkipDnsInfo 0x0800
|
||||||
|
|
||||||
/* Values for the IfType parameter
|
/* Values for the IfType parameter
|
||||||
* See: https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh
|
* See:
|
||||||
|
* https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh
|
||||||
*/
|
*/
|
||||||
#define kNtIfTypeOther 1
|
#define kNtIfTypeOther 1
|
||||||
#define kNtIfTypeEthernetCsmacd 6
|
#define kNtIfTypeEthernetCsmacd 6
|
||||||
|
@ -38,9 +37,8 @@ COSMOPOLITAN_C_START_
|
||||||
#define kNtIfTypeTunnel 131
|
#define kNtIfTypeTunnel 131
|
||||||
#define kNtIfTypeIeee1394 144 /* firewire */
|
#define kNtIfTypeIeee1394 144 /* firewire */
|
||||||
|
|
||||||
|
|
||||||
/* Enums --------------------------------------------------------------- */
|
/* Enums --------------------------------------------------------------- */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kNtIpPrefixOriginOther,
|
kNtIpPrefixOriginOther,
|
||||||
kNtIpPrefixOriginManual,
|
kNtIpPrefixOriginManual,
|
||||||
kNtIpPrefixOriginWellKnown,
|
kNtIpPrefixOriginWellKnown,
|
||||||
|
@ -49,7 +47,7 @@ typedef enum {
|
||||||
kNtIpPrefixOriginUnchanged
|
kNtIpPrefixOriginUnchanged
|
||||||
} NtPrefixOrigin;
|
} NtPrefixOrigin;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kNtNlsoOther,
|
kNtNlsoOther,
|
||||||
kNtNlsoManual,
|
kNtNlsoManual,
|
||||||
kNtNlsoWellKnown,
|
kNtNlsoWellKnown,
|
||||||
|
@ -65,7 +63,7 @@ typedef enum {
|
||||||
kNtIpSuffixOriginUnchanged
|
kNtIpSuffixOriginUnchanged
|
||||||
} NtSuffixOrigin;
|
} NtSuffixOrigin;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kNtNldsInvalid,
|
kNtNldsInvalid,
|
||||||
kNtNldsTentative,
|
kNtNldsTentative,
|
||||||
kNtNldsDuplicate,
|
kNtNldsDuplicate,
|
||||||
|
@ -89,10 +87,10 @@ typedef enum {
|
||||||
} NtIfOperStatus;
|
} NtIfOperStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kNtNetIfConnectionDedicated = 1,
|
kNtNetIfConnectionDedicated = 1,
|
||||||
kNtNetIfConnectionPassive = 2,
|
kNtNetIfConnectionPassive = 2,
|
||||||
kNtNetIfConnectionDemand = 3,
|
kNtNetIfConnectionDemand = 3,
|
||||||
kNtNetIfConnectionMaximum = 4
|
kNtNetIfConnectionMaximum = 4
|
||||||
} NtNetIfConnectionType;
|
} NtNetIfConnectionType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -105,7 +103,6 @@ typedef enum {
|
||||||
kNtTunnelTypeIphttps = 15
|
kNtTunnelTypeIphttps = 15
|
||||||
} NtTunnelType;
|
} NtTunnelType;
|
||||||
|
|
||||||
|
|
||||||
/* Inner Types --------------------------------------------------------- */
|
/* Inner Types --------------------------------------------------------- */
|
||||||
typedef struct _NtIpAdapterUnicastAddress {
|
typedef struct _NtIpAdapterUnicastAddress {
|
||||||
union {
|
union {
|
||||||
|
@ -115,15 +112,15 @@ typedef struct _NtIpAdapterUnicastAddress {
|
||||||
uint32_t Flags;
|
uint32_t Flags;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterUnicastAddress * Next;
|
struct _NtIpAdapterUnicastAddress *Next;
|
||||||
struct NtSocketAddress Address;
|
struct NtSocketAddress Address;
|
||||||
NtPrefixOrigin PrefixOrigin;
|
NtPrefixOrigin PrefixOrigin;
|
||||||
NtSuffixOrigin SuffixOrigin;
|
NtSuffixOrigin SuffixOrigin;
|
||||||
NtDadState DadState;
|
NtDadState DadState;
|
||||||
uint32_t ValidLifetime;
|
uint32_t ValidLifetime;
|
||||||
uint32_t PreferredLifetime;
|
uint32_t PreferredLifetime;
|
||||||
uint32_t LeaseLifetime;
|
uint32_t LeaseLifetime;
|
||||||
uint8_t OnLinkPrefixLength;
|
uint8_t OnLinkPrefixLength;
|
||||||
} NtIpAdapterUnicastAddress;
|
} NtIpAdapterUnicastAddress;
|
||||||
|
|
||||||
typedef struct NtIpAdapterAnycastAddress {
|
typedef struct NtIpAdapterAnycastAddress {
|
||||||
|
@ -135,7 +132,7 @@ typedef struct NtIpAdapterAnycastAddress {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterAnycastAddress *Next;
|
struct _NtIpAdapterAnycastAddress *Next;
|
||||||
struct NtSocketAddress Address;
|
struct NtSocketAddress Address;
|
||||||
} NtIpAdapterAnycastAddress;
|
} NtIpAdapterAnycastAddress;
|
||||||
|
|
||||||
typedef struct NtIpAdapterMulticastAddress {
|
typedef struct NtIpAdapterMulticastAddress {
|
||||||
|
@ -147,10 +144,9 @@ typedef struct NtIpAdapterMulticastAddress {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterMulticastAddress *Next;
|
struct _NtIpAdapterMulticastAddress *Next;
|
||||||
struct NtSocketAddress Address;
|
struct NtSocketAddress Address;
|
||||||
} NtIpAdapterMulticastAddress;
|
} NtIpAdapterMulticastAddress;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _NtIpAdapterDnsServerAddress {
|
typedef struct _NtIpAdapterDnsServerAddress {
|
||||||
union {
|
union {
|
||||||
uint64_t Alignment;
|
uint64_t Alignment;
|
||||||
|
@ -160,32 +156,32 @@ typedef struct _NtIpAdapterDnsServerAddress {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterDnsServerAddress *Next;
|
struct _NtIpAdapterDnsServerAddress *Next;
|
||||||
struct NtSocketAddress Address;
|
struct NtSocketAddress Address;
|
||||||
} NtIpAdapterDnsServerAddress;
|
} NtIpAdapterDnsServerAddress;
|
||||||
|
|
||||||
typedef struct _NtIpAdapterPrefix {
|
typedef struct _NtIpAdapterPrefix {
|
||||||
union {
|
union {
|
||||||
uint64_t Alignment;
|
uint64_t Alignment;
|
||||||
struct {
|
struct {
|
||||||
uint32_t Length;
|
uint32_t Length;
|
||||||
uint32_t Flags;
|
uint32_t Flags;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterPrefix *Next;
|
};
|
||||||
struct NtSocketAddress Address;
|
struct _NtIpAdapterPrefix *Next;
|
||||||
uint32_t PrefixLength;
|
struct NtSocketAddress Address;
|
||||||
|
uint32_t PrefixLength;
|
||||||
} NtIpAdapterPrefix;
|
} NtIpAdapterPrefix;
|
||||||
|
|
||||||
typedef struct _NtIpAdapterWinsServerAddress {
|
typedef struct _NtIpAdapterWinsServerAddress {
|
||||||
union {
|
union {
|
||||||
uint64_t Alignment;
|
uint64_t Alignment;
|
||||||
struct {
|
struct {
|
||||||
uint32_t Length;
|
uint32_t Length;
|
||||||
uint32_t Reserved;
|
uint32_t Reserved;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterWinsServerAddress *Next;
|
};
|
||||||
struct NtSocketAddress Address;
|
struct _NtIpAdapterWinsServerAddress *Next;
|
||||||
|
struct NtSocketAddress Address;
|
||||||
} NtIpAdapterWinsServerAddress;
|
} NtIpAdapterWinsServerAddress;
|
||||||
|
|
||||||
typedef struct _NtIpAdapterGatewayAddress {
|
typedef struct _NtIpAdapterGatewayAddress {
|
||||||
|
@ -197,53 +193,50 @@ typedef struct _NtIpAdapterGatewayAddress {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterGatewayAddress *Next;
|
struct _NtIpAdapterGatewayAddress *Next;
|
||||||
struct NtSocketAddress Address;
|
struct NtSocketAddress Address;
|
||||||
} NtIpAdapterGatewayAddress;
|
} NtIpAdapterGatewayAddress;
|
||||||
|
|
||||||
typedef struct _NtGUID {
|
typedef struct _NtGUID {
|
||||||
uint32_t Data1;
|
uint32_t Data1;
|
||||||
uint16_t Data2;
|
uint16_t Data2;
|
||||||
uint16_t Data3;
|
uint16_t Data3;
|
||||||
uint8_t Data4[8];
|
uint8_t Data4[8];
|
||||||
} NtGUID;
|
} NtGUID;
|
||||||
|
|
||||||
typedef union _NtNetLUID
|
typedef union _NtNetLUID {
|
||||||
{
|
uint64_t Value;
|
||||||
uint64_t Value;
|
struct {
|
||||||
struct
|
uint64_t Reserved : 24;
|
||||||
{
|
uint64_t NetLuidIndex : 24;
|
||||||
uint64_t Reserved:24;
|
uint64_t IfType : 16;
|
||||||
uint64_t NetLuidIndex:24;
|
} Info;
|
||||||
uint64_t IfType:16;
|
|
||||||
}Info;
|
|
||||||
} NtNetLUID;
|
} NtNetLUID;
|
||||||
|
|
||||||
typedef struct _NtIpAdapterDnsSuffix {
|
typedef struct _NtIpAdapterDnsSuffix {
|
||||||
struct _NtIpAdapterDnsSuffix *Next;
|
struct _NtIpAdapterDnsSuffix *Next;
|
||||||
uint16_t String[kNtMaxDnsSuffixStringLength];
|
uint16_t String[kNtMaxDnsSuffixStringLength];
|
||||||
} NtIpAdapterDnsSuffix;
|
} NtIpAdapterDnsSuffix;
|
||||||
|
|
||||||
|
|
||||||
/* Top level ----------------------------------------------------------- */
|
/* Top level ----------------------------------------------------------- */
|
||||||
typedef struct _NtIpAdapterAddresses {
|
typedef struct _NtIpAdapterAddresses {
|
||||||
union {
|
union {
|
||||||
uint64_t Alignment;
|
uint64_t Alignment;
|
||||||
struct {
|
struct {
|
||||||
uint32_t Length;
|
uint32_t Length;
|
||||||
uint32_t IfIndex;
|
uint32_t IfIndex;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct _NtIpAdapterAddresses * Next;
|
struct _NtIpAdapterAddresses *Next;
|
||||||
char * AdapterName;
|
char *AdapterName;
|
||||||
NtIpAdapterUnicastAddress * FirstUnicastAddress;
|
NtIpAdapterUnicastAddress *FirstUnicastAddress;
|
||||||
NtIpAdapterAnycastAddress * FirstAnycastAddress;
|
NtIpAdapterAnycastAddress *FirstAnycastAddress;
|
||||||
NtIpAdapterMulticastAddress * FirstMulticastAddress;
|
NtIpAdapterMulticastAddress *FirstMulticastAddress;
|
||||||
NtIpAdapterDnsServerAddress * FirstDnsServerAddress;
|
NtIpAdapterDnsServerAddress *FirstDnsServerAddress;
|
||||||
uint16_t * DnsSuffix;
|
uint16_t *DnsSuffix;
|
||||||
uint16_t * Description;
|
uint16_t *Description;
|
||||||
uint16_t * FriendlyName;
|
uint16_t *FriendlyName;
|
||||||
uint8_t PhysicalAddress[kNtMaxAdapterAddressLength];
|
uint8_t PhysicalAddress[kNtMaxAdapterAddressLength];
|
||||||
uint32_t PhysicalAddressLength;
|
uint32_t PhysicalAddressLength;
|
||||||
union {
|
union {
|
||||||
uint32_t Flags;
|
uint32_t Flags;
|
||||||
struct {
|
struct {
|
||||||
|
@ -259,33 +252,31 @@ typedef struct _NtIpAdapterAddresses {
|
||||||
uint32_t Ipv6ManagedAddressConfigurationSupported : 1;
|
uint32_t Ipv6ManagedAddressConfigurationSupported : 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
uint32_t Mtu;
|
uint32_t Mtu;
|
||||||
uint32_t IfType;
|
uint32_t IfType;
|
||||||
NtIfOperStatus OperStatus;
|
NtIfOperStatus OperStatus;
|
||||||
uint32_t Ipv6IfIndex;
|
uint32_t Ipv6IfIndex;
|
||||||
uint32_t ZoneIndices[16];
|
uint32_t ZoneIndices[16];
|
||||||
NtIpAdapterPrefix * FirstPrefix;
|
NtIpAdapterPrefix *FirstPrefix;
|
||||||
uint64_t TransmitLinkSpeed;
|
uint64_t TransmitLinkSpeed;
|
||||||
uint64_t ReceiveLinkSpeed;
|
uint64_t ReceiveLinkSpeed;
|
||||||
NtIpAdapterWinsServerAddress * FirstWinsServerAddress;
|
NtIpAdapterWinsServerAddress *FirstWinsServerAddress;
|
||||||
NtIpAdapterGatewayAddress * FirstGatewayAddress;
|
NtIpAdapterGatewayAddress *FirstGatewayAddress;
|
||||||
uint32_t Ipv4Metric;
|
uint32_t Ipv4Metric;
|
||||||
uint32_t Ipv6Metric;
|
uint32_t Ipv6Metric;
|
||||||
NtNetLUID Luid;
|
NtNetLUID Luid;
|
||||||
struct NtSocketAddress Dhcpv4Server;
|
struct NtSocketAddress Dhcpv4Server;
|
||||||
uint32_t CompartmentId;
|
uint32_t CompartmentId;
|
||||||
NtGUID NetworkGuid;
|
NtGUID NetworkGuid;
|
||||||
NtNetIfConnectionType ConnectionType;
|
NtNetIfConnectionType ConnectionType;
|
||||||
NtTunnelType TunnelType;
|
NtTunnelType TunnelType;
|
||||||
struct NtSocketAddress Dhcpv6Server;
|
struct NtSocketAddress Dhcpv6Server;
|
||||||
uint8_t Dhcpv6ClientDuid[kNtMaxDhcpv6DuidLength];
|
uint8_t Dhcpv6ClientDuid[kNtMaxDhcpv6DuidLength];
|
||||||
uint32_t Dhcpv6ClientDuidLength;
|
uint32_t Dhcpv6ClientDuidLength;
|
||||||
uint32_t Dhcpv6Iaid;
|
uint32_t Dhcpv6Iaid;
|
||||||
NtIpAdapterDnsSuffix * FirstDnsSuffix;
|
NtIpAdapterDnsSuffix *FirstDnsSuffix;
|
||||||
} NtIpAdapterAddresses;
|
} NtIpAdapterAddresses;
|
||||||
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IP_ADAPTER_ADDRESSES_H_ */
|
||||||
|
|
||||||
|
|
|
@ -16,35 +16,196 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/bits.h"
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/nexgen32e/kcpuids.h"
|
||||||
|
#include "libc/nexgen32e/rdtsc.h"
|
||||||
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
|
#include "libc/nexgen32e/x86feature.h"
|
||||||
|
#include "libc/nexgen32e/x86info.h"
|
||||||
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/rand/xorshift.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/at.h"
|
||||||
|
#include "libc/sysv/consts/auxv.h"
|
||||||
|
#include "libc/sysv/consts/grnd.h"
|
||||||
|
#include "libc/sysv/consts/o.h"
|
||||||
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
static bool have_getrandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns random bytes appropriate for random seeding.
|
* Returns cryptographic random data.
|
||||||
*
|
*
|
||||||
* @param size should be the smallest value that meets your requirements
|
* This random number seed generator blends information from:
|
||||||
* @param flags may be GRND_{RANDOM,NONBLOCK}
|
*
|
||||||
* @return number of bytes copied on success; or -1 w/ errno, which
|
* - getrandom() on Linux
|
||||||
* indicates only that the request couldn't be serviced by the host
|
* - getentropy() on XNU and OpenBSD
|
||||||
* kernel; this wrapper will still fill the buffer with random bytes
|
* - sysctl(KERN_ARND) on FreeBSD and NetBSD
|
||||||
* from fallback sources no matter what
|
* - RDSEED on Broadwell+ and Xen+ unless GRND_NORDRND
|
||||||
|
* - RDRAND on Ivybridge+ and Xen+ unless GRND_NORDRND|GRND_RANDOM
|
||||||
|
*
|
||||||
|
* The following flags may be specified:
|
||||||
|
*
|
||||||
|
* - GRND_NORDRND: Don't source rando from hardware.
|
||||||
|
* - GRND_NOSYSTEM: Don't source rando from operating system.
|
||||||
|
* - GRND_RANDOM: Halt the entire system while I tap an entropy pool
|
||||||
|
* so small that it's hard to use statistics to test if it's random
|
||||||
|
* - GRND_NONBLOCK: Do not wait for i/o events or me to jiggle my
|
||||||
|
* mouse, and instead return immediately the moment data isn't
|
||||||
|
* available, even if the result needs to be -1 w/ EAGAIN
|
||||||
|
*
|
||||||
|
* This function is safe to use with fork() and vfork(). It will also
|
||||||
|
* close any file descriptor it ends up needing before it returns.
|
||||||
|
*
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
ssize_t getrandom(void *buf, size_t size, unsigned flags) {
|
ssize_t getrandom(void *p, size_t n, unsigned f) {
|
||||||
ssize_t rc = sys_getrandom(buf, size, flags);
|
char cf;
|
||||||
size_t i = rc == -1 ? 0 : (size_t)rc;
|
ssize_t rc;
|
||||||
if (i > size) abort();
|
uint64_t x;
|
||||||
if (i < size) {
|
size_t i, j, m;
|
||||||
unsigned char *p = buf;
|
int fd, cmd[2];
|
||||||
int olderr = errno;
|
sigset_t neu, old;
|
||||||
do {
|
if (n > 256) n = 256;
|
||||||
uint64_t i64 = rand64();
|
if (!IsTiny() &&
|
||||||
memcpy(&p[i], &i64, min(sizeof(i64), size - i));
|
(f & ~(GRND_RANDOM | GRND_NONBLOCK | GRND_NORDRND | GRND_NOSYSTEM))) {
|
||||||
} while ((i += sizeof(uint64_t)) < size);
|
return einval();
|
||||||
errno = olderr;
|
}
|
||||||
|
if (!(f & GRND_NOSYSTEM)) {
|
||||||
|
if (IsWindows()) {
|
||||||
|
if (RtlGenRandom(p, n)) {
|
||||||
|
rc = n;
|
||||||
|
} else {
|
||||||
|
return __winerr();
|
||||||
|
}
|
||||||
|
} else if (IsFreebsd() || IsNetbsd()) {
|
||||||
|
if (IsFreebsd()) {
|
||||||
|
cmd[0] = 1; /* CTL_KERN */
|
||||||
|
cmd[1] = 37; /* KERN_ARND */
|
||||||
|
} else {
|
||||||
|
cmd[0] = 1; /* CTL_KERN */
|
||||||
|
cmd[1] = 81; /* KERN_ARND */
|
||||||
|
}
|
||||||
|
m = n;
|
||||||
|
if ((rc = sysctl(cmd, 2, p, &m, 0, 0)) != -1) {
|
||||||
|
rc = m;
|
||||||
|
}
|
||||||
|
} else if (have_getrandom) {
|
||||||
|
if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) {
|
||||||
|
if (!rc && (IsXnu() || IsOpenbsd())) {
|
||||||
|
rc = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((fd = __sys_openat(
|
||||||
|
AT_FDCWD,
|
||||||
|
(f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom",
|
||||||
|
O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) !=
|
||||||
|
-1) {
|
||||||
|
rc = sys_read(fd, p, n);
|
||||||
|
sys_close(fd);
|
||||||
|
} else {
|
||||||
|
return enosys();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memset(p, 0, n);
|
||||||
|
rc = n;
|
||||||
|
}
|
||||||
|
if (rc != -1) {
|
||||||
|
if (!IsTiny()) {
|
||||||
|
if (rc < 0 || rc > n) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (f & (GRND_RANDOM | GRND_NONBLOCK)) {
|
||||||
|
if (n && !rc) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rc != n) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(f & GRND_NORDRND)) {
|
||||||
|
if (X86_HAVE(RDSEED)) {
|
||||||
|
for (i = j = 0; i < rc; ++j) {
|
||||||
|
/* CF=1: Destination register valid. Quoth Intel DRNG-SIG 4.1.3 */
|
||||||
|
asm volatile(CFLAG_ASM("rdseed\t%1")
|
||||||
|
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||||
|
: /* no inputs */
|
||||||
|
: "cc");
|
||||||
|
if (cf) {
|
||||||
|
j = 0;
|
||||||
|
if (i + 8 <= rc) {
|
||||||
|
x ^= READ64LE((char *)p + i);
|
||||||
|
WRITE64LE((char *)p + i, x);
|
||||||
|
i += 8;
|
||||||
|
} else {
|
||||||
|
for (; i < rc; x >>= 8) {
|
||||||
|
((char *)p)[i++] ^= x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (j == 10) {
|
||||||
|
asm volatile("pause");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = i;
|
||||||
|
} else if (X86_HAVE(RDRND)) {
|
||||||
|
for (i = j = 0; i < rc; ++j) {
|
||||||
|
/* CF=1: Destination register valid. Quoth Intel DRNG-SIG 4.1.3 */
|
||||||
|
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||||
|
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||||
|
: /* no inputs */
|
||||||
|
: "cc");
|
||||||
|
if (cf) {
|
||||||
|
j = 0;
|
||||||
|
if (i + 8 <= rc) {
|
||||||
|
x ^= READ64LE((char *)p + i);
|
||||||
|
WRITE64LE((char *)p + i, x);
|
||||||
|
i += 8;
|
||||||
|
} else {
|
||||||
|
for (; i < rc; x >>= 8) {
|
||||||
|
((char *)p)[i++] ^= x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (j == 10) {
|
||||||
|
asm volatile("pause");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = i;
|
||||||
|
} else if (f & GRND_NOSYSTEM) {
|
||||||
|
return enosys();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static textstartup void getrandom_init(int argc, char **argv, char **envp,
|
||||||
|
intptr_t *auxv) {
|
||||||
|
extern unsigned kMutableCpuids[KCPUIDS_LEN][4] asm("kCpuids");
|
||||||
|
/*
|
||||||
|
* Clear RDRAND on AMD models before Zen and then some
|
||||||
|
* since it's not only slow but can freeze after sleep
|
||||||
|
* https://bugzilla.redhat.com/show_bug.cgi?id=1150286
|
||||||
|
*/
|
||||||
|
if ((X86_HAVE(RDRND) || X86_HAVE(RDSEED)) &&
|
||||||
|
(IsAuthenticAMD() &&
|
||||||
|
(kX86CpuFamily < 0x17 ||
|
||||||
|
(kX86CpuFamily == 0x17 &&
|
||||||
|
(0x70 <= kX86CpuModel && kX86CpuModel <= 0x7F))))) {
|
||||||
|
kMutableCpuids[KCPUIDS_1H][KCPUIDS_ECX] &= ~(1u << 30);
|
||||||
|
kMutableCpuids[KCPUIDS_7H][KCPUIDS_EBX] &= ~(1u << 18);
|
||||||
|
}
|
||||||
|
if (sys_getrandom(0, 0, 0) == 0) {
|
||||||
|
have_getrandom = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *const g_getrandom_init[] initarray = {getrandom_init};
|
||||||
|
|
|
@ -6,12 +6,11 @@ COSMOPOLITAN_C_START_
|
||||||
│ cosmopolitan § random ─╬─│┼
|
│ cosmopolitan § random ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
||||||
#define RAND_MAX __INT_MAX__ /* only applies to rand() */
|
#define RAND_MAX __INT_MAX__
|
||||||
void srand(uint64_t) nothrow nocallback; /* seeds rand() only */
|
void srand(uint64_t) nothrow nocallback;
|
||||||
int rand(void) nothrow nocallback; /* ≥0 unseeded lcg prng */
|
int rand(void) nothrow nocallback;
|
||||||
uint32_t rand32(void) nothrow nocallback; /* random as possible rng */
|
uint64_t rand64(void) nothrow nocallback;
|
||||||
uint64_t rand64(void) nothrow nocallback; /* random as possible rng */
|
double poz(double);
|
||||||
double poz(double); /* verify our claims */
|
|
||||||
double pochisq(double, int);
|
double pochisq(double, int);
|
||||||
void rt_init(int);
|
void rt_init(int);
|
||||||
void rt_add(void *, int);
|
void rt_add(void *, int);
|
||||||
|
@ -20,8 +19,6 @@ void *rngset(void *, size_t, uint64_t (*)(void), size_t) paramsnonnull();
|
||||||
char *strfry(char *);
|
char *strfry(char *);
|
||||||
int getentropy(void *, size_t);
|
int getentropy(void *, size_t);
|
||||||
ssize_t getrandom(void *, size_t, unsigned);
|
ssize_t getrandom(void *, size_t, unsigned);
|
||||||
int devrand(void *, size_t);
|
|
||||||
int64_t winrandish(void);
|
|
||||||
uint64_t rdrand(void);
|
uint64_t rdrand(void);
|
||||||
uint64_t rdseed(void);
|
uint64_t rdseed(void);
|
||||||
float randf(void);
|
float randf(void);
|
||||||
|
|
|
@ -27,7 +27,7 @@ LIBC_RAND_A_DIRECTDEPS = \
|
||||||
LIBC_CALLS \
|
LIBC_CALLS \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_NT_KERNEL32 \
|
LIBC_NT_ADVAPI32 \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
|
|
|
@ -16,34 +16,58 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/dce.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/nexgen32e/rdtsc.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
#include "libc/rand/xorshift.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/sysv/consts/auxv.h"
|
||||||
|
|
||||||
hidden extern uint64_t g_rando64;
|
static uint64_t thepool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns nondeterministic random number.
|
* Returns nondeterministic random data.
|
||||||
*
|
*
|
||||||
* This function uses a good random source if it's available, which
|
* This random number seed generator blends information from:
|
||||||
* takes ~400 cycles (~99ns). Otherwise it's seeded at program start
|
|
||||||
* with the system provided random value and may perform a few
|
|
||||||
* microseconds worth of system calls to get a good value.
|
|
||||||
*
|
*
|
||||||
* @see rngset()
|
* - rdtsc() hardware clock
|
||||||
|
* - getpid() process identifier
|
||||||
|
* - getauxval(AT_RANDOM) on Linux
|
||||||
|
*
|
||||||
|
* It's 100% guaranteed to not hard block the system.
|
||||||
|
*
|
||||||
|
* @see rngset(), getrandom()
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
nodebuginfo uint64_t rand64(void) {
|
uint64_t rand64(void) {
|
||||||
uint64_t res;
|
register uint64_t t;
|
||||||
if (X86_HAVE(RDRND)) {
|
t = thepool;
|
||||||
res = rdrand();
|
t ^= getpid() * 11400714819643198487ull + 123456789123456789;
|
||||||
} else {
|
t ^= t << 13;
|
||||||
if (IsWindows()) {
|
t ^= t >> 7;
|
||||||
res = winrandish();
|
t ^= t << 17;
|
||||||
} else {
|
t ^= rdtsc() * 11400714819643198487ull + 123456789123456789;
|
||||||
devrand(&res, sizeof(res));
|
t ^= t << 13;
|
||||||
}
|
t ^= t >> 7;
|
||||||
res ^= MarsagliaXorshift64(&g_rando64);
|
t ^= t << 17;
|
||||||
}
|
thepool ^= t;
|
||||||
return res;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static textstartup void rand64_init(int argc, char **argv, char **envp,
|
||||||
|
intptr_t *auxv) {
|
||||||
|
uint64_t t;
|
||||||
|
t = kStartTsc * 88172645463325252 + 123456789123456789;
|
||||||
|
if (AT_RANDOM) {
|
||||||
|
for (; auxv[0]; auxv += 2) {
|
||||||
|
if (auxv[0] == AT_RANDOM) {
|
||||||
|
t ^= READ64LE((const char *)auxv[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thepool = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *const g_rand64_init[] initarray = {rand64_init};
|
||||||
|
|
|
@ -16,31 +16,8 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
|
||||||
#include "libc/bits/bits.h"
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Intel Secure Key Digital Random Number Generator
|
|
||||||
* Introduced w/ Ivy Bridge c. 2013 and Excavator c. 2015
|
|
||||||
* @see rdseed(), rand32(), rand64(), and randcpy()
|
|
||||||
*/
|
|
||||||
uint64_t rdrand(void) {
|
uint64_t rdrand(void) {
|
||||||
char cf;
|
return rand64();
|
||||||
size_t i;
|
|
||||||
uint64_t res;
|
|
||||||
assert(X86_HAVE(RDRND));
|
|
||||||
for (;;) {
|
|
||||||
for (i = 0; i < 10; ++i) {
|
|
||||||
/* CF=1: Destination register valid. Quoth Intel DRNG-SIG 4.1.3 */
|
|
||||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
|
||||||
: CFLAG_CONSTRAINT(cf), "=r"(res)
|
|
||||||
: /* no inputs */
|
|
||||||
: "cc");
|
|
||||||
if (cf) return res;
|
|
||||||
}
|
|
||||||
asm volatile("rep nop"); /* unlikely 140 cycle spin */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,31 +16,17 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
|
||||||
#include "libc/bits/bits.h"
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/sysv/consts/grnd.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Intel Securer Key Digital Random Number Generator
|
|
||||||
* Introduced w/ Ivy Bridge c. 2013 and Excavator c. 2015
|
|
||||||
* @see rdrand(), rand32(), rand64(), and randcpy()
|
|
||||||
*/
|
|
||||||
uint64_t rdseed(void) {
|
uint64_t rdseed(void) {
|
||||||
char cf;
|
register uint64_t x;
|
||||||
size_t i;
|
volatile uint64_t b;
|
||||||
uint64_t res;
|
if (getrandom(&b, 8, GRND_NONBLOCK | GRND_RANDOM) == 8) {
|
||||||
assert(X86_HAVE(RDSEED));
|
x = b;
|
||||||
for (;;) {
|
b = 0;
|
||||||
for (i = 0; i < 10; ++i) {
|
} else {
|
||||||
/* CF=1: Destination register valid. Quoth Intel DRNG-SIG 4.1.3 */
|
x = (uint64_t)rand() << 62 | (uint64_t)rand() << 31 | rand();
|
||||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
|
||||||
: CFLAG_CONSTRAINT(cf), "=r"(res)
|
|
||||||
: /* no inputs */
|
|
||||||
: "cc");
|
|
||||||
if (cf) return res;
|
|
||||||
}
|
|
||||||
asm volatile("rep nop"); /* unlikely 140 cycle spin */
|
|
||||||
}
|
}
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,9 +89,9 @@ relegated wontreturn noasan void __assert_fail(const char *expr,
|
||||||
if (line < 1) line = 1;
|
if (line < 1) line = 1;
|
||||||
for (i = 0; line; line /= 10) linebuf[i++] = '0' + line % 10;
|
for (i = 0; line; line /= 10) linebuf[i++] = '0' + line % 10;
|
||||||
while (i) *p++ = linebuf[--i];
|
while (i) *p++ = linebuf[--i];
|
||||||
p = __assert_stpcpy(p, ":");
|
p = __assert_stpcpy(p, ": assert(");
|
||||||
p = __assert_stpcpy(p, expr);
|
p = __assert_stpcpy(p, expr);
|
||||||
p = __assert_stpcpy(p, "\r\n");
|
p = __assert_stpcpy(p, ")\r\n");
|
||||||
__assert_write(msg, p - msg);
|
__assert_write(msg, p - msg);
|
||||||
if (weaken(__die)) weaken(__die)();
|
if (weaken(__die)) weaken(__die)();
|
||||||
}
|
}
|
||||||
|
|
122
libc/sock/gethostips.c
Normal file
122
libc/sock/gethostips.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/bits/bits.h"
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/nt/errors.h"
|
||||||
|
#include "libc/nt/iphlpapi.h"
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "libc/sysv/consts/ipproto.h"
|
||||||
|
#include "libc/sysv/consts/sio.h"
|
||||||
|
#include "libc/sysv/consts/sock.h"
|
||||||
|
|
||||||
|
/* TODO(jart): DELETE */
|
||||||
|
|
||||||
|
static uint32_t *GetUnixIps(void) {
|
||||||
|
int fd, n;
|
||||||
|
uint64_t z;
|
||||||
|
uint32_t *a;
|
||||||
|
char *b, *p, *e, c[16];
|
||||||
|
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) return 0;
|
||||||
|
a = 0;
|
||||||
|
n = 0;
|
||||||
|
z = 15000;
|
||||||
|
b = malloc(z);
|
||||||
|
memcpy(c, &z, 8);
|
||||||
|
memcpy(c + (IsXnu() ? 4 : 8), &b, 8);
|
||||||
|
if (sys_ioctl(fd, SIOCGIFCONF, &c) != -1) {
|
||||||
|
for (p = b, e = p + MIN(z, READ32LE(c)); p + 16 + 16 <= e;
|
||||||
|
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
||||||
|
if ((p[IsBsd() ? 17 : 16] & 255) != AF_INET) continue;
|
||||||
|
a = realloc(a, ++n * sizeof(*a));
|
||||||
|
a[n - 1] = READ32BE(p + 20);
|
||||||
|
}
|
||||||
|
a = realloc(a, ++n * sizeof(*a));
|
||||||
|
a[n - 1] = 0;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
free(b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static textwindows uint32_t *GetWindowsIps(void) {
|
||||||
|
uint32_t i, z, n, rc, *a;
|
||||||
|
NtIpAdapterUnicastAddress *u;
|
||||||
|
NtIpAdapterAddresses *p, *ifaces;
|
||||||
|
i = 0;
|
||||||
|
z = 15000;
|
||||||
|
do {
|
||||||
|
if (!(ifaces = malloc(z))) return 0;
|
||||||
|
rc = GetAdaptersAddresses(AF_INET,
|
||||||
|
kNtGaaFlagSkipAnycast | kNtGaaFlagSkipMulticast |
|
||||||
|
kNtGaaFlagSkipDnsServer |
|
||||||
|
kNtGaaFlagSkipFriendlyName,
|
||||||
|
0, ifaces, &z);
|
||||||
|
if (rc != kNtErrorBufferOverflow) break;
|
||||||
|
free(ifaces);
|
||||||
|
ifaces = 0;
|
||||||
|
} while (++i < 3);
|
||||||
|
if (rc == kNtErrorNoData) {
|
||||||
|
a = calloc(1, sizeof(*a));
|
||||||
|
} else if (rc == kNtNoError) {
|
||||||
|
for (a = 0, n = 0, p = ifaces; p; p = p->Next) {
|
||||||
|
if (p->OperStatus != kNtIfOperStatusUp) continue;
|
||||||
|
for (u = p->FirstUnicastAddress; u; u = u->Next) {
|
||||||
|
if (u->Address.lpSockaddr->sa_family != AF_INET) continue;
|
||||||
|
a = realloc(a, ++n * sizeof(*a));
|
||||||
|
a[n - 1] = ntohl(
|
||||||
|
((struct sockaddr_in *)u->Address.lpSockaddr)->sin_addr.s_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = realloc(a, ++n * sizeof(*a));
|
||||||
|
a[n - 1] = 0;
|
||||||
|
} else {
|
||||||
|
__winerr();
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
free(ifaces);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns IP addresses of system.
|
||||||
|
*
|
||||||
|
* Normally return values will look like `{0x7f000001, 0x0a0a0a7c, 0}`
|
||||||
|
* which means the same thing as `{"127.0.0.1", "10.10.10.124", 0}`.
|
||||||
|
* Returned IPs will IPv4 anycast addresses bound to network interfaces
|
||||||
|
* which come in a NULL-terminated array with no particular ordering.
|
||||||
|
*
|
||||||
|
* uint32_t *ip, *ips = GetIps();
|
||||||
|
* for (ip = ips; *ip; ++ip) {
|
||||||
|
* printf("%hhu.%hhu.%hhu.%hhu\n", *ip >> 24, *ip >> 16, *ip >> 8, *ip);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* This function supports Windows, Linux, XNU, FreeBSD, NetBSD, OpenBSD.
|
||||||
|
*
|
||||||
|
* @return null-terminated ip array on success, or null w/ errno
|
||||||
|
*/
|
||||||
|
uint32_t *GetHostIps(void) {
|
||||||
|
if (!IsWindows()) {
|
||||||
|
return GetUnixIps();
|
||||||
|
} else {
|
||||||
|
return GetWindowsIps();
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,11 +24,11 @@
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
||||||
void *out_opt_optval, uint32_t *out_optlen) {
|
void *out_opt_optval, uint32_t *out_optlen) {
|
||||||
/* TODO(jart): Use WSAIoctl? */
|
/* TODO(jart): Use WSAIoctl? */
|
||||||
assert(fd->kind == kFdSocket);
|
assert(fd->kind == kFdSocket);
|
||||||
if (__sys_getsockopt_nt(fd->handle, level, optname, out_opt_optval, out_optlen) !=
|
if (__sys_getsockopt_nt(fd->handle, level, optname, out_opt_optval,
|
||||||
-1) {
|
out_optlen) != -1) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return __winsockerr();
|
return __winsockerr();
|
||||||
|
|
|
@ -23,27 +23,70 @@
|
||||||
/**
|
/**
|
||||||
* Formats internet address to string.
|
* Formats internet address to string.
|
||||||
*
|
*
|
||||||
* @param af can be AF_INET
|
* @param af can be AF_INET or AF_INET6
|
||||||
* @param src is the binary-encoded address, e.g. &addr->sin_addr
|
* @param src is the binary-encoded address, e.g. &addr->sin_addr
|
||||||
* @param dst is the output string buffer
|
* @param dst is the output string buffer
|
||||||
* @param size is bytes in dst, which needs 16+ for IPv4
|
* @param size needs to be 16+ for IPv4 and 72+ for IPv6
|
||||||
* @return dst on success or NULL w/ errno
|
* @return dst on success or NULL w/ errno
|
||||||
*/
|
*/
|
||||||
const char *inet_ntop(int af, const void *src, char *dst, uint32_t size) {
|
const char *inet_ntop(int af, const void *src, char *dst, uint32_t size) {
|
||||||
char *p;
|
char *p;
|
||||||
unsigned char *ip4;
|
unsigned char *ip;
|
||||||
if (src) {
|
int i, t, a, b, c, d;
|
||||||
|
p = dst;
|
||||||
|
if ((ip = src)) {
|
||||||
if (af == AF_INET) {
|
if (af == AF_INET) {
|
||||||
if (size >= 16) {
|
if (size >= 16) {
|
||||||
p = dst;
|
p += uint64toarray_radix10(ip[0], p);
|
||||||
ip4 = src;
|
|
||||||
p += uint64toarray_radix10(ip4[0], p);
|
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
p += uint64toarray_radix10(ip4[1], p);
|
p += uint64toarray_radix10(ip[1], p);
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
p += uint64toarray_radix10(ip4[2], p);
|
p += uint64toarray_radix10(ip[2], p);
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
p += uint64toarray_radix10(ip4[3], p);
|
p += uint64toarray_radix10(ip[3], p);
|
||||||
|
*p = '\0';
|
||||||
|
return dst;
|
||||||
|
} else {
|
||||||
|
enospc();
|
||||||
|
}
|
||||||
|
} else if (af == AF_INET6) {
|
||||||
|
if (size >= 16 * 4 + 8) {
|
||||||
|
t = 0;
|
||||||
|
i = 0;
|
||||||
|
for (i = 0; i < 16; i += 2) {
|
||||||
|
switch (t) {
|
||||||
|
case 0:
|
||||||
|
if (!ip[i] && !ip[i + 1]) {
|
||||||
|
t = 1;
|
||||||
|
*p++ = ':';
|
||||||
|
*p++ = ':';
|
||||||
|
continue;
|
||||||
|
} else if (i) {
|
||||||
|
*p++ = ':';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (!ip[i] && !ip[i + 1]) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
t = 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*p++ = ':';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
a = (ip[i + 0] & 0xF0) >> 4;
|
||||||
|
b = (ip[i + 0] & 0x0F) >> 0;
|
||||||
|
c = (ip[i + 1] & 0xF0) >> 4;
|
||||||
|
d = (ip[i + 1] & 0x0F) >> 0;
|
||||||
|
if (a) *p++ = "0123456789abcdef"[a];
|
||||||
|
if (a || b) *p++ = "0123456789abcdef"[b];
|
||||||
|
if (a || b || c) *p++ = "0123456789abcdef"[c];
|
||||||
|
*p++ = "0123456789abcdef"[d];
|
||||||
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return dst;
|
return dst;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -181,7 +181,7 @@ int sys_close_epoll(int) hidden;
|
||||||
* Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
|
* Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
|
||||||
*/
|
*/
|
||||||
forceinline void sockaddr2bsd(void *saddr) {
|
forceinline void sockaddr2bsd(void *saddr) {
|
||||||
uint8_t *p;
|
char *p;
|
||||||
uint16_t fam;
|
uint16_t fam;
|
||||||
if (saddr) {
|
if (saddr) {
|
||||||
p = saddr;
|
p = saddr;
|
||||||
|
@ -195,7 +195,7 @@ forceinline void sockaddr2bsd(void *saddr) {
|
||||||
* Converts sockaddr_in_bsd (XNU/BSD) → sockaddr (Linux/Windows).
|
* Converts sockaddr_in_bsd (XNU/BSD) → sockaddr (Linux/Windows).
|
||||||
*/
|
*/
|
||||||
forceinline void sockaddr2linux(void *saddr) {
|
forceinline void sockaddr2linux(void *saddr) {
|
||||||
uint8_t *p, fam;
|
char *p, fam;
|
||||||
if (saddr) {
|
if (saddr) {
|
||||||
p = saddr;
|
p = saddr;
|
||||||
fam = p[1];
|
fam = p[1];
|
||||||
|
|
|
@ -81,7 +81,6 @@ struct msghdr { /* Linux+NT ABI */
|
||||||
uint32_t msg_flags; /* MSG_XXX */
|
uint32_t msg_flags; /* MSG_XXX */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure used in SIOCGIFCONF request.
|
* Structure used in SIOCGIFCONF request.
|
||||||
* Used to retrieve interface configuration
|
* Used to retrieve interface configuration
|
||||||
|
@ -89,50 +88,47 @@ struct msghdr { /* Linux+NT ABI */
|
||||||
* must know all networks accessible).
|
* must know all networks accessible).
|
||||||
*/
|
*/
|
||||||
struct ifconf {
|
struct ifconf {
|
||||||
uint64_t ifc_len; /* size of buffer */
|
uint64_t ifc_len; /* size of buffer */
|
||||||
union {
|
union {
|
||||||
char *ifcu_buf;
|
char *ifcu_buf;
|
||||||
struct ifreq *ifcu_req;
|
struct ifreq *ifcu_req;
|
||||||
} ifc_ifcu;
|
} ifc_ifcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Shortcuts to the ifconf buffer or ifreq array */
|
/* Shortcuts to the ifconf buffer or ifreq array */
|
||||||
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
||||||
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
|
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
|
||||||
|
|
||||||
#define IFHWADDRLEN 6
|
#define IFHWADDRLEN 6
|
||||||
#define IF_NAMESIZE 16
|
#define IF_NAMESIZE 16
|
||||||
#define IFNAMSIZ IF_NAMESIZE
|
#define IFNAMSIZ IF_NAMESIZE
|
||||||
struct ifreq {
|
struct ifreq {
|
||||||
union {
|
union {
|
||||||
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
|
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
|
||||||
} ifr_ifrn;
|
} ifr_ifrn;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct sockaddr ifru_addr; /* SIOCGIFADDR */
|
struct sockaddr ifru_addr; /* SIOCGIFADDR */
|
||||||
struct sockaddr ifru_dstaddr; /* SIOCGIFDSTADDR */
|
struct sockaddr ifru_dstaddr; /* SIOCGIFDSTADDR */
|
||||||
struct sockaddr ifru_netmask; /* SIOCGIFNETMASK */
|
struct sockaddr ifru_netmask; /* SIOCGIFNETMASK */
|
||||||
struct sockaddr ifru_broadaddr; /* SIOCGIFBRDADDR */
|
struct sockaddr ifru_broadaddr; /* SIOCGIFBRDADDR */
|
||||||
short ifru_flags; /* SIOCGIFFLAGS */
|
short ifru_flags; /* SIOCGIFFLAGS */
|
||||||
char ifru_pad[24]; /* ifru_map is the largest, just pad */
|
char ifru_pad[24]; /* ifru_map is the largest, just pad */
|
||||||
} ifr_ifru;
|
} ifr_ifru;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
|
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
|
||||||
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||||
#define ifr_netmask ifr_ifru.ifru_netmask /* netmask */
|
#define ifr_netmask ifr_ifru.ifru_netmask /* netmask */
|
||||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* destination address */
|
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* destination address */
|
||||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||||
|
|
||||||
#define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
|
|
||||||
#define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
|
|
||||||
#define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
|
|
||||||
|
|
||||||
#define IFF_UP (1<<0)
|
|
||||||
|
|
||||||
|
#define _IOT_ifreq _IOT(_IOTS(char), IFNAMSIZ, _IOTS(char), 16, 0, 0)
|
||||||
|
#define _IOT_ifreq_short _IOT(_IOTS(char), IFNAMSIZ, _IOTS(short), 1, 0, 0)
|
||||||
|
#define _IOT_ifreq_int _IOT(_IOTS(char), IFNAMSIZ, _IOTS(int), 1, 0, 0)
|
||||||
|
|
||||||
|
#define IFF_UP (1 << 0)
|
||||||
|
|
||||||
const char *inet_ntop(int, const void *, char *, uint32_t);
|
const char *inet_ntop(int, const void *, char *, uint32_t);
|
||||||
int inet_aton(const char *, struct in_addr *);
|
int inet_aton(const char *, struct in_addr *);
|
||||||
|
@ -140,6 +136,7 @@ int inet_pton(int, const char *, void *);
|
||||||
uint32_t inet_addr(const char *);
|
uint32_t inet_addr(const char *);
|
||||||
char *inet_ntoa(struct in_addr);
|
char *inet_ntoa(struct in_addr);
|
||||||
int parseport(const char *);
|
int parseport(const char *);
|
||||||
|
uint32_t *GetHostIps(void);
|
||||||
|
|
||||||
int socket(int, int, int) nodiscard;
|
int socket(int, int, int) nodiscard;
|
||||||
int accept(int, void *, uint32_t *) nodiscard;
|
int accept(int, void *, uint32_t *) nodiscard;
|
||||||
|
|
|
@ -24,11 +24,9 @@ LIBC_SOCK_A_DIRECTDEPS = \
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
LIBC_MEM \
|
LIBC_MEM \
|
||||||
LIBC_TIME \
|
|
||||||
LIBC_STR \
|
|
||||||
LIBC_UNICODE \
|
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_NT_ADVAPI32 \
|
LIBC_NT_ADVAPI32 \
|
||||||
|
LIBC_NT_IPHLPAPI \
|
||||||
LIBC_NT_KERNEL32 \
|
LIBC_NT_KERNEL32 \
|
||||||
LIBC_NT_MSWSOCK \
|
LIBC_NT_MSWSOCK \
|
||||||
LIBC_NT_NTDLL \
|
LIBC_NT_NTDLL \
|
||||||
|
@ -37,8 +35,11 @@ LIBC_SOCK_A_DIRECTDEPS = \
|
||||||
LIBC_RUNTIME \
|
LIBC_RUNTIME \
|
||||||
LIBC_STDIO \
|
LIBC_STDIO \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
LIBC_SYSV_CALLS \
|
LIBC_SYSV_CALLS \
|
||||||
|
LIBC_TIME \
|
||||||
|
LIBC_UNICODE \
|
||||||
LIBC_SYSV
|
LIBC_SYSV
|
||||||
|
|
||||||
LIBC_SOCK_A_DEPS := \
|
LIBC_SOCK_A_DEPS := \
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/struct/dirent.h"
|
#include "libc/calls/struct/dirent.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -27,10 +30,13 @@
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/struct/win32finddata.h"
|
#include "libc/nt/struct/win32finddata.h"
|
||||||
|
#include "libc/nt/synchronization.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/dt.h"
|
#include "libc/sysv/consts/dt.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
#include "libc/zip.h"
|
||||||
|
#include "libc/zipos/zipos.internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview Directory Streams for Linux+Mac+Windows+FreeBSD+OpenBSD.
|
* @fileoverview Directory Streams for Linux+Mac+Windows+FreeBSD+OpenBSD.
|
||||||
|
@ -46,14 +52,21 @@
|
||||||
* Directory stream object.
|
* Directory stream object.
|
||||||
*/
|
*/
|
||||||
struct dirstream {
|
struct dirstream {
|
||||||
|
bool iszip;
|
||||||
int64_t fd;
|
int64_t fd;
|
||||||
int64_t tell;
|
int64_t tell;
|
||||||
|
struct {
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t records;
|
||||||
|
uint8_t *prefix;
|
||||||
|
size_t prefixlen;
|
||||||
|
} zip;
|
||||||
struct dirent ent;
|
struct dirent ent;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
unsigned buf_pos;
|
unsigned buf_pos;
|
||||||
unsigned buf_end;
|
unsigned buf_end;
|
||||||
char buf[BUFSIZ];
|
uint64_t buf[BUFSIZ / 8];
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
bool isdone;
|
bool isdone;
|
||||||
|
@ -100,7 +113,9 @@ struct dirent_netbsd {
|
||||||
static textwindows DIR *opendir_nt_impl(char16_t name[PATH_MAX], size_t len) {
|
static textwindows DIR *opendir_nt_impl(char16_t name[PATH_MAX], size_t len) {
|
||||||
DIR *res;
|
DIR *res;
|
||||||
if (len + 2 + 1 <= PATH_MAX) {
|
if (len + 2 + 1 <= PATH_MAX) {
|
||||||
if (name[len - 1] != u'\\') name[len++] = u'\\';
|
if (len > 1 && name[len - 1] != u'\\') {
|
||||||
|
name[len++] = u'\\';
|
||||||
|
}
|
||||||
name[len++] = u'*';
|
name[len++] = u'*';
|
||||||
name[len] = u'\0';
|
name[len] = u'\0';
|
||||||
if ((res = calloc(1, sizeof(DIR)))) {
|
if ((res = calloc(1, sizeof(DIR)))) {
|
||||||
|
@ -141,34 +156,39 @@ static textwindows noinline DIR *fdopendir_nt(int fd) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static textwindows uint8_t GetNtDirentType(struct NtWin32FindData *w) {
|
||||||
|
switch (w->dwFileType) {
|
||||||
|
case kNtFileTypeDisk:
|
||||||
|
return DT_BLK;
|
||||||
|
case kNtFileTypeChar:
|
||||||
|
return DT_CHR;
|
||||||
|
case kNtFileTypePipe:
|
||||||
|
return DT_FIFO;
|
||||||
|
default:
|
||||||
|
if (w->dwFileAttributes & kNtFileAttributeDirectory) {
|
||||||
|
return DT_DIR;
|
||||||
|
} else {
|
||||||
|
return DT_REG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static textwindows noinline struct dirent *readdir_nt(DIR *dir) {
|
static textwindows noinline struct dirent *readdir_nt(DIR *dir) {
|
||||||
|
size_t i;
|
||||||
if (!dir->isdone) {
|
if (!dir->isdone) {
|
||||||
memset(&dir->ent, 0, sizeof(dir->ent));
|
memset(&dir->ent, 0, sizeof(dir->ent));
|
||||||
dir->ent.d_ino = 0;
|
dir->ent.d_ino++;
|
||||||
dir->ent.d_off = dir->tell++;
|
dir->ent.d_off = dir->tell++;
|
||||||
dir->ent.d_reclen = sizeof(dir->ent) +
|
dir->ent.d_reclen =
|
||||||
tprecode16to8(dir->ent.d_name, sizeof(dir->ent.d_name),
|
tprecode16to8(dir->ent.d_name, sizeof(dir->ent.d_name) - 2,
|
||||||
dir->windata.cFileName)
|
dir->windata.cFileName)
|
||||||
.ax +
|
.ax;
|
||||||
1;
|
for (i = 0; i < dir->ent.d_reclen; ++i) {
|
||||||
switch (dir->windata.dwFileType) {
|
if (dir->ent.d_name[i] == '\\') {
|
||||||
case kNtFileTypeDisk:
|
dir->ent.d_name[i] = '/';
|
||||||
dir->ent.d_type = DT_BLK;
|
}
|
||||||
break;
|
|
||||||
case kNtFileTypeChar:
|
|
||||||
dir->ent.d_type = DT_CHR;
|
|
||||||
break;
|
|
||||||
case kNtFileTypePipe:
|
|
||||||
dir->ent.d_type = DT_FIFO;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (dir->windata.dwFileAttributes & kNtFileAttributeDirectory) {
|
|
||||||
dir->ent.d_type = DT_DIR;
|
|
||||||
} else {
|
|
||||||
dir->ent.d_type = DT_REG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
dir->ent.d_type = GetNtDirentType(&dir->windata);
|
||||||
dir->isdone = !FindNextFile(dir->fd, &dir->windata);
|
dir->isdone = !FindNextFile(dir->fd, &dir->windata);
|
||||||
return &dir->ent;
|
return &dir->ent;
|
||||||
} else {
|
} else {
|
||||||
|
@ -194,10 +214,29 @@ static textwindows noinline struct dirent *readdir_nt(DIR *dir) {
|
||||||
DIR *opendir(const char *name) {
|
DIR *opendir(const char *name) {
|
||||||
int fd;
|
int fd;
|
||||||
DIR *res;
|
DIR *res;
|
||||||
if (!IsWindows()) {
|
struct Zipos *zip;
|
||||||
|
struct ZiposUri zipname;
|
||||||
|
if (weaken(__zipos_get) && weaken(__zipos_parseuri)(name, &zipname) != -1) {
|
||||||
|
zip = weaken(__zipos_get)();
|
||||||
|
res = calloc(1, sizeof(DIR));
|
||||||
|
res->iszip = true;
|
||||||
|
res->fd = -1;
|
||||||
|
res->zip.offset = GetZipCdirOffset(zip->cdir);
|
||||||
|
res->zip.records = GetZipCdirRecords(zip->cdir);
|
||||||
|
res->zip.prefix = malloc(zipname.len + 2);
|
||||||
|
memcpy(res->zip.prefix, zipname.path, zipname.len);
|
||||||
|
if (zipname.len && res->zip.prefix[zipname.len - 1] != '/') {
|
||||||
|
res->zip.prefix[zipname.len++] = '/';
|
||||||
|
}
|
||||||
|
res->zip.prefix[zipname.len] = '\0';
|
||||||
|
res->zip.prefixlen = zipname.len;
|
||||||
|
return res;
|
||||||
|
} else if (!IsWindows()) {
|
||||||
res = NULL;
|
res = NULL;
|
||||||
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) {
|
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) {
|
||||||
if (!(res = fdopendir(fd))) close(fd);
|
if (!(res = fdopendir(fd))) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
|
@ -234,13 +273,44 @@ DIR *fdopendir(int fd) {
|
||||||
* differentiated by setting errno to 0 beforehand
|
* differentiated by setting errno to 0 beforehand
|
||||||
*/
|
*/
|
||||||
struct dirent *readdir(DIR *dir) {
|
struct dirent *readdir(DIR *dir) {
|
||||||
int rc;
|
size_t n;
|
||||||
long basep;
|
long basep;
|
||||||
|
int rc, mode;
|
||||||
|
uint8_t *s, *p;
|
||||||
|
struct Zipos *zip;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
struct dirent_bsd *bsd;
|
struct dirent_bsd *bsd;
|
||||||
struct dirent_netbsd *nbsd;
|
struct dirent_netbsd *nbsd;
|
||||||
struct dirent_openbsd *obsd;
|
struct dirent_openbsd *obsd;
|
||||||
if (!IsWindows()) {
|
if (dir->iszip) {
|
||||||
|
ent = 0;
|
||||||
|
zip = weaken(__zipos_get)();
|
||||||
|
while (!ent && dir->tell < dir->zip.records) {
|
||||||
|
assert(ZIP_CFILE_MAGIC(zip->map + dir->zip.offset) == kZipCfileHdrMagic);
|
||||||
|
s = ZIP_CFILE_NAME(zip->map + dir->zip.offset);
|
||||||
|
n = ZIP_CFILE_NAMESIZE(zip->map + dir->zip.offset);
|
||||||
|
if (dir->zip.prefixlen < n &&
|
||||||
|
!memcmp(dir->zip.prefix, s, dir->zip.prefixlen)) {
|
||||||
|
s += dir->zip.prefixlen;
|
||||||
|
n -= dir->zip.prefixlen;
|
||||||
|
p = memchr(s, '/', n);
|
||||||
|
if (!p || p + 1 - s == n) {
|
||||||
|
if (p + 1 - s == n) --n;
|
||||||
|
mode = GetZipCfileMode(zip->map + dir->zip.offset);
|
||||||
|
ent = (struct dirent *)dir->buf;
|
||||||
|
ent->d_ino++;
|
||||||
|
ent->d_off = dir->zip.offset;
|
||||||
|
ent->d_reclen = MIN(n, 255);
|
||||||
|
ent->d_type = S_ISDIR(mode) ? DT_DIR : DT_REG;
|
||||||
|
memcpy(ent->d_name, s, ent->d_reclen);
|
||||||
|
ent->d_name[ent->d_reclen] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir->zip.offset += ZIP_CFILE_HDRSIZE(zip->map + dir->zip.offset);
|
||||||
|
dir->tell++;
|
||||||
|
}
|
||||||
|
return ent;
|
||||||
|
} else if (!IsWindows()) {
|
||||||
if (dir->buf_pos >= dir->buf_end) {
|
if (dir->buf_pos >= dir->buf_end) {
|
||||||
basep = dir->tell; /* TODO(jart): what does xnu do */
|
basep = dir->tell; /* TODO(jart): what does xnu do */
|
||||||
rc = getdents(dir->fd, dir->buf, sizeof(dir->buf) - 256, &basep);
|
rc = getdents(dir->fd, dir->buf, sizeof(dir->buf) - 256, &basep);
|
||||||
|
@ -249,11 +319,11 @@ struct dirent *readdir(DIR *dir) {
|
||||||
dir->buf_end = rc;
|
dir->buf_end = rc;
|
||||||
}
|
}
|
||||||
if (IsLinux()) {
|
if (IsLinux()) {
|
||||||
ent = (struct dirent *)(dir->buf + dir->buf_pos);
|
ent = (struct dirent *)((char *)dir->buf + dir->buf_pos);
|
||||||
dir->buf_pos += ent->d_reclen;
|
dir->buf_pos += ent->d_reclen;
|
||||||
dir->tell = ent->d_off;
|
dir->tell = ent->d_off;
|
||||||
} else if (IsOpenbsd()) {
|
} else if (IsOpenbsd()) {
|
||||||
obsd = (struct dirent_openbsd *)(dir->buf + dir->buf_pos);
|
obsd = (struct dirent_openbsd *)((char *)dir->buf + dir->buf_pos);
|
||||||
dir->buf_pos += obsd->d_reclen;
|
dir->buf_pos += obsd->d_reclen;
|
||||||
ent = &dir->ent;
|
ent = &dir->ent;
|
||||||
ent->d_ino = obsd->d_fileno;
|
ent->d_ino = obsd->d_fileno;
|
||||||
|
@ -262,7 +332,7 @@ struct dirent *readdir(DIR *dir) {
|
||||||
ent->d_type = obsd->d_type;
|
ent->d_type = obsd->d_type;
|
||||||
memcpy(ent->d_name, obsd->d_name, obsd->d_namlen + 1);
|
memcpy(ent->d_name, obsd->d_name, obsd->d_namlen + 1);
|
||||||
} else if (IsNetbsd()) {
|
} else if (IsNetbsd()) {
|
||||||
nbsd = (struct dirent_netbsd *)(dir->buf + dir->buf_pos);
|
nbsd = (struct dirent_netbsd *)((char *)dir->buf + dir->buf_pos);
|
||||||
dir->buf_pos += nbsd->d_reclen;
|
dir->buf_pos += nbsd->d_reclen;
|
||||||
ent = &dir->ent;
|
ent = &dir->ent;
|
||||||
ent->d_ino = nbsd->d_fileno;
|
ent->d_ino = nbsd->d_fileno;
|
||||||
|
@ -271,7 +341,7 @@ struct dirent *readdir(DIR *dir) {
|
||||||
ent->d_type = nbsd->d_type;
|
ent->d_type = nbsd->d_type;
|
||||||
memcpy(ent->d_name, nbsd->d_name, MAX(256, nbsd->d_namlen + 1));
|
memcpy(ent->d_name, nbsd->d_name, MAX(256, nbsd->d_namlen + 1));
|
||||||
} else {
|
} else {
|
||||||
bsd = (struct dirent_bsd *)(dir->buf + dir->buf_pos);
|
bsd = (struct dirent_bsd *)((char *)dir->buf + dir->buf_pos);
|
||||||
dir->buf_pos += bsd->d_reclen;
|
dir->buf_pos += bsd->d_reclen;
|
||||||
ent = &dir->ent;
|
ent = &dir->ent;
|
||||||
ent->d_ino = bsd->d_fileno;
|
ent->d_ino = bsd->d_fileno;
|
||||||
|
@ -293,7 +363,10 @@ struct dirent *readdir(DIR *dir) {
|
||||||
int closedir(DIR *dir) {
|
int closedir(DIR *dir) {
|
||||||
int rc;
|
int rc;
|
||||||
if (dir) {
|
if (dir) {
|
||||||
if (!IsWindows()) {
|
if (dir->iszip) {
|
||||||
|
free(dir->zip.prefix);
|
||||||
|
rc = 0;
|
||||||
|
} else if (!IsWindows()) {
|
||||||
rc = close(dir->fd);
|
rc = close(dir->fd);
|
||||||
} else {
|
} else {
|
||||||
rc = FindClose(dir->fd) ? 0 : __winerr();
|
rc = FindClose(dir->fd) ? 0 : __winerr();
|
||||||
|
@ -316,6 +389,7 @@ long telldir(DIR *dir) {
|
||||||
* Returns file descriptor associated with DIR object.
|
* Returns file descriptor associated with DIR object.
|
||||||
*/
|
*/
|
||||||
int dirfd(DIR *dir) {
|
int dirfd(DIR *dir) {
|
||||||
|
if (dir->iszip) return eopnotsupp();
|
||||||
if (IsWindows()) return eopnotsupp();
|
if (IsWindows()) return eopnotsupp();
|
||||||
return dir->fd;
|
return dir->fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,15 +66,6 @@ size_t mbsrtowcs(wchar_t *ws, const char **src, size_t wn, mbstate_t *st) {
|
||||||
}
|
}
|
||||||
if (!ws)
|
if (!ws)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#ifdef __GNUC__
|
|
||||||
typedef uint32_t __attribute__((__may_alias__)) w32;
|
|
||||||
if (*s - 1u < 0x7f && (uintptr_t)s % 4 == 0) {
|
|
||||||
while (!((*(w32 *)s | *(w32 *)s - 0x01010101) & 0x80808080)) {
|
|
||||||
s += 4;
|
|
||||||
wn -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (*s - 1u < 0x7f) {
|
if (*s - 1u < 0x7f) {
|
||||||
s++;
|
s++;
|
||||||
wn--;
|
wn--;
|
||||||
|
@ -111,19 +102,6 @@ size_t mbsrtowcs(wchar_t *ws, const char **src, size_t wn, mbstate_t *st) {
|
||||||
*src = (const void *)s;
|
*src = (const void *)s;
|
||||||
return wn0;
|
return wn0;
|
||||||
}
|
}
|
||||||
#ifdef __GNUC__
|
|
||||||
typedef uint32_t __attribute__((__may_alias__)) w32;
|
|
||||||
if (*s - 1u < 0x7f && (uintptr_t)s % 4 == 0) {
|
|
||||||
while (wn >= 5 &&
|
|
||||||
!((*(w32 *)s | *(w32 *)s - 0x01010101) & 0x80808080)) {
|
|
||||||
*ws++ = *s++;
|
|
||||||
*ws++ = *s++;
|
|
||||||
*ws++ = *s++;
|
|
||||||
*ws++ = *s++;
|
|
||||||
wn -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (*s - 1u < 0x7f) {
|
if (*s - 1u < 0x7f) {
|
||||||
*ws++ = *s++;
|
*ws++ = *s++;
|
||||||
wn--;
|
wn--;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.include "o/libc/sysv/macros.internal.inc"
|
.include "o/libc/sysv/macros.internal.inc"
|
||||||
.scall sys_getrandom,0x05b00723321f413e,globl,hidden
|
.scall sys_getrandom,0xfff00723321f413e,globl,hidden
|
||||||
|
|
|
@ -151,6 +151,7 @@ syscon sig SIGIO 29 23 23 23 23 29 # bsd consensus
|
||||||
syscon sig SIGSYS 31 12 12 12 12 31 # wut; bsd consensus
|
syscon sig SIGSYS 31 12 12 12 12 31 # wut; bsd consensus
|
||||||
syscon sig SIGRTMAX 0 0 126 0 63 0
|
syscon sig SIGRTMAX 0 0 126 0 63 0
|
||||||
syscon sig SIGRTMIN 0 0 65 0 33 0
|
syscon sig SIGRTMIN 0 0 65 0 33 0
|
||||||
|
syscon sig SIGEMT 0 7 7 7 7 0 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||||
syscon compat SIGPOLL 29 23 23 23 23 29 # same as SIGIO
|
syscon compat SIGPOLL 29 23 23 23 23 29 # same as SIGIO
|
||||||
syscon compat SIGIOT 6 6 6 6 6 6 # PDP-11 feature; same as SIGABRT
|
syscon compat SIGIOT 6 6 6 6 6 6 # PDP-11 feature; same as SIGABRT
|
||||||
syscon compat SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
syscon compat SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||||
|
@ -170,7 +171,7 @@ syscon open O_APPEND 0x00000400 8 8 8 8 0x00000004 # bsd consensus
|
||||||
syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux
|
syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux
|
||||||
syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux
|
syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux
|
||||||
syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux
|
syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux
|
||||||
syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x02000000 # kNtFileFlagBackupSemantics
|
syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x02000000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics)
|
||||||
syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00200000 # kNtFileFlagNoBuffering>>8
|
syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00200000 # kNtFileFlagNoBuffering>>8
|
||||||
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux
|
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux
|
||||||
syscon open O_TMPFILE 0x00410000 0 0 0 0 0x04000100 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose
|
syscon open O_TMPFILE 0x00410000 0 0 0 0 0x04000100 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose
|
||||||
|
|
2
libc/sysv/consts/SIGEMT.S
Normal file
2
libc/sysv/consts/SIGEMT.S
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
|
.syscon sig,SIGEMT,0,7,7,7,7,0
|
|
@ -2,7 +2,9 @@
|
||||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_
|
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_
|
||||||
#include "libc/runtime/symbolic.h"
|
#include "libc/runtime/symbolic.h"
|
||||||
|
|
||||||
#define GRND_NONBLOCK LITERALLY(1)
|
#define GRND_NONBLOCK 1
|
||||||
#define GRND_RANDOM LITERALLY(2)
|
#define GRND_RANDOM 2
|
||||||
|
#define GRND_NORDRND 64
|
||||||
|
#define GRND_NOSYSTEM 128
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_ */
|
||||||
|
|
|
@ -41,6 +41,7 @@ extern const long SIGVTALRM;
|
||||||
extern const long SIGWINCH;
|
extern const long SIGWINCH;
|
||||||
extern const long SIGXCPU;
|
extern const long SIGXCPU;
|
||||||
extern const long SIGXFSZ;
|
extern const long SIGXFSZ;
|
||||||
|
extern const long SIGEMT;
|
||||||
|
|
||||||
extern const long SIG_ATOMIC_MIN;
|
extern const long SIG_ATOMIC_MIN;
|
||||||
extern const long SIG_BLOCK;
|
extern const long SIG_BLOCK;
|
||||||
|
@ -50,47 +51,48 @@ extern const long SIG_UNBLOCK;
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
||||||
#define SIGABRT LITERALLY(6)
|
#define SIGABRT LITERALLY(6)
|
||||||
#define SIGALRM LITERALLY(14)
|
#define SIGALRM LITERALLY(14)
|
||||||
#define SIGBUS SYMBOLIC(SIGBUS)
|
#define SIGBUS SYMBOLIC(SIGBUS)
|
||||||
#define SIGCHLD SYMBOLIC(SIGCHLD)
|
#define SIGCHLD SYMBOLIC(SIGCHLD)
|
||||||
#define SIGCONT SYMBOLIC(SIGCONT)
|
#define SIGCONT SYMBOLIC(SIGCONT)
|
||||||
#define SIGFPE LITERALLY(8)
|
#define SIGFPE LITERALLY(8)
|
||||||
#define SIGHUP LITERALLY(1)
|
#define SIGHUP LITERALLY(1)
|
||||||
#define SIGILL LITERALLY(4)
|
#define SIGILL LITERALLY(4)
|
||||||
#define SIGINT LITERALLY(2)
|
#define SIGINT LITERALLY(2)
|
||||||
#define SIGIO SYMBOLIC(SIGIO)
|
#define SIGIO SYMBOLIC(SIGIO)
|
||||||
#define SIGIOT LITERALLY(6)
|
#define SIGIOT LITERALLY(6)
|
||||||
#define SIGKILL LITERALLY(9)
|
#define SIGKILL LITERALLY(9)
|
||||||
#define SIGPIPE LITERALLY(13)
|
#define SIGPIPE LITERALLY(13)
|
||||||
#define SIGPOLL SYMBOLIC(SIGPOLL)
|
#define SIGPOLL SYMBOLIC(SIGPOLL)
|
||||||
#define SIGPROF LITERALLY(27)
|
#define SIGPROF LITERALLY(27)
|
||||||
#define SIGPWR SYMBOLIC(SIGPWR)
|
#define SIGPWR SYMBOLIC(SIGPWR)
|
||||||
#define SIGQUIT LITERALLY(3)
|
#define SIGQUIT LITERALLY(3)
|
||||||
#define SIGRTMAX SYMBOLIC(SIGRTMAX)
|
#define SIGRTMAX SYMBOLIC(SIGRTMAX)
|
||||||
#define SIGRTMIN SYMBOLIC(SIGRTMIN)
|
#define SIGRTMIN SYMBOLIC(SIGRTMIN)
|
||||||
#define SIGSEGV LITERALLY(11)
|
#define SIGSEGV LITERALLY(11)
|
||||||
#define SIGSTKFLT SYMBOLIC(SIGSTKFLT)
|
#define SIGSTKFLT SYMBOLIC(SIGSTKFLT)
|
||||||
#define SIGSTKSZ SYMBOLIC(SIGSTKSZ)
|
#define SIGSTKSZ SYMBOLIC(SIGSTKSZ)
|
||||||
#define SIGSTOP SYMBOLIC(SIGSTOP)
|
#define SIGSTOP SYMBOLIC(SIGSTOP)
|
||||||
#define SIGSYS SYMBOLIC(SIGSYS)
|
#define SIGSYS SYMBOLIC(SIGSYS)
|
||||||
#define SIGTERM LITERALLY(15)
|
#define SIGTERM LITERALLY(15)
|
||||||
#define SIGTRAP LITERALLY(5)
|
#define SIGTRAP LITERALLY(5)
|
||||||
#define SIGTSTP SYMBOLIC(SIGTSTP)
|
#define SIGTSTP SYMBOLIC(SIGTSTP)
|
||||||
#define SIGTTIN LITERALLY(21)
|
#define SIGTTIN LITERALLY(21)
|
||||||
#define SIGTTOU LITERALLY(22)
|
#define SIGTTOU LITERALLY(22)
|
||||||
#define SIGUNUSED SYMBOLIC(SIGUNUSED)
|
#define SIGUNUSED SYMBOLIC(SIGUNUSED)
|
||||||
#define SIGURG SYMBOLIC(SIGURG)
|
#define SIGURG SYMBOLIC(SIGURG)
|
||||||
#define SIGUSR1 SYMBOLIC(SIGUSR1)
|
#define SIGUSR1 SYMBOLIC(SIGUSR1)
|
||||||
#define SIGUSR2 SYMBOLIC(SIGUSR2)
|
#define SIGUSR2 SYMBOLIC(SIGUSR2)
|
||||||
#define SIGVTALRM LITERALLY(26)
|
#define SIGVTALRM LITERALLY(26)
|
||||||
#define SIGWINCH LITERALLY(28)
|
#define SIGWINCH LITERALLY(28)
|
||||||
#define SIGXCPU LITERALLY(24)
|
#define SIGXCPU LITERALLY(24)
|
||||||
#define SIGXFSZ LITERALLY(25)
|
#define SIGXFSZ LITERALLY(25)
|
||||||
|
#define SIGEMT SYMBOLIC(SIGEMT)
|
||||||
|
|
||||||
#define SIG_ATOMIC_MIN SYMBOLIC(SIG_ATOMIC_MIN)
|
#define SIG_ATOMIC_MIN SYMBOLIC(SIG_ATOMIC_MIN)
|
||||||
#define SIG_BLOCK SYMBOLIC(SIG_BLOCK)
|
#define SIG_BLOCK SYMBOLIC(SIG_BLOCK)
|
||||||
#define SIG_SETMASK SYMBOLIC(SIG_SETMASK)
|
#define SIG_SETMASK SYMBOLIC(SIG_SETMASK)
|
||||||
#define SIG_UNBLOCK SYMBOLIC(SIG_UNBLOCK)
|
#define SIG_UNBLOCK SYMBOLIC(SIG_UNBLOCK)
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SIG_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SIG_H_ */
|
||||||
|
|
|
@ -349,7 +349,7 @@ scall sched_setattr 0xfffffffffffff13a globl # ├─ desktop replaced with ta
|
||||||
scall sched_getattr 0xfffffffffffff13b globl # ├─ karen sandler requires systemd init and boot for tablet gui
|
scall sched_getattr 0xfffffffffffff13b globl # ├─ karen sandler requires systemd init and boot for tablet gui
|
||||||
scall renameat2 0xfffffffffffff13c globl # └─ debian founder ian murdock found strangled with vacuum cord
|
scall renameat2 0xfffffffffffff13c globl # └─ debian founder ian murdock found strangled with vacuum cord
|
||||||
scall seccomp 0xfffffffffffff13d globl
|
scall seccomp 0xfffffffffffff13d globl
|
||||||
scall sys_getrandom 0x05b00723321f413e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD
|
scall sys_getrandom 0xfff00723321f413e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD, coming to NetBSD in 9.2
|
||||||
scall memfd_create 0xfffffffffffff13f globl # wut
|
scall memfd_create 0xfffffffffffff13f globl # wut
|
||||||
scall kexec_file_load 0xfffffffffffff140 globl
|
scall kexec_file_load 0xfffffffffffff140 globl
|
||||||
scall bpf 0xfffffffffffff141 globl
|
scall bpf 0xfffffffffffff141 globl
|
||||||
|
|
|
@ -25,17 +25,21 @@
|
||||||
* Turns string into code.
|
* Turns string into code.
|
||||||
*/
|
*/
|
||||||
nodiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) {
|
nodiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) {
|
||||||
switch (cw) {
|
if (s) {
|
||||||
case 1:
|
switch (cw) {
|
||||||
if (n == -1) n = s ? strlen(s) : 0;
|
case 1:
|
||||||
return xasprintf("%`'.*s", n, s);
|
if (n == -1) n = s ? strlen(s) : 0;
|
||||||
case 2:
|
return xasprintf("%`'.*s", n, s);
|
||||||
if (n == -1) n = s ? strlen16(s) : 0;
|
case 2:
|
||||||
return xasprintf("%`'.*hs", n, s);
|
if (n == -1) n = s ? strlen16(s) : 0;
|
||||||
case 4:
|
return xasprintf("%`'.*hs", n, s);
|
||||||
if (n == -1) n = s ? wcslen(s) : 0;
|
case 4:
|
||||||
return xasprintf("%`'.*ls", n, s);
|
if (n == -1) n = s ? wcslen(s) : 0;
|
||||||
default:
|
return xasprintf("%`'.*ls", n, s);
|
||||||
abort();
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return strdup("NULL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,6 @@ static char *strftime_timefmt(char *p, const char *pe, const char *format,
|
||||||
*/
|
*/
|
||||||
size_t strftime(char *s, size_t size, const char *f, const struct tm *t) {
|
size_t strftime(char *s, size_t size, const char *f, const struct tm *t) {
|
||||||
char *p;
|
char *p;
|
||||||
assert(t);
|
|
||||||
p = strftime_timefmt(s, s + size, f, t);
|
p = strftime_timefmt(s, s + size, f, t);
|
||||||
if (p < s + size) {
|
if (p < s + size) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
|
@ -75,7 +75,9 @@ char *xiso8601ts(struct timespec *) mallocesque;
|
||||||
│ cosmopolitan § eXtended apis » input / output ─╬─│┼
|
│ cosmopolitan § eXtended apis » input / output ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
||||||
char *xslurp(const char *, size_t *) paramsnonnull((1)) _XMALPG nodiscard;
|
char *xslurp(const char *, size_t *)
|
||||||
|
paramsnonnull((1)) returnspointerwithnoaliases
|
||||||
|
returnsaligned((PAGESIZE)) nodiscard;
|
||||||
int xbarf(const char *, const void *, size_t);
|
int xbarf(const char *, const void *, size_t);
|
||||||
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- 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│
|
│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 │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,38 +16,36 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/rand/rand.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/calls/internal.h"
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/zipos/zipos.internal.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
|
||||||
#include "libc/sysv/consts/o.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads random bytes from system pseudo random number api.
|
* Changes current position of zip file handle.
|
||||||
* @return 0 on success or -1 w/ errno
|
*
|
||||||
|
* @param offset is the relative byte count
|
||||||
|
* @param whence can be SEEK_SET, SEEK_CUR, or SEEK_END
|
||||||
|
* @return new position relative to beginning, or -1 on error
|
||||||
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int devrand(void *buf, size_t size) {
|
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
|
||||||
int fd;
|
int64_t i;
|
||||||
size_t got;
|
switch (whence) {
|
||||||
ssize_t rc;
|
case SEEK_SET:
|
||||||
unsigned char *p, *pe;
|
i = offset;
|
||||||
fd = -1;
|
break;
|
||||||
if (IsWindows()) return enosys();
|
case SEEK_CUR:
|
||||||
if ((fd = sys_openat(AT_FDCWD, "/dev/urandom", O_RDONLY, 0)) == -1) {
|
i = h->pos + offset;
|
||||||
return -1;
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
i = h->size - offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return einval();
|
||||||
}
|
}
|
||||||
p = buf;
|
if (i < 0) {
|
||||||
pe = p + size;
|
return einval();
|
||||||
while (p < pe) {
|
|
||||||
if ((rc = sys_read(fd, p, pe - p)) == -1) break;
|
|
||||||
if (!(got = (size_t)rc)) break;
|
|
||||||
p += got;
|
|
||||||
}
|
}
|
||||||
sys_close(fd);
|
h->pos = i;
|
||||||
return p == pe ? 0 : -1;
|
return i;
|
||||||
}
|
}
|
|
@ -94,18 +94,16 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
||||||
kZipCompressionDeflate);
|
kZipCompressionDeflate);
|
||||||
if (!(h = calloc(1, sizeof(*h)))) return -1;
|
if (!(h = calloc(1, sizeof(*h)))) return -1;
|
||||||
h->cfile = cf;
|
h->cfile = cf;
|
||||||
if ((h->size = GetZipLfileUncompressedSize(zipos->map + lf))) {
|
h->size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||||
if (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) {
|
if (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) {
|
||||||
assert(GetZipLfileCompressedSize(zipos->map + lf));
|
if ((h->freeme = malloc(h->size)) &&
|
||||||
if ((h->freeme = malloc(h->size)) &&
|
(IsTiny() ? __zipos_inflate_tiny : __zipos_inflate_fast)(
|
||||||
(IsTiny() ? __zipos_inflate_tiny : __zipos_inflate_fast)(
|
h, ZIP_LFILE_CONTENT(zipos->map + lf),
|
||||||
h, ZIP_LFILE_CONTENT(zipos->map + lf),
|
GetZipLfileCompressedSize(zipos->map + lf)) != -1) {
|
||||||
GetZipLfileCompressedSize(zipos->map + lf)) != -1) {
|
h->mem = h->freeme;
|
||||||
h->mem = h->freeme;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
h->mem = ZIP_LFILE_CONTENT(zipos->map + lf);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
h->mem = ZIP_LFILE_CONTENT(zipos->map + lf);
|
||||||
}
|
}
|
||||||
if (!IsTiny() && h->mem &&
|
if (!IsTiny() && h->mem &&
|
||||||
crc32_z(0, h->mem, h->size) != ZIP_LFILE_CRC32(zipos->map + lf)) {
|
crc32_z(0, h->mem, h->size) != ZIP_LFILE_CRC32(zipos->map + lf)) {
|
||||||
|
@ -138,7 +136,7 @@ int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
|
||||||
ssize_t cf;
|
ssize_t cf;
|
||||||
sigset_t oldmask;
|
sigset_t oldmask;
|
||||||
struct Zipos *zipos;
|
struct Zipos *zipos;
|
||||||
assert((flags & O_ACCMODE) == O_RDONLY);
|
if ((flags & O_ACCMODE) != O_RDONLY) return einval();
|
||||||
if ((zipos = __zipos_get())) {
|
if ((zipos = __zipos_get())) {
|
||||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||||
fd = __zipos_load(zipos, cf, flags, mode);
|
fd = __zipos_load(zipos, cf, flags, mode);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
.yoink __zipos_close
|
.yoink __zipos_close
|
||||||
.yoink __zipos_fstat
|
.yoink __zipos_fstat
|
||||||
.yoink __zipos_open
|
.yoink __zipos_open
|
||||||
|
.yoink __zipos_lseek
|
||||||
.yoink __zipos_parseuri
|
.yoink __zipos_parseuri
|
||||||
.yoink __zipos_read
|
.yoink __zipos_read
|
||||||
.yoink __zipos_stat
|
.yoink __zipos_stat
|
||||||
|
|
|
@ -40,6 +40,7 @@ ssize_t __zipos_read(struct ZiposHandle *, const struct iovec *, size_t,
|
||||||
ssize_t) hidden;
|
ssize_t) hidden;
|
||||||
ssize_t __zipos_write(struct ZiposHandle *, const struct iovec *, size_t,
|
ssize_t __zipos_write(struct ZiposHandle *, const struct iovec *, size_t,
|
||||||
ssize_t) hidden;
|
ssize_t) hidden;
|
||||||
|
int64_t __zipos_lseek(struct ZiposHandle *, int64_t, unsigned) hidden;
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "net/http/escape.h"
|
#include "net/http/escape.h"
|
||||||
|
@ -23,10 +24,10 @@
|
||||||
static const signed char kBase64[256] = {
|
static const signed char kBase64[256] = {
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 0x20
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, // 0x20
|
||||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, // 0x30
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, // 0x30
|
||||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 0x40
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 0x40
|
||||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 0x50
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, // 0x50
|
||||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 0x60
|
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 0x60
|
||||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 0x70
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 0x70
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x80
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x80
|
||||||
|
@ -42,6 +43,11 @@ static const signed char kBase64[256] = {
|
||||||
/**
|
/**
|
||||||
* Decodes base64 ascii representation to binary.
|
* Decodes base64 ascii representation to binary.
|
||||||
*
|
*
|
||||||
|
* This supports the following alphabets:
|
||||||
|
*
|
||||||
|
* - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
|
||||||
|
* - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
|
||||||
|
*
|
||||||
* @param data is input value
|
* @param data is input value
|
||||||
* @param size if -1 implies strlen
|
* @param size if -1 implies strlen
|
||||||
* @param out_size if non-NULL receives output length
|
* @param out_size if non-NULL receives output length
|
||||||
|
@ -53,7 +59,7 @@ char *DecodeBase64(const char *data, size_t size, size_t *out_size) {
|
||||||
int a, b, c, d, w;
|
int a, b, c, d, w;
|
||||||
const char *p, *pe;
|
const char *p, *pe;
|
||||||
if (size == -1) size = data ? strlen(data) : 0;
|
if (size == -1) size = data ? strlen(data) : 0;
|
||||||
if ((r = malloc(size / 4 * 3 + 1))) {
|
if ((r = malloc(ROUNDUP(size, 4) / 4 * 3 + 1))) {
|
||||||
q = r;
|
q = r;
|
||||||
p = data;
|
p = data;
|
||||||
pe = p + size;
|
pe = p + size;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
* @param n is byte length of s where -1 implies strlen
|
* @param n is byte length of s where -1 implies strlen
|
||||||
* @return true if substring present
|
* @return true if substring present
|
||||||
*/
|
*/
|
||||||
bool HeaderHas(struct HttpRequest *m, const char *b, int h, const char *s,
|
bool HeaderHas(struct HttpMessage *m, const char *b, int h, const char *s,
|
||||||
size_t n) {
|
size_t n) {
|
||||||
size_t i;
|
size_t i;
|
||||||
assert(0 <= h && h < kHttpHeadersMax);
|
assert(0 <= h && h < kHttpHeadersMax);
|
||||||
|
|
|
@ -99,27 +99,32 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
struct HttpRequestSlice {
|
struct HttpSlice {
|
||||||
short a, b;
|
short a, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HttpRequest {
|
struct HttpHeader {
|
||||||
int i, a;
|
struct HttpSlice k;
|
||||||
|
struct HttpSlice v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HttpHeaders {
|
||||||
|
unsigned n;
|
||||||
|
struct HttpHeader *p;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HttpMessage {
|
||||||
|
int i, a, status;
|
||||||
unsigned char t;
|
unsigned char t;
|
||||||
unsigned char method;
|
unsigned char method;
|
||||||
unsigned char version;
|
unsigned char version;
|
||||||
struct HttpRequestSlice k;
|
struct HttpSlice k;
|
||||||
struct HttpRequestSlice uri;
|
struct HttpSlice uri;
|
||||||
struct HttpRequestSlice scratch;
|
struct HttpSlice scratch;
|
||||||
struct HttpRequestSlice headers[kHttpHeadersMax];
|
struct HttpSlice message;
|
||||||
struct HttpRequestSlice xmethod;
|
struct HttpSlice headers[kHttpHeadersMax];
|
||||||
struct HttpRequestHeaders {
|
struct HttpSlice xmethod;
|
||||||
unsigned n;
|
struct HttpHeaders xheaders;
|
||||||
struct HttpRequestHeader {
|
|
||||||
struct HttpRequestSlice k;
|
|
||||||
struct HttpRequestSlice v;
|
|
||||||
} * p;
|
|
||||||
} xheaders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char kHttpToken[256];
|
extern const char kHttpToken[256];
|
||||||
|
@ -130,10 +135,13 @@ const char *GetHttpReason(int);
|
||||||
const char *GetHttpHeaderName(int);
|
const char *GetHttpHeaderName(int);
|
||||||
int GetHttpHeader(const char *, size_t);
|
int GetHttpHeader(const char *, size_t);
|
||||||
int GetHttpMethod(const char *, size_t);
|
int GetHttpMethod(const char *, size_t);
|
||||||
void InitHttpRequest(struct HttpRequest *);
|
void InitHttpRequest(struct HttpMessage *);
|
||||||
void DestroyHttpRequest(struct HttpRequest *);
|
void DestroyHttpRequest(struct HttpMessage *);
|
||||||
int ParseHttpRequest(struct HttpRequest *, const char *, size_t);
|
int ParseHttpRequest(struct HttpMessage *, const char *, size_t);
|
||||||
bool HeaderHas(struct HttpRequest *, const char *, int, const char *, size_t);
|
void InitHttpResponse(struct HttpMessage *);
|
||||||
|
void DestroyHttpResponse(struct HttpMessage *);
|
||||||
|
int ParseHttpResponse(struct HttpMessage *, const char *, size_t);
|
||||||
|
bool HeaderHas(struct HttpMessage *, const char *, int, const char *, size_t);
|
||||||
int64_t ParseContentLength(const char *, size_t);
|
int64_t ParseContentLength(const char *, size_t);
|
||||||
char *FormatHttpDateTime(char[hasatleast 30], struct tm *);
|
char *FormatHttpDateTime(char[hasatleast 30], struct tm *);
|
||||||
bool ParseHttpRange(const char *, size_t, long, long *, long *);
|
bool ParseHttpRange(const char *, size_t, long, long *, long *);
|
||||||
|
|
|
@ -35,14 +35,14 @@ enum { START, METHOD, URI, VERSION, HKEY, HSEP, HVAL, CR1, LF1, LF2 };
|
||||||
/**
|
/**
|
||||||
* Initializes HTTP request parser.
|
* Initializes HTTP request parser.
|
||||||
*/
|
*/
|
||||||
void InitHttpRequest(struct HttpRequest *r) {
|
void InitHttpRequest(struct HttpMessage *r) {
|
||||||
memset(r, 0, sizeof(*r));
|
memset(r, 0, sizeof(*r));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys HTTP request parser.
|
* Destroys HTTP request parser.
|
||||||
*/
|
*/
|
||||||
void DestroyHttpRequest(struct HttpRequest *r) {
|
void DestroyHttpRequest(struct HttpMessage *r) {
|
||||||
if (r->xheaders.p) {
|
if (r->xheaders.p) {
|
||||||
free(r->xheaders.p);
|
free(r->xheaders.p);
|
||||||
r->xheaders.p = NULL;
|
r->xheaders.p = NULL;
|
||||||
|
@ -83,9 +83,9 @@ void DestroyHttpRequest(struct HttpRequest *r) {
|
||||||
* @see HTTP/1.1 RFC2616 RFC2068
|
* @see HTTP/1.1 RFC2616 RFC2068
|
||||||
* @see HTTP/1.0 RFC1945
|
* @see HTTP/1.0 RFC1945
|
||||||
*/
|
*/
|
||||||
int ParseHttpRequest(struct HttpRequest *r, const char *p, size_t n) {
|
int ParseHttpRequest(struct HttpMessage *r, const char *p, size_t n) {
|
||||||
int c, h, i;
|
int c, h, i;
|
||||||
struct HttpRequestHeader *x;
|
struct HttpHeader *x;
|
||||||
for (n = MIN(n, LIMIT); r->i < n; ++r->i) {
|
for (n = MIN(n, LIMIT); r->i < n; ++r->i) {
|
||||||
c = p[r->i] & 0xff;
|
c = p[r->i] & 0xff;
|
||||||
switch (r->t) {
|
switch (r->t) {
|
||||||
|
|
187
net/http/parsehttpresponse.c
Normal file
187
net/http/parsehttpresponse.c
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/bits/bits.h"
|
||||||
|
#include "libc/limits.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/errfuns.h"
|
||||||
|
#include "net/http/http.h"
|
||||||
|
|
||||||
|
#define LIMIT (SHRT_MAX - 2)
|
||||||
|
|
||||||
|
enum { START, VERSION, STATUS, MESSAGE, HKEY, HSEP, HVAL, CR1, LF1, LF2 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes HTTP response parser.
|
||||||
|
*/
|
||||||
|
void InitHttpResponse(struct HttpMessage *r) {
|
||||||
|
memset(r, 0, sizeof(*r));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys HTTP response parser.
|
||||||
|
*/
|
||||||
|
void DestroyHttpResponse(struct HttpMessage *r) {
|
||||||
|
if (r->xheaders.p) {
|
||||||
|
free(r->xheaders.p);
|
||||||
|
r->xheaders.p = NULL;
|
||||||
|
r->xheaders.n = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses HTTP response.
|
||||||
|
*/
|
||||||
|
int ParseHttpResponse(struct HttpMessage *r, const char *p, size_t n) {
|
||||||
|
int c, h, i;
|
||||||
|
struct HttpHeader *x;
|
||||||
|
for (n = MIN(n, LIMIT); r->i < n; ++r->i) {
|
||||||
|
c = p[r->i] & 0xff;
|
||||||
|
switch (r->t) {
|
||||||
|
case START:
|
||||||
|
if (c == '\r' || c == '\n') break; /* RFC7230 § 3.5 */
|
||||||
|
if (c != 'H') return ebadmsg();
|
||||||
|
r->t = VERSION;
|
||||||
|
r->a = r->i;
|
||||||
|
break;
|
||||||
|
case VERSION:
|
||||||
|
if (c == ' ') {
|
||||||
|
if (r->i - r->a == 8 &&
|
||||||
|
(READ64BE(p + r->a) & 0xFFFFFFFFFF00FF00) == 0x485454502F002E00 &&
|
||||||
|
isdigit(p[r->a + 5]) && isdigit(p[r->a + 7])) {
|
||||||
|
r->version = (p[r->a + 5] - '0') * 10 + (p[r->a + 7] - '0');
|
||||||
|
r->t = STATUS;
|
||||||
|
} else {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATUS:
|
||||||
|
for (;;) {
|
||||||
|
if (c == ' ' || c == '\r' || c == '\n') {
|
||||||
|
if (r->status < 100) return ebadmsg();
|
||||||
|
if (c == ' ') {
|
||||||
|
r->a = r->i + 1;
|
||||||
|
r->t = MESSAGE;
|
||||||
|
} else {
|
||||||
|
r->t = c == '\r' ? CR1 : LF1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if ('0' <= c && c <= '9') {
|
||||||
|
r->status *= 10;
|
||||||
|
r->status += c - '0';
|
||||||
|
if (r->status > 999) return ebadmsg();
|
||||||
|
} else {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
if (++r->i == n) break;
|
||||||
|
c = p[r->i] & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MESSAGE:
|
||||||
|
for (;;) {
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
r->message.a = r->a;
|
||||||
|
r->message.b = r->i;
|
||||||
|
r->t = c == '\r' ? CR1 : LF1;
|
||||||
|
break;
|
||||||
|
} else if (c < 0x20 || (0x7F <= c && c < 0xA0)) {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
if (++r->i == n) break;
|
||||||
|
c = p[r->i] & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CR1:
|
||||||
|
if (c != '\n') return ebadmsg();
|
||||||
|
r->t = LF1;
|
||||||
|
break;
|
||||||
|
case LF1:
|
||||||
|
if (c == '\r') {
|
||||||
|
r->t = LF2;
|
||||||
|
break;
|
||||||
|
} else if (c == '\n') {
|
||||||
|
return ++r->i;
|
||||||
|
} else if (!kHttpToken[c]) {
|
||||||
|
return ebadmsg(); /* RFC7230 § 3.2.4 */
|
||||||
|
}
|
||||||
|
r->k.a = r->i;
|
||||||
|
r->t = HKEY;
|
||||||
|
break;
|
||||||
|
case HKEY:
|
||||||
|
for (;;) {
|
||||||
|
if (c == ':') {
|
||||||
|
r->k.b = r->i;
|
||||||
|
r->t = HSEP;
|
||||||
|
break;
|
||||||
|
} else if (!kHttpToken[c]) {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
if (++r->i == n) break;
|
||||||
|
c = p[r->i] & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HSEP:
|
||||||
|
if (c == ' ' || c == '\t') break;
|
||||||
|
r->a = r->i;
|
||||||
|
r->t = HVAL;
|
||||||
|
/* fallthrough */
|
||||||
|
case HVAL:
|
||||||
|
for (;;) {
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
i = r->i;
|
||||||
|
while (i > r->a && (p[i - 1] == ' ' || p[i - 1] == '\t')) --i;
|
||||||
|
if ((h = GetHttpHeader(p + r->k.a, r->k.b - r->k.a)) != -1 &&
|
||||||
|
(!r->headers[h].a || !kHttpRepeatable[h])) {
|
||||||
|
r->headers[h].a = r->a;
|
||||||
|
r->headers[h].b = i;
|
||||||
|
} else if ((x = realloc(
|
||||||
|
r->xheaders.p,
|
||||||
|
(r->xheaders.n + 1) * sizeof(*r->xheaders.p)))) {
|
||||||
|
x[r->xheaders.n].k = r->k;
|
||||||
|
x[r->xheaders.n].v.a = r->a;
|
||||||
|
x[r->xheaders.n].v.b = i;
|
||||||
|
r->xheaders.p = x;
|
||||||
|
++r->xheaders.n;
|
||||||
|
}
|
||||||
|
r->t = c == '\r' ? CR1 : LF1;
|
||||||
|
break;
|
||||||
|
} else if ((c < 0x20 && c != '\t') || (0x7F <= c && c < 0xA0)) {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
if (++r->i == n) break;
|
||||||
|
c = p[r->i] & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LF2:
|
||||||
|
if (c == '\n') {
|
||||||
|
return ++r->i;
|
||||||
|
}
|
||||||
|
return ebadmsg();
|
||||||
|
default:
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r->i < LIMIT) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return ebadmsg();
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,9 @@
|
||||||
char p[16];
|
char p[16];
|
||||||
struct TtyCursor c;
|
struct TtyCursor c;
|
||||||
|
|
||||||
void SetUp(void) { rngset(p, sizeof(p), rand64, -1); }
|
void SetUp(void) {
|
||||||
|
rngset(p, sizeof(p), rand64, -1);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ttymove, sameCoord_doesNothing) {
|
TEST(ttymove, sameCoord_doesNothing) {
|
||||||
c.y = 0;
|
c.y = 0;
|
||||||
|
@ -144,47 +146,3 @@ TEST(ttymove, left) {
|
||||||
c.y = 70, c.x = 70;
|
c.y = 70, c.x = 70;
|
||||||
MOVE("\e[2D", 70, 68);
|
MOVE("\e[2D", 70, 68);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEST(ttymove, bench_absmove) { */
|
|
||||||
/* EZBENCH( */
|
|
||||||
/* { */
|
|
||||||
/* c.y = 70; */
|
|
||||||
/* c.x = 30; */
|
|
||||||
/* }, */
|
|
||||||
/* ttymove(&c, p, 7, 9)); */
|
|
||||||
/* ASSERT_STREQ("\e[8;10H", p); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* TEST(ttymove, bench_crlf) { */
|
|
||||||
/* EZBENCH( */
|
|
||||||
/* { */
|
|
||||||
/* c.y = 0; */
|
|
||||||
/* c.x = 10; */
|
|
||||||
/* }, */
|
|
||||||
/* ttymove(&c, p, 1, 0)); */
|
|
||||||
/* ASSERT_STREQ("\r\n", p); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* TEST(ttymove, bench_forward1) { */
|
|
||||||
/* EZBENCH( */
|
|
||||||
/* { */
|
|
||||||
/* c.y = 0; */
|
|
||||||
/* c.x = 10; */
|
|
||||||
/* }, */
|
|
||||||
/* ttymove(&c, p, 0, 11)); */
|
|
||||||
/* ASSERT_STREQ("\e[C", p); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* TEST(ttymove, bench_forward2) { */
|
|
||||||
/* int y2, x2; */
|
|
||||||
/* EZBENCH( */
|
|
||||||
/* { */
|
|
||||||
/* y2 = rand32() & 127; */
|
|
||||||
/* x2 = rand32() & 127; */
|
|
||||||
/* c.y = rand32() & 127; */
|
|
||||||
/* c.x = rand32() & 127; */
|
|
||||||
/* }, */
|
|
||||||
/* ttymove(&c, p, y2, x2)); */
|
|
||||||
/* int z; */
|
|
||||||
/* EZBENCH(z = rand32() & 127, _memcpy(&z, "\e[2C", 4)); */
|
|
||||||
/* } */
|
|
||||||
|
|
|
@ -1,335 +0,0 @@
|
||||||
/*-*- 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 │
|
|
||||||
│ │
|
|
||||||
│ 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/crypto/rijndael.h"
|
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/fmt/bing.internal.h"
|
|
||||||
#include "libc/runtime/internal.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/sysv/consts/prot.h"
|
|
||||||
#include "libc/testlib/testlib.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test vectors published by:
|
|
||||||
*
|
|
||||||
* Morris Dworkin
|
|
||||||
* National Institute of Standards and Technology
|
|
||||||
* Recommendation for Block Cipher Modes of Operation: Methods and Techniques
|
|
||||||
* SP 800-38A (DOI)
|
|
||||||
* December 2001
|
|
||||||
*/
|
|
||||||
|
|
||||||
FIXTURE(rijndael, disableHardwareExtensions) {
|
|
||||||
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.1: ECB-AES128.Encrypt
|
|
||||||
*
|
|
||||||
* Key 2b7e151628aed2a6abf7158809cf4f3c
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Plaintext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Input Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Output Block 3ad77bb40d7a3660a89ecaf32466ef97
|
|
||||||
* Ciphertext 3ad77bb40d7a3660a89ecaf32466ef97
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Output Block f5d3d58503b9699de785895a96fdbaaf
|
|
||||||
* Ciphertext f5d3d58503b9699de785895a96fdbaaf
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Output Block 43b1cd7f598ece23881b00e3ed030688
|
|
||||||
* Ciphertext 43b1cd7f598ece23881b00e3ed030688
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Plaintext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Input Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Output Block 7b0c785e27e8ad3f8223207104725dd4
|
|
||||||
* Ciphertext 7b0c785e27e8ad3f8223207104725dd4
|
|
||||||
*/
|
|
||||||
TEST(aes128, testNistEcbRijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, block;
|
|
||||||
unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c");
|
|
||||||
rijndaelinit(&ctx, 10, k1, k1);
|
|
||||||
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
|
|
||||||
block = rijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("3ad77bb40d7a3660a89ecaf32466ef97", &block);
|
|
||||||
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
|
|
||||||
block = rijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("f5d3d58503b9699de785895a96fdbaaf", &block);
|
|
||||||
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
|
|
||||||
block = rijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("43b1cd7f598ece23881b00e3ed030688", &block);
|
|
||||||
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
|
|
||||||
block = rijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("7b0c785e27e8ad3f8223207104725dd4", &block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.2: ECB-AES128.Decrypt
|
|
||||||
*
|
|
||||||
* Key 2b7e151628aed2a6abf7158809cf4f3c
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Plaintext 3ad77bb40d7a3660a89ecaf32466ef97
|
|
||||||
* Input Block 3ad77bb40d7a3660a89ecaf32466ef97
|
|
||||||
* Output Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Plaintext f5d3d58503b9699de785895a96fdbaaf
|
|
||||||
* Input Block f5d3d58503b9699de785895a96fdbaaf
|
|
||||||
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Plaintext 43b1cd7f598ece23881b00e3ed030688
|
|
||||||
* Input Block 43b1cd7f598ece23881b00e3ed030688
|
|
||||||
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Plaintext 7b0c785e27e8ad3f8223207104725dd4
|
|
||||||
* Input Block 7b0c785e27e8ad3f8223207104725dd4
|
|
||||||
* Output Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
*/
|
|
||||||
TEST(aes128, testNistEcbUnrijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, block;
|
|
||||||
unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c");
|
|
||||||
unrijndaelinit(&ctx, 10, k1, k1);
|
|
||||||
unhexbuf(&block, 16, "3ad77bb40d7a3660a89ecaf32466ef97");
|
|
||||||
block = unrijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
|
|
||||||
unhexbuf(&block, 16, "f5d3d58503b9699de785895a96fdbaaf");
|
|
||||||
block = unrijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
|
|
||||||
unhexbuf(&block, 16, "43b1cd7f598ece23881b00e3ed030688");
|
|
||||||
block = unrijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
|
|
||||||
unhexbuf(&block, 16, "7b0c785e27e8ad3f8223207104725dd4");
|
|
||||||
block = unrijndael(10, block, &ctx);
|
|
||||||
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.3: ECB-AES192.Encrypt
|
|
||||||
*
|
|
||||||
* Key 8e73b0f7da0e6452c810f32b809079e5
|
|
||||||
* 62f8ead2522c6b7b
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Plaintext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Input Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Output Block bd334f1d6e45f25ff712a214571fa5cc
|
|
||||||
* Ciphertext bd334f1d6e45f25ff712a214571fa5cc
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Output Block 974104846d0ad3ad7734ecb3ecee4eef
|
|
||||||
* Ciphertext 974104846d0ad3ad7734ecb3ecee4eef
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Output Block ef7afd2270e2e60adce0ba2face6444e
|
|
||||||
* Ciphertext ef7afd2270e2e60adce0ba2face6444e
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Plaintext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Input Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Output Block 9a4b41ba738d6c72fb16691603c18e0e
|
|
||||||
* Ciphertext 9a4b41ba738d6c72fb16691603c18e0e
|
|
||||||
*/
|
|
||||||
TEST(aes192, testNistEcbRijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, k2, block;
|
|
||||||
unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5");
|
|
||||||
unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE");
|
|
||||||
rijndaelinit(&ctx, 12, k1, k2);
|
|
||||||
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
|
|
||||||
block = rijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("bd334f1d6e45f25ff712a214571fa5cc", &block);
|
|
||||||
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
|
|
||||||
block = rijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("974104846d0ad3ad7734ecb3ecee4eef", &block);
|
|
||||||
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
|
|
||||||
block = rijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("ef7afd2270e2e60adce0ba2face6444e", &block);
|
|
||||||
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
|
|
||||||
block = rijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("9a4b41ba738d6c72fb16691603c18e0e", &block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.4: ECB-AES192.Decrypt
|
|
||||||
*
|
|
||||||
* Key 8e73b0f7da0e6452c810f32b809079e5
|
|
||||||
* 62f8ead2522c6b7b
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Plaintext bd334f1d6e45f25ff712a214571fa5cc
|
|
||||||
* Input Block bd334f1d6e45f25ff712a214571fa5cc
|
|
||||||
* Output Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Plaintext 974104846d0ad3ad7734ecb3ecee4eef
|
|
||||||
* Input Block 974104846d0ad3ad7734ecb3ecee4eef
|
|
||||||
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Plaintext ef7afd2270e2e60adce0ba2face6444e
|
|
||||||
* Input Block ef7afd2270e2e60adce0ba2face6444e
|
|
||||||
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Plaintext 9a4b41ba738d6c72fb16691603c18e0e
|
|
||||||
* Input Block 9a4b41ba738d6c72fb16691603c18e0e
|
|
||||||
* Output Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
*/
|
|
||||||
TEST(aes192, testNistEcbUnrijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, k2, block;
|
|
||||||
unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5");
|
|
||||||
unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE");
|
|
||||||
unrijndaelinit(&ctx, 12, k1, k2);
|
|
||||||
unhexbuf(&block, 16, "bd334f1d6e45f25ff712a214571fa5cc");
|
|
||||||
block = unrijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
|
|
||||||
unhexbuf(&block, 16, "974104846d0ad3ad7734ecb3ecee4eef");
|
|
||||||
block = unrijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
|
|
||||||
unhexbuf(&block, 16, "ef7afd2270e2e60adce0ba2face6444e");
|
|
||||||
block = unrijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
|
|
||||||
unhexbuf(&block, 16, "9a4b41ba738d6c72fb16691603c18e0e");
|
|
||||||
block = unrijndael(12, block, &ctx);
|
|
||||||
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.5: ECB-AES256.Encrypt
|
|
||||||
*
|
|
||||||
* Key 603deb1015ca71be2b73aef0857d7781
|
|
||||||
* 1f352c073b6108d72d9810a30914dff4
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Plaintext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Input Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Output Block f3eed1bdb5d2a03c064b5a7e3db181f8
|
|
||||||
* Ciphertext f3eed1bdb5d2a03c064b5a7e3db181f8
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Output Block 591ccb10d410ed26dc5ba74a31362870
|
|
||||||
* Ciphertext 591ccb10d410ed26dc5ba74a31362870
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Output Block b6ed21b99ca6f4f9f153e7b1beafed1d
|
|
||||||
* Ciphertext b6ed21b99ca6f4f9f153e7b1beafed1d
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Plaintext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Input Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Output Block 23304b7a39f9f3ff067d8d8f9e24ecc7
|
|
||||||
* Ciphertext 23304b7a39f9f3ff067d8d8f9e24ecc7
|
|
||||||
*/
|
|
||||||
TEST(aes256, testNistEcbRijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, k2, block;
|
|
||||||
unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781");
|
|
||||||
unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4");
|
|
||||||
rijndaelinit(&ctx, 14, k1, k2);
|
|
||||||
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
|
|
||||||
block = rijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("f3eed1bdb5d2a03c064b5a7e3db181f8", &block);
|
|
||||||
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
|
|
||||||
block = rijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("591ccb10d410ed26dc5ba74a31362870", &block);
|
|
||||||
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
|
|
||||||
block = rijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("b6ed21b99ca6f4f9f153e7b1beafed1d", &block);
|
|
||||||
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
|
|
||||||
block = rijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("23304b7a39f9f3ff067d8d8f9e24ecc7", &block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* F.1.6: ECB-AES256.Decrypt
|
|
||||||
*
|
|
||||||
* Key 603deb1015ca71be2b73aef0857d7781
|
|
||||||
* 1f352c073b6108d72d9810a30914dff4
|
|
||||||
*
|
|
||||||
* Block No. 1
|
|
||||||
* Input Block f3eed1bdb5d2a03c064b5a7e3db181f8
|
|
||||||
* Plaintext f3eed1bdb5d2a03c064b5a7e3db181f8
|
|
||||||
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
* Output Block 6bc1bee22e409f96e93d7e117393172a
|
|
||||||
*
|
|
||||||
* Block No. 2
|
|
||||||
* Input Block 591ccb10d410ed26dc5ba74a31362870
|
|
||||||
* Plaintext 591ccb10d410ed26dc5ba74a31362870
|
|
||||||
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
|
|
||||||
*
|
|
||||||
* Block No. 3
|
|
||||||
* Input Block b6ed21b99ca6f4f9f153e7b1beafed1d
|
|
||||||
* Plaintext b6ed21b99ca6f4f9f153e7b1beafed1d
|
|
||||||
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
|
|
||||||
*
|
|
||||||
* Block No. 4
|
|
||||||
* Input Block 23304b7a39f9f3ff067d8d8f9e24ecc7
|
|
||||||
* Plaintext 23304b7a39f9f3ff067d8d8f9e24ecc7
|
|
||||||
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
* Output Block f69f2445df4f9b17ad2b417be66c3710
|
|
||||||
*/
|
|
||||||
TEST(aes256, testNistEcbUnrijndael) {
|
|
||||||
struct Rijndael ctx;
|
|
||||||
aes_block_t k1, k2, block;
|
|
||||||
unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781");
|
|
||||||
unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4");
|
|
||||||
unrijndaelinit(&ctx, 14, k1, k2);
|
|
||||||
unhexbuf(&block, 16, "f3eed1bdb5d2a03c064b5a7e3db181f8");
|
|
||||||
block = unrijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
|
|
||||||
unhexbuf(&block, 16, "591ccb10d410ed26dc5ba74a31362870");
|
|
||||||
block = unrijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
|
|
||||||
unhexbuf(&block, 16, "b6ed21b99ca6f4f9f153e7b1beafed1d");
|
|
||||||
block = unrijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
|
|
||||||
unhexbuf(&block, 16, "23304b7a39f9f3ff067d8d8f9e24ecc7");
|
|
||||||
block = unrijndael(14, block, &ctx);
|
|
||||||
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
|
||||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
|
||||||
|
|
||||||
PKGS += TEST_LIBC_CRYPTO
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_SRCS := $(wildcard test/libc/crypto/*.c)
|
|
||||||
TEST_LIBC_CRYPTO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CRYPTO_SRCS))
|
|
||||||
TEST_LIBC_CRYPTO_COMS = $(TEST_LIBC_CRYPTO_OBJS:%.o=%.com)
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_OBJS = \
|
|
||||||
$(TEST_LIBC_CRYPTO_SRCS:%.c=o/$(MODE)/%.o)
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_BINS = \
|
|
||||||
$(TEST_LIBC_CRYPTO_COMS) \
|
|
||||||
$(TEST_LIBC_CRYPTO_COMS:%=%.dbg)
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_TESTS = \
|
|
||||||
$(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_CHECKS = \
|
|
||||||
$(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_DIRECTDEPS = \
|
|
||||||
LIBC_CRYPTO \
|
|
||||||
LIBC_FMT \
|
|
||||||
LIBC_INTRIN \
|
|
||||||
LIBC_NEXGEN32E \
|
|
||||||
LIBC_RUNTIME \
|
|
||||||
LIBC_STR \
|
|
||||||
LIBC_STUBS \
|
|
||||||
LIBC_TESTLIB
|
|
||||||
|
|
||||||
TEST_LIBC_CRYPTO_DEPS := \
|
|
||||||
$(call uniq,$(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x))))
|
|
||||||
|
|
||||||
o/$(MODE)/test/libc/crypto/crypto.pkg: \
|
|
||||||
$(TEST_LIBC_CRYPTO_OBJS) \
|
|
||||||
$(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x)_A).pkg)
|
|
||||||
|
|
||||||
o/$(MODE)/test/libc/crypto/%.com.dbg: \
|
|
||||||
$(TEST_LIBC_CRYPTO_DEPS) \
|
|
||||||
o/$(MODE)/test/libc/crypto/%.o \
|
|
||||||
o/$(MODE)/test/libc/crypto/crypto.pkg \
|
|
||||||
$(LIBC_TESTMAIN) \
|
|
||||||
$(CRT) \
|
|
||||||
$(APE)
|
|
||||||
@$(APELINK)
|
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/test/libc/crypto
|
|
||||||
o/$(MODE)/test/libc/crypto: \
|
|
||||||
$(TEST_LIBC_CRYPTO_BINS) \
|
|
||||||
$(TEST_LIBC_CRYPTO_CHECKS)
|
|
|
@ -48,20 +48,19 @@ TEST(ParseHostsTxt, testCorrectlyTokenizesAndSorts) {
|
||||||
ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f));
|
ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f));
|
||||||
rewind(f);
|
rewind(f);
|
||||||
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
SortHostsTxt(ht);
|
|
||||||
ASSERT_EQ(4, ht->entries.i);
|
ASSERT_EQ(4, ht->entries.i);
|
||||||
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].name]);
|
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[0].name]);
|
||||||
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].canon]);
|
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[0].canon]);
|
||||||
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[0].ip));
|
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[0].ip));
|
||||||
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].name]);
|
EXPECT_STREQ("lol", &ht->strings.p[ht->entries.p[1].name]);
|
||||||
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].canon]);
|
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].canon]);
|
||||||
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[1].ip));
|
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[1].ip));
|
||||||
EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[2].name]);
|
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[2].name]);
|
||||||
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[2].canon]);
|
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[2].canon]);
|
||||||
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[2].ip));
|
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[2].ip));
|
||||||
EXPECT_STREQ("lol", &ht->strings.p[ht->entries.p[3].name]);
|
EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[3].name]);
|
||||||
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[3].canon]);
|
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[3].canon]);
|
||||||
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[3].ip));
|
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[3].ip));
|
||||||
FreeHostsTxt(&ht);
|
FreeHostsTxt(&ht);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
77
test/libc/dns/resolvehostsreverse_test.c
Normal file
77
test/libc/dns/resolvehostsreverse_test.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/dns/hoststxt.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
TEST(ParseHostsTxt, testNotFound) {
|
||||||
|
const char kInput[] = "# this is a comment\n"
|
||||||
|
"# IP HOST1 HOST2\n"
|
||||||
|
"203.0.113.1 lol.example lol\n"
|
||||||
|
"203.0.113.2 cat.example cat\n";
|
||||||
|
char name[256];
|
||||||
|
uint8_t ip[4] = {127, 0, 113, 1};
|
||||||
|
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
||||||
|
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
|
||||||
|
ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f));
|
||||||
|
rewind(f);
|
||||||
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
|
ASSERT_EQ(4, ht->entries.i);
|
||||||
|
ASSERT_EQ(0, ResolveHostsReverse(ht, AF_INET, ip, name, sizeof(name)));
|
||||||
|
FreeHostsTxt(&ht);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHostsTxt, testFirstLookup) {
|
||||||
|
const char kInput[] = "# this is a comment\n"
|
||||||
|
"# IP HOST1 HOST2\n"
|
||||||
|
"203.0.113.1 lol.example lol\n"
|
||||||
|
"203.0.113.2 cat.example cat\n";
|
||||||
|
char name[256];
|
||||||
|
uint8_t ip[4] = {203, 0, 113, 1};
|
||||||
|
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
||||||
|
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
|
||||||
|
ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f));
|
||||||
|
rewind(f);
|
||||||
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
|
ASSERT_EQ(4, ht->entries.i);
|
||||||
|
ASSERT_EQ(1, ResolveHostsReverse(ht, AF_INET, ip, name, sizeof(name)));
|
||||||
|
EXPECT_STREQ("lol.example", name);
|
||||||
|
FreeHostsTxt(&ht);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHostsTxt, testSecondLookup) {
|
||||||
|
const char kInput[] = "# this is a comment\n"
|
||||||
|
"# IP HOST1 HOST2\n"
|
||||||
|
"203.0.113.1 lol.example lol\n"
|
||||||
|
"203.0.113.2 cat.example cat\n";
|
||||||
|
char name[256];
|
||||||
|
uint8_t ip[4] = {203, 0, 113, 2};
|
||||||
|
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
||||||
|
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
|
||||||
|
ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f));
|
||||||
|
rewind(f);
|
||||||
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
|
ASSERT_EQ(4, ht->entries.i);
|
||||||
|
ASSERT_EQ(1, ResolveHostsReverse(ht, AF_INET, ip, name, sizeof(name)));
|
||||||
|
EXPECT_STREQ("cat.example", name);
|
||||||
|
FreeHostsTxt(&ht);
|
||||||
|
fclose(f);
|
||||||
|
}
|
|
@ -49,7 +49,6 @@ TEST(ResolveHostsTxt, testBasicLookups) {
|
||||||
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
||||||
FILE *f = fmemopen(kInput, strlen(kInput), "r+");
|
FILE *f = fmemopen(kInput, strlen(kInput), "r+");
|
||||||
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
SortHostsTxt(ht);
|
|
||||||
ASSERT_EQ(5, ht->entries.i);
|
ASSERT_EQ(5, ht->entries.i);
|
||||||
EXPECT_STREQ("127.0.0.1", EzIp4Lookup(ht, "localhost"));
|
EXPECT_STREQ("127.0.0.1", EzIp4Lookup(ht, "localhost"));
|
||||||
EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol"));
|
EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol"));
|
||||||
|
@ -66,7 +65,6 @@ TEST(ResolveHostsTxt, testCanonicalize) {
|
||||||
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
|
||||||
FILE *f = fmemopen(kInput, strlen(kInput), "r+");
|
FILE *f = fmemopen(kInput, strlen(kInput), "r+");
|
||||||
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
ASSERT_EQ(0, ParseHostsTxt(ht, f));
|
||||||
SortHostsTxt(ht);
|
|
||||||
ASSERT_EQ(5, ht->entries.i);
|
ASSERT_EQ(5, ht->entries.i);
|
||||||
EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost"));
|
EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost"));
|
||||||
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol"));
|
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol"));
|
||||||
|
|
|
@ -22,18 +22,12 @@
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(devrand, test) {
|
TEST(getrandom, test) {
|
||||||
if (IsWindows()) return;
|
void *A = gc(calloc(1, 8));
|
||||||
const size_t kSize = 8;
|
void *B = gc(calloc(1, 8));
|
||||||
void *A = malloc(kSize);
|
EXPECT_EQ(8, getrandom(A, 8, 0));
|
||||||
void *B = malloc(kSize);
|
EXPECT_EQ(8, getrandom(B, 8, 0));
|
||||||
memset(A, 0, kSize);
|
|
||||||
memset(B, 0, kSize);
|
|
||||||
EXPECT_EQ(0, devrand(A, kSize));
|
|
||||||
EXPECT_EQ(0, devrand(B, kSize));
|
|
||||||
EXPECT_BINNE(u" ", A);
|
EXPECT_BINNE(u" ", A);
|
||||||
EXPECT_BINNE(u" ", B);
|
EXPECT_BINNE(u" ", B);
|
||||||
EXPECT_NE(0, memcmp(A, B, kSize));
|
EXPECT_NE(0, memcmp(A, B, 8));
|
||||||
free(B);
|
|
||||||
free(A);
|
|
||||||
}
|
}
|
||||||
|
|
237
test/libc/rand/getrandom_test.c
Normal file
237
test/libc/rand/getrandom_test.c
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/log/check.h"
|
||||||
|
#include "libc/math.h"
|
||||||
|
#include "libc/rand/lcg.internal.h"
|
||||||
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/sysv/consts/grnd.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
/* JustReturnZero */
|
||||||
|
/* entropy: 0 */
|
||||||
|
/* chi-square: 2.55e+07 */
|
||||||
|
/* chi-square percent: 0 */
|
||||||
|
/* mean: 0 */
|
||||||
|
/* monte-carlo-pi: 27.324 */
|
||||||
|
/* serial-correlation: -100000 */
|
||||||
|
|
||||||
|
/* JustIncrement */
|
||||||
|
/* entropy: 2.63951 */
|
||||||
|
/* chi-square: 1.443e+07 */
|
||||||
|
/* chi-square percent: 0 */
|
||||||
|
/* mean: 18.8803 */
|
||||||
|
/* monte-carlo-pi: 27.324 */
|
||||||
|
/* serial-correlation: 0.0092003 */
|
||||||
|
|
||||||
|
/* UNIX Sixth Edition */
|
||||||
|
/* entropy: 8 */
|
||||||
|
/* chi-square: 0.1536 */
|
||||||
|
/* chi-square percent: 1 */
|
||||||
|
/* mean: 127.502 */
|
||||||
|
/* monte-carlo-pi: 3.4192 */
|
||||||
|
/* serial-correlation: -0.470645 */
|
||||||
|
|
||||||
|
/* UNIX Seventh Edition */
|
||||||
|
/* entropy: 7.99818 */
|
||||||
|
/* chi-square: 251.843 */
|
||||||
|
/* chi-square percent: 0.544128 */
|
||||||
|
/* mean: 127.955 */
|
||||||
|
/* monte-carlo-pi: 0.675703 */
|
||||||
|
/* serial-correlation: -0.00207669 */
|
||||||
|
|
||||||
|
/* KnuthLcg */
|
||||||
|
/* entropy: 7.99835 */
|
||||||
|
/* chi-square: 228.383 */
|
||||||
|
/* chi-square percent: 0.883476 */
|
||||||
|
/* mean: 127.1 */
|
||||||
|
/* monte-carlo-pi: 0.561935 */
|
||||||
|
/* serial-correlation: -0.0038954 */
|
||||||
|
|
||||||
|
/* rand64 */
|
||||||
|
/* entropy: 7.99832 */
|
||||||
|
/* chi-square: 233.267 */
|
||||||
|
/* chi-square percent: 0.831821 */
|
||||||
|
/* mean: 127.427 */
|
||||||
|
/* monte-carlo-pi: 0.0271532 */
|
||||||
|
/* serial-correlation: -0.00255319 */
|
||||||
|
|
||||||
|
/* Rand64LowByte */
|
||||||
|
/* entropy: 7.99798 */
|
||||||
|
/* chi-square: 278.344 */
|
||||||
|
/* chi-square percent: 0.150796 */
|
||||||
|
/* mean: 127.88 */
|
||||||
|
/* monte-carlo-pi: 0.00340573 */
|
||||||
|
/* serial-correlation: 0.00162231 */
|
||||||
|
|
||||||
|
/* GetRandomNoSystem */
|
||||||
|
/* entropy: 7.99819 */
|
||||||
|
/* chi-square: 249.743 */
|
||||||
|
/* chi-square percent: 0.58114 */
|
||||||
|
/* mean: 127.124 */
|
||||||
|
/* monte-carlo-pi: 0.293716 */
|
||||||
|
/* serial-correlation: 0.00198516 */
|
||||||
|
|
||||||
|
/* GetRandomNoRdrrnd */
|
||||||
|
/* entropy: 7.99816 */
|
||||||
|
/* chi-square: 254.797 */
|
||||||
|
/* chi-square percent: 0.491811 */
|
||||||
|
/* mean: 127.308 */
|
||||||
|
/* monte-carlo-pi: 0.0118738 */
|
||||||
|
/* serial-correlation: 0.000197669 */
|
||||||
|
|
||||||
|
/* GetRandom */
|
||||||
|
/* entropy: 7.99808 */
|
||||||
|
/* chi-square: 266.737 */
|
||||||
|
/* chi-square percent: 0.294131 */
|
||||||
|
/* mean: 127.178 */
|
||||||
|
/* monte-carlo-pi: 0.0577122 */
|
||||||
|
/* serial-correlation: 0.00598793 */
|
||||||
|
|
||||||
|
typedef uint64_t (*random_f)(void);
|
||||||
|
|
||||||
|
static uint32_t randx = 1;
|
||||||
|
|
||||||
|
uint64_t JustReturnZero(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t JustIncrement(void) {
|
||||||
|
static uint64_t x;
|
||||||
|
return x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SixthEditionRand(void) {
|
||||||
|
static int16_t gorp;
|
||||||
|
gorp = (gorp + 625) & 077777;
|
||||||
|
return gorp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SixthEditionLowByte(void) {
|
||||||
|
unsigned i;
|
||||||
|
uint64_t x;
|
||||||
|
for (x = i = 0; i < 8; ++i) {
|
||||||
|
x <<= 8;
|
||||||
|
x |= SixthEditionRand() & 255;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SeventhEditionRand(void) {
|
||||||
|
return ((randx = randx * 1103515245 + 12345) >> 16) & 077777;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SeventhEditionLowByte(void) {
|
||||||
|
unsigned i;
|
||||||
|
uint64_t x;
|
||||||
|
for (x = i = 0; i < 8; ++i) {
|
||||||
|
x <<= 8;
|
||||||
|
x |= SeventhEditionRand() & 255;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t KnuthLcg(void) {
|
||||||
|
unsigned i;
|
||||||
|
uint64_t x;
|
||||||
|
for (x = i = 0; i < 8; ++i) {
|
||||||
|
x <<= 8;
|
||||||
|
x |= rand() & 255;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Rand64LowByte(void) {
|
||||||
|
unsigned i;
|
||||||
|
uint64_t x;
|
||||||
|
for (x = i = 0; i < 8; ++i) {
|
||||||
|
x <<= 8;
|
||||||
|
x |= rand64() & 255;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetRandomNoRdrrnd(void) {
|
||||||
|
uint64_t x;
|
||||||
|
ASSERT_EQ(8, getrandom(&x, 8, GRND_NORDRND));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetRandomNoSystem(void) {
|
||||||
|
uint64_t x;
|
||||||
|
ASSERT_EQ(8, getrandom(&x, 8, GRND_NOSYSTEM));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetRandom(void) {
|
||||||
|
uint64_t x;
|
||||||
|
ASSERT_EQ(8, getrandom(&x, 8, 0));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct RandomFunction {
|
||||||
|
const char *s;
|
||||||
|
random_f f;
|
||||||
|
bool r;
|
||||||
|
} kRandomFunctions[] = {
|
||||||
|
{"JustReturnZero", JustReturnZero, false}, //
|
||||||
|
{"JustIncrement", JustIncrement, false}, //
|
||||||
|
{"SixthEditionLowByte", SixthEditionLowByte, false}, //
|
||||||
|
{"SeventhEditionLowByte", SeventhEditionLowByte, false}, //
|
||||||
|
{"KnuthLcg", KnuthLcg, false}, //
|
||||||
|
{"rand64", rand64, true}, //
|
||||||
|
{"Rand64LowByte", Rand64LowByte, true}, //
|
||||||
|
{"GetRandomNoRdrrnd", GetRandomNoRdrrnd, true}, //
|
||||||
|
{"GetRandomNoSystem", GetRandomNoSystem, true}, //
|
||||||
|
{"GetRandom", GetRandom, true}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(getrandom, sanityTest) {
|
||||||
|
uint64_t q;
|
||||||
|
size_t i, j, k;
|
||||||
|
double montepi, chip, scc, ent, mean, chisq;
|
||||||
|
for (k = 0; k < 1; ++k) {
|
||||||
|
for (j = 0; j < ARRAYLEN(kRandomFunctions); ++j) {
|
||||||
|
rt_init(0);
|
||||||
|
for (i = 0; i + 8 <= 100000; i += 8) {
|
||||||
|
q = kRandomFunctions[j].f();
|
||||||
|
rt_add(&q, 8);
|
||||||
|
}
|
||||||
|
rt_end(&ent, &chisq, &mean, &montepi, &scc);
|
||||||
|
chip = pochisq(chisq, 255);
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "/* %-32s */\n", kRandomFunctions[j].s);
|
||||||
|
fprintf(stderr, "/* entropy: %-12g */\n", ent);
|
||||||
|
fprintf(stderr, "/* chi-square: %-12g */\n", chisq);
|
||||||
|
fprintf(stderr, "/* chi-square percent: %-12g */\n", chip);
|
||||||
|
fprintf(stderr, "/* mean: %-12g */\n", mean);
|
||||||
|
fprintf(stderr, "/* monte-carlo-pi: %-12g */\n",
|
||||||
|
100 * fabs(M_PI - montepi) / M_PI);
|
||||||
|
fprintf(stderr, "/* serial-correlation: %-12g */\n", scc);
|
||||||
|
#endif
|
||||||
|
if (kRandomFunctions[j].r) {
|
||||||
|
CHECK_GE(chisq, 180, "%s", kRandomFunctions[j].s);
|
||||||
|
CHECK_GE(ent * 10, 78, "%s", kRandomFunctions[j].s);
|
||||||
|
CHECK_LT(fabs(scc) * 100, 5, "%s", kRandomFunctions[j].s);
|
||||||
|
CHECK_LT(fabs(128 - mean), 3, "%s", kRandomFunctions[j].s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,9 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(rand002, alwaysReturnsPositiveNumbers) {
|
TEST(rand002, alwaysReturnsPositiveNumbers) {
|
||||||
|
@ -34,11 +36,18 @@ TEST(rand003, srandSmokeTest) {
|
||||||
ASSERT_EQ(1059165278, rand());
|
ASSERT_EQ(1059165278, rand());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(rand004, rand32SmokeTest) {
|
|
||||||
ASSERT_TRUE(rand32() != rand32() || rand32() != rand32() ||
|
|
||||||
rand32() != rand32() || rand32() != rand32());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(rand005, rand64SmokeTest) {
|
TEST(rand005, rand64SmokeTest) {
|
||||||
ASSERT_TRUE(rand64() != rand64() || rand64() != rand64());
|
ASSERT_TRUE(rand64() != rand64() || rand64() != rand64());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(rand64, test) {
|
||||||
|
char *p;
|
||||||
|
size_t i;
|
||||||
|
uint64_t x;
|
||||||
|
p = memcpy(malloc(kHyperionSize), kHyperion, kHyperionSize);
|
||||||
|
for (i = 0; i < kHyperionSize / 8; ++i) {
|
||||||
|
x = rand64();
|
||||||
|
WRITE64LE(p + i * 8, x);
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
|
@ -21,15 +21,20 @@ TEST_LIBC_RAND_CHECKS = \
|
||||||
TEST_LIBC_RAND_DIRECTDEPS = \
|
TEST_LIBC_RAND_DIRECTDEPS = \
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
|
LIBC_TINYMATH \
|
||||||
LIBC_MEM \
|
LIBC_MEM \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_RAND \
|
LIBC_RAND \
|
||||||
LIBC_RUNTIME \
|
LIBC_RUNTIME \
|
||||||
|
LIBC_STDIO \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
|
LIBC_LOG \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
LIBC_TESTLIB \
|
LIBC_TESTLIB \
|
||||||
LIBC_X
|
LIBC_UNICODE \
|
||||||
|
LIBC_X \
|
||||||
|
THIRD_PARTY_GDTOA
|
||||||
|
|
||||||
TEST_LIBC_RAND_DEPS := \
|
TEST_LIBC_RAND_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x))))
|
||||||
|
|
|
@ -54,3 +54,47 @@ TEST(inet_ntop, testNoSpace) {
|
||||||
ASSERT_STREQ("", buf);
|
ASSERT_STREQ("", buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_testMin_isJustColons) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
EXPECT_STREQ("::", inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_testMax) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
|
EXPECT_STREQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
|
||||||
|
inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_loopback_isColonsThenJustOne) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
EXPECT_STREQ("::1", inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_rfc4291example) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0x20, 0x01, 0x0D, 0xB8, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x08, 0x00, 0x20, 0x0C, 0x41, 0x7A};
|
||||||
|
EXPECT_STREQ("2001:db8::8:800:200c:417a",
|
||||||
|
inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_leading) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
EXPECT_STREQ("1::", inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(inet_ntop, ipv6_kindOfLeading) {
|
||||||
|
char buf[72];
|
||||||
|
uint8_t ip[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
EXPECT_STREQ("100::", inet_ntop(AF_INET6, ip, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,15 @@ TEST(inet_pton, testLocalhost) {
|
||||||
EXPECT_EQ(1, addr[3]);
|
EXPECT_EQ(1, addr[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(inet_pton, testAny) {
|
||||||
|
uint8_t addr[4] = {255, 255, 255, 255};
|
||||||
|
EXPECT_EQ(1, inet_pton(AF_INET, "0.0.0.0", &addr));
|
||||||
|
EXPECT_EQ(0, addr[0]);
|
||||||
|
EXPECT_EQ(0, addr[1]);
|
||||||
|
EXPECT_EQ(0, addr[2]);
|
||||||
|
EXPECT_EQ(0, addr[3]);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(inet_pton, testShortAddress_doesntFillFullValue) {
|
TEST(inet_pton, testShortAddress_doesntFillFullValue) {
|
||||||
uint8_t addr[4] = {255, 255, 255, 255};
|
uint8_t addr[4] = {255, 255, 255, 255};
|
||||||
EXPECT_EQ(0, inet_pton(AF_INET, "127.0.0", &addr));
|
EXPECT_EQ(0, inet_pton(AF_INET, "127.0.0", &addr));
|
||||||
|
|
|
@ -25,17 +25,18 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
|
STATIC_YOINK("zip_uri_support");
|
||||||
|
|
||||||
TEST(dirstream, test) {
|
TEST(dirstream, test) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
char *dpath, *file1, *file2;
|
char *dpath, *file1, *file2;
|
||||||
dpath = gc(xasprintf("%s%s%lu", kTmpPath, "dirstream", rand32()));
|
dpath = gc(xasprintf("%s%s%lu", kTmpPath, "dirstream", rand64()));
|
||||||
file1 = gc(xasprintf("%s/%s", dpath, "foo"));
|
file1 = gc(xasprintf("%s/%s", dpath, "foo"));
|
||||||
file2 = gc(xasprintf("%s/%s", dpath, "bar"));
|
file2 = gc(xasprintf("%s/%s", dpath, "bar"));
|
||||||
EXPECT_NE(-1, mkdir(dpath, 0755));
|
EXPECT_NE(-1, mkdir(dpath, 0755));
|
||||||
EXPECT_NE(-1, touch(file1, 0644));
|
EXPECT_NE(-1, touch(file1, 0644));
|
||||||
EXPECT_NE(-1, touch(file2, 0644));
|
EXPECT_NE(-1, touch(file2, 0644));
|
||||||
|
|
||||||
EXPECT_TRUE(NULL != (dir = opendir(dpath)));
|
EXPECT_TRUE(NULL != (dir = opendir(dpath)));
|
||||||
bool hasfoo = false;
|
bool hasfoo = false;
|
||||||
bool hasbar = false;
|
bool hasbar = false;
|
||||||
|
@ -46,8 +47,21 @@ TEST(dirstream, test) {
|
||||||
EXPECT_TRUE(hasfoo);
|
EXPECT_TRUE(hasfoo);
|
||||||
EXPECT_TRUE(hasbar);
|
EXPECT_TRUE(hasbar);
|
||||||
EXPECT_NE(-1, closedir(dir));
|
EXPECT_NE(-1, closedir(dir));
|
||||||
|
|
||||||
EXPECT_NE(-1, unlink(file2));
|
EXPECT_NE(-1, unlink(file2));
|
||||||
EXPECT_NE(-1, unlink(file1));
|
EXPECT_NE(-1, unlink(file1));
|
||||||
EXPECT_NE(-1, rmdir(dpath));
|
EXPECT_NE(-1, rmdir(dpath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(dirstream, zipTest) {
|
||||||
|
bool foundNewYork = false;
|
||||||
|
DIR *d;
|
||||||
|
struct dirent *e;
|
||||||
|
const char *path = "zip:usr/share/zoneinfo/";
|
||||||
|
ASSERT_NE(0, _gc(xiso8601ts(NULL)));
|
||||||
|
ASSERT_NE(NULL, (d = opendir(path)));
|
||||||
|
while ((e = readdir(d))) {
|
||||||
|
foundNewYork |= !strcmp(e->d_name, "New_York");
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
EXPECT_TRUE(foundNewYork);
|
||||||
|
}
|
||||||
|
|
|
@ -36,8 +36,10 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
LIBC_TESTLIB \
|
LIBC_TESTLIB \
|
||||||
|
LIBC_TIME \
|
||||||
LIBC_UNICODE \
|
LIBC_UNICODE \
|
||||||
LIBC_X
|
LIBC_X \
|
||||||
|
LIBC_ZIPOS
|
||||||
|
|
||||||
TEST_LIBC_STDIO_DEPS := \
|
TEST_LIBC_STDIO_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(TEST_LIBC_STDIO_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(TEST_LIBC_STDIO_DIRECTDEPS),$($(x))))
|
||||||
|
|
|
@ -40,6 +40,7 @@ TEST_LIBC_STR_DIRECTDEPS = \
|
||||||
LIBC_UNICODE \
|
LIBC_UNICODE \
|
||||||
LIBC_X \
|
LIBC_X \
|
||||||
LIBC_ZIPOS \
|
LIBC_ZIPOS \
|
||||||
|
THIRD_PARTY_MBEDTLS \
|
||||||
THIRD_PARTY_REGEX \
|
THIRD_PARTY_REGEX \
|
||||||
THIRD_PARTY_ZLIB
|
THIRD_PARTY_ZLIB
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ o/$(MODE)/test/libc: \
|
||||||
o/$(MODE)/test/libc/alg \
|
o/$(MODE)/test/libc/alg \
|
||||||
o/$(MODE)/test/libc/bits \
|
o/$(MODE)/test/libc/bits \
|
||||||
o/$(MODE)/test/libc/calls \
|
o/$(MODE)/test/libc/calls \
|
||||||
o/$(MODE)/test/libc/crypto \
|
|
||||||
o/$(MODE)/test/libc/dns \
|
o/$(MODE)/test/libc/dns \
|
||||||
o/$(MODE)/test/libc/fmt \
|
o/$(MODE)/test/libc/fmt \
|
||||||
o/$(MODE)/test/libc/intrin \
|
o/$(MODE)/test/libc/intrin \
|
||||||
|
|
109
test/net/http/decodebase64_test.c
Normal file
109
test/net/http/decodebase64_test.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/testlib/testlib.h"
|
||||||
|
#include "net/http/escape.h"
|
||||||
|
|
||||||
|
size_t i, n, m;
|
||||||
|
char *p, *q, b[32];
|
||||||
|
|
||||||
|
TEST(DecodeBase64, paddingIsOptional) {
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("", 0, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AA", 2, 0)));
|
||||||
|
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("BB", 2, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAA", 3, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAAA", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"λ ", gc(DecodeBase64("/w", 2, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλ ", gc(DecodeBase64("//8", 3, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλλ ", gc(DecodeBase64("////", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8", 7, 0)));
|
||||||
|
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8", -1, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeBase64, altUrlFormat) {
|
||||||
|
EXPECT_BINEQ(u"λ ", gc(DecodeBase64("_w", 2, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλ ", gc(DecodeBase64("__8", 3, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλλ ", gc(DecodeBase64("____", 4, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeBase64, test) {
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("", 0, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AA==", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("BB==", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAA=", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAAA", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"λ ", gc(DecodeBase64("/w==", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλ ", gc(DecodeBase64("//8=", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"λλλ ", gc(DecodeBase64("////", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8=", 8, 0)));
|
||||||
|
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8=", -1, 0)));
|
||||||
|
EXPECT_EQ(
|
||||||
|
0,
|
||||||
|
memcmp(
|
||||||
|
"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020"
|
||||||
|
"\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041"
|
||||||
|
"\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062"
|
||||||
|
"\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103"
|
||||||
|
"\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124"
|
||||||
|
"\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145"
|
||||||
|
"\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166"
|
||||||
|
"\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207"
|
||||||
|
"\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230"
|
||||||
|
"\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251"
|
||||||
|
"\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272"
|
||||||
|
"\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313"
|
||||||
|
"\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334"
|
||||||
|
"\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355"
|
||||||
|
"\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376"
|
||||||
|
"\377",
|
||||||
|
gc(DecodeBase64(
|
||||||
|
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUm\r\n"
|
||||||
|
"JygpKissLS4vMDEy\r\n"
|
||||||
|
"MzQ1Njc4OTo7PD0+\r\n"
|
||||||
|
"P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2Rl\r\n"
|
||||||
|
"ZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+\r\n"
|
||||||
|
"AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeY\r\n"
|
||||||
|
"mZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/\r\n"
|
||||||
|
"wMHCw8TFxsfIycrL\r\n"
|
||||||
|
"zM3Oz9DR0tPU1dbX2Nna29zd3t/\r\n"
|
||||||
|
"g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+\r\n"
|
||||||
|
"/w==\r\n",
|
||||||
|
-1, &n)),
|
||||||
|
256));
|
||||||
|
EXPECT_EQ(256, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeBase64, testSeparators_skipsOverThemAtAnyState) {
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64(" ", 1, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64(" A A = = ", 9, 0)));
|
||||||
|
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64(" B B = = ", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("a\nG\nV\ns\nb\nG\n8\n=\n", 16, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeBase64, testInvalidSequences_skipsOverThem) {
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("A===", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u" ", gc(DecodeBase64("B===", 4, 0)));
|
||||||
|
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("B===BB==", 8, 0)));
|
||||||
|
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("====BB==", 8, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeBase64, testOom_returnsNullAndSetsSizeToZero) {
|
||||||
|
n = 31337;
|
||||||
|
EXPECT_EQ(NULL, DecodeBase64("hello", 0x1000000000000, &n));
|
||||||
|
EXPECT_EQ(0, n);
|
||||||
|
}
|
|
@ -24,6 +24,7 @@
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "net/http/escape.h"
|
#include "net/http/escape.h"
|
||||||
|
#include "third_party/mbedtls/base64.h"
|
||||||
|
|
||||||
size_t i, n, m;
|
size_t i, n, m;
|
||||||
char *p, *q, b[32];
|
char *p, *q, b[32];
|
||||||
|
@ -65,73 +66,6 @@ TEST(EncodeBase64, test) {
|
||||||
EXPECT_EQ(344, n);
|
EXPECT_EQ(344, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DecodeBase64, test) {
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("", 0, 0)));
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("AA==", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("BB==", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAA=", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("AAAA", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"λ ", gc(DecodeBase64("/w==", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"λλ ", gc(DecodeBase64("//8=", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"λλλ ", gc(DecodeBase64("////", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8=", 8, 0)));
|
|
||||||
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("aGVsbG8=", -1, 0)));
|
|
||||||
EXPECT_EQ(
|
|
||||||
0,
|
|
||||||
memcmp(
|
|
||||||
"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020"
|
|
||||||
"\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041"
|
|
||||||
"\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062"
|
|
||||||
"\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103"
|
|
||||||
"\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124"
|
|
||||||
"\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145"
|
|
||||||
"\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166"
|
|
||||||
"\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207"
|
|
||||||
"\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230"
|
|
||||||
"\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251"
|
|
||||||
"\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272"
|
|
||||||
"\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313"
|
|
||||||
"\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334"
|
|
||||||
"\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355"
|
|
||||||
"\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376"
|
|
||||||
"\377",
|
|
||||||
gc(DecodeBase64(
|
|
||||||
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUm\r\n"
|
|
||||||
"JygpKissLS4vMDEy\r\n"
|
|
||||||
"MzQ1Njc4OTo7PD0+\r\n"
|
|
||||||
"P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2Rl\r\n"
|
|
||||||
"ZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+\r\n"
|
|
||||||
"AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeY\r\n"
|
|
||||||
"mZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/\r\n"
|
|
||||||
"wMHCw8TFxsfIycrL\r\n"
|
|
||||||
"zM3Oz9DR0tPU1dbX2Nna29zd3t/\r\n"
|
|
||||||
"g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+\r\n"
|
|
||||||
"/w==\r\n",
|
|
||||||
-1, &n)),
|
|
||||||
256));
|
|
||||||
EXPECT_EQ(256, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DecodeBase64, testSeparators_skipsOverThemAtAnyState) {
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64(" ", 1, 0)));
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64(" A A = = ", 9, 0)));
|
|
||||||
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64(" B B = = ", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"hello ", gc(DecodeBase64("a\nG\nV\ns\nb\nG\n8\n=\n", 16, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DecodeBase64, testInvalidSequences_skipsOverThem) {
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("A===", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u" ", gc(DecodeBase64("B===", 4, 0)));
|
|
||||||
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("B===BB==", 8, 0)));
|
|
||||||
EXPECT_BINEQ(u"♦ ", gc(DecodeBase64("====BB==", 8, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DecodeBase64, testOom_returnsNullAndSetsSizeToZero) {
|
|
||||||
n = 31337;
|
|
||||||
EXPECT_EQ(NULL, DecodeBase64("hello", 0x1000000000000, &n));
|
|
||||||
EXPECT_EQ(0, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(EncodeBase64, testOom_returnsNullAndSetsSizeToZero) {
|
TEST(EncodeBase64, testOom_returnsNullAndSetsSizeToZero) {
|
||||||
n = 31337;
|
n = 31337;
|
||||||
EXPECT_EQ(NULL, EncodeBase64("hello", 0x1000000000000, &n));
|
EXPECT_EQ(NULL, EncodeBase64("hello", 0x1000000000000, &n));
|
||||||
|
@ -165,3 +99,16 @@ BENCH(EncodeBase64, bench) {
|
||||||
p = gc(EncodeBase64(kHyperion, kHyperionSize, &n));
|
p = gc(EncodeBase64(kHyperion, kHyperionSize, &n));
|
||||||
EZBENCH2("DecodeBase64", donothing, free(DecodeBase64(p, n, 0)));
|
EZBENCH2("DecodeBase64", donothing, free(DecodeBase64(p, n, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BENCH(MbedtlsEncodeBase64, bench) {
|
||||||
|
size_t olen;
|
||||||
|
size_t dlen = kHyperionSize * 4;
|
||||||
|
uint8_t *dst = gc(malloc(dlen));
|
||||||
|
uint8_t *res = gc(malloc(dlen));
|
||||||
|
EZBENCH2("mbedtls_base64_encode", donothing,
|
||||||
|
mbedtls_base64_encode(dst, dlen, &olen, (void *)kHyperion,
|
||||||
|
kHyperionSize));
|
||||||
|
EZBENCH2("mbedtls_base64_decode", donothing,
|
||||||
|
mbedtls_base64_decode(res, dlen, &olen, dst, olen));
|
||||||
|
ASSERT_EQ(0, memcmp(res, kHyperion, olen));
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ TEST(IsReasonablePath, test) {
|
||||||
EXPECT_TRUE(IsReasonablePath("/index.html", 11));
|
EXPECT_TRUE(IsReasonablePath("/index.html", 11));
|
||||||
EXPECT_TRUE(IsReasonablePath("/index.html", -1));
|
EXPECT_TRUE(IsReasonablePath("/index.html", -1));
|
||||||
EXPECT_TRUE(IsReasonablePath("/redbean.png", -1));
|
EXPECT_TRUE(IsReasonablePath("/redbean.png", -1));
|
||||||
|
EXPECT_TRUE(IsReasonablePath("/.ca.key", -1));
|
||||||
|
EXPECT_TRUE(IsReasonablePath(".ca.key", -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(IsReasonablePath, testEmptyString_allowedIfYouLikeImplicitLeadingSlash) {
|
TEST(IsReasonablePath, testEmptyString_allowedIfYouLikeImplicitLeadingSlash) {
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
#include "net/http/http.h"
|
#include "net/http/http.h"
|
||||||
|
|
||||||
struct HttpRequest req[1];
|
struct HttpMessage req[1];
|
||||||
|
|
||||||
static char *slice(const char *m, struct HttpRequestSlice s) {
|
static char *slice(const char *m, struct HttpSlice s) {
|
||||||
char *p;
|
char *p;
|
||||||
p = xmalloc(s.b - s.a + 1);
|
p = xmalloc(s.b - s.a + 1);
|
||||||
memcpy(p, m + s.a, s.b - s.a);
|
memcpy(p, m + s.a, s.b - s.a);
|
||||||
|
@ -47,7 +47,7 @@ void TearDown(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseHttpRequest, soLittleState) {
|
TEST(ParseHttpRequest, soLittleState) {
|
||||||
ASSERT_LE(sizeof(struct HttpRequest), 512);
|
ASSERT_LE(sizeof(struct HttpMessage), 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseHttpRequest, testEmpty_tooShort) {
|
TEST(ParseHttpRequest, testEmpty_tooShort) {
|
||||||
|
|
175
test/net/http/parsehttpresponse_test.c
Normal file
175
test/net/http/parsehttpresponse_test.c
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/*-*- 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 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 │
|
||||||
|
│ 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/log/check.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/testlib/ezbench.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
#include "net/http/http.h"
|
||||||
|
|
||||||
|
struct HttpMessage req[1];
|
||||||
|
|
||||||
|
static char *slice(const char *m, struct HttpSlice s) {
|
||||||
|
char *p;
|
||||||
|
p = xmalloc(s.b - s.a + 1);
|
||||||
|
memcpy(p, m + s.a, s.b - s.a);
|
||||||
|
p[s.b - s.a] = 0;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUp(void) {
|
||||||
|
InitHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(void) {
|
||||||
|
DestroyHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, soLittleState) {
|
||||||
|
ASSERT_LE(sizeof(struct HttpMessage), 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testEmpty_tooShort) {
|
||||||
|
EXPECT_EQ(0, ParseHttpResponse(req, "", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testTooShort) {
|
||||||
|
EXPECT_EQ(0, ParseHttpResponse(req, "\r\n", 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testNoHeaders) {
|
||||||
|
static const char m[] = "HTTP/1.0 200 OK\r\n\r\n";
|
||||||
|
EXPECT_EQ(strlen(m), ParseHttpResponse(req, m, strlen(m)));
|
||||||
|
EXPECT_EQ(200, req->status);
|
||||||
|
EXPECT_STREQ("OK", gc(slice(m, req->message)));
|
||||||
|
EXPECT_EQ(10, req->version);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testSomeHeaders) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.0 200 OK\r\n\
|
||||||
|
Host: foo.example\r\n\
|
||||||
|
Content-Length: 0\r\n\
|
||||||
|
\r\n";
|
||||||
|
EXPECT_EQ(strlen(m), ParseHttpResponse(req, m, strlen(m)));
|
||||||
|
EXPECT_EQ(200, req->status);
|
||||||
|
EXPECT_STREQ("OK", gc(slice(m, req->message)));
|
||||||
|
EXPECT_EQ(10, req->version);
|
||||||
|
EXPECT_STREQ("foo.example", gc(slice(m, req->headers[kHttpHost])));
|
||||||
|
EXPECT_STREQ("0", gc(slice(m, req->headers[kHttpContentLength])));
|
||||||
|
EXPECT_STREQ("", gc(slice(m, req->headers[kHttpEtag])));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testHttp101) {
|
||||||
|
static const char m[] = "HTTP/1.1 300 OMG\r\n\r\n";
|
||||||
|
EXPECT_EQ(strlen(m), ParseHttpResponse(req, m, strlen(m)));
|
||||||
|
EXPECT_EQ(300, req->status);
|
||||||
|
EXPECT_STREQ("OMG", gc(slice(m, req->message)));
|
||||||
|
EXPECT_EQ(11, req->version);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParseHttpResponse, testHttp100) {
|
||||||
|
static const char m[] = "HTTP/1.0 404 Not Found\r\n\r\n";
|
||||||
|
EXPECT_EQ(strlen(m), ParseHttpResponse(req, m, strlen(m)));
|
||||||
|
EXPECT_EQ(404, req->status);
|
||||||
|
EXPECT_STREQ("Not Found", gc(slice(m, req->message)));
|
||||||
|
EXPECT_EQ(10, req->version);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoTiniestHttpResponse(void) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.0 200\r\n\
|
||||||
|
\r\n";
|
||||||
|
InitHttpResponse(req);
|
||||||
|
ParseHttpResponse(req, m, sizeof(m));
|
||||||
|
DestroyHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoTinyHttpResponse(void) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.0 200\r\n\
|
||||||
|
Accept-Encoding: gzip\r\n\
|
||||||
|
\r\n";
|
||||||
|
InitHttpResponse(req);
|
||||||
|
ParseHttpResponse(req, m, sizeof(m));
|
||||||
|
DestroyHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoStandardChromeResponse(void) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.1 200 OK\r\n\
|
||||||
|
Host: 10.10.10.124:8080\r\n\
|
||||||
|
Connection: keep-alive\r\n\
|
||||||
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36\r\n\
|
||||||
|
DNT: \t1 \r\n\
|
||||||
|
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8\r\n\
|
||||||
|
Referer: http://10.10.10.124:8080/\r\n\
|
||||||
|
Accept-Encoding: gzip, deflate\r\n\
|
||||||
|
Accept-Language: en-US,en;q=0.9\r\n\
|
||||||
|
\r\n";
|
||||||
|
InitHttpResponse(req);
|
||||||
|
CHECK_EQ(sizeof(m) - 1, ParseHttpResponse(req, m, sizeof(m)));
|
||||||
|
DestroyHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoUnstandardChromeResponse(void) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.1 200 OK\r\n\
|
||||||
|
X-Host: 10.10.10.124:8080\r\n\
|
||||||
|
X-Connection: keep-alive\r\n\
|
||||||
|
X-User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36\r\n\
|
||||||
|
X-DNT: \t1 \r\n\
|
||||||
|
X-Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8\r\n\
|
||||||
|
X-Referer: http://10.10.10.124:8080/\r\n\
|
||||||
|
X-Accept-Encoding: gzip, deflate\r\n\
|
||||||
|
X-Accept-Language: en-US,en;q=0.9\r\n\
|
||||||
|
\r\n";
|
||||||
|
InitHttpResponse(req);
|
||||||
|
CHECK_EQ(sizeof(m) - 1, ParseHttpResponse(req, m, sizeof(m)));
|
||||||
|
DestroyHttpResponse(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCH(ParseHttpResponse, bench) {
|
||||||
|
EZBENCH2("DoTiniestHttpResponse", donothing, DoTiniestHttpResponse());
|
||||||
|
EZBENCH2("DoTinyHttpResponse", donothing, DoTinyHttpResponse());
|
||||||
|
EZBENCH2("DoStandardChromeResponse", donothing, DoStandardChromeResponse());
|
||||||
|
EZBENCH2("DoUnstandardChromeResponse", donothing,
|
||||||
|
DoUnstandardChromeResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCH(HeaderHas, bench) {
|
||||||
|
static const char m[] = "\
|
||||||
|
HTTP/1.1 200 OK\r\n\
|
||||||
|
X-In-Your-Way-A: a\r\n\
|
||||||
|
X-In-Your-Way-B: b\r\n\
|
||||||
|
X-In-Your-Way-C: b\r\n\
|
||||||
|
Accept-Encoding: deflate\r\n\
|
||||||
|
ACCEPT-ENCODING: gzip\r\n\
|
||||||
|
ACCEPT-encoding: bzip2\r\n\
|
||||||
|
\r\n";
|
||||||
|
EXPECT_EQ(strlen(m), ParseHttpResponse(req, m, strlen(m)));
|
||||||
|
EZBENCH2("HeaderHas text/plain", donothing,
|
||||||
|
HeaderHas(req, m, kHttpAccept, "text/plain", 7));
|
||||||
|
EZBENCH2("HeaderHas deflate", donothing,
|
||||||
|
HeaderHas(req, m, kHttpAcceptEncoding, "deflate", 7));
|
||||||
|
EZBENCH2("HeaderHas gzip", donothing,
|
||||||
|
HeaderHas(req, m, kHttpAcceptEncoding, "gzip", 4));
|
||||||
|
EZBENCH2("IsMimeType", donothing,
|
||||||
|
IsMimeType("text/plain; charset=utf-8", -1, "text/plain"));
|
||||||
|
}
|
|
@ -362,6 +362,16 @@ TEST(ParseUrl, testObviouslyIllegalIpLiteral_getsTreatedAsRegName) {
|
||||||
ASSERT_STREQ("//vf.%3A%3A1%00", gc(EncodeUrl(&h, 0)));
|
ASSERT_STREQ("//vf.%3A%3A1%00", gc(EncodeUrl(&h, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ParseHost, testEmpty) {
|
||||||
|
struct Url h = {0};
|
||||||
|
gc(ParseHost("", -1, &h));
|
||||||
|
gc(h.params.p);
|
||||||
|
ASSERT_EQ(0, h.host.n);
|
||||||
|
ASSERT_EQ(0, h.port.n);
|
||||||
|
ASSERT_NE(0, h.host.p);
|
||||||
|
ASSERT_EQ(0, h.port.p);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ParseHost, test) {
|
TEST(ParseHost, test) {
|
||||||
struct Url h = {0};
|
struct Url h = {0};
|
||||||
gc(ParseHost("foo.example:80", -1, &h));
|
gc(ParseHost("foo.example:80", -1, &h));
|
||||||
|
|
|
@ -21,7 +21,8 @@ TEST_NET_HTTP_CHECKS = \
|
||||||
|
|
||||||
TEST_NET_HTTP_DIRECTDEPS = \
|
TEST_NET_HTTP_DIRECTDEPS = \
|
||||||
NET_HTTP \
|
NET_HTTP \
|
||||||
LIBC_TESTLIB
|
LIBC_TESTLIB \
|
||||||
|
THIRD_PARTY_MBEDTLS
|
||||||
|
|
||||||
TEST_NET_HTTP_DEPS := \
|
TEST_NET_HTTP_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(TEST_NET_HTTP_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(TEST_NET_HTTP_DIRECTDEPS),$($(x))))
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue