mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Add libresolv from Musl Libc
Locally modified to get nameservers from Windows Registry when `\etc\resolv.conf` isn't defined.
This commit is contained in:
parent
8874a37abc
commit
1a96de6eda
36 changed files with 2313 additions and 73 deletions
18
Makefile
18
Makefile
|
@ -208,20 +208,20 @@ include libc/log/BUILD.mk # │
|
||||||
include third_party/getopt/BUILD.mk # │
|
include third_party/getopt/BUILD.mk # │
|
||||||
include third_party/bzip2/BUILD.mk # │
|
include third_party/bzip2/BUILD.mk # │
|
||||||
include dsp/core/BUILD.mk # │
|
include dsp/core/BUILD.mk # │
|
||||||
include third_party/musl/BUILD.mk # │
|
|
||||||
include libc/x/BUILD.mk # │
|
|
||||||
include third_party/stb/BUILD.mk # │
|
|
||||||
include dsp/scale/BUILD.mk # │
|
|
||||||
include dsp/mpeg/BUILD.mk # │
|
|
||||||
include dsp/BUILD.mk # │
|
|
||||||
include third_party/zlib/gz/BUILD.mk # │
|
include third_party/zlib/gz/BUILD.mk # │
|
||||||
include third_party/intel/BUILD.mk # │
|
include third_party/intel/BUILD.mk # │
|
||||||
include third_party/aarch64/BUILD.mk # │
|
include third_party/aarch64/BUILD.mk # │
|
||||||
include libc/BUILD.mk #─┘
|
include libc/BUILD.mk #─┘
|
||||||
include libc/sock/BUILD.mk #─┐
|
include libc/sock/BUILD.mk #─┐
|
||||||
include dsp/tty/BUILD.mk # ├──ONLINE RUNTIME
|
include libc/dns/BUILD.mk # ├──ONLINE RUNTIME
|
||||||
include libc/dns/BUILD.mk # │ You can communicate with the network
|
include net/http/BUILD.mk # │ You can communicate with the network
|
||||||
include net/http/BUILD.mk # │
|
include third_party/musl/BUILD.mk # │
|
||||||
|
include libc/x/BUILD.mk # │
|
||||||
|
include dsp/scale/BUILD.mk # │
|
||||||
|
include dsp/mpeg/BUILD.mk # │
|
||||||
|
include dsp/tty/BUILD.mk # │
|
||||||
|
include dsp/BUILD.mk # │
|
||||||
|
include third_party/stb/BUILD.mk # │
|
||||||
include third_party/mbedtls/BUILD.mk # │
|
include third_party/mbedtls/BUILD.mk # │
|
||||||
include third_party/libcxx/BUILD.mk # │
|
include third_party/libcxx/BUILD.mk # │
|
||||||
include third_party/ggml/BUILD.mk # │
|
include third_party/ggml/BUILD.mk # │
|
||||||
|
|
|
@ -14,6 +14,7 @@ libc/isystem/arm_bf16.h \
|
||||||
libc/isystem/arm_fp16.h \
|
libc/isystem/arm_fp16.h \
|
||||||
libc/isystem/arm_neon.h \
|
libc/isystem/arm_neon.h \
|
||||||
libc/isystem/arpa/inet.h \
|
libc/isystem/arpa/inet.h \
|
||||||
|
libc/isystem/arpa/nameser.h \
|
||||||
libc/isystem/array \
|
libc/isystem/array \
|
||||||
libc/isystem/assert.h \
|
libc/isystem/assert.h \
|
||||||
libc/isystem/atomic \
|
libc/isystem/atomic \
|
||||||
|
@ -98,6 +99,7 @@ libc/isystem/langinfo.h \
|
||||||
libc/isystem/libgen.h \
|
libc/isystem/libgen.h \
|
||||||
libc/isystem/limits \
|
libc/isystem/limits \
|
||||||
libc/isystem/limits.h \
|
libc/isystem/limits.h \
|
||||||
|
libc/isystem/link.h \
|
||||||
libc/isystem/linux/futex.h \
|
libc/isystem/linux/futex.h \
|
||||||
libc/isystem/linux/limits.h \
|
libc/isystem/linux/limits.h \
|
||||||
libc/isystem/linux/param.h \
|
libc/isystem/linux/param.h \
|
||||||
|
@ -154,6 +156,7 @@ libc/isystem/random \
|
||||||
libc/isystem/ratio \
|
libc/isystem/ratio \
|
||||||
libc/isystem/regex \
|
libc/isystem/regex \
|
||||||
libc/isystem/regex.h \
|
libc/isystem/regex.h \
|
||||||
|
libc/isystem/resolv.h \
|
||||||
libc/isystem/sched.h \
|
libc/isystem/sched.h \
|
||||||
libc/isystem/scoped_allocator \
|
libc/isystem/scoped_allocator \
|
||||||
libc/isystem/search.h \
|
libc/isystem/search.h \
|
||||||
|
|
|
@ -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/dns/dns.h"
|
#include "libc/dns/ent.h"
|
||||||
|
|
||||||
/**
|
// error number global for gethostbyname*(), gethostbyaddr*(), etc.
|
||||||
* Error number global for gethostbyname*(), gethostbyaddr*(), etc.
|
static _Thread_local int __h_errno;
|
||||||
*/
|
|
||||||
int h_errno;
|
errno_t *__h_errno_location(void) {
|
||||||
|
return &__h_errno;
|
||||||
|
}
|
|
@ -15,14 +15,12 @@ char *dlerror(void);
|
||||||
void *dlopen(const char *, int);
|
void *dlopen(const char *, int);
|
||||||
void *dlsym(void *, const char *);
|
void *dlsym(void *, const char *);
|
||||||
int dlclose(void *);
|
int dlclose(void *);
|
||||||
int dl_iterate_phdr(int (*)(void *, size_t, void *), void *);
|
|
||||||
|
|
||||||
#ifdef _COSMO_SOURCE
|
#ifdef _COSMO_SOURCE
|
||||||
char *cosmo_dlerror(void);
|
char *cosmo_dlerror(void);
|
||||||
void *cosmo_dlopen(const char *, int);
|
void *cosmo_dlopen(const char *, int);
|
||||||
void *cosmo_dlsym(void *, const char *);
|
void *cosmo_dlsym(void *, const char *);
|
||||||
int cosmo_dlclose(void *);
|
int cosmo_dlclose(void *);
|
||||||
int cosmo_dl_iterate_phdr(int (*)(void *, size_t, void *), void *);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -39,7 +39,9 @@ struct servent {
|
||||||
char *s_proto; /* protocol to use */
|
char *s_proto; /* protocol to use */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int h_errno;
|
#define h_errno (*__h_errno_location())
|
||||||
|
errno_t *__h_errno_location(void) dontthrow pureconst;
|
||||||
|
|
||||||
void herror(const char *);
|
void herror(const char *);
|
||||||
const char *hstrerror(int);
|
const char *hstrerror(int);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#define SYSDEBUG 0
|
#define SYSDEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _NTTRACE 0 /* not configurable w/ flag yet */
|
#define _NTTRACE 1 /* not configurable w/ flag yet */
|
||||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||||
#define _LOCKTRACE 0 /* not configurable w/ flag yet */
|
#define _LOCKTRACE 0 /* not configurable w/ flag yet */
|
||||||
|
|
|
@ -46,7 +46,7 @@ textwindows int WSARecv(
|
||||||
// be NULL only if the lpOverlapped parameter is not NULL.
|
// be NULL only if the lpOverlapped parameter is not NULL.
|
||||||
unassert(!opt_out_lpNumberOfBytesRecvd);
|
unassert(!opt_out_lpNumberOfBytesRecvd);
|
||||||
}
|
}
|
||||||
#if defined(SYSDEBUG) && _NTTRACE
|
#if SYSDEBUG && _NTTRACE
|
||||||
uint32_t NumberOfBytesRecvd;
|
uint32_t NumberOfBytesRecvd;
|
||||||
if (opt_out_lpNumberOfBytesRecvd) {
|
if (opt_out_lpNumberOfBytesRecvd) {
|
||||||
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
|
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/intrin/likely.h"
|
#include "libc/intrin/likely.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -39,7 +40,7 @@ textwindows int WSARecvFrom(
|
||||||
struct NtOverlapped *opt_inout_lpOverlapped,
|
struct NtOverlapped *opt_inout_lpOverlapped,
|
||||||
const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) {
|
const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) {
|
||||||
int rc;
|
int rc;
|
||||||
#if defined(SYSDEBUG) && _NTTRACE
|
#if SYSDEBUG && _NTTRACE
|
||||||
uint32_t NumberOfBytesRecvd;
|
uint32_t NumberOfBytesRecvd;
|
||||||
if (opt_out_lpNumberOfBytesRecvd) {
|
if (opt_out_lpNumberOfBytesRecvd) {
|
||||||
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
|
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
|
||||||
|
@ -55,10 +56,10 @@ textwindows int WSARecvFrom(
|
||||||
kprintf(STRACE_PROLOGUE "WSARecvFrom(%lu, [", s);
|
kprintf(STRACE_PROLOGUE "WSARecvFrom(%lu, [", s);
|
||||||
DescribeIovNt(inout_lpBuffers, dwBufferCount,
|
DescribeIovNt(inout_lpBuffers, dwBufferCount,
|
||||||
rc != -1 ? NumberOfBytesRecvd : 0);
|
rc != -1 ? NumberOfBytesRecvd : 0);
|
||||||
kprintf("], %u, [%'u], %p, %p, %p, %s, %p) → %d% lm\n", dwBufferCount,
|
kprintf("], %u, [%'u], %p, %p, %p, %s, %p) → %d %d\n", dwBufferCount,
|
||||||
NumberOfBytesRecvd, opt_out_fromsockaddr, opt_inout_fromsockaddrlen,
|
NumberOfBytesRecvd, opt_out_fromsockaddr, opt_inout_fromsockaddrlen,
|
||||||
inout_lpFlags, DescribeNtOverlapped(opt_inout_lpOverlapped),
|
inout_lpFlags, DescribeNtOverlapped(opt_inout_lpOverlapped),
|
||||||
opt_lpCompletionRoutine, rc);
|
opt_lpCompletionRoutine, rc, GetLastError());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
rc = __imp_WSARecvFrom(s, inout_lpBuffers, dwBufferCount,
|
rc = __imp_WSARecvFrom(s, inout_lpBuffers, dwBufferCount,
|
||||||
|
|
4
libc/isystem/arpa/nameser.h
Normal file
4
libc/isystem/arpa/nameser.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#ifndef _ARPA_NAMESER_H
|
||||||
|
#define _ARPA_NAMESER_H
|
||||||
|
#include "third_party/musl/nameser.h"
|
||||||
|
#endif /* _ARPA_NAMESER_H */
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_
|
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_
|
||||||
#define COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_
|
#define COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
|
#include "libc/sock/in.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sock/struct/in6_pktinfo.h"
|
#include "libc/sock/struct/in6_pktinfo.h"
|
||||||
#include "libc/sock/struct/in_pktinfo.h"
|
#include "libc/sock/struct/in_pktinfo.h"
|
||||||
|
@ -17,46 +18,4 @@
|
||||||
#include "libc/sysv/consts/mcast.h"
|
#include "libc/sysv/consts/mcast.h"
|
||||||
#include "libc/sysv/consts/pf.h"
|
#include "libc/sysv/consts/pf.h"
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
|
|
||||||
# define IN6_ARE_ADDR_EQUAL(a,b) \
|
|
||||||
((((const uint32_t *) (a))[0] == ((const uint32_t *) (b))[0]) \
|
|
||||||
&& (((const uint32_t *) (a))[1] == ((const uint32_t *) (b))[1]) \
|
|
||||||
&& (((const uint32_t *) (a))[2] == ((const uint32_t *) (b))[2]) \
|
|
||||||
&& (((const uint32_t *) (a))[3] == ((const uint32_t *) (b))[3]))
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_UNSPECIFIED(a) \
|
|
||||||
(((const uint32_t *) (a))[0] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[1] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[2] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[3] == 0)
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_LOOPBACK(a) \
|
|
||||||
(((const uint32_t *) (a))[0] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[1] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[2] == 0 \
|
|
||||||
&& ((const uint32_t *) (a))[3] == htonl (1))
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_LINKLOCAL(a) \
|
|
||||||
((((const uint32_t *) (a))[0] & htonl (0xffc00000)) \
|
|
||||||
== htonl (0xfe800000))
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_SITELOCAL(a) \
|
|
||||||
((((const uint32_t *) (a))[0] & htonl (0xffc00000)) \
|
|
||||||
== htonl (0xfec00000))
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_V4MAPPED(a) \
|
|
||||||
((((const uint32_t *) (a))[0] == 0) \
|
|
||||||
&& (((const uint32_t *) (a))[1] == 0) \
|
|
||||||
&& (((const uint32_t *) (a))[2] == htonl (0xffff)))
|
|
||||||
|
|
||||||
# define IN6_IS_ADDR_V4COMPAT(a) \
|
|
||||||
((((const uint32_t *) (a))[0] == 0) \
|
|
||||||
&& (((const uint32_t *) (a))[1] == 0) \
|
|
||||||
&& (((const uint32_t *) (a))[2] == 0) \
|
|
||||||
&& (ntohl (((const uint32_t *) (a))[3]) > 1))
|
|
||||||
|
|
||||||
#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_ */
|
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_ */
|
||||||
|
|
5
libc/isystem/resolv.h
Normal file
5
libc/isystem/resolv.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef _RESOLV_H
|
||||||
|
#define _RESOLV_H
|
||||||
|
#include "third_party/musl/nameser.h"
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
#endif /* _RESOLV_H */
|
71
libc/sock/in.h
Normal file
71
libc/sock/in.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_SOCK_IN_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_SOCK_IN_H_
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
|
|
||||||
|
#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0)
|
||||||
|
#define IN_CLASSA_NET 0xff000000
|
||||||
|
#define IN_CLASSA_NSHIFT 24
|
||||||
|
#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
|
||||||
|
#define IN_CLASSA_MAX 128
|
||||||
|
#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
|
||||||
|
#define IN_CLASSB_NET 0xffff0000
|
||||||
|
#define IN_CLASSB_NSHIFT 16
|
||||||
|
#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
|
||||||
|
#define IN_CLASSB_MAX 65536
|
||||||
|
#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
|
||||||
|
#define IN_CLASSC_NET 0xffffff00
|
||||||
|
#define IN_CLASSC_NSHIFT 8
|
||||||
|
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
|
||||||
|
#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
|
||||||
|
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||||
|
#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
|
||||||
|
#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_UNSPECIFIED(a) \
|
||||||
|
(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
|
||||||
|
((uint32_t *)(a))[2] == 0 && ((uint32_t *)(a))[3] == 0)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_LOOPBACK(a) \
|
||||||
|
(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
|
||||||
|
((uint32_t *)(a))[2] == 0 && ((uint8_t *)(a))[12] == 0 && \
|
||||||
|
((uint8_t *)(a))[13] == 0 && ((uint8_t *)(a))[14] == 0 && \
|
||||||
|
((uint8_t *)(a))[15] == 1)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *)(a))[0] == 0xff)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_LINKLOCAL(a) \
|
||||||
|
((((uint8_t *)(a))[0]) == 0xfe && (((uint8_t *)(a))[1] & 0xc0) == 0x80)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_SITELOCAL(a) \
|
||||||
|
((((uint8_t *)(a))[0]) == 0xfe && (((uint8_t *)(a))[1] & 0xc0) == 0xc0)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_V4MAPPED(a) \
|
||||||
|
(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
|
||||||
|
((uint8_t *)(a))[8] == 0 && ((uint8_t *)(a))[9] == 0 && \
|
||||||
|
((uint8_t *)(a))[10] == 0xff && ((uint8_t *)(a))[11] == 0xff)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_V4COMPAT(a) \
|
||||||
|
(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
|
||||||
|
((uint32_t *)(a))[2] == 0 && ((uint8_t *)(a))[15] > 1)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
|
||||||
|
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *)(a))[1] & 0xf) == 0x1))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
|
||||||
|
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *)(a))[1] & 0xf) == 0x2))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
|
||||||
|
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *)(a))[1] & 0xf) == 0x5))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
|
||||||
|
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *)(a))[1] & 0xf) == 0x8))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MC_GLOBAL(a) \
|
||||||
|
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *)(a))[1] & 0xf) == 0xe))
|
||||||
|
|
||||||
|
#define __ARE_4_EQUAL(a, b) \
|
||||||
|
(!((0 [a] - 0 [b]) | (1 [a] - 1 [b]) | (2 [a] - 2 [b]) | (3 [a] - 3 [b])))
|
||||||
|
#define IN6_ARE_ADDR_EQUAL(a, b) \
|
||||||
|
__ARE_4_EQUAL((const uint32_t *)(a), (const uint32_t *)(b))
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_SOCK_IN_H_ */
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/nt/struct/iovec.h"
|
#include "libc/nt/struct/iovec.h"
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
#include "libc/sock/syscall_fd.internal.h"
|
#include "libc/sock/syscall_fd.internal.h"
|
||||||
#include "libc/sysv/consts/msg.h"
|
#include "libc/sysv/consts/msg.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
#include "libc/calls/struct/iovec.internal.h"
|
#include "libc/calls/struct/iovec.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/intrin/strace.internal.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sock/struct/msghdr.h"
|
#include "libc/sock/struct/msghdr.h"
|
||||||
#include "libc/sock/struct/msghdr.internal.h"
|
#include "libc/sock/struct/msghdr.internal.h"
|
||||||
|
@ -99,12 +103,12 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) {
|
||||||
}
|
}
|
||||||
END_CANCELATION_POINT;
|
END_CANCELATION_POINT;
|
||||||
|
|
||||||
#if defined(SYSDEBUG) && _DATATRACE
|
#if SYSDEBUG && _DATATRACE
|
||||||
if (__strace > 0 && strace_enabled(0) > 0) {
|
if (__strace > 0 && strace_enabled(0) > 0) {
|
||||||
if (!msg || (rc == -1 && errno == EFAULT)) {
|
if (!msg || (rc == -1 && errno == EFAULT)) {
|
||||||
DATATRACE("recvmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc);
|
DATATRACE("recvmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc);
|
||||||
} else {
|
} else {
|
||||||
kprintf(STRACE_PROLOGUE "recvmsg(%d, [{");
|
kprintf(STRACE_PROLOGUE "recvmsg(%d, [{", fd);
|
||||||
if (msg->msg_namelen)
|
if (msg->msg_namelen)
|
||||||
kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name);
|
kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name);
|
||||||
if (msg->msg_controllen)
|
if (msg->msg_controllen)
|
||||||
|
|
|
@ -87,10 +87,10 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
||||||
}
|
}
|
||||||
END_CANCELATION_POINT;
|
END_CANCELATION_POINT;
|
||||||
|
|
||||||
#if defined(SYSDEBUG) && _DATATRACE
|
#if SYSDEBUG && _DATATRACE
|
||||||
// TODO(jart): Write a DescribeMsg() function.
|
// TODO(jart): Write a DescribeMsg() function.
|
||||||
if (strace_enabled(0) > 0) {
|
if (strace_enabled(0) > 0) {
|
||||||
kprintf(STRACE_PROLOGUE "sendmsg(");
|
kprintf(STRACE_PROLOGUE "sendmsg(%d, ", fd);
|
||||||
if ((!IsAsan() && kisdangerous(msg)) ||
|
if ((!IsAsan() && kisdangerous(msg)) ||
|
||||||
(IsAsan() && !__asan_is_valid(msg, sizeof(*msg)))) {
|
(IsAsan() && !__asan_is_valid(msg, sizeof(*msg)))) {
|
||||||
kprintf("%p", msg);
|
kprintf("%p", msg);
|
||||||
|
|
|
@ -16,16 +16,18 @@ struct ifreq {
|
||||||
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 */
|
||||||
|
int ifru_ivalue; /* todo(jart) */
|
||||||
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 ifr_ifindex ifr_ifru.ifru_ivalue
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_ */
|
||||||
|
|
2
third_party/musl/BUILD.mk
vendored
2
third_party/musl/BUILD.mk
vendored
|
@ -22,8 +22,10 @@ THIRD_PARTY_MUSL_A_DIRECTDEPS = \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
LIBC_MEM \
|
LIBC_MEM \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
|
LIBC_NT_ADVAPI32 \
|
||||||
LIBC_PROC \
|
LIBC_PROC \
|
||||||
LIBC_RUNTIME \
|
LIBC_RUNTIME \
|
||||||
|
LIBC_SOCK \
|
||||||
LIBC_STDIO \
|
LIBC_STDIO \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
|
|
139
third_party/musl/dn_comp.c
vendored
Normal file
139
third_party/musl/dn_comp.c
vendored
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
/* RFC 1035 message compression */
|
||||||
|
|
||||||
|
/* label start offsets of a compressed domain name s */
|
||||||
|
static int getoffs(short *offs, const unsigned char *base, const unsigned char *s)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for (;;) {
|
||||||
|
while (*s & 0xc0) {
|
||||||
|
if ((*s & 0xc0) != 0xc0) return 0;
|
||||||
|
s = base + ((s[0]&0x3f)<<8 | s[1]);
|
||||||
|
}
|
||||||
|
if (!*s) return i;
|
||||||
|
if (s-base >= 0x4000) return 0;
|
||||||
|
offs[i++] = s-base;
|
||||||
|
s += *s + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* label lengths of an ascii domain name s */
|
||||||
|
static int getlens(unsigned char *lens, const char *s, int l)
|
||||||
|
{
|
||||||
|
int i=0,j=0,k=0;
|
||||||
|
for (;;) {
|
||||||
|
for (; j<l && s[j]!='.'; j++);
|
||||||
|
if (j-k-1u > 62) return 0;
|
||||||
|
lens[i++] = j-k;
|
||||||
|
if (j==l) return i;
|
||||||
|
k = ++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* longest suffix match of an ascii domain with a compressed domain name dn */
|
||||||
|
static int match(int *offset, const unsigned char *base, const unsigned char *dn,
|
||||||
|
const char *end, const unsigned char *lens, int nlen)
|
||||||
|
{
|
||||||
|
int l, o, m=0;
|
||||||
|
short offs[128];
|
||||||
|
int noff = getoffs(offs, base, dn);
|
||||||
|
if (!noff) return 0;
|
||||||
|
for (;;) {
|
||||||
|
l = lens[--nlen];
|
||||||
|
o = offs[--noff];
|
||||||
|
end -= l;
|
||||||
|
if (l != base[o] || memcmp(base+o+1, end, l))
|
||||||
|
return m;
|
||||||
|
*offset = o;
|
||||||
|
m += l;
|
||||||
|
if (nlen) m++;
|
||||||
|
if (!nlen || !noff) return m;
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dnptrs, unsigned char **lastdnptr)
|
||||||
|
{
|
||||||
|
int i, j, n, m=0, offset, bestlen=0, bestoff;
|
||||||
|
unsigned char lens[127];
|
||||||
|
unsigned char **p;
|
||||||
|
const char *end;
|
||||||
|
size_t l = strnlen(src, 255);
|
||||||
|
if (l && src[l-1] == '.') l--;
|
||||||
|
if (l>253 || space<=0) return -1;
|
||||||
|
if (!l) {
|
||||||
|
*dst = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
end = src+l;
|
||||||
|
n = getlens(lens, src, l);
|
||||||
|
if (!n) return -1;
|
||||||
|
|
||||||
|
p = dnptrs;
|
||||||
|
if (p && *p) for (p++; *p; p++) {
|
||||||
|
m = match(&offset, *dnptrs, *p, end, lens, n);
|
||||||
|
if (m > bestlen) {
|
||||||
|
bestlen = m;
|
||||||
|
bestoff = offset;
|
||||||
|
if (m == l)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode unmatched part */
|
||||||
|
if (space < l-bestlen+2+(bestlen-1 < l-1)) return -1;
|
||||||
|
memcpy(dst+1, src, l-bestlen);
|
||||||
|
for (i=j=0; i<l-bestlen; i+=lens[j++]+1)
|
||||||
|
dst[i] = lens[j];
|
||||||
|
|
||||||
|
/* add tail */
|
||||||
|
if (bestlen) {
|
||||||
|
dst[i++] = 0xc0 | bestoff>>8;
|
||||||
|
dst[i++] = bestoff;
|
||||||
|
} else
|
||||||
|
dst[i++] = 0;
|
||||||
|
|
||||||
|
/* save dst pointer */
|
||||||
|
if (i>2 && lastdnptr && dnptrs && *dnptrs) {
|
||||||
|
while (*p) p++;
|
||||||
|
if (p+1 < lastdnptr) {
|
||||||
|
*p++ = dst;
|
||||||
|
*p=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
65
third_party/musl/dn_expand.c
vendored
Normal file
65
third_party/musl/dn_expand.c
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "third_party/musl/resolv.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int __dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
|
||||||
|
{
|
||||||
|
const unsigned char *p = src;
|
||||||
|
char *dend, *dbegin = dest;
|
||||||
|
int len = -1, i, j;
|
||||||
|
if (p==end || space <= 0) return -1;
|
||||||
|
dend = dest + (space > 254 ? 254 : space);
|
||||||
|
/* detect reference loop using an iteration counter */
|
||||||
|
for (i=0; i < end-base; i+=2) {
|
||||||
|
/* loop invariants: p<end, dest<dend */
|
||||||
|
if (*p & 0xc0) {
|
||||||
|
if (p+1==end) return -1;
|
||||||
|
j = ((p[0] & 0x3f) << 8) | p[1];
|
||||||
|
if (len < 0) len = p+2-src;
|
||||||
|
if (j >= end-base) return -1;
|
||||||
|
p = base+j;
|
||||||
|
} else if (*p) {
|
||||||
|
if (dest != dbegin) *dest++ = '.';
|
||||||
|
j = *p++;
|
||||||
|
if (j >= end-p || j >= dend-dest) return -1;
|
||||||
|
while (j--) *dest++ = *p++;
|
||||||
|
} else {
|
||||||
|
*dest = 0;
|
||||||
|
if (len < 0) len = p+1-src;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak_reference(__dn_expand, dn_expand);
|
47
third_party/musl/dn_skipname.c
vendored
Normal file
47
third_party/musl/dn_skipname.c
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int dn_skipname(const unsigned char *s, const unsigned char *end)
|
||||||
|
{
|
||||||
|
const unsigned char *p = s;
|
||||||
|
while (p < end)
|
||||||
|
if (!*p) return p-s+1;
|
||||||
|
else if (*p>=192)
|
||||||
|
if (p+1<end) return p-s+2;
|
||||||
|
else break;
|
||||||
|
else
|
||||||
|
if (end-p<*p+1) break;
|
||||||
|
else p += *p + 1;
|
||||||
|
return -1;
|
||||||
|
}
|
52
third_party/musl/lookup.internal.h
vendored
Normal file
52
third_party/musl/lookup.internal.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_LOOKUP_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_MUSL_LOOKUP_INTERNAL_H_
|
||||||
|
#include "libc/sock/struct/sockaddr6.h"
|
||||||
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
|
#include "libc/dns/dns.h"
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
struct aibuf {
|
||||||
|
struct addrinfo ai;
|
||||||
|
union sa {
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
} sa;
|
||||||
|
volatile int lock[1];
|
||||||
|
short slot, ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct address {
|
||||||
|
int family;
|
||||||
|
unsigned scopeid;
|
||||||
|
uint8_t addr[16];
|
||||||
|
int sortkey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct service {
|
||||||
|
uint16_t port;
|
||||||
|
unsigned char proto, socktype;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAXNS 3
|
||||||
|
|
||||||
|
struct resolvconf {
|
||||||
|
struct address ns[MAXNS];
|
||||||
|
unsigned nns, attempts, ndots;
|
||||||
|
unsigned timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The limit of 48 results is a non-sharp bound on the number of addresses
|
||||||
|
* that can fit in one 512-byte DNS packet full of v4 results and a second
|
||||||
|
* packet full of v6 results. Due to headers, the actual limit is lower. */
|
||||||
|
#define MAXADDRS 48
|
||||||
|
#define MAXSERVS 2
|
||||||
|
|
||||||
|
int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags);
|
||||||
|
int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
|
||||||
|
int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
|
||||||
|
int __get_resolv_conf(struct resolvconf *, char *, size_t);
|
||||||
|
int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
|
||||||
|
int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *, int), void *);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_LOOKUP_INTERNAL_H_ */
|
90
third_party/musl/lookup_ipliteral.c
vendored
Normal file
90
third_party/musl/lookup_ipliteral.c
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "libc/limits.h"
|
||||||
|
#include "third_party/musl/lookup.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
|
||||||
|
{
|
||||||
|
struct in_addr a4;
|
||||||
|
struct in6_addr a6;
|
||||||
|
if (inet_aton(name, &a4) > 0) {
|
||||||
|
if (family == AF_INET6) /* wrong family */
|
||||||
|
return EAI_NODATA;
|
||||||
|
memcpy(&buf[0].addr, &a4, sizeof a4);
|
||||||
|
buf[0].family = AF_INET;
|
||||||
|
buf[0].scopeid = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp[64];
|
||||||
|
char *p = strchr(name, '%'), *z;
|
||||||
|
unsigned long long scopeid = 0;
|
||||||
|
if (p && p-name < 64) {
|
||||||
|
memcpy(tmp, name, p-name);
|
||||||
|
tmp[p-name] = 0;
|
||||||
|
name = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET6, name, &a6) <= 0)
|
||||||
|
return 0;
|
||||||
|
if (family == AF_INET) /* wrong family */
|
||||||
|
return EAI_NODATA;
|
||||||
|
|
||||||
|
memcpy(&buf[0].addr, &a6, sizeof a6);
|
||||||
|
buf[0].family = AF_INET6;
|
||||||
|
if (p) {
|
||||||
|
if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
|
||||||
|
else z = p-1;
|
||||||
|
if (*z) {
|
||||||
|
#if 1
|
||||||
|
// todo(jart): do something
|
||||||
|
return EAI_NONAME;
|
||||||
|
#else
|
||||||
|
if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
|
||||||
|
!IN6_IS_ADDR_MC_LINKLOCAL(&a6))
|
||||||
|
return EAI_NONAME;
|
||||||
|
scopeid = if_nametoindex(p);
|
||||||
|
if (!scopeid)
|
||||||
|
return EAI_NONAME;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (scopeid > UINT_MAX)
|
||||||
|
return EAI_NONAME;
|
||||||
|
}
|
||||||
|
buf[0].scopeid = scopeid;
|
||||||
|
return 1;
|
||||||
|
}
|
446
third_party/musl/nameser.h
vendored
Normal file
446
third_party/musl/nameser.h
vendored
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_NAMESER_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_MUSL_NAMESER_H_
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define __NAMESER 19991006
|
||||||
|
#define NS_PACKETSZ 512
|
||||||
|
#define NS_MAXDNAME 1025
|
||||||
|
#define NS_MAXMSG 65535
|
||||||
|
#define NS_MAXCDNAME 255
|
||||||
|
#define NS_MAXLABEL 63
|
||||||
|
#define NS_HFIXEDSZ 12
|
||||||
|
#define NS_QFIXEDSZ 4
|
||||||
|
#define NS_RRFIXEDSZ 10
|
||||||
|
#define NS_INT32SZ 4
|
||||||
|
#define NS_INT16SZ 2
|
||||||
|
#define NS_INT8SZ 1
|
||||||
|
#define NS_INADDRSZ 4
|
||||||
|
#define NS_IN6ADDRSZ 16
|
||||||
|
#define NS_CMPRSFLGS 0xc0
|
||||||
|
#define NS_DEFAULTPORT 53
|
||||||
|
|
||||||
|
typedef enum __ns_sect {
|
||||||
|
ns_s_qd = 0,
|
||||||
|
ns_s_zn = 0,
|
||||||
|
ns_s_an = 1,
|
||||||
|
ns_s_pr = 1,
|
||||||
|
ns_s_ns = 2,
|
||||||
|
ns_s_ud = 2,
|
||||||
|
ns_s_ar = 3,
|
||||||
|
ns_s_max = 4
|
||||||
|
} ns_sect;
|
||||||
|
|
||||||
|
typedef struct __ns_msg {
|
||||||
|
const unsigned char *_msg, *_eom;
|
||||||
|
uint16_t _id, _flags, _counts[ns_s_max];
|
||||||
|
const unsigned char *_sections[ns_s_max];
|
||||||
|
ns_sect _sect;
|
||||||
|
int _rrnum;
|
||||||
|
const unsigned char *_msg_ptr;
|
||||||
|
} ns_msg;
|
||||||
|
|
||||||
|
struct _ns_flagdata { int mask, shift; };
|
||||||
|
extern const struct _ns_flagdata _ns_flagdata[];
|
||||||
|
|
||||||
|
#define ns_msg_id(handle) ((handle)._id + 0)
|
||||||
|
#define ns_msg_base(handle) ((handle)._msg + 0)
|
||||||
|
#define ns_msg_end(handle) ((handle)._eom + 0)
|
||||||
|
#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
|
||||||
|
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
|
||||||
|
#define ns_msg_getflag(handle, flag) \
|
||||||
|
(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
|
||||||
|
|
||||||
|
typedef struct __ns_rr {
|
||||||
|
char name[NS_MAXDNAME];
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t rr_class;
|
||||||
|
uint32_t ttl;
|
||||||
|
uint16_t rdlength;
|
||||||
|
const unsigned char *rdata;
|
||||||
|
} ns_rr;
|
||||||
|
|
||||||
|
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
|
||||||
|
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
|
||||||
|
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
|
||||||
|
#define ns_rr_ttl(rr) ((rr).ttl + 0)
|
||||||
|
#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
|
||||||
|
#define ns_rr_rdata(rr) ((rr).rdata + 0)
|
||||||
|
|
||||||
|
typedef enum __ns_flag {
|
||||||
|
ns_f_qr,
|
||||||
|
ns_f_opcode,
|
||||||
|
ns_f_aa,
|
||||||
|
ns_f_tc,
|
||||||
|
ns_f_rd,
|
||||||
|
ns_f_ra,
|
||||||
|
ns_f_z,
|
||||||
|
ns_f_ad,
|
||||||
|
ns_f_cd,
|
||||||
|
ns_f_rcode,
|
||||||
|
ns_f_max
|
||||||
|
} ns_flag;
|
||||||
|
|
||||||
|
typedef enum __ns_opcode {
|
||||||
|
ns_o_query = 0,
|
||||||
|
ns_o_iquery = 1,
|
||||||
|
ns_o_status = 2,
|
||||||
|
ns_o_notify = 4,
|
||||||
|
ns_o_update = 5,
|
||||||
|
ns_o_max = 6
|
||||||
|
} ns_opcode;
|
||||||
|
|
||||||
|
typedef enum __ns_rcode {
|
||||||
|
ns_r_noerror = 0,
|
||||||
|
ns_r_formerr = 1,
|
||||||
|
ns_r_servfail = 2,
|
||||||
|
ns_r_nxdomain = 3,
|
||||||
|
ns_r_notimpl = 4,
|
||||||
|
ns_r_refused = 5,
|
||||||
|
ns_r_yxdomain = 6,
|
||||||
|
ns_r_yxrrset = 7,
|
||||||
|
ns_r_nxrrset = 8,
|
||||||
|
ns_r_notauth = 9,
|
||||||
|
ns_r_notzone = 10,
|
||||||
|
ns_r_max = 11,
|
||||||
|
ns_r_badvers = 16,
|
||||||
|
ns_r_badsig = 16,
|
||||||
|
ns_r_badkey = 17,
|
||||||
|
ns_r_badtime = 18
|
||||||
|
} ns_rcode;
|
||||||
|
|
||||||
|
typedef enum __ns_update_operation {
|
||||||
|
ns_uop_delete = 0,
|
||||||
|
ns_uop_add = 1,
|
||||||
|
ns_uop_max = 2
|
||||||
|
} ns_update_operation;
|
||||||
|
|
||||||
|
struct ns_tsig_key {
|
||||||
|
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
|
||||||
|
unsigned char *data;
|
||||||
|
int len;
|
||||||
|
};
|
||||||
|
typedef struct ns_tsig_key ns_tsig_key;
|
||||||
|
|
||||||
|
struct ns_tcp_tsig_state {
|
||||||
|
int counter;
|
||||||
|
struct dst_key *key;
|
||||||
|
void *ctx;
|
||||||
|
unsigned char sig[NS_PACKETSZ];
|
||||||
|
int siglen;
|
||||||
|
};
|
||||||
|
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
|
||||||
|
|
||||||
|
#define NS_TSIG_FUDGE 300
|
||||||
|
#define NS_TSIG_TCP_COUNT 100
|
||||||
|
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
|
||||||
|
|
||||||
|
#define NS_TSIG_ERROR_NO_TSIG -10
|
||||||
|
#define NS_TSIG_ERROR_NO_SPACE -11
|
||||||
|
#define NS_TSIG_ERROR_FORMERR -12
|
||||||
|
|
||||||
|
typedef enum __ns_type {
|
||||||
|
ns_t_invalid = 0,
|
||||||
|
ns_t_a = 1,
|
||||||
|
ns_t_ns = 2,
|
||||||
|
ns_t_md = 3,
|
||||||
|
ns_t_mf = 4,
|
||||||
|
ns_t_cname = 5,
|
||||||
|
ns_t_soa = 6,
|
||||||
|
ns_t_mb = 7,
|
||||||
|
ns_t_mg = 8,
|
||||||
|
ns_t_mr = 9,
|
||||||
|
ns_t_null = 10,
|
||||||
|
ns_t_wks = 11,
|
||||||
|
ns_t_ptr = 12,
|
||||||
|
ns_t_hinfo = 13,
|
||||||
|
ns_t_minfo = 14,
|
||||||
|
ns_t_mx = 15,
|
||||||
|
ns_t_txt = 16,
|
||||||
|
ns_t_rp = 17,
|
||||||
|
ns_t_afsdb = 18,
|
||||||
|
ns_t_x25 = 19,
|
||||||
|
ns_t_isdn = 20,
|
||||||
|
ns_t_rt = 21,
|
||||||
|
ns_t_nsap = 22,
|
||||||
|
ns_t_nsap_ptr = 23,
|
||||||
|
ns_t_sig = 24,
|
||||||
|
ns_t_key = 25,
|
||||||
|
ns_t_px = 26,
|
||||||
|
ns_t_gpos = 27,
|
||||||
|
ns_t_aaaa = 28,
|
||||||
|
ns_t_loc = 29,
|
||||||
|
ns_t_nxt = 30,
|
||||||
|
ns_t_eid = 31,
|
||||||
|
ns_t_nimloc = 32,
|
||||||
|
ns_t_srv = 33,
|
||||||
|
ns_t_atma = 34,
|
||||||
|
ns_t_naptr = 35,
|
||||||
|
ns_t_kx = 36,
|
||||||
|
ns_t_cert = 37,
|
||||||
|
ns_t_a6 = 38,
|
||||||
|
ns_t_dname = 39,
|
||||||
|
ns_t_sink = 40,
|
||||||
|
ns_t_opt = 41,
|
||||||
|
ns_t_apl = 42,
|
||||||
|
ns_t_tkey = 249,
|
||||||
|
ns_t_tsig = 250,
|
||||||
|
ns_t_ixfr = 251,
|
||||||
|
ns_t_axfr = 252,
|
||||||
|
ns_t_mailb = 253,
|
||||||
|
ns_t_maila = 254,
|
||||||
|
ns_t_any = 255,
|
||||||
|
ns_t_zxfr = 256,
|
||||||
|
ns_t_max = 65536
|
||||||
|
} ns_type;
|
||||||
|
|
||||||
|
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
|
||||||
|
(t) == ns_t_mailb || (t) == ns_t_maila)
|
||||||
|
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
|
||||||
|
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
|
||||||
|
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
|
||||||
|
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
|
||||||
|
(t) == ns_t_zxfr)
|
||||||
|
|
||||||
|
typedef enum __ns_class {
|
||||||
|
ns_c_invalid = 0,
|
||||||
|
ns_c_in = 1,
|
||||||
|
ns_c_2 = 2,
|
||||||
|
ns_c_chaos = 3,
|
||||||
|
ns_c_hs = 4,
|
||||||
|
ns_c_none = 254,
|
||||||
|
ns_c_any = 255,
|
||||||
|
ns_c_max = 65536
|
||||||
|
} ns_class;
|
||||||
|
|
||||||
|
typedef enum __ns_key_types {
|
||||||
|
ns_kt_rsa = 1,
|
||||||
|
ns_kt_dh = 2,
|
||||||
|
ns_kt_dsa = 3,
|
||||||
|
ns_kt_private = 254
|
||||||
|
} ns_key_types;
|
||||||
|
|
||||||
|
typedef enum __ns_cert_types {
|
||||||
|
cert_t_pkix = 1,
|
||||||
|
cert_t_spki = 2,
|
||||||
|
cert_t_pgp = 3,
|
||||||
|
cert_t_url = 253,
|
||||||
|
cert_t_oid = 254
|
||||||
|
} ns_cert_types;
|
||||||
|
|
||||||
|
#define NS_KEY_TYPEMASK 0xC000
|
||||||
|
#define NS_KEY_TYPE_AUTH_CONF 0x0000
|
||||||
|
#define NS_KEY_TYPE_CONF_ONLY 0x8000
|
||||||
|
#define NS_KEY_TYPE_AUTH_ONLY 0x4000
|
||||||
|
#define NS_KEY_TYPE_NO_KEY 0xC000
|
||||||
|
#define NS_KEY_NO_AUTH 0x8000
|
||||||
|
#define NS_KEY_NO_CONF 0x4000
|
||||||
|
#define NS_KEY_RESERVED2 0x2000
|
||||||
|
#define NS_KEY_EXTENDED_FLAGS 0x1000
|
||||||
|
#define NS_KEY_RESERVED4 0x0800
|
||||||
|
#define NS_KEY_RESERVED5 0x0400
|
||||||
|
#define NS_KEY_NAME_TYPE 0x0300
|
||||||
|
#define NS_KEY_NAME_USER 0x0000
|
||||||
|
#define NS_KEY_NAME_ENTITY 0x0200
|
||||||
|
#define NS_KEY_NAME_ZONE 0x0100
|
||||||
|
#define NS_KEY_NAME_RESERVED 0x0300
|
||||||
|
#define NS_KEY_RESERVED8 0x0080
|
||||||
|
#define NS_KEY_RESERVED9 0x0040
|
||||||
|
#define NS_KEY_RESERVED10 0x0020
|
||||||
|
#define NS_KEY_RESERVED11 0x0010
|
||||||
|
#define NS_KEY_SIGNATORYMASK 0x000F
|
||||||
|
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
|
||||||
|
NS_KEY_RESERVED4 | \
|
||||||
|
NS_KEY_RESERVED5 | \
|
||||||
|
NS_KEY_RESERVED8 | \
|
||||||
|
NS_KEY_RESERVED9 | \
|
||||||
|
NS_KEY_RESERVED10 | \
|
||||||
|
NS_KEY_RESERVED11 )
|
||||||
|
#define NS_KEY_RESERVED_BITMASK2 0xFFFF
|
||||||
|
#define NS_ALG_MD5RSA 1
|
||||||
|
#define NS_ALG_DH 2
|
||||||
|
#define NS_ALG_DSA 3
|
||||||
|
#define NS_ALG_DSS NS_ALG_DSA
|
||||||
|
#define NS_ALG_EXPIRE_ONLY 253
|
||||||
|
#define NS_ALG_PRIVATE_OID 254
|
||||||
|
|
||||||
|
#define NS_KEY_PROT_TLS 1
|
||||||
|
#define NS_KEY_PROT_EMAIL 2
|
||||||
|
#define NS_KEY_PROT_DNSSEC 3
|
||||||
|
#define NS_KEY_PROT_IPSEC 4
|
||||||
|
#define NS_KEY_PROT_ANY 255
|
||||||
|
|
||||||
|
#define NS_MD5RSA_MIN_BITS 512
|
||||||
|
#define NS_MD5RSA_MAX_BITS 4096
|
||||||
|
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
|
||||||
|
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
|
||||||
|
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
|
||||||
|
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
|
||||||
|
|
||||||
|
#define NS_DSA_SIG_SIZE 41
|
||||||
|
#define NS_DSA_MIN_SIZE 213
|
||||||
|
#define NS_DSA_MAX_BYTES 405
|
||||||
|
|
||||||
|
#define NS_SIG_TYPE 0
|
||||||
|
#define NS_SIG_ALG 2
|
||||||
|
#define NS_SIG_LABELS 3
|
||||||
|
#define NS_SIG_OTTL 4
|
||||||
|
#define NS_SIG_EXPIR 8
|
||||||
|
#define NS_SIG_SIGNED 12
|
||||||
|
#define NS_SIG_FOOT 16
|
||||||
|
#define NS_SIG_SIGNER 18
|
||||||
|
#define NS_NXT_BITS 8
|
||||||
|
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
|
||||||
|
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
|
||||||
|
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
|
||||||
|
#define NS_NXT_MAX 127
|
||||||
|
|
||||||
|
#define NS_OPT_DNSSEC_OK 0x8000U
|
||||||
|
#define NS_OPT_NSID 3
|
||||||
|
|
||||||
|
#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
|
||||||
|
#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
|
||||||
|
#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
|
||||||
|
#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
|
||||||
|
|
||||||
|
unsigned ns_get16(const unsigned char *);
|
||||||
|
unsigned long ns_get32(const unsigned char *);
|
||||||
|
void ns_put16(unsigned, unsigned char *);
|
||||||
|
void ns_put32(unsigned long, unsigned char *);
|
||||||
|
|
||||||
|
int ns_initparse(const unsigned char *, int, ns_msg *);
|
||||||
|
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
|
||||||
|
int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
|
||||||
|
int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
|
||||||
|
|
||||||
|
|
||||||
|
#define __BIND 19950621
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned id :16;
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
unsigned qr: 1;
|
||||||
|
unsigned opcode: 4;
|
||||||
|
unsigned aa: 1;
|
||||||
|
unsigned tc: 1;
|
||||||
|
unsigned rd: 1;
|
||||||
|
unsigned ra: 1;
|
||||||
|
unsigned unused :1;
|
||||||
|
unsigned ad: 1;
|
||||||
|
unsigned cd: 1;
|
||||||
|
unsigned rcode :4;
|
||||||
|
#else
|
||||||
|
unsigned rd :1;
|
||||||
|
unsigned tc :1;
|
||||||
|
unsigned aa :1;
|
||||||
|
unsigned opcode :4;
|
||||||
|
unsigned qr :1;
|
||||||
|
unsigned rcode :4;
|
||||||
|
unsigned cd: 1;
|
||||||
|
unsigned ad: 1;
|
||||||
|
unsigned unused :1;
|
||||||
|
unsigned ra :1;
|
||||||
|
#endif
|
||||||
|
unsigned qdcount :16;
|
||||||
|
unsigned ancount :16;
|
||||||
|
unsigned nscount :16;
|
||||||
|
unsigned arcount :16;
|
||||||
|
} HEADER;
|
||||||
|
|
||||||
|
#define PACKETSZ NS_PACKETSZ
|
||||||
|
#define MAXDNAME NS_MAXDNAME
|
||||||
|
#define MAXCDNAME NS_MAXCDNAME
|
||||||
|
#define MAXLABEL NS_MAXLABEL
|
||||||
|
#define HFIXEDSZ NS_HFIXEDSZ
|
||||||
|
#define QFIXEDSZ NS_QFIXEDSZ
|
||||||
|
#define RRFIXEDSZ NS_RRFIXEDSZ
|
||||||
|
#define INT32SZ NS_INT32SZ
|
||||||
|
#define INT16SZ NS_INT16SZ
|
||||||
|
#define INT8SZ NS_INT8SZ
|
||||||
|
#define INADDRSZ NS_INADDRSZ
|
||||||
|
#define IN6ADDRSZ NS_IN6ADDRSZ
|
||||||
|
#define INDIR_MASK NS_CMPRSFLGS
|
||||||
|
#define NAMESERVER_PORT NS_DEFAULTPORT
|
||||||
|
|
||||||
|
#define S_ZONE ns_s_zn
|
||||||
|
#define S_PREREQ ns_s_pr
|
||||||
|
#define S_UPDATE ns_s_ud
|
||||||
|
#define S_ADDT ns_s_ar
|
||||||
|
|
||||||
|
#define QUERY ns_o_query
|
||||||
|
#define IQUERY ns_o_iquery
|
||||||
|
#define STATUS ns_o_status
|
||||||
|
#define NS_NOTIFY_OP ns_o_notify
|
||||||
|
#define NS_UPDATE_OP ns_o_update
|
||||||
|
|
||||||
|
#define NOERROR ns_r_noerror
|
||||||
|
#define FORMERR ns_r_formerr
|
||||||
|
#define SERVFAIL ns_r_servfail
|
||||||
|
#define NXDOMAIN ns_r_nxdomain
|
||||||
|
#define NOTIMP ns_r_notimpl
|
||||||
|
#define REFUSED ns_r_refused
|
||||||
|
#define YXDOMAIN ns_r_yxdomain
|
||||||
|
#define YXRRSET ns_r_yxrrset
|
||||||
|
#define NXRRSET ns_r_nxrrset
|
||||||
|
#define NOTAUTH ns_r_notauth
|
||||||
|
#define NOTZONE ns_r_notzone
|
||||||
|
|
||||||
|
#define DELETE ns_uop_delete
|
||||||
|
#define ADD ns_uop_add
|
||||||
|
|
||||||
|
#define T_A ns_t_a
|
||||||
|
#define T_NS ns_t_ns
|
||||||
|
#define T_MD ns_t_md
|
||||||
|
#define T_MF ns_t_mf
|
||||||
|
#define T_CNAME ns_t_cname
|
||||||
|
#define T_SOA ns_t_soa
|
||||||
|
#define T_MB ns_t_mb
|
||||||
|
#define T_MG ns_t_mg
|
||||||
|
#define T_MR ns_t_mr
|
||||||
|
#define T_NULL ns_t_null
|
||||||
|
#define T_WKS ns_t_wks
|
||||||
|
#define T_PTR ns_t_ptr
|
||||||
|
#define T_HINFO ns_t_hinfo
|
||||||
|
#define T_MINFO ns_t_minfo
|
||||||
|
#define T_MX ns_t_mx
|
||||||
|
#define T_TXT ns_t_txt
|
||||||
|
#define T_RP ns_t_rp
|
||||||
|
#define T_AFSDB ns_t_afsdb
|
||||||
|
#define T_X25 ns_t_x25
|
||||||
|
#define T_ISDN ns_t_isdn
|
||||||
|
#define T_RT ns_t_rt
|
||||||
|
#define T_NSAP ns_t_nsap
|
||||||
|
#define T_NSAP_PTR ns_t_nsap_ptr
|
||||||
|
#define T_SIG ns_t_sig
|
||||||
|
#define T_KEY ns_t_key
|
||||||
|
#define T_PX ns_t_px
|
||||||
|
#define T_GPOS ns_t_gpos
|
||||||
|
#define T_AAAA ns_t_aaaa
|
||||||
|
#define T_LOC ns_t_loc
|
||||||
|
#define T_NXT ns_t_nxt
|
||||||
|
#define T_EID ns_t_eid
|
||||||
|
#define T_NIMLOC ns_t_nimloc
|
||||||
|
#define T_SRV ns_t_srv
|
||||||
|
#define T_ATMA ns_t_atma
|
||||||
|
#define T_NAPTR ns_t_naptr
|
||||||
|
#define T_A6 ns_t_a6
|
||||||
|
#define T_DNAME ns_t_dname
|
||||||
|
#define T_TSIG ns_t_tsig
|
||||||
|
#define T_IXFR ns_t_ixfr
|
||||||
|
#define T_AXFR ns_t_axfr
|
||||||
|
#define T_MAILB ns_t_mailb
|
||||||
|
#define T_MAILA ns_t_maila
|
||||||
|
#define T_ANY ns_t_any
|
||||||
|
|
||||||
|
#define C_IN ns_c_in
|
||||||
|
#define C_CHAOS ns_c_chaos
|
||||||
|
#define C_HS ns_c_hs
|
||||||
|
#define C_NONE ns_c_none
|
||||||
|
#define C_ANY ns_c_any
|
||||||
|
|
||||||
|
#define GETSHORT NS_GET16
|
||||||
|
#define GETLONG NS_GET32
|
||||||
|
#define PUTSHORT NS_PUT16
|
||||||
|
#define PUTLONG NS_PUT32
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_NAMESER_H_ */
|
201
third_party/musl/ns_parse.c
vendored
Normal file
201
third_party/musl/ns_parse.c
vendored
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
#include "third_party/musl/nameser.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
const struct _ns_flagdata _ns_flagdata[16] = {
|
||||||
|
{ 0x8000, 15 },
|
||||||
|
{ 0x7800, 11 },
|
||||||
|
{ 0x0400, 10 },
|
||||||
|
{ 0x0200, 9 },
|
||||||
|
{ 0x0100, 8 },
|
||||||
|
{ 0x0080, 7 },
|
||||||
|
{ 0x0040, 6 },
|
||||||
|
{ 0x0020, 5 },
|
||||||
|
{ 0x0010, 4 },
|
||||||
|
{ 0x000f, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
{ 0x0000, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned ns_get16(const unsigned char *cp)
|
||||||
|
{
|
||||||
|
return cp[0]<<8 | cp[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ns_get32(const unsigned char *cp)
|
||||||
|
{
|
||||||
|
return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ns_put16(unsigned s, unsigned char *cp)
|
||||||
|
{
|
||||||
|
*cp++ = s>>8;
|
||||||
|
*cp++ = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ns_put32(unsigned long l, unsigned char *cp)
|
||||||
|
{
|
||||||
|
*cp++ = l>>24;
|
||||||
|
*cp++ = l>>16;
|
||||||
|
*cp++ = l>>8;
|
||||||
|
*cp++ = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
|
||||||
|
{
|
||||||
|
int i, r;
|
||||||
|
|
||||||
|
handle->_msg = msg;
|
||||||
|
handle->_eom = msg + msglen;
|
||||||
|
if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
|
||||||
|
NS_GET16(handle->_id, msg);
|
||||||
|
NS_GET16(handle->_flags, msg);
|
||||||
|
for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
|
||||||
|
for (i = 0; i < ns_s_max; i++) {
|
||||||
|
if (handle->_counts[i]) {
|
||||||
|
handle->_sections[i] = msg;
|
||||||
|
r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
|
||||||
|
if (r < 0) return -1;
|
||||||
|
msg += r;
|
||||||
|
} else {
|
||||||
|
handle->_sections[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (msg != handle->_eom) goto bad;
|
||||||
|
handle->_sect = ns_s_max;
|
||||||
|
handle->_rrnum = -1;
|
||||||
|
handle->_msg_ptr = NULL;
|
||||||
|
return 0;
|
||||||
|
bad:
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
|
||||||
|
{
|
||||||
|
const unsigned char *p = ptr;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
while (count--) {
|
||||||
|
r = dn_skipname(p, eom);
|
||||||
|
if (r < 0) goto bad;
|
||||||
|
if (r + 2 * NS_INT16SZ > eom - p) goto bad;
|
||||||
|
p += r + 2 * NS_INT16SZ;
|
||||||
|
if (section != ns_s_qd) {
|
||||||
|
if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
|
||||||
|
p += NS_INT32SZ;
|
||||||
|
NS_GET16(r, p);
|
||||||
|
if (r > eom - p) goto bad;
|
||||||
|
p += r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p - ptr;
|
||||||
|
bad:
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (section < 0 || section >= ns_s_max) goto bad;
|
||||||
|
if (section != handle->_sect) {
|
||||||
|
handle->_sect = section;
|
||||||
|
handle->_rrnum = 0;
|
||||||
|
handle->_msg_ptr = handle->_sections[section];
|
||||||
|
}
|
||||||
|
if (rrnum == -1) rrnum = handle->_rrnum;
|
||||||
|
if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
|
||||||
|
if (rrnum < handle->_rrnum) {
|
||||||
|
handle->_rrnum = 0;
|
||||||
|
handle->_msg_ptr = handle->_sections[section];
|
||||||
|
}
|
||||||
|
if (rrnum > handle->_rrnum) {
|
||||||
|
r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
|
||||||
|
if (r < 0) return -1;
|
||||||
|
handle->_msg_ptr += r;
|
||||||
|
handle->_rrnum = rrnum;
|
||||||
|
}
|
||||||
|
r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
|
||||||
|
if (r < 0) return -1;
|
||||||
|
handle->_msg_ptr += r;
|
||||||
|
if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
|
||||||
|
NS_GET16(rr->type, handle->_msg_ptr);
|
||||||
|
NS_GET16(rr->rr_class, handle->_msg_ptr);
|
||||||
|
if (section != ns_s_qd) {
|
||||||
|
if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
|
||||||
|
NS_GET32(rr->ttl, handle->_msg_ptr);
|
||||||
|
NS_GET16(rr->rdlength, handle->_msg_ptr);
|
||||||
|
if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
|
||||||
|
rr->rdata = handle->_msg_ptr;
|
||||||
|
handle->_msg_ptr += rr->rdlength;
|
||||||
|
} else {
|
||||||
|
rr->ttl = 0;
|
||||||
|
rr->rdlength = 0;
|
||||||
|
rr->rdata = NULL;
|
||||||
|
}
|
||||||
|
handle->_rrnum++;
|
||||||
|
if (handle->_rrnum > handle->_counts[section]) {
|
||||||
|
handle->_sect = section + 1;
|
||||||
|
if (handle->_sect == ns_s_max) {
|
||||||
|
handle->_rrnum = -1;
|
||||||
|
handle->_msg_ptr = NULL;
|
||||||
|
} else {
|
||||||
|
handle->_rrnum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
bad:
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
size:
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
|
||||||
|
const unsigned char *src, char *dst, size_t dstsiz)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = dn_expand(msg, eom, src, dst, dstsiz);
|
||||||
|
if (r < 0) errno = EMSGSIZE;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
6
third_party/musl/res_init.c
vendored
Normal file
6
third_party/musl/res_init.c
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
|
||||||
|
int res_init()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
78
third_party/musl/res_mkquery.c
vendored
Normal file
78
third_party/musl/res_mkquery.c
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/struct/timespec.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/clock.h"
|
||||||
|
#include "third_party/musl/resolv.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int __res_mkquery(int op, const char *dname, int class, int type,
|
||||||
|
const unsigned char *data, int datalen,
|
||||||
|
const unsigned char *newrr, unsigned char *buf, int buflen)
|
||||||
|
{
|
||||||
|
int id, i, j;
|
||||||
|
unsigned char q[280];
|
||||||
|
struct timespec ts;
|
||||||
|
size_t l = strnlen(dname, 255);
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (l && dname[l-1]=='.') l--;
|
||||||
|
if (l && dname[l-1]=='.') return -1;
|
||||||
|
n = 17+l+!!l;
|
||||||
|
if (l>253 || buflen<n || op>15u || class>255u || type>255u)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Construct query template - ID will be filled later */
|
||||||
|
memset(q, 0, n);
|
||||||
|
q[2] = op*8 + 1;
|
||||||
|
q[3] = 32; /* AD */
|
||||||
|
q[5] = 1;
|
||||||
|
memcpy((char *)q+13, dname, l);
|
||||||
|
for (i=13; q[i]; i=j+1) {
|
||||||
|
for (j=i; q[j] && q[j] != '.'; j++);
|
||||||
|
if (j-i-1u > 62u) return -1;
|
||||||
|
q[i-1] = j-i;
|
||||||
|
}
|
||||||
|
q[i+1] = type;
|
||||||
|
q[i+3] = class;
|
||||||
|
|
||||||
|
/* Make a reasonably unpredictable id */
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
id = (ts.tv_nsec + ts.tv_nsec/65536UL) & 0xffff;
|
||||||
|
q[0] = id/256;
|
||||||
|
q[1] = id;
|
||||||
|
|
||||||
|
memcpy(buf, q, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak_reference(__res_mkquery, res_mkquery);
|
363
third_party/musl/res_msend.c
vendored
Normal file
363
third_party/musl/res_msend.c
vendored
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/sock/struct/pollfd.h"
|
||||||
|
#include "libc/calls/struct/timespec.h"
|
||||||
|
#include "libc/sysv/consts/clock.h"
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/sock/struct/msghdr.h"
|
||||||
|
#include "libc/sysv/consts/poll.h"
|
||||||
|
#include "libc/sysv/consts/tcp.h"
|
||||||
|
#include "libc/sysv/consts/msg.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "libc/thread/thread.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/calls/weirdtypes.h"
|
||||||
|
#include "libc/sysv/consts/sock.h"
|
||||||
|
#include "libc/sysv/consts/ipproto.h"
|
||||||
|
#include "libc/sysv/consts/ipv6.h"
|
||||||
|
#include "lookup.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
static void cleanup(void *p)
|
||||||
|
{
|
||||||
|
struct pollfd *pfd = p;
|
||||||
|
for (int i=0; pfd[i].fd >= -1; i++)
|
||||||
|
if (pfd[i].fd >= 0)
|
||||||
|
close(pfd[i].fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long mtime()
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0 && errno == ENOSYS)
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
return (unsigned long)ts.tv_sec * 1000
|
||||||
|
+ ts.tv_nsec / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int start_tcp(struct pollfd *pfd, int family, const void *sa, socklen_t sl, const unsigned char *q, int ql)
|
||||||
|
{
|
||||||
|
struct msghdr mh = {
|
||||||
|
.msg_name = (void *)sa,
|
||||||
|
.msg_namelen = sl,
|
||||||
|
.msg_iovlen = 2,
|
||||||
|
.msg_iov = (struct iovec [2]){
|
||||||
|
{ .iov_base = (uint8_t[]){ ql>>8, ql }, .iov_len = 2 },
|
||||||
|
{ .iov_base = (void *)q, .iov_len = ql } }
|
||||||
|
};
|
||||||
|
int r;
|
||||||
|
int fd = socket(family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||||
|
pfd->fd = fd;
|
||||||
|
pfd->events = POLLOUT;
|
||||||
|
if (!setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
|
||||||
|
&(int){1}, sizeof(int))) {
|
||||||
|
r = sendmsg(fd, &mh, MSG_FASTOPEN|MSG_NOSIGNAL);
|
||||||
|
if (r == ql+2) pfd->events = POLLIN;
|
||||||
|
if (r >= 0) return r;
|
||||||
|
if (errno == EINPROGRESS) return 0;
|
||||||
|
}
|
||||||
|
r = connect(fd, sa, sl);
|
||||||
|
if (!r || errno == EINPROGRESS) return 0;
|
||||||
|
close(fd);
|
||||||
|
pfd->fd = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void step_mh(struct msghdr *mh, size_t n)
|
||||||
|
{
|
||||||
|
/* Adjust iovec in msghdr to skip first n bytes. */
|
||||||
|
while (mh->msg_iovlen && n >= mh->msg_iov->iov_len) {
|
||||||
|
n -= mh->msg_iov->iov_len;
|
||||||
|
mh->msg_iov++;
|
||||||
|
mh->msg_iovlen--;
|
||||||
|
}
|
||||||
|
if (!mh->msg_iovlen) return;
|
||||||
|
mh->msg_iov->iov_base = (char *)mh->msg_iov->iov_base + n;
|
||||||
|
mh->msg_iov->iov_len -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal contract for __res_msend[_rc]: asize must be >=512, nqueries
|
||||||
|
* must be sufficiently small to be safe as VLA size. In practice it's
|
||||||
|
* either 1 or 2, anyway. */
|
||||||
|
|
||||||
|
int __res_msend_rc(int nqueries, const unsigned char *const *queries,
|
||||||
|
const int *qlens, unsigned char *const *answers, int *alens, int asize,
|
||||||
|
const struct resolvconf *conf)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int timeout, attempts, retry_interval, servfail_retry = 0;
|
||||||
|
union {
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
} sa = {0}, ns[MAXNS] = {0};
|
||||||
|
socklen_t sl = sizeof sa.sin;
|
||||||
|
int nns = 0;
|
||||||
|
int family = AF_INET;
|
||||||
|
int rlen;
|
||||||
|
int next;
|
||||||
|
int i, j;
|
||||||
|
int cs;
|
||||||
|
struct pollfd pfd[nqueries+2];
|
||||||
|
int qpos[nqueries], apos[nqueries];
|
||||||
|
unsigned char alen_buf[nqueries][2];
|
||||||
|
int r;
|
||||||
|
unsigned long t0, t1, t2;
|
||||||
|
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||||
|
|
||||||
|
timeout = 1000*conf->timeout;
|
||||||
|
attempts = conf->attempts;
|
||||||
|
|
||||||
|
for (nns=0; nns<conf->nns; nns++) {
|
||||||
|
const struct address *iplit = &conf->ns[nns];
|
||||||
|
if (iplit->family == AF_INET) {
|
||||||
|
memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
|
||||||
|
ns[nns].sin.sin_port = htons(53);
|
||||||
|
ns[nns].sin.sin_family = AF_INET;
|
||||||
|
} else {
|
||||||
|
sl = sizeof sa.sin6;
|
||||||
|
memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
|
||||||
|
ns[nns].sin6.sin6_port = htons(53);
|
||||||
|
ns[nns].sin6.sin6_scope_id = iplit->scopeid;
|
||||||
|
ns[nns].sin6.sin6_family = family = AF_INET6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get local address and open/bind a socket */
|
||||||
|
fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||||
|
|
||||||
|
/* Handle case where system lacks IPv6 support */
|
||||||
|
if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
|
||||||
|
for (i=0; i<nns && conf->ns[nns].family == AF_INET6; i++);
|
||||||
|
if (i==nns) {
|
||||||
|
pthread_setcancelstate(cs, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||||
|
family = AF_INET;
|
||||||
|
sl = sizeof sa.sin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert any IPv4 addresses in a mixed environment to v4-mapped */
|
||||||
|
if (fd >= 0 && family == AF_INET6) {
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
|
||||||
|
for (i=0; i<nns; i++) {
|
||||||
|
if (ns[i].sin.sin_family != AF_INET) continue;
|
||||||
|
memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
|
||||||
|
&ns[i].sin.sin_addr, 4);
|
||||||
|
memcpy(ns[i].sin6.sin6_addr.s6_addr,
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
|
||||||
|
ns[i].sin6.sin6_family = AF_INET6;
|
||||||
|
ns[i].sin6.sin6_flowinfo = 0;
|
||||||
|
ns[i].sin6.sin6_scope_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.sin.sin_family = family;
|
||||||
|
if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {
|
||||||
|
if (fd >= 0) close(fd);
|
||||||
|
pthread_setcancelstate(cs, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Past this point, there are no errors. Each individual query will
|
||||||
|
* yield either no reply (indicated by zero length) or an answer
|
||||||
|
* packet which is up to the caller to interpret. */
|
||||||
|
|
||||||
|
for (i=0; i<nqueries; i++) pfd[i].fd = -1;
|
||||||
|
pfd[nqueries].fd = fd;
|
||||||
|
pfd[nqueries].events = POLLIN;
|
||||||
|
pfd[nqueries+1].fd = -2;
|
||||||
|
|
||||||
|
pthread_cleanup_push(cleanup, pfd);
|
||||||
|
pthread_setcancelstate(cs, 0);
|
||||||
|
|
||||||
|
memset(alens, 0, sizeof *alens * nqueries);
|
||||||
|
|
||||||
|
retry_interval = timeout / attempts;
|
||||||
|
next = 0;
|
||||||
|
t0 = t2 = mtime();
|
||||||
|
t1 = t2 - retry_interval;
|
||||||
|
|
||||||
|
for (; t2-t0 < timeout; t2=mtime()) {
|
||||||
|
/* This is the loop exit condition: that all queries
|
||||||
|
* have an accepted answer. */
|
||||||
|
for (i=0; i<nqueries && alens[i]>0; i++);
|
||||||
|
if (i==nqueries) break;
|
||||||
|
|
||||||
|
if (t2-t1 >= retry_interval) {
|
||||||
|
/* Query all configured namservers in parallel */
|
||||||
|
for (i=0; i<nqueries; i++)
|
||||||
|
if (!alens[i])
|
||||||
|
for (j=0; j<nns; j++)
|
||||||
|
sendto(fd, queries[i],
|
||||||
|
qlens[i], MSG_NOSIGNAL,
|
||||||
|
(void *)&ns[j], sl);
|
||||||
|
t1 = t2;
|
||||||
|
servfail_retry = 2 * nqueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a response, or until time to retry */
|
||||||
|
if (poll(pfd, nqueries+1, t1+retry_interval-t2) <= 0) continue;
|
||||||
|
|
||||||
|
while (next < nqueries) {
|
||||||
|
struct msghdr mh = {
|
||||||
|
.msg_name = (void *)&sa,
|
||||||
|
.msg_namelen = sl,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
.msg_iov = (struct iovec []){
|
||||||
|
{ .iov_base = (void *)answers[next],
|
||||||
|
.iov_len = asize }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
rlen = recvmsg(fd, &mh, 0);
|
||||||
|
if (rlen < 0) break;
|
||||||
|
|
||||||
|
/* Ignore non-identifiable packets */
|
||||||
|
if (rlen < 4) continue;
|
||||||
|
|
||||||
|
/* Ignore replies from addresses we didn't send to */
|
||||||
|
for (j=0; j<nns && memcmp(ns+j, &sa, sl); j++);
|
||||||
|
if (j==nns) continue;
|
||||||
|
|
||||||
|
/* Find which query this answer goes with, if any */
|
||||||
|
for (i=next; i<nqueries && (
|
||||||
|
answers[next][0] != queries[i][0] ||
|
||||||
|
answers[next][1] != queries[i][1] ); i++);
|
||||||
|
if (i==nqueries) continue;
|
||||||
|
if (alens[i]) continue;
|
||||||
|
|
||||||
|
/* Only accept positive or negative responses;
|
||||||
|
* retry immediately on server failure, and ignore
|
||||||
|
* all other codes such as refusal. */
|
||||||
|
switch (answers[next][3] & 15) {
|
||||||
|
case 0:
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (servfail_retry && servfail_retry--)
|
||||||
|
sendto(fd, queries[i],
|
||||||
|
qlens[i], MSG_NOSIGNAL,
|
||||||
|
(void *)&ns[j], sl);
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store answer in the right slot, or update next
|
||||||
|
* available temp slot if it's already in place. */
|
||||||
|
alens[i] = rlen;
|
||||||
|
if (i == next)
|
||||||
|
for (; next<nqueries && alens[next]; next++);
|
||||||
|
else
|
||||||
|
memcpy(answers[i], answers[next], rlen);
|
||||||
|
|
||||||
|
/* Ignore further UDP if all slots full or TCP-mode */
|
||||||
|
if (next == nqueries) pfd[nqueries].events = 0;
|
||||||
|
|
||||||
|
/* If answer is truncated (TC bit), fallback to TCP */
|
||||||
|
if ((answers[i][2] & 2) || (mh.msg_flags & MSG_TRUNC)) {
|
||||||
|
alens[i] = -1;
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
|
||||||
|
r = start_tcp(pfd+i, family, ns+j, sl, queries[i], qlens[i]);
|
||||||
|
pthread_setcancelstate(cs, 0);
|
||||||
|
if (r >= 0) {
|
||||||
|
qpos[i] = r;
|
||||||
|
apos[i] = 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<nqueries; i++) {
|
||||||
|
if (pfd[i].revents & POLLOUT) {
|
||||||
|
struct msghdr mh = {
|
||||||
|
.msg_iovlen = 2,
|
||||||
|
.msg_iov = (struct iovec [2]){
|
||||||
|
{ .iov_base = (uint8_t[]){ qlens[i]>>8, qlens[i] }, .iov_len = 2 },
|
||||||
|
{ .iov_base = (void *)queries[i], .iov_len = qlens[i] } }
|
||||||
|
};
|
||||||
|
step_mh(&mh, qpos[i]);
|
||||||
|
r = sendmsg(pfd[i].fd, &mh, MSG_NOSIGNAL);
|
||||||
|
if (r < 0) goto out;
|
||||||
|
qpos[i] += r;
|
||||||
|
if (qpos[i] == qlens[i]+2)
|
||||||
|
pfd[i].events = POLLIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<nqueries; i++) {
|
||||||
|
if (pfd[i].revents & POLLIN) {
|
||||||
|
struct msghdr mh = {
|
||||||
|
.msg_iovlen = 2,
|
||||||
|
.msg_iov = (struct iovec [2]){
|
||||||
|
{ .iov_base = alen_buf[i], .iov_len = 2 },
|
||||||
|
{ .iov_base = answers[i], .iov_len = asize } }
|
||||||
|
};
|
||||||
|
step_mh(&mh, apos[i]);
|
||||||
|
r = recvmsg(pfd[i].fd, &mh, 0);
|
||||||
|
if (r <= 0) goto out;
|
||||||
|
apos[i] += r;
|
||||||
|
if (apos[i] < 2) continue;
|
||||||
|
int alen = alen_buf[i][0]*256 + alen_buf[i][1];
|
||||||
|
if (alen < 13) goto out;
|
||||||
|
if (apos[i] < alen+2 && apos[i] < asize+2)
|
||||||
|
continue;
|
||||||
|
int rcode = answers[i][3] & 15;
|
||||||
|
if (rcode != 0 && rcode != 3)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Storing the length here commits the accepted answer.
|
||||||
|
* Immediately close TCP socket so as not to consume
|
||||||
|
* resources we no longer need. */
|
||||||
|
alens[i] = alen;
|
||||||
|
close(pfd[i].fd);
|
||||||
|
pfd[i].fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
pthread_cleanup_pop(1);
|
||||||
|
|
||||||
|
/* Disregard any incomplete TCP results */
|
||||||
|
for (i=0; i<nqueries; i++) if (alens[i]<0) alens[i] = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __res_msend(int nqueries, const unsigned char *const *queries,
|
||||||
|
const int *qlens, unsigned char *const *answers, int *alens, int asize)
|
||||||
|
{
|
||||||
|
struct resolvconf conf;
|
||||||
|
if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
|
||||||
|
return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
|
||||||
|
}
|
58
third_party/musl/res_query.c
vendored
Normal file
58
third_party/musl/res_query.c
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dns/ent.h"
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
#include "third_party/musl/resolv.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int res_query(const char *name, int class, int type, unsigned char *dest, int len)
|
||||||
|
{
|
||||||
|
unsigned char q[280];
|
||||||
|
int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
|
||||||
|
if (ql < 0) return ql;
|
||||||
|
int r = __res_send(q, ql, dest, len);
|
||||||
|
if (r<12) {
|
||||||
|
h_errno = TRY_AGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((dest[3] & 15) == 3) {
|
||||||
|
h_errno = HOST_NOT_FOUND;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((dest[3] & 15) == 0 && !dest[6] && !dest[7]) {
|
||||||
|
h_errno = NO_DATA;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak_reference(res_query, res_search);
|
46
third_party/musl/res_querydomain.c
vendored
Normal file
46
third_party/musl/res_querydomain.c
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *dest, int len)
|
||||||
|
{
|
||||||
|
char tmp[255];
|
||||||
|
size_t nl = strnlen(name, 255);
|
||||||
|
size_t dl = strnlen(domain, 255);
|
||||||
|
if (nl+dl+1 > 254) return -1;
|
||||||
|
memcpy(tmp, name, nl);
|
||||||
|
tmp[nl] = '.';
|
||||||
|
memcpy(tmp+nl+1, domain, dl+1);
|
||||||
|
return res_query(tmp, class, type, dest, len);
|
||||||
|
}
|
49
third_party/musl/res_send.c
vendored
Normal file
49
third_party/musl/res_send.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "third_party/musl/resolv.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, int anslen)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if (anslen < 512) {
|
||||||
|
unsigned char buf[512];
|
||||||
|
r = __res_send(msg, msglen, buf, sizeof buf);
|
||||||
|
if (r >= 0) memcpy(answer, buf, r < anslen ? r : anslen);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
|
||||||
|
return r<0 || !anslen ? -1 : anslen;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak_reference(__res_send, res_send);
|
9
third_party/musl/res_state.c
vendored
Normal file
9
third_party/musl/res_state.c
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
|
||||||
|
/* This is completely unused, and exists purely to satisfy broken apps. */
|
||||||
|
|
||||||
|
struct __res_state *__res_state()
|
||||||
|
{
|
||||||
|
static struct __res_state res;
|
||||||
|
return &res;
|
||||||
|
}
|
134
third_party/musl/resolv.h
vendored
Normal file
134
third_party/musl/resolv.h
vendored
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_H_
|
||||||
|
#include "libc/sock/struct/sockaddr6.h"
|
||||||
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define MAXNS 3
|
||||||
|
#define MAXDFLSRCH 3
|
||||||
|
#define MAXDNSRCH 6
|
||||||
|
#define LOCALDOMAINPARTS 2
|
||||||
|
|
||||||
|
#define RES_TIMEOUT 5
|
||||||
|
#define MAXRESOLVSORT 10
|
||||||
|
#define RES_MAXNDOTS 15
|
||||||
|
#define RES_MAXRETRANS 30
|
||||||
|
#define RES_MAXRETRY 5
|
||||||
|
#define RES_DFLRETRY 2
|
||||||
|
#define RES_MAXTIME 65535
|
||||||
|
|
||||||
|
/* unused; purely for broken apps */
|
||||||
|
typedef struct __res_state {
|
||||||
|
int retrans;
|
||||||
|
int retry;
|
||||||
|
unsigned long options;
|
||||||
|
int nscount;
|
||||||
|
struct sockaddr_in nsaddr_list[MAXNS];
|
||||||
|
# define nsaddr nsaddr_list[0]
|
||||||
|
unsigned short id;
|
||||||
|
char *dnsrch[MAXDNSRCH+1];
|
||||||
|
char defdname[256];
|
||||||
|
unsigned long pfcode;
|
||||||
|
unsigned ndots:4;
|
||||||
|
unsigned nsort:4;
|
||||||
|
unsigned ipv6_unavail:1;
|
||||||
|
unsigned unused:23;
|
||||||
|
struct {
|
||||||
|
struct in_addr addr;
|
||||||
|
uint32_t mask;
|
||||||
|
} sort_list[MAXRESOLVSORT];
|
||||||
|
void *qhook;
|
||||||
|
void *rhook;
|
||||||
|
int res_h_errno;
|
||||||
|
int _vcsock;
|
||||||
|
unsigned _flags;
|
||||||
|
union {
|
||||||
|
char pad[52];
|
||||||
|
struct {
|
||||||
|
uint16_t nscount;
|
||||||
|
uint16_t nsmap[MAXNS];
|
||||||
|
int nssocks[MAXNS];
|
||||||
|
uint16_t nscount6;
|
||||||
|
uint16_t nsinit;
|
||||||
|
struct sockaddr_in6 *nsaddrs[MAXNS];
|
||||||
|
unsigned int _initstamp[2];
|
||||||
|
} _ext;
|
||||||
|
} _u;
|
||||||
|
} *res_state;
|
||||||
|
|
||||||
|
#define __RES 19960801
|
||||||
|
|
||||||
|
#ifndef _PATH_RESCONF
|
||||||
|
#define _PATH_RESCONF "/etc/resolv.conf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct res_sym {
|
||||||
|
int number;
|
||||||
|
char *name;
|
||||||
|
char *humanname;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RES_F_VC 0x00000001
|
||||||
|
#define RES_F_CONN 0x00000002
|
||||||
|
#define RES_F_EDNS0ERR 0x00000004
|
||||||
|
|
||||||
|
#define RES_EXHAUSTIVE 0x00000001
|
||||||
|
|
||||||
|
#define RES_INIT 0x00000001
|
||||||
|
#define RES_DEBUG 0x00000002
|
||||||
|
#define RES_AAONLY 0x00000004
|
||||||
|
#define RES_USEVC 0x00000008
|
||||||
|
#define RES_PRIMARY 0x00000010
|
||||||
|
#define RES_IGNTC 0x00000020
|
||||||
|
#define RES_RECURSE 0x00000040
|
||||||
|
#define RES_DEFNAMES 0x00000080
|
||||||
|
#define RES_STAYOPEN 0x00000100
|
||||||
|
#define RES_DNSRCH 0x00000200
|
||||||
|
#define RES_INSECURE1 0x00000400
|
||||||
|
#define RES_INSECURE2 0x00000800
|
||||||
|
#define RES_NOALIASES 0x00001000
|
||||||
|
#define RES_USE_INET6 0x00002000
|
||||||
|
#define RES_ROTATE 0x00004000
|
||||||
|
#define RES_NOCHECKNAME 0x00008000
|
||||||
|
#define RES_KEEPTSIG 0x00010000
|
||||||
|
#define RES_BLAST 0x00020000
|
||||||
|
#define RES_USEBSTRING 0x00040000
|
||||||
|
#define RES_NOIP6DOTINT 0x00080000
|
||||||
|
#define RES_USE_EDNS0 0x00100000
|
||||||
|
#define RES_SNGLKUP 0x00200000
|
||||||
|
#define RES_SNGLKUPREOP 0x00400000
|
||||||
|
#define RES_USE_DNSSEC 0x00800000
|
||||||
|
|
||||||
|
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
|
||||||
|
|
||||||
|
#define RES_PRF_STATS 0x00000001
|
||||||
|
#define RES_PRF_UPDATE 0x00000002
|
||||||
|
#define RES_PRF_CLASS 0x00000004
|
||||||
|
#define RES_PRF_CMD 0x00000008
|
||||||
|
#define RES_PRF_QUES 0x00000010
|
||||||
|
#define RES_PRF_ANS 0x00000020
|
||||||
|
#define RES_PRF_AUTH 0x00000040
|
||||||
|
#define RES_PRF_ADD 0x00000080
|
||||||
|
#define RES_PRF_HEAD1 0x00000100
|
||||||
|
#define RES_PRF_HEAD2 0x00000200
|
||||||
|
#define RES_PRF_TTLID 0x00000400
|
||||||
|
#define RES_PRF_HEADX 0x00000800
|
||||||
|
#define RES_PRF_QUERY 0x00001000
|
||||||
|
#define RES_PRF_REPLY 0x00002000
|
||||||
|
#define RES_PRF_INIT 0x00004000
|
||||||
|
|
||||||
|
struct __res_state *__res_state(void);
|
||||||
|
#define _res (*__res_state())
|
||||||
|
|
||||||
|
int res_init(void);
|
||||||
|
int res_query(const char *, int, int, unsigned char *, int);
|
||||||
|
int res_querydomain(const char *, const char *, int, int, unsigned char *, int);
|
||||||
|
int res_search(const char *, int, int, unsigned char *, int);
|
||||||
|
int res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
|
||||||
|
int res_send(const unsigned char *, int, unsigned char *, int);
|
||||||
|
int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **);
|
||||||
|
int dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
|
||||||
|
int dn_skipname(const unsigned char *, const unsigned char *);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_H_ */
|
11
third_party/musl/resolv.internal.h
vendored
Normal file
11
third_party/musl/resolv.internal.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_INTERNAL_H_
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
|
||||||
|
int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
|
||||||
|
int __res_send(const unsigned char *, int, unsigned char *, int);
|
||||||
|
int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_RESOLV_INTERNAL_H_ */
|
196
third_party/musl/resolvconf.c
vendored
Normal file
196
third_party/musl/resolvconf.c
vendored
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│ vi: set noet ft=c ts=8 tw=8 fenc=utf-8 :vi │
|
||||||
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
│ │
|
||||||
|
│ Musl Libc │
|
||||||
|
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||||
|
│ │
|
||||||
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/syscall_support-nt.internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "libc/nt/enum/keyaccess.h"
|
||||||
|
#include "libc/nt/enum/reggetvalueflags.h"
|
||||||
|
#include "libc/nt/registry.h"
|
||||||
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/stdio/internal.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "third_party/musl/lookup.internal.h"
|
||||||
|
|
||||||
|
asm(".ident\t\"\\n\\n\
|
||||||
|
Musl libc (MIT License)\\n\
|
||||||
|
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
|
|
||||||
|
// TODO(jart): ipv6 nameservers on windows
|
||||||
|
// TODO(jart): can we polyfill `search` on windows
|
||||||
|
static dontinline textwindows int __get_resolv_conf_nt(struct resolvconf *conf)
|
||||||
|
{
|
||||||
|
int64_t hkInterfaces;
|
||||||
|
uint32_t i, keycount;
|
||||||
|
|
||||||
|
if (RegOpenKeyEx(
|
||||||
|
kNtHkeyLocalMachine,
|
||||||
|
u"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
|
||||||
|
0, kNtKeyRead, &hkInterfaces)) {
|
||||||
|
return __winerr();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegQueryInfoKey(hkInterfaces, 0, 0, 0, &keycount, 0, 0, 0, 0, 0, 0, 0)) {
|
||||||
|
RegCloseKey(hkInterfaces);
|
||||||
|
return __winerr();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < keycount; ++i) {
|
||||||
|
char value8[128];
|
||||||
|
uint32_t valuebytes, uuidlen;
|
||||||
|
char16_t value[128], uuid[64];
|
||||||
|
uuidlen = sizeof(uuid);
|
||||||
|
if (!RegEnumKeyEx(hkInterfaces, i, uuid, &uuidlen, 0, 0, 0, 0) &&
|
||||||
|
((!RegGetValue(hkInterfaces, uuid, u"DhcpIpAddress",
|
||||||
|
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||||
|
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||||
|
valuebytes > 2 * sizeof(char16_t)) ||
|
||||||
|
(!RegGetValue(hkInterfaces, uuid, u"IpAddress",
|
||||||
|
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||||
|
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||||
|
valuebytes > 2 * sizeof(char16_t))) &&
|
||||||
|
((!RegGetValue(hkInterfaces, uuid, u"DhcpNameServer",
|
||||||
|
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||||
|
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||||
|
valuebytes > 2 * sizeof(char16_t)) ||
|
||||||
|
(!RegGetValue(hkInterfaces, uuid, u"NameServer",
|
||||||
|
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||||
|
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||||
|
valuebytes > 2 * sizeof(char16_t)))) {
|
||||||
|
char *state, *addr, *tmp;
|
||||||
|
tprecode16to8(value8, sizeof(value8), value);
|
||||||
|
tmp = value8;
|
||||||
|
while ((addr = strtok_r(tmp, ", ", &state))) {
|
||||||
|
uint32_t ip;
|
||||||
|
if (inet_pton(AF_INET, addr, &ip) == 1) {
|
||||||
|
if (conf->nns < MAXNS) {
|
||||||
|
conf->ns[conf->nns].family = AF_INET;
|
||||||
|
conf->ns[conf->nns].scopeid = 0;
|
||||||
|
memcpy(conf->ns[conf->nns].addr, &ip, 4);
|
||||||
|
++conf->nns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkInterfaces);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int nns = 0;
|
||||||
|
char line[256];
|
||||||
|
|
||||||
|
conf->ndots = 1;
|
||||||
|
conf->timeout = 5;
|
||||||
|
conf->attempts = 2;
|
||||||
|
if (search) *search = 0;
|
||||||
|
|
||||||
|
f = fopen("/etc/resolv.conf", "rb");
|
||||||
|
if (!f) {
|
||||||
|
if (errno == ENOENT ||
|
||||||
|
errno == ENOTDIR ||
|
||||||
|
errno == EACCES) {
|
||||||
|
if (IsWindows())
|
||||||
|
return __get_resolv_conf_nt(conf);
|
||||||
|
goto no_resolv_conf;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(line, sizeof line, f)) {
|
||||||
|
char *p, *z;
|
||||||
|
if (!strchr(line, '\n') && !feof(f)) {
|
||||||
|
/* Ignore lines that get truncated rather than
|
||||||
|
* potentially misinterpreting them. */
|
||||||
|
int c;
|
||||||
|
do c = getc(f);
|
||||||
|
while (c != '\n' && c != EOF);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line, "options", 7) && isspace(line[7])) {
|
||||||
|
p = strstr(line, "ndots:");
|
||||||
|
if (p && isdigit(p[6])) {
|
||||||
|
p += 6;
|
||||||
|
unsigned long x = strtoul(p, &z, 10);
|
||||||
|
if (z != p) conf->ndots = x > 15 ? 15 : x;
|
||||||
|
}
|
||||||
|
p = strstr(line, "attempts:");
|
||||||
|
if (p && isdigit(p[9])) {
|
||||||
|
p += 9;
|
||||||
|
unsigned long x = strtoul(p, &z, 10);
|
||||||
|
if (z != p) conf->attempts = x > 10 ? 10 : x;
|
||||||
|
}
|
||||||
|
p = strstr(line, "timeout:");
|
||||||
|
if (p && (isdigit(p[8]) || p[8]=='.')) {
|
||||||
|
p += 8;
|
||||||
|
unsigned long x = strtoul(p, &z, 10);
|
||||||
|
if (z != p) conf->timeout = x > 60 ? 60 : x;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
|
||||||
|
if (nns >= MAXNS) continue;
|
||||||
|
for (p=line+11; isspace(*p); p++);
|
||||||
|
for (z=p; *z && !isspace(*z); z++);
|
||||||
|
*z=0;
|
||||||
|
if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
|
||||||
|
nns++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!search) continue;
|
||||||
|
if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
|
||||||
|
|| !isspace(line[6]))
|
||||||
|
continue;
|
||||||
|
for (p=line+7; isspace(*p); p++);
|
||||||
|
size_t l = strlen(p);
|
||||||
|
/* This can never happen anyway with chosen buffer sizes. */
|
||||||
|
if (l >= search_sz) continue;
|
||||||
|
memcpy(search, p, l+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
no_resolv_conf:
|
||||||
|
if (!nns) {
|
||||||
|
__lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
|
||||||
|
nns = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->nns = nns;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ TOOL_NET_COMS = \
|
||||||
o/$(MODE)/tool/net/redbean.com \
|
o/$(MODE)/tool/net/redbean.com \
|
||||||
o/$(MODE)/tool/net/redbean-demo.com \
|
o/$(MODE)/tool/net/redbean-demo.com \
|
||||||
o/$(MODE)/tool/net/redbean-static.com \
|
o/$(MODE)/tool/net/redbean-static.com \
|
||||||
|
o/$(MODE)/tool/net/libresolv_query.com \
|
||||||
o/$(MODE)/tool/net/redbean-unsecure.com \
|
o/$(MODE)/tool/net/redbean-unsecure.com \
|
||||||
o/$(MODE)/tool/net/redbean-original.com
|
o/$(MODE)/tool/net/redbean-original.com
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ TOOL_NET_DIRECTDEPS = \
|
||||||
THIRD_PARTY_LUA \
|
THIRD_PARTY_LUA \
|
||||||
THIRD_PARTY_LUA_UNIX \
|
THIRD_PARTY_LUA_UNIX \
|
||||||
THIRD_PARTY_MAXMIND \
|
THIRD_PARTY_MAXMIND \
|
||||||
|
THIRD_PARTY_MUSL \
|
||||||
THIRD_PARTY_MBEDTLS \
|
THIRD_PARTY_MBEDTLS \
|
||||||
THIRD_PARTY_REGEX \
|
THIRD_PARTY_REGEX \
|
||||||
THIRD_PARTY_SQLITE3 \
|
THIRD_PARTY_SQLITE3 \
|
||||||
|
|
194
tool/net/libresolv_query.c
Normal file
194
tool/net/libresolv_query.c
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 by Wil Tan <wil@cloudregistry.net>
|
||||||
|
*
|
||||||
|
* Based on dump_dns.c from the dnscap <https://www.dns-oarc.net/tools/dnscap>
|
||||||
|
* originally written by Paul Vixie.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 ISC DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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/calls/typedef/u.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/stdio/internal.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "third_party/musl/nameser.h"
|
||||||
|
#include "third_party/musl/resolv.h"
|
||||||
|
|
||||||
|
const char *_res_opcodes[] = {
|
||||||
|
"QUERY", //
|
||||||
|
"IQUERY", //
|
||||||
|
"CQUERYM", //
|
||||||
|
"CQUERYU", //
|
||||||
|
"NOTIFY", //
|
||||||
|
"UPDATE", //
|
||||||
|
"6", //
|
||||||
|
"7", //
|
||||||
|
"8", //
|
||||||
|
"9", //
|
||||||
|
"10", //
|
||||||
|
"11", //
|
||||||
|
"12", //
|
||||||
|
"13", //
|
||||||
|
"ZONEINIT", //
|
||||||
|
"ZONEREF", //
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MY_GET16(s, cp) \
|
||||||
|
do { \
|
||||||
|
register const u_char *t_cp = (const u_char *)(cp); \
|
||||||
|
(s) = ((u_int16_t)t_cp[0] << 8) | ((u_int16_t)t_cp[1]); \
|
||||||
|
(cp) += NS_INT16SZ; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MY_GET32(l, cp) \
|
||||||
|
do { \
|
||||||
|
register const u_char *t_cp = (const u_char *)(cp); \
|
||||||
|
(l) = ((u_int32_t)t_cp[0] << 24) | ((u_int32_t)t_cp[1] << 16) | \
|
||||||
|
((u_int32_t)t_cp[2] << 8) | ((u_int32_t)t_cp[3]); \
|
||||||
|
(cp) += NS_INT32SZ; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void dump_dns_rr(ns_msg *msg, ns_rr *rr, ns_sect sect, FILE *trace) {
|
||||||
|
char buf[NS_MAXDNAME];
|
||||||
|
u_int class, type;
|
||||||
|
const u_char *rd;
|
||||||
|
u_int32_t soa[5];
|
||||||
|
u_int16_t mx;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
class = ns_rr_class(*rr);
|
||||||
|
type = ns_rr_type(*rr);
|
||||||
|
fprintf(trace, "%s,%d,%d", ns_rr_name(*rr), class, type);
|
||||||
|
if (sect == ns_s_qd) return;
|
||||||
|
fprintf(trace, ",%lu", (u_long)ns_rr_ttl(*rr));
|
||||||
|
rd = ns_rr_rdata(*rr);
|
||||||
|
switch (type) {
|
||||||
|
case ns_t_soa:
|
||||||
|
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||||
|
sizeof buf);
|
||||||
|
if (n < 0) goto error;
|
||||||
|
putc(',', trace);
|
||||||
|
fputs(buf, trace);
|
||||||
|
rd += n;
|
||||||
|
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||||
|
sizeof buf);
|
||||||
|
if (n < 0) goto error;
|
||||||
|
putc(',', trace);
|
||||||
|
fputs(buf, trace);
|
||||||
|
rd += n;
|
||||||
|
if (ns_msg_end(*msg) - rd < 5 * NS_INT32SZ) goto error;
|
||||||
|
for (n = 0; n < 5; n++) MY_GET32(soa[n], rd);
|
||||||
|
sprintf(buf, "%u,%u,%u,%u,%u", soa[0], soa[1], soa[2], soa[3], soa[4]);
|
||||||
|
break;
|
||||||
|
case ns_t_a:
|
||||||
|
inet_ntop(AF_INET, rd, buf, sizeof buf);
|
||||||
|
break;
|
||||||
|
case ns_t_aaaa:
|
||||||
|
inet_ntop(AF_INET6, rd, buf, sizeof buf);
|
||||||
|
break;
|
||||||
|
case ns_t_mx:
|
||||||
|
MY_GET16(mx, rd);
|
||||||
|
fprintf(trace, ",%u", mx);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ns_t_ns:
|
||||||
|
case ns_t_ptr:
|
||||||
|
case ns_t_cname:
|
||||||
|
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||||
|
sizeof buf);
|
||||||
|
if (n < 0) goto error;
|
||||||
|
break;
|
||||||
|
case ns_t_txt:
|
||||||
|
snprintf(buf, (size_t)rd[0] + 1, "%s", rd + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error:
|
||||||
|
sprintf(buf, "[%u]", ns_rr_rdlen(*rr));
|
||||||
|
}
|
||||||
|
if (buf[0] != '\0') {
|
||||||
|
putc(',', trace);
|
||||||
|
fputs(buf, trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_dns_sect(ns_msg *msg, ns_sect sect, FILE *trace,
|
||||||
|
const char *endline) {
|
||||||
|
int rrnum, rrmax;
|
||||||
|
const char *sep;
|
||||||
|
ns_rr rr;
|
||||||
|
|
||||||
|
rrmax = ns_msg_count(*msg, sect);
|
||||||
|
if (rrmax == 0) {
|
||||||
|
fputs(" 0", trace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(trace, " %s%d", endline, rrmax);
|
||||||
|
sep = "";
|
||||||
|
for (rrnum = 0; rrnum < rrmax; rrnum++) {
|
||||||
|
if (ns_parserr(msg, sect, rrnum, &rr)) {
|
||||||
|
fputs(strerror(errno), trace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(trace, " %s", sep);
|
||||||
|
dump_dns_rr(msg, &rr, sect, trace);
|
||||||
|
sep = endline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_dns(const u_char *payload, size_t paylen, FILE *trace,
|
||||||
|
const char *endline) {
|
||||||
|
u_int opcode, rcode, id;
|
||||||
|
const char *sep;
|
||||||
|
ns_msg msg;
|
||||||
|
|
||||||
|
fprintf(trace, " %sdns ", endline);
|
||||||
|
if (ns_initparse(payload, paylen, &msg) < 0) {
|
||||||
|
fputs(strerror(errno), trace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
opcode = ns_msg_getflag(msg, ns_f_opcode);
|
||||||
|
rcode = ns_msg_getflag(msg, ns_f_rcode);
|
||||||
|
id = ns_msg_id(msg);
|
||||||
|
fprintf(trace, "%s,%d,%u", _res_opcodes[opcode], rcode, id);
|
||||||
|
sep = ",";
|
||||||
|
#define FLAG(t, f) \
|
||||||
|
if (ns_msg_getflag(msg, f)) { \
|
||||||
|
fprintf(trace, "%s%s", sep, t); \
|
||||||
|
sep = "|"; \
|
||||||
|
}
|
||||||
|
FLAG("qr", ns_f_qr);
|
||||||
|
FLAG("aa", ns_f_aa);
|
||||||
|
FLAG("tc", ns_f_tc);
|
||||||
|
FLAG("rd", ns_f_rd);
|
||||||
|
FLAG("ra", ns_f_ra);
|
||||||
|
FLAG("z", ns_f_z);
|
||||||
|
FLAG("ad", ns_f_ad);
|
||||||
|
FLAG("cd", ns_f_cd);
|
||||||
|
#undef FLAG
|
||||||
|
|
||||||
|
dump_dns_sect(&msg, ns_s_an, trace, endline);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ShowCrashReports();
|
||||||
|
u_char answer[1024] = "";
|
||||||
|
res_init();
|
||||||
|
int rv = res_query("google.com", ns_c_in, ns_t_txt, answer, sizeof(answer));
|
||||||
|
// printf("rv=%d\n", rv);
|
||||||
|
dump_dns(answer, rv, stdout, "\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
Loading…
Reference in a new issue