Polyfill IPv6 on non-Linux

This commit is contained in:
Justine Tunney 2022-09-08 06:06:22 -07:00
parent b73e35c6fa
commit 0547eabcd6
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
10 changed files with 185 additions and 78 deletions

View file

@ -18,7 +18,6 @@
#define in_addr_t uint32_t
#define in_addr_t uint32_t
#define in_port_t uint16_t
#define in_port_t uint16_t
#define ino_t uint64_t
#define key_t int32_t
#define loff_t int64_t

View file

@ -38,6 +38,12 @@ OpenBSD Sorting (BSD-3)\\n\
Copyright 1993 The Regents of the University of California\"");
asm(".include \"libc/disclaimer.inc\"");
#define SWAPTYPE_BYTEV 1
#define SWAPTYPE_INTV 2
#define SWAPTYPE_LONGV 3
#define SWAPTYPE_INT 4
#define SWAPTYPE_LONG 5
#define CMPPAR int (*cmp)(const void *, const void *, void *),void *arg
#define CMPARG cmp, arg
#define CMP(a, b) cmp(a, b, arg)
@ -46,30 +52,6 @@ asm(".include \"libc/disclaimer.inc\"");
static inline char *med3(char *, char *, char *, CMPPAR);
static inline void swapfunc(char *, char *, size_t, int);
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*
* This version differs from Bentley & McIlroy in the following ways:
* 1. The partition value is swapped into a[0] instead of being
* stored out of line.
*
* 2. The swap function can swap 32-bit aligned elements on 64-bit
* platforms instead of swapping them as byte-aligned.
*
* 3. It uses David Musser's introsort algorithm to fall back to
* heapsort(3) when the recursion depth reaches 2*lg(n + 1).
* This avoids quicksort's quadratic behavior for pathological
* input without appreciably changing the average run time.
*
* 4. Tail recursion is eliminated when sorting the larger of two
* subpartitions to save stack space.
*/
#define SWAPTYPE_BYTEV 1
#define SWAPTYPE_INTV 2
#define SWAPTYPE_LONGV 3
#define SWAPTYPE_INT 4
#define SWAPTYPE_LONG 5
#define TYPE_ALIGNED(TYPE, a, es) \
(((char *)a - (char *)0) % sizeof(TYPE) == 0 && es % sizeof(TYPE) == 0)

View file

