mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
cc1920749e
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
208 lines
7 KiB
C
208 lines
7 KiB
C
#ifndef COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
|
#define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
|
#include "libc/bits/bits.h"
|
|
#include "libc/calls/internal.h"
|
|
#include "libc/nt/thunk/msabi.h"
|
|
#include "libc/nt/winsock.h"
|
|
#include "libc/sock/select.h"
|
|
#include "libc/sock/sock.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define FD_READ (1 << FD_READ_BIT)
|
|
#define FD_READ_BIT 0
|
|
#define FD_WRITE (1 << FD_WRITE_BIT)
|
|
#define FD_WRITE_BIT 1
|
|
#define FD_OOB (1 << FD_OOB_BIT)
|
|
#define FD_OOB_BIT 2
|
|
#define FD_ACCEPT (1 << FD_ACCEPT_BIT)
|
|
#define FD_ACCEPT_BIT 3
|
|
#define FD_CONNECT (1 << FD_CONNECT_BIT)
|
|
#define FD_CONNECT_BIT 4
|
|
#define FD_CLOSE (1 << FD_CLOSE_BIT)
|
|
#define FD_CLOSE_BIT 5
|
|
|
|
struct sockaddr_bsd {
|
|
uint8_t sa_len; /* « different type */
|
|
uint8_t sa_family; /* « different type */
|
|
char sa_data[14];
|
|
};
|
|
|
|
struct sockaddr_in_bsd {
|
|
uint8_t sin_len; /* « different type */
|
|
uint8_t sin_family; /* « different type */
|
|
uint16_t sin_port;
|
|
struct in_addr sin_addr;
|
|
uint8_t sin_zero[8];
|
|
};
|
|
|
|
struct msghdr_bsd {
|
|
void *msg_name;
|
|
uint32_t msg_namelen;
|
|
struct iovec *msg_iov;
|
|
uint32_t msg_iovlen; /* « different type */
|
|
void *msg_control;
|
|
uint64_t msg_controllen;
|
|
uint32_t msg_flags; /* « different type */
|
|
};
|
|
|
|
struct sockaddr_un_bsd {
|
|
uint8_t sun_len; /* sockaddr len including NUL on freebsd but excluding it on
|
|
openbsd/xnu */
|
|
uint8_t sun_family;
|
|
char sun_path[108];
|
|
};
|
|
|
|
/* -----------------------------------------------------------------------------------
|
|
* ioctl SIOCGIFCONF & others:
|
|
*
|
|
* BSD has a different structure. All the ioctl will adjust to use
|
|
* the ifreq with the ifreq_bsd
|
|
*/
|
|
struct ifreq_bsd {
|
|
union {
|
|
char ifrn_name[IFNAMSIZ];
|
|
} ifr_ifrn;
|
|
|
|
union {
|
|
/* Right now we only list the structures used by the few ioctl that are
|
|
* supported by Cosmopolitan. Add your own definition here if you need
|
|
* a particular ioctl that requires polyfill for BSD
|
|
*/
|
|
struct sockaddr_bsd ifru_addr;
|
|
struct sockaddr_bsd ifru_netmask;
|
|
struct sockaddr_bsd ifru_dstaddr;
|
|
struct sockaddr_bsd ifru_broadaddr;
|
|
short ifru_flags;
|
|
char ifru_pad[16]; /* used as padding */
|
|
} ifr_ifru;
|
|
};
|
|
|
|
#pragma pack(4)
|
|
struct ifconf_bsd {
|
|
uint32_t ifc_len; /* size of buffer */
|
|
union {
|
|
char *ifcu_buf;
|
|
struct ifreq_bsd *ifcu_req;
|
|
} ifc_ifcu;
|
|
};
|
|
#pragma pack()
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
|
|
|
|
struct SockFd {
|
|
int family;
|
|
int type;
|
|
int protocol;
|
|
int64_t event;
|
|
bool32 (*AcceptEx)(int64_t sListenSocket, int64_t sAcceptSocket,
|
|
void *out_lpOutputBuffer /*[recvlen+local+remoteaddrlen]*/,
|
|
uint32_t dwReceiveDataLength,
|
|
uint32_t dwLocalAddressLength,
|
|
uint32_t dwRemoteAddressLength,
|
|
uint32_t *out_lpdwBytesReceived,
|
|
struct NtOverlapped *inout_lpOverlapped) __msabi;
|
|
};
|
|
|
|
hidden extern int64_t __iocp;
|
|
|
|
errno_t __dos2errno(uint32_t);
|
|
|
|
int32_t __sys_accept(int32_t, void *, uint32_t *, int) nodiscard hidden;
|
|
int32_t __sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden;
|
|
int32_t __sys_connect(int32_t, const void *, uint32_t) hidden;
|
|
int32_t __sys_socket(int32_t, int32_t, int32_t) hidden;
|
|
int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
|
int32_t __sys_getpeername(int32_t, void *, uint32_t *) hidden;
|
|
int32_t __sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
|
|
|
|
int32_t sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden;
|
|
int32_t sys_accept(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_bind(int32_t, const void *, uint32_t) hidden;
|
|
int32_t sys_connect(int32_t, const void *, uint32_t) hidden;
|
|
int32_t sys_getsockopt(int32_t, int32_t, int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_listen(int32_t, int32_t) hidden;
|
|
int32_t sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_getpeername(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_poll(struct pollfd *, uint64_t, signed) hidden;
|
|
int32_t sys_shutdown(int32_t, int32_t) hidden;
|
|
int32_t sys_socket(int32_t, int32_t, int32_t) hidden;
|
|
int32_t sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
|
|
int64_t sys_readv(int32_t, const struct iovec *, int32_t) hidden;
|
|
int64_t sys_writev(int32_t, const struct iovec *, int32_t) hidden;
|
|
ssize_t sys_recvfrom(int, void *, size_t, int, void *, uint32_t *) hidden;
|
|
ssize_t sys_sendto(int, const void *, size_t, int, const void *,
|
|
uint32_t) hidden;
|
|
ssize_t sys_sendmsg(int, const struct msghdr *, int) hidden;
|
|
ssize_t sys_recvmsg(int, struct msghdr *, int) hidden;
|
|
int32_t sys_select(int32_t, fd_set *, fd_set *, fd_set *,
|
|
struct timeval *) hidden;
|
|
int sys_setsockopt(int, int, int, const void *, uint32_t) hidden;
|
|
int32_t sys_epoll_create(int32_t) hidden;
|
|
int32_t sys_epoll_ctl(int32_t, int32_t, int32_t, void *) hidden;
|
|
int32_t sys_epoll_wait(int32_t, void *, int32_t, int32_t) hidden;
|
|
|
|
int sys_poll_nt(struct pollfd *, uint64_t, uint64_t) hidden;
|
|
int sys_getsockopt_nt(struct Fd *, int, int, void *, uint32_t *) hidden;
|
|
int sys_getsockname_nt(struct Fd *, void *, uint32_t *) hidden;
|
|
int sys_getpeername_nt(struct Fd *, void *, uint32_t *) hidden;
|
|
int sys_listen_nt(struct Fd *, int) hidden;
|
|
int sys_connect_nt(struct Fd *, const void *, uint32_t) hidden;
|
|
int sys_bind_nt(struct Fd *, const void *, uint32_t);
|
|
int sys_accept_nt(struct Fd *, void *, uint32_t *, int) hidden;
|
|
int sys_closesocket_nt(struct Fd *) hidden;
|
|
int sys_socket_nt(int, int, int) hidden;
|
|
/*
|
|
int sys_socketpair_nt_stream(int, int, int, int[2]) hidden;
|
|
int sys_socketpair_nt_dgram(int, int, int, int[2]) hidden;
|
|
*/
|
|
int sys_socketpair_nt(int, int, int, int[2]) hidden;
|
|
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *) hidden;
|
|
int sys_shutdown_nt(struct Fd *, int) hidden;
|
|
int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden;
|
|
|
|
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
|
size_t) hidden;
|
|
ssize_t sys_sendto_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
|
void *, uint32_t) hidden;
|
|
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
|
void *, uint32_t *) hidden;
|
|
|
|
void WinSockInit(void) hidden;
|
|
int64_t __winsockerr(void) nocallback hidden;
|
|
int __fixupnewsockfd(int, int) hidden;
|
|
int64_t __winsockblock(int64_t, unsigned, int64_t) hidden;
|
|
|
|
int sys_close_epoll(int) hidden;
|
|
|
|
/**
|
|
* Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
|
|
*/
|
|
forceinline void sockaddr2bsd(void *saddr) {
|
|
char *p;
|
|
uint16_t fam;
|
|
if (saddr) {
|
|
p = saddr;
|
|
fam = READ16LE(p);
|
|
p[0] = sizeof(struct sockaddr_in_bsd);
|
|
p[1] = fam;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Converts sockaddr_in_bsd (XNU/BSD) → sockaddr (Linux/Windows).
|
|
*/
|
|
forceinline void sockaddr2linux(void *saddr) {
|
|
char *p, fam;
|
|
if (saddr) {
|
|
p = saddr;
|
|
fam = p[1];
|
|
WRITE16LE(p, fam);
|
|
}
|
|
}
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ */
|