@ -18,6 +18,7 @@
*/
#include "libc/sock/internal.h"
#include "libc/sock/struct/sockaddr.internal.h"
#include "libc/sock/struct/sockaddr6-bsd.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/errfuns.h"
@ -41,6 +42,21 @@ int sockaddr2bsd(const void *addr, uint32_t addrsize,
} else {
return einval();
}
} else if (((struct sockaddr *)addr)->sa_family == AF_INET6) {
if (addrsize >= sizeof(struct sockaddr_in6)) {
out_addr->sin6.sin6_len = 0;
out_addr->sin6.sin6_family = AF_INET6;
out_addr->sin6.sin6_port = ((struct sockaddr_in6 *)addr)->sin6_port;
out_addr->sin6.sin6_flowinfo =
((struct sockaddr_in6 *)addr)->sin6_flowinfo;
out_addr->sin6.sin6_addr = ((struct sockaddr_in6 *)addr)->sin6_addr;
out_addr->sin6.sin6_scope_id =
((struct sockaddr_in6 *)addr)->sin6_scope_id;
*out_addrsize = sizeof(struct sockaddr_in6_bsd);
return 0;
} else {
return einval();
}
} else if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
famsize = sizeof(((struct sockaddr_un *)addr)->sun_family);
if (addrsize >= famsize &&

View file

@ -19,6 +19,7 @@
#include "libc/macros.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/struct/sockaddr.internal.h"
#include "libc/sock/struct/sockaddr6-bsd.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/errfuns.h"
@ -42,6 +43,16 @@ void sockaddr2linux(const union sockaddr_storage_bsd *addr, uint32_t addrsize,
out_addr->sin.sin_addr = addr->sin.sin_addr;
*inout_addrsize = sizeof(struct sockaddr_in);
}
} else if (addr->sa.sa_family == AF_INET6) {
if (addrsize >= sizeof(struct sockaddr_in6_bsd) &&
size >= sizeof(struct sockaddr_in6)) {
out_addr->sin6.sin6_family = AF_INET6;
out_addr->sin6.sin6_port = addr->sin6.sin6_port;
out_addr->sin6.sin6_addr = addr->sin6.sin6_addr;
out_addr->sin6.sin6_flowinfo = addr->sin6.sin6_flowinfo;
out_addr->sin6.sin6_scope_id = addr->sin6.sin6_scope_id;
*inout_addrsize = sizeof(struct sockaddr_in6);
}
} else if (addr->sa.sa_family == AF_UNIX) {
if (addrsize >=
sizeof(addr->sun.sun_len) + sizeof(addr->sun.sun_family) &&

View file

@ -2,6 +2,7 @@
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR_INTERNAL_H_
#include "libc/mem/alloca.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/sock/struct/sockaddr6-bsd.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -29,12 +30,14 @@ struct sockaddr_un_bsd {
union sockaddr_storage_bsd {
struct sockaddr_bsd sa;
struct sockaddr_in_bsd sin;
struct sockaddr_in6_bsd sin6;
struct sockaddr_un_bsd sun;
};
union sockaddr_storage_linux {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_un sun;
};

View file

@ -0,0 +1,18 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR6_BSD_INTERNAL_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR6_BSD_INTERNAL_H_
#include "libc/sock/struct/sockaddr6.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct sockaddr_in6_bsd {
uint8_t sin6_len;
uint8_t sin6_family;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR6_BSD_INTERNAL_H_ */

View file

@ -17,47 +17,22 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h"
forceinline void longsorter(long *x, size_t n, size_t t) {
long a, b, c;
size_t i, p, q;
for (p = t; p > 0; p >>= 1) {
for (i = 0; i < n - p; ++i) {
if (!(i & p)) {
a = x[i + 0];
b = x[i + p];
if (a > b) c = a, a = b, b = c;
x[i + 0] = a;
x[i + p] = b;
}
}
for (q = t; q > p; q >>= 1) {
for (i = 0; i < n - q; ++i) {
if (!(i & p)) {
a = x[i + p];
b = x[i + q];
if (a > b) c = a, a = b, b = c;
x[i + p] = a;
x[i + q] = b;
}
}
}
static void longsorter(long *A, size_t n) {
long t, p;
size_t i, j;
if (n < 2) return;
for (p = A[n / 2], i = 0, j = n - 1;; i++, j--) {
while (A[i] < p) i++;
while (A[j] > p) j--;
if (i >= j) break;
t = A[i];
A[i] = A[j];
A[j] = t;
}
}
static microarchitecture("avx2") optimizespeed noasan
void longsort_avx2(long *x, size_t n, size_t t) {
longsorter(x, n, t);
}
static optimizesize noasan void longsort_pure(long *x, size_t n, size_t t) {
longsorter(x, n, t);
longsorter(A, i);
longsorter(A + i, n - i);
}
/**
@ -67,21 +42,9 @@ static optimizesize noasan void longsort_pure(long *x, size_t n, size_t t) {
* -Lord Capulet
*
*/
void longsort(long *x, size_t n) {
size_t t, m;
if (IsAsan()) {
if (__builtin_mul_overflow(n, sizeof(long), &m)) m = -1;
__asan_verify(x, m);
}
if (n > 1) {
t = 1ul << bsrl(n - 1);
if (!IsTiny() && X86_HAVE(AVX2)) {
longsort_avx2(x, n, t);
} else {
longsort_pure(x, n, t);
}
}
void longsort(long *A, size_t n) {
longsorter(A, n);
if (n > 1000) {
STRACE("longsort(%p, %'zu)", x, n);
STRACE("longsort(%p, %'zu)", A, n);
}
}