mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 23:08:31 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
13
libc/dns/consts.h
Normal file
13
libc/dns/consts.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_CONSTS_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_CONSTS_H_
|
||||
#include "libc/sock/sock.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define DNS_TYPE_A 1
|
||||
#define DNS_CLASS_IN 1
|
||||
|
||||
#define kMinSockaddr4Size \
|
||||
(offsetof(struct sockaddr_in, sin_addr) + sizeof(struct in_addr))
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_CONSTS_H_ */
|
40
libc/dns/dns.h
Normal file
40
libc/dns/dns.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define DNS_PORT 53
|
||||
#define DNS_NAME_MAX 253
|
||||
#define DNS_LABEL_MAX 63
|
||||
|
||||
struct sockaddr;
|
||||
struct sockaddr_in;
|
||||
struct ResolvConf;
|
||||
|
||||
struct addrinfo {
|
||||
int32_t ai_flags; /* AI_XXX */
|
||||
int32_t ai_family; /* AF_INET */
|
||||
int32_t ai_socktype; /* SOCK_XXX */
|
||||
int32_t ai_protocol; /* IPPROTO_XXX */
|
||||
uint32_t ai_addrlen;
|
||||
union {
|
||||
struct sockaddr *ai_addr;
|
||||
struct sockaddr_in *ai_addr4;
|
||||
};
|
||||
char *ai_canonname /*[DNS_NAME_MAX + 1]*/;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
|
||||
int getaddrinfo(const char *, const char *, const struct addrinfo *,
|
||||
struct addrinfo **) paramsnonnull((4));
|
||||
int freeaddrinfo(struct addrinfo *);
|
||||
const char *eai2str(int);
|
||||
int dnsnamecmp(const char *, const char *) paramsnonnull();
|
||||
int pascalifydnsname(uint8_t *, size_t, const char *) paramsnonnull();
|
||||
int resolvedns(const struct ResolvConf *, int, const char *, struct sockaddr *,
|
||||
uint32_t) paramsnonnull();
|
||||
struct addrinfo *newaddrinfo(uint16_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_DNS_H_ */
|
61
libc/dns/dns.mk
Normal file
61
libc/dns/dns.mk
Normal file
|
@ -0,0 +1,61 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += LIBC_DNS
|
||||
|
||||
LIBC_DNS_ARTIFACTS += LIBC_DNS_A
|
||||
LIBC_DNS = $(LIBC_DNS_A_DEPS) $(LIBC_DNS_A)
|
||||
LIBC_DNS_A = o/$(MODE)/libc/dns/dns.a
|
||||
LIBC_DNS_A_FILES := $(wildcard libc/dns/*)
|
||||
LIBC_DNS_A_HDRS = $(filter %.h,$(LIBC_DNS_A_FILES))
|
||||
LIBC_DNS_A_SRCS_C = $(filter %.c,$(LIBC_DNS_A_FILES))
|
||||
LIBC_DNS_A_SRCS_S = $(filter %.S,$(LIBC_DNS_A_FILES))
|
||||
|
||||
LIBC_DNS_A_SRCS = \
|
||||
$(LIBC_DNS_A_SRCS_S) \
|
||||
$(LIBC_DNS_A_SRCS_C)
|
||||
|
||||
LIBC_DNS_A_OBJS = \
|
||||
$(LIBC_DNS_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_DNS_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_DNS_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
LIBC_DNS_A_CHECKS = \
|
||||
$(LIBC_DNS_A).pkg \
|
||||
$(LIBC_DNS_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_DNS_A_DIRECTDEPS = \
|
||||
LIBC_ALG \
|
||||
LIBC_CALLS \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_STUBS \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_NT_KERNELBASE
|
||||
|
||||
LIBC_DNS_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_DNS_A): libc/dns/ \
|
||||
$(LIBC_DNS_A).pkg \
|
||||
$(LIBC_DNS_A_OBJS)
|
||||
|
||||
$(LIBC_DNS_A).pkg: \
|
||||
$(LIBC_DNS_A_OBJS) \
|
||||
$(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
LIBC_DNS_LIBS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)))
|
||||
LIBC_DNS_SRCS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_DNS_HDRS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_DNS_CHECKS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_DNS_OBJS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_OBJS))
|
||||
$(LIBC_DNS_OBJS): $(BUILD_FILES) libc/dns/dns.mk
|
||||
|
||||
.PHONY: o/$(MODE)/libc/dns
|
||||
o/$(MODE)/libc/dns: $(LIBC_DNS_CHECKS)
|
BIN
libc/dns/dns.png
Normal file
BIN
libc/dns/dns.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 624 KiB |
64
libc/dns/dnsheader.c
Normal file
64
libc/dns/dnsheader.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/dns/dnsheader.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Serializes DNS message header to wire.
|
||||
*
|
||||
* @return number of bytes written (always 12) or -1 w/ errno
|
||||
* @see pascalifydnsname()
|
||||
*/
|
||||
int serializednsheader(uint8_t *buf, size_t size,
|
||||
const struct DnsHeader header) {
|
||||
if (size < 12) return enospc();
|
||||
buf[0x0] = header.id >> 010u;
|
||||
buf[0x1] = header.id >> 000u;
|
||||
buf[0x2] = header.bf1;
|
||||
buf[0x3] = header.bf2;
|
||||
buf[0x4] = header.qdcount >> 010u;
|
||||
buf[0x5] = header.qdcount >> 000u;
|
||||
buf[0x6] = header.ancount >> 010u;
|
||||
buf[0x7] = header.ancount >> 000u;
|
||||
buf[0x8] = header.nscount >> 010u;
|
||||
buf[0x9] = header.nscount >> 000u;
|
||||
buf[0xa] = header.arcount >> 010u;
|
||||
buf[0xb] = header.arcount >> 000u;
|
||||
return 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes DNS message header to wire.
|
||||
*
|
||||
* @return number of bytes read (always 12) or -1 w/ errno
|
||||
*/
|
||||
int deserializednsheader(struct DnsHeader *header, const uint8_t *buf,
|
||||
size_t size) {
|
||||
if (size < 12) return ebadmsg();
|
||||
header->id = read16be(buf + 0);
|
||||
header->bf1 = buf[2];
|
||||
header->bf2 = buf[3];
|
||||
header->qdcount = read16be(buf + 4);
|
||||
header->ancount = read16be(buf + 6);
|
||||
header->nscount = read16be(buf + 8);
|
||||
header->arcount = read16be(buf + 10);
|
||||
return 12;
|
||||
}
|
23
libc/dns/dnsheader.h
Normal file
23
libc/dns/dnsheader.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct DnsHeader {
|
||||
uint16_t id; /* transaction id */
|
||||
uint8_t bf1; /* bit field 1 */
|
||||
uint8_t bf2; /* bit field 2 */
|
||||
uint16_t qdcount; /* question count */
|
||||
uint16_t ancount; /* answer count */
|
||||
uint16_t nscount; /* nameserver count */
|
||||
uint16_t arcount; /* additional record count */
|
||||
};
|
||||
|
||||
int serializednsheader(uint8_t *buf, size_t size,
|
||||
const struct DnsHeader header);
|
||||
int deserializednsheader(struct DnsHeader *header, const uint8_t *buf,
|
||||
size_t size);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_ */
|
76
libc/dns/dnsnamecmp.c
Normal file
76
libc/dns/dnsnamecmp.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
forceinline void FindDnsLabel(const char *A, size_t *i, size_t *n) {
|
||||
while (*i) {
|
||||
if (A[*i - 1] == '.') {
|
||||
if (*i == *n) {
|
||||
--(*n);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
--(*i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares DNS hostnames in reverse lexicographical asciibetical order.
|
||||
* @return <0, 0, or >0
|
||||
* @see test/libc/dns/dnsnamecmp_test.c (the code that matters)
|
||||
*/
|
||||
int dnsnamecmp(const char *A, const char *B) {
|
||||
if (A == B) return 0;
|
||||
size_t n = strlen(A);
|
||||
size_t m = strlen(B);
|
||||
if (!n || !m || ((A[n - 1] == '.') ^ (B[m - 1] == '.'))) {
|
||||
if (n && m && A[n - 1] == '.' && strchr(B, '.')) {
|
||||
--m;
|
||||
} else if (n && m && B[m - 1] == '.' && strchr(A, '.')) {
|
||||
--n;
|
||||
} else {
|
||||
return A[n ? n - 1 : 0] - B[m ? m - 1 : 0];
|
||||
}
|
||||
}
|
||||
size_t i = n;
|
||||
size_t j = m;
|
||||
bool first = true;
|
||||
for (;;) {
|
||||
FindDnsLabel(A, &i, &n);
|
||||
FindDnsLabel(B, &j, &m);
|
||||
if (first) {
|
||||
first = false;
|
||||
if (!i && j) return 1;
|
||||
if (!j && i) return -1;
|
||||
}
|
||||
int res;
|
||||
if ((res = strncasecmp(&A[i], &B[j], min(n - i + 1, m - j + 1)))) {
|
||||
return res;
|
||||
}
|
||||
if (!i || !j) {
|
||||
return i - j;
|
||||
}
|
||||
n = i;
|
||||
m = j;
|
||||
}
|
||||
}
|
32
libc/dns/dnsquestion.h
Normal file
32
libc/dns/dnsquestion.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct DnsQuestion {
|
||||
const char *qname;
|
||||
uint16_t qtype;
|
||||
uint16_t qclass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes DNS question record to wire.
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @see pascalifydnsname()
|
||||
*/
|
||||
forceinline int serializednsquestion(uint8_t *buf, size_t size,
|
||||
struct DnsQuestion dq) {
|
||||
int wrote;
|
||||
if ((wrote = pascalifydnsname(buf, size, dq.qname)) == -1) return -1;
|
||||
if (wrote + 1 + 4 > size) return enospc();
|
||||
buf[wrote + 1] = dq.qtype >> 010, buf[wrote + 2] = dq.qtype >> 000;
|
||||
buf[wrote + 3] = dq.qclass >> 010, buf[wrote + 4] = dq.qclass >> 000;
|
||||
return wrote + 5;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_ */
|
47
libc/dns/eai2str.c
Normal file
47
libc/dns/eai2str.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/sysv/consts/eai.h"
|
||||
|
||||
/**
|
||||
* Turns getaddrinfo() return code into string.
|
||||
*/
|
||||
const char *eai2str(int code) {
|
||||
if (code == EAI_ADDRFAMILY) return "ADDRFAMILY";
|
||||
if (code == EAI_AGAIN) return "AGAIN";
|
||||
if (code == EAI_ALLDONE) return "ALLDONE";
|
||||
if (code == EAI_BADFLAGS) return "BADFLAGS";
|
||||
if (code == EAI_CANCELED) return "CANCELED";
|
||||
if (code == EAI_FAIL) return "FAIL";
|
||||
if (code == EAI_FAMILY) return "FAMILY";
|
||||
if (code == EAI_IDN_ENCODE) return "ENCODE";
|
||||
if (code == EAI_INPROGRESS) return "INPROGRESS";
|
||||
if (code == EAI_INTR) return "INTR";
|
||||
if (code == EAI_MEMORY) return "MEMORY";
|
||||
if (code == EAI_NODATA) return "NODATA";
|
||||
if (code == EAI_NONAME) return "NONAME";
|
||||
if (code == EAI_NOTCANCELED) return "NOTCANCELED";
|
||||
if (code == EAI_OVERFLOW) return "OVERFLOW";
|
||||
if (code == EAI_SERVICE) return "SERVICE";
|
||||
if (code == EAI_SOCKTYPE) return "SOCKTYPE";
|
||||
if (code == EAI_SUCCESS) return "SUCCESS";
|
||||
if (code == EAI_SYSTEM) return "SYSTEM";
|
||||
return "???";
|
||||
}
|
35
libc/dns/freeaddrinfo.c
Normal file
35
libc/dns/freeaddrinfo.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
/**
|
||||
* Frees addresses returned by getaddrinfo().
|
||||
*/
|
||||
int freeaddrinfo(struct addrinfo *addrs) {
|
||||
struct addrinfo *next;
|
||||
while (addrs) {
|
||||
/* we assume ai_addr and ai_canonname are shoehorned */
|
||||
next = addrs->ai_next;
|
||||
free(addrs);
|
||||
addrs = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
32
libc/dns/freehoststxt.c
Normal file
32
libc/dns/freehoststxt.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Frees HOSTS.TXT data structure populated by parsehoststxt().
|
||||
*/
|
||||
void freehoststxt(struct HostsTxt **ht) {
|
||||
if (*ht) {
|
||||
free_s(&(*ht)->entries.p);
|
||||
free_s(&(*ht)->strings.p);
|
||||
free_s(ht);
|
||||
}
|
||||
}
|
31
libc/dns/freeresolvconf.c
Normal file
31
libc/dns/freeresolvconf.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Frees resolv.conf data structure populated by parseresolvconf().
|
||||
*/
|
||||
void freeresolvconf(struct ResolvConf **rvp) {
|
||||
if (*rvp) {
|
||||
free_s(&(*rvp)->nameservers.p);
|
||||
free_s(rvp);
|
||||
}
|
||||
}
|
98
libc/dns/getaddrinfo.c
Normal file
98
libc/dns/getaddrinfo.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ai.h"
|
||||
#include "libc/sysv/consts/eai.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
|
||||
/**
|
||||
* Resolves address for internet name.
|
||||
*
|
||||
* @param node is either an ip string or a utf-8 hostname
|
||||
* @param service is the port number as a string
|
||||
* @param hints may be passed to specialize behavior (optional)
|
||||
* @param res receives a pointer that must be freed with freeaddrinfo(),
|
||||
* and won't be modified if -1 is returned
|
||||
* @return 0 on success or EAI_xxx value
|
||||
*/
|
||||
int getaddrinfo(const char *name, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res) {
|
||||
int port = 0;
|
||||
struct addrinfo *ai;
|
||||
if ((!name && !service) || (service && (port = parseport(service)) == -1)) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
if (!name && (hints->ai_flags & AI_CANONNAME) == AI_CANONNAME) {
|
||||
return EAI_BADFLAGS;
|
||||
}
|
||||
if (!(ai = newaddrinfo(port))) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
if (service) {
|
||||
ai->ai_addr4->sin_port = htons(port);
|
||||
}
|
||||
if (hints) {
|
||||
ai->ai_socktype = hints->ai_socktype;
|
||||
ai->ai_protocol = hints->ai_protocol;
|
||||
}
|
||||
if (!name) {
|
||||
ai->ai_addr4->sin_addr.s_addr =
|
||||
(hints && (hints->ai_flags & AI_PASSIVE) == AI_PASSIVE)
|
||||
? INADDR_ANY
|
||||
: INADDR_LOOPBACK;
|
||||
return 0;
|
||||
}
|
||||
const char *canon;
|
||||
if (inet_pton(AF_INET, name, &ai->ai_addr4->sin_addr.s_addr) == 1) {
|
||||
*res = ai;
|
||||
return 0;
|
||||
} else if (hints && (hints->ai_flags & AI_NUMERICHOST) == AI_NUMERICHOST) {
|
||||
freeaddrinfo(ai);
|
||||
return EAI_NONAME;
|
||||
} else if (resolvehoststxt(gethoststxt(), AF_INET, name, ai->ai_addr,
|
||||
sizeof(ai->ai_addr4), &canon) > 0) {
|
||||
memcpy(ai->ai_canonname, canon, min(strlen(canon), DNS_NAME_MAX) + 1);
|
||||
*res = ai;
|
||||
return 0;
|
||||
} else {
|
||||
int rc = resolvedns(getresolvconf(), AF_INET, name, ai->ai_addr,
|
||||
sizeof(ai->ai_addr4));
|
||||
if (rc > 0) {
|
||||
*res = ai;
|
||||
return 0;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
if (rc == 0) {
|
||||
return EAI_NONAME;
|
||||
} else {
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
}
|
||||
}
|
79
libc/dns/gethoststxt.c
Normal file
79
libc/dns/gethoststxt.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static struct HostsTxt *g_hoststxt;
|
||||
static struct HostsTxtInitialStaticMemory {
|
||||
struct HostsTxt ht;
|
||||
struct HostsTxtEntry entries[8];
|
||||
char strings[64];
|
||||
} g_hoststxt_init;
|
||||
|
||||
static textwindows noinline char *getnthoststxtpath(char *pathbuf,
|
||||
uint32_t size) {
|
||||
const char *const kWinHostsPath = "\\drivers\\etc\\hosts";
|
||||
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
||||
if (len && len + strlen(kWinHostsPath) + 1 < size) {
|
||||
if (pathbuf[len] == '\\') pathbuf[len--] = '\0';
|
||||
memcpy(&pathbuf[len], kWinHostsPath, strlen(kWinHostsPath) + 1);
|
||||
return &pathbuf[0];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns parsed sorted singleton hardcoded hostname→ip4 map.
|
||||
*
|
||||
* @note yoinking realloc() ensures there's no size limits
|
||||
*/
|
||||
const struct HostsTxt *gethoststxt(void) {
|
||||
struct HostsTxtInitialStaticMemory *init = &g_hoststxt_init;
|
||||
if (!g_hoststxt) {
|
||||
g_hoststxt = &init->ht;
|
||||
init->ht.entries.n = pushpop(ARRAYLEN(init->entries));
|
||||
init->ht.entries.p = init->entries;
|
||||
init->ht.strings.n = pushpop(ARRAYLEN(init->strings));
|
||||
init->ht.strings.p = init->strings;
|
||||
__cxa_atexit(freehoststxt, &g_hoststxt, NULL);
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path = "/etc/hosts";
|
||||
if (IsWindows()) {
|
||||
path = firstnonnull(getnthoststxtpath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
FILE *f;
|
||||
if (!(f = fopen(path, "r")) || parsehoststxt(g_hoststxt, f) == -1) {
|
||||
if (!IsTiny()) fprintf(stderr, "%s: %s: %m\n", "warning", path);
|
||||
}
|
||||
fclose(f);
|
||||
sorthoststxt(g_hoststxt);
|
||||
}
|
||||
return g_hoststxt;
|
||||
}
|
87
libc/dns/getntnameservers.c
Normal file
87
libc/dns/getntnameservers.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/nt/registry.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
/**
|
||||
* Extracts DNS nameserver IPs from Windows Registry.
|
||||
*
|
||||
* @param resolv points to a ResolvConf object, which should be zero
|
||||
* initialized by the caller; or if it already contains items,
|
||||
* this function will append
|
||||
* @return number of nameservers appended, or -1 w/ errno
|
||||
*/
|
||||
textwindows int getntnameservers(struct ResolvConf *resolv) {
|
||||
int rc;
|
||||
int64_t hkInterfaces = kNtInvalidHandleValue;
|
||||
uint32_t keycount = 0;
|
||||
if (!RegOpenKeyEx(
|
||||
kNtHkeyLocalMachine,
|
||||
u"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
|
||||
0, kNtKeyRead, &hkInterfaces) &&
|
||||
!RegQueryInfoKey(hkInterfaces, NULL, NULL, NULL, &keycount, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL)) {
|
||||
struct sockaddr_in nameserver;
|
||||
nameserver.sin_family = AF_INET;
|
||||
nameserver.sin_port = htons(DNS_PORT);
|
||||
rc = 0;
|
||||
for (uint32_t i = 0; i < keycount; ++i) {
|
||||
char16_t value[128], ifaceuuid[64];
|
||||
uint32_t valuebytes, ifaceuuidlen = sizeof(ifaceuuid);
|
||||
if (!RegEnumKeyEx(hkInterfaces, i, ifaceuuid, &ifaceuuidlen, NULL, NULL,
|
||||
NULL, NULL) &&
|
||||
((!RegGetValue(hkInterfaces, ifaceuuid, u"DhcpIpAddress",
|
||||
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||
valuebytes > 2 * sizeof(char16_t)) ||
|
||||
(!RegGetValue(hkInterfaces, ifaceuuid, u"IpAddress",
|
||||
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||
valuebytes > 2 * sizeof(char16_t))) &&
|
||||
((!RegGetValue(hkInterfaces, ifaceuuid, u"DhcpNameServer",
|
||||
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||
valuebytes > 2 * sizeof(char16_t)) ||
|
||||
(!RegGetValue(hkInterfaces, ifaceuuid, u"NameServer",
|
||||
kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value,
|
||||
((valuebytes = sizeof(value)), &valuebytes)) &&
|
||||
valuebytes > 2 * sizeof(char16_t)))) {
|
||||
char value8[128];
|
||||
tprecode16to8(value8, sizeof(value8), value);
|
||||
if (inet_pton(AF_INET, value8, &nameserver.sin_addr.s_addr) == 1) {
|
||||
if (append(&resolv->nameservers, &nameserver) != -1) ++rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rc = winerr();
|
||||
}
|
||||
RegCloseKey(hkInterfaces);
|
||||
return rc;
|
||||
}
|
62
libc/dns/getresolvconf.c
Normal file
62
libc/dns/getresolvconf.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
static struct ResolvConf *g_resolvconf;
|
||||
static struct ResolvConfInitialStaticMemory {
|
||||
struct ResolvConf rv;
|
||||
struct sockaddr_in nameservers[3];
|
||||
} g_resolvconf_init;
|
||||
|
||||
/**
|
||||
* Returns singleton with DNS server address.
|
||||
*/
|
||||
const struct ResolvConf *getresolvconf(void) {
|
||||
struct ResolvConfInitialStaticMemory *init = &g_resolvconf_init;
|
||||
if (!g_resolvconf) {
|
||||
g_resolvconf = &init->rv;
|
||||
pushmov(&init->rv.nameservers.n, ARRAYLEN(init->nameservers));
|
||||
init->rv.nameservers.p = init->nameservers;
|
||||
__cxa_atexit(freeresolvconf, &g_resolvconf, NULL);
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
FILE *f;
|
||||
if ((f = fopen("/etc/resolv.conf", "r"))) {
|
||||
rc = parseresolvconf(g_resolvconf, f);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
fclose(f);
|
||||
} else {
|
||||
rc = getntnameservers(g_resolvconf);
|
||||
}
|
||||
if (rc == -1 && !IsTiny()) {
|
||||
fprintf(stderr, "%s: %m\n", "nameserver discovery failed");
|
||||
}
|
||||
}
|
||||
return g_resolvconf;
|
||||
}
|
42
libc/dns/hoststxt.h
Normal file
42
libc/dns/hoststxt.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
struct sockaddr;
|
||||
|
||||
struct HostsTxtEntry {
|
||||
unsigned char ip[4]; /* inet_ntop(AF_INET, he->ip, buf, size) */
|
||||
uint32_t name; /* &ht->strings.p[he->name] */
|
||||
uint32_t canon; /* &ht->strings.p[he->canon] */
|
||||
};
|
||||
|
||||
struct HostsTxtEntries {
|
||||
size_t i;
|
||||
size_t n;
|
||||
struct HostsTxtEntry *p;
|
||||
};
|
||||
|
||||
struct HostsTxtStrings {
|
||||
size_t i;
|
||||
size_t n;
|
||||
char *p;
|
||||
};
|
||||
|
||||
struct HostsTxt {
|
||||
struct HostsTxtEntries entries;
|
||||
struct HostsTxtStrings strings;
|
||||
};
|
||||
|
||||
const struct HostsTxt *gethoststxt(void) returnsnonnull;
|
||||
void freehoststxt(struct HostsTxt **) paramsnonnull();
|
||||
int parsehoststxt(struct HostsTxt *, struct FILE *) paramsnonnull();
|
||||
void sorthoststxt(struct HostsTxt *) paramsnonnull();
|
||||
int resolvehoststxt(const struct HostsTxt *, int, const char *,
|
||||
struct sockaddr *, uint32_t, const char **)
|
||||
paramsnonnull((1, 3));
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_ */
|
41
libc/dns/newaddrinfo.c
Normal file
41
libc/dns/newaddrinfo.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
struct addrinfo *newaddrinfo(uint16_t port) {
|
||||
void *mem;
|
||||
struct addrinfo *ai = NULL;
|
||||
/* shoehorning is ok since this'll never be realloc()'d */
|
||||
uint32_t size = ROUNDUP(sizeof(struct addrinfo), sizeof(void *));
|
||||
uint32_t addrlen = sizeof(struct sockaddr_in);
|
||||
if ((ai = mem = calloc(1, size + addrlen + DNS_NAME_MAX + 1))) {
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_addrlen = addrlen;
|
||||
ai->ai_addr4 = (struct sockaddr_in *)((char *)mem + size);
|
||||
ai->ai_addr4->sin_family = AF_INET;
|
||||
ai->ai_addr4->sin_port = htons(port);
|
||||
ai->ai_canonname = (char *)mem + size + addrlen;
|
||||
}
|
||||
return ai;
|
||||
}
|
69
libc/dns/parsehoststxt.c
Normal file
69
libc/dns/parsehoststxt.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
/**
|
||||
* Parses HOSTS.TXT contents.
|
||||
*
|
||||
* Hostnames were invented by Peggy Karp; her format looks like this:
|
||||
*
|
||||
* # this is a comment
|
||||
* # IP CANON [ALT...]
|
||||
* 203.0.113.1 lol.example. lol
|
||||
* 203.0.113.2 cat.example. cat
|
||||
*
|
||||
* @param htp points to a HostsTxt object, which should be zero
|
||||
* initialized by the caller; or if it already contains items,
|
||||
* this function will append
|
||||
* @param f is the file content; see fopen() and fmemopen()
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see hoststxtsort() which is the logical next step
|
||||
*/
|
||||
int parsehoststxt(struct HostsTxt *ht, FILE *f) {
|
||||
int rc = 0;
|
||||
char stackline[128];
|
||||
char *line = stackline;
|
||||
size_t linecap = sizeof(stackline);
|
||||
while ((getline(&line, &linecap, f)) != -1) {
|
||||
struct HostsTxtEntry entry;
|
||||
char *addr, *name, *tok, *comment;
|
||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||
if ((addr = strtok_r(line, " \t\r\n\v", &tok)) &&
|
||||
inet_pton(AF_INET, addr, entry.ip) == 1) {
|
||||
entry.canon = ht->strings.i;
|
||||
while ((name = strtok_r(NULL, " \t\r\n\v", &tok))) {
|
||||
entry.name = ht->strings.i;
|
||||
if (concat(&ht->strings, name, strnlen(name, DNS_NAME_MAX) + 1) == -1 ||
|
||||
append(&ht->entries, &entry) == -1) {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free_s(&line);
|
||||
return rc | ferror(f);
|
||||
}
|
68
libc/dns/parseresolvconf.c
Normal file
68
libc/dns/parseresolvconf.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
|
||||
/**
|
||||
* Parses /etc/resolv.conf file.
|
||||
*
|
||||
* The content of the file usually looks like this:
|
||||
*
|
||||
* nameserver 8.8.8.8
|
||||
* nameserver 8.8.4.4
|
||||
*
|
||||
* @param resolv points to a ResolvConf object, which should be zero
|
||||
* initialized by the caller; or if it already contains items,
|
||||
* this function will append
|
||||
* @param f is an open stream with file content
|
||||
* @return number of nameservers appended, or -1 w/ errno
|
||||
*/
|
||||
int parseresolvconf(struct ResolvConf *resolv, struct FILE *f) {
|
||||
/* TODO(jart): options ndots:5 */
|
||||
int rc = 0;
|
||||
char stackline[32];
|
||||
char *line = stackline;
|
||||
size_t linecap = sizeof(stackline);
|
||||
struct sockaddr_in nameserver;
|
||||
nameserver.sin_family = AF_INET;
|
||||
nameserver.sin_port = htons(DNS_PORT);
|
||||
while (getline(&line, &linecap, f) != -1) {
|
||||
char *directive, *value, *tok, *comment;
|
||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||
if ((directive = strtok_r(line, " \t\r\n\v", &tok)) &&
|
||||
(value = strtok_r(NULL, " \t\r\n\v", &tok))) {
|
||||
if ((strcmp(directive, "nameserver") == 0 &&
|
||||
inet_pton(AF_INET, value, &nameserver.sin_addr.s_addr) == 1) ||
|
||||
(strcmp(directive, "search") == 0 && strcmp(value, "local") == 0 &&
|
||||
(nameserver.sin_addr.s_addr = htonl(INADDR_LOOPBACK)))) {
|
||||
if (append(&resolv->nameservers, &nameserver) != -1) ++rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_s(&line);
|
||||
return rc | ferror(f);
|
||||
}
|
60
libc/dns/pascalifydnsname.c
Normal file
60
libc/dns/pascalifydnsname.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Writes dotted hostname to DNS message wire.
|
||||
*
|
||||
* The wire format is basically a sequence of Pascal strings, for each
|
||||
* label in the name. We only do enough validation to maintain protocol
|
||||
* invariants.
|
||||
*
|
||||
* @param name is a dotted NUL-terminated hostname string
|
||||
* @return bytes written (excluding NUL) or -1 w/ errno
|
||||
*/
|
||||
int pascalifydnsname(uint8_t *buf, size_t size, const char *name) {
|
||||
size_t i = 0;
|
||||
size_t namelen = strlen(name);
|
||||
if (namelen > DNS_NAME_MAX) return enametoolong();
|
||||
if (size || namelen) {
|
||||
if (namelen + 1 > size) return enospc();
|
||||
buf[0] = '\0';
|
||||
size_t j = 0;
|
||||
for (;;) {
|
||||
size_t k;
|
||||
for (k = 0; name[j + k] && name[j + k] != '.'; ++k) {
|
||||
buf[i + k + 1] = name[j + k];
|
||||
}
|
||||
if (k) {
|
||||
if (k > DNS_LABEL_MAX) return enametoolong();
|
||||
buf[i] = k;
|
||||
i += k + 1;
|
||||
}
|
||||
j += k + 1;
|
||||
if (!name[j - 1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
}
|
||||
return i;
|
||||
}
|
25
libc/dns/resolvconf.h
Normal file
25
libc/dns/resolvconf.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
struct sockaddr_in;
|
||||
|
||||
struct Nameservers {
|
||||
size_t i, n;
|
||||
struct sockaddr_in *p;
|
||||
};
|
||||
|
||||
struct ResolvConf {
|
||||
struct Nameservers nameservers;
|
||||
};
|
||||
|
||||
const struct ResolvConf *getresolvconf(void) returnsnonnull;
|
||||
int parseresolvconf(struct ResolvConf *, struct FILE *) paramsnonnull();
|
||||
void freeresolvconf(struct ResolvConf **) paramsnonnull();
|
||||
int getntnameservers(struct ResolvConf *resolv) paramsnonnull();
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_ */
|
121
libc/dns/resolvedns.c
Normal file
121
libc/dns/resolvedns.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dns/consts.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/dnsheader.h"
|
||||
#include "libc/dns/dnsquestion.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Queries Domain Name System for address associated with name.
|
||||
*
|
||||
* @param resolvconf can be getresolvconf()
|
||||
* @param af can be AF_INET, AF_UNSPEC
|
||||
* @param name can be a local or fully-qualified hostname
|
||||
* @param addr should point to a struct sockaddr_in; if this function
|
||||
* succeeds, its sin_family and sin_addr fields will be modified
|
||||
* @param addrsize is the byte size of addr
|
||||
* @return number of matches found, or -1 w/ errno
|
||||
* @error EAFNOSUPPORT. ENETDOWN, ENAMETOOLONG, EBADMSG
|
||||
*/
|
||||
int resolvedns(const struct ResolvConf *resolvconf, int af, const char *name,
|
||||
struct sockaddr *addr, uint32_t addrsize) {
|
||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||
if (!resolvconf->nameservers.i) return 0;
|
||||
struct DnsHeader header;
|
||||
struct DnsQuestion question;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.id = rand32();
|
||||
header.bf1 = 1; /* recursion desired */
|
||||
header.qdcount = 1;
|
||||
question.qname = name;
|
||||
question.qtype = DNS_TYPE_A;
|
||||
question.qclass = DNS_CLASS_IN;
|
||||
const size_t kMsgMax = 512;
|
||||
uint8_t *outmsg = NULL;
|
||||
uint8_t *inmsg = NULL;
|
||||
size_t msgsize;
|
||||
int res = -1;
|
||||
int rc, rc2;
|
||||
if ((outmsg = malloc(kMsgMax)) && (inmsg = malloc(kMsgMax)) &&
|
||||
(rc = serializednsheader(outmsg, kMsgMax, header)) != -1 &&
|
||||
(rc2 = serializednsquestion(outmsg + rc, kMsgMax - rc, question)) != -1) {
|
||||
msgsize = rc + rc2;
|
||||
int fd;
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1 &&
|
||||
sendto(fd, outmsg, msgsize, 0, (void *)&resolvconf->nameservers.p[0],
|
||||
sizeof(resolvconf->nameservers.p[0])) == msgsize) {
|
||||
struct DnsHeader response;
|
||||
if ((rc = recv(fd, inmsg, kMsgMax, 0)) != -1 &&
|
||||
(rc2 = deserializednsheader(&response, inmsg, rc)) != -1 &&
|
||||
response.id == header.id) {
|
||||
res = 0;
|
||||
if (response.ancount) {
|
||||
uint8_t *p = inmsg + rc2;
|
||||
uint8_t *pe = inmsg + rc;
|
||||
while (p < pe && response.qdcount) {
|
||||
p += strnlen((char *)p, pe - p) + 1 + 4;
|
||||
response.qdcount--;
|
||||
}
|
||||
if (p + 1 < pe) {
|
||||
if ((p[0] & 0b11000000) == 0b11000000) { /* name pointer */
|
||||
p += 2;
|
||||
} else {
|
||||
p += strnlen((char *)p, pe - p) + 1;
|
||||
}
|
||||
if (p + 2 + 2 + 4 + 2 < pe) {
|
||||
uint16_t rtype, rclass, rdlength;
|
||||
rtype = read16be(p), p += 2;
|
||||
rclass = read16be(p), p += 2;
|
||||
/* ttl */ p += 4;
|
||||
rdlength = read16be(p), p += 2;
|
||||
if (p + rdlength <= pe && rdlength == 4 &&
|
||||
(rtype == DNS_TYPE_A && rclass == DNS_CLASS_IN)) {
|
||||
res = 1;
|
||||
if (addrsize) {
|
||||
if (addrsize >= kMinSockaddr4Size) {
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
memcpy(&addr4->sin_addr.s_addr, p, 4);
|
||||
} else {
|
||||
res = einval();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res |= close(fd);
|
||||
}
|
||||
free(outmsg);
|
||||
return res;
|
||||
}
|
69
libc/dns/resolvehoststxt.c
Normal file
69
libc/dns/resolvehoststxt.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/dns/consts.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
static int hoststxtgetcmp(const char *node, const struct HostsTxtEntry *entry,
|
||||
const char *strings) {
|
||||
return dnsnamecmp(node, &strings[entry->name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds address associated with name in HOSTS.TXT table.
|
||||
*
|
||||
* This function performs binary search, so sorthoststxt() must be
|
||||
* called on the table beforehand.
|
||||
*
|
||||
* @param ht can be gethoststxt()
|
||||
* @param af can be AF_INET, AF_UNSPEC
|
||||
* @param name can be a local or fully-qualified hostname
|
||||
* @param addr should point to a struct sockaddr_in; if this function
|
||||
* succeeds, its sin_family and sin_addr fields will be modified
|
||||
* @param addrsize is the byte size of addr
|
||||
* @param canon be used to return a pointer to the canonical name
|
||||
* @return number of matches found, or -1 w/ errno
|
||||
* @error EAFNOSUPPORT
|
||||
*/
|
||||
int resolvehoststxt(const struct HostsTxt *ht, int af, const char *name,
|
||||
struct sockaddr *addr, uint32_t addrsize,
|
||||
const char **canon) {
|
||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||
struct HostsTxtEntry *entry = bsearch_r(
|
||||
name, ht->entries.p, ht->entries.i, sizeof(struct HostsTxtEntry),
|
||||
(void *)hoststxtgetcmp, ht->strings.p);
|
||||
if (entry) {
|
||||
if (addr) {
|
||||
if (addrsize < kMinSockaddr4Size) return einval();
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
|
||||
addr4->sin_family = AF_INET;
|
||||
memcpy(&addr4->sin_addr.s_addr, &entry->ip[0], 4);
|
||||
}
|
||||
if (canon) *canon = &ht->strings.p[entry->canon];
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
59
libc/dns/rfc0226.txt
Normal file
59
libc/dns/rfc0226.txt
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NETWORK WORKING GROUP PEGGY KARP
|
||||
REQUEST FOR COMMENTS #226 MITRE
|
||||
NIC #7625 20 SEPT 71
|
||||
CATEGORIES: D.3
|
||||
UPDATES: NONE
|
||||
OBSOLETES: NONE
|
||||
|
||||
STANDARDIZATION OF HOST MNEUMONICS
|
||||
|
||||
IN EACH TELNET IMPLEMENTATION, A LIST OF HOST NMEUMONICS IS PROVIDED
|
||||
FOR THE USER TO INDICATE THE SERVING HOST DESIRED. CURRENTLY, EACH
|
||||
SITE EMPLOYS THEIR OWN SPECIAL LIST. RATHER THAN REQUIRE THE USER TO
|
||||
BE COGNIZANT OF THE IDIOSYNCRASIES OF EACH LIST, ESPECIALLY WHEN
|
||||
CHAINED THROUGH SEVERAL HOSTS VIA TELNET, IT HAS BEEN RECOMMENDED THAT
|
||||
STANDARD HOST DESIGNATORS BE ADOPTED.
|
||||
|
||||
THE FOLLOWING LIST OF SIX CHARACTER DESIGNATORS IS PROPOSED AS THE
|
||||
STANDARD LIST. REGISTER ANY OBJECTIONS BY 3 OCTOBER TO P. KARP (703)
|
||||
893-3500 X2391, X2318. AN OFFICIAL POLICY AND IMPLEMENTATION DATE WILL
|
||||
BE SET ON 8 OCTOBER.
|
||||
|
||||
THE LIST:
|
||||
HOST # DESIGNATOR
|
||||
1 UCLA
|
||||
65 UCLA36
|
||||
2 SRIARC
|
||||
66 SRIAI
|
||||
3 UCSB
|
||||
4 UTAH
|
||||
6 MULTCS
|
||||
70 MITDM
|
||||
7 RAND
|
||||
8 SDC
|
||||
9 HARV
|
||||
10 LNCTX2
|
||||
74 LNC360
|
||||
11 STAN
|
||||
12 ILL
|
||||
69 BBN
|
||||
133 BBNB
|
||||
144 AMES
|
||||
145 MITRE
|
||||
158 TIP
|
||||
|
||||
[ This RFC was put into machine readable form for entry ]
|
||||
[ into the online RFC archives by BBN Corp. under the ]
|
||||
[ direction of Alex McKenzie. 12/96 ]
|
||||
|
||||
|
||||
|
||||
|
||||
[Page 1]
|
||||
|
222
libc/dns/rfc0247.txt
Normal file
222
libc/dns/rfc0247.txt
Normal file
|
@ -0,0 +1,222 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group Peggy Karp
|
||||
Request for Comments: #247 MITRE
|
||||
NIC 7688 12 October 1971
|
||||
Categories: Policy, Telnet
|
||||
Related: #226, 236, 239, 233, 237
|
||||
Obsoletes: #226
|
||||
|
||||
Proferred Set of Standard Host Names
|
||||
|
||||
In RFC #226, BBN's TENEX list of Host names was set up as a strawman
|
||||
set of standard Host names. Comments received since then (an RFC
|
||||
actually generated comments!!!) have influenced me to propose the
|
||||
following general rules for forming Host names.
|
||||
|
||||
The Host names will be 8 characters in length. The general form is
|
||||
|
||||
<site> '-' <machine>
|
||||
|
||||
<site> will be at most 4 characters, formed as follows:
|
||||
|
||||
(a) Use the keyword in the site name, if not more than
|
||||
four characters, e.g., NASA Ames, Case Western
|
||||
Reserve. ---- ----
|
||||
|
||||
(b) Use the standard acronym, if not more than four
|
||||
characters, e.g., UCLA, RADC, NBS.
|
||||
|
||||
(c) If a standard abbreviation exists, use it, e.g., Ill.
|
||||
|
||||
(d) If none of the above apply, use the first four letters
|
||||
in the site name, e.g., Burr, Mitr, Harv.
|
||||
|
||||
(e) If none of the above is acceptable to the site, the
|
||||
technical liaison should select the site mnemonic.
|
||||
|
||||
<machine> will be at most 4 characters of the form <mfg. #>
|
||||
<designator>.
|
||||
Examples of mfg. # are:
|
||||
|
||||
IBM 360 2 digit model number
|
||||
IBM 370 3 digit model number
|
||||
PDP 1 - 2 digit model number
|
||||
Burroughs 4 digits
|
||||
CDC 4 digits
|
||||
etc.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Page 1]
|
||||
|
||||
RFC #247
|
||||
|
||||
|
||||
<designator> will be used when more than one machine of the same
|
||||
type is located at a site (e.g., 2 PDP-10s at MIT, at SRI, and
|
||||
at BBN).
|
||||
|
||||
Limiting <machine> to 4 characters does not permit distinctions
|
||||
to be made between machines with 4 digit mfg. #s. I expect
|
||||
the situation will be handled in an ad hoc manner by the NIC if
|
||||
it arises.
|
||||
|
||||
TIPs are identified as 'TIP' rather than by '316'. If a Host
|
||||
is not to be permanently addressable, the machine is identified
|
||||
as 'TEST'.
|
||||
|
||||
A list of Host names, formed according to these rules, is
|
||||
attached. Alternate Host names should be provided, as
|
||||
suggested by Jon Postel (RFC #236). RFC's 206, 233, and
|
||||
236 present lists with 4-character alternate names. The
|
||||
Technical Liaison should select the alternate name for his
|
||||
site and communicate the selection to the NIC.
|
||||
|
||||
|
||||
The preceding rules and the attached list of Host names are
|
||||
subject to the approval of the NWG. Hereafter, the list will
|
||||
be generated and maintained by the NIC in cooperation with
|
||||
the Technical Liaison at each site, as suggested in RFC #237.
|
||||
Comments should be addressed to Dick Watson.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[ This RFC was put into machine readable form for entry ]
|
||||
|
||||
[ into the online RFC archives by BBN Corp. under the ]
|
||||
|
||||
[ direction of Alex McKenzie. 12/96 ]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Page 2]
|
||||
|
||||
RFC #247
|
||||
Attachment 1
|
||||
|
||||
NETWORK ADDRESS STANDARD NAME
|
||||
--------------- -------------
|
||||
1 UCLA-7
|
||||
65 UCLA-91
|
||||
2 SRI-10NI
|
||||
66 SRI-10AI
|
||||
3 UCSB-75
|
||||
4 UTAH-10
|
||||
5 BBN-516
|
||||
69 BBN-10A
|
||||
133 BBN-10B
|
||||
6 MIT-645
|
||||
70 MIT-10DM
|
||||
134 MIT-10AI
|
||||
7 RAND-65
|
||||
71 RAND-10
|
||||
8 SDC-75
|
||||
9 HARV-10
|
||||
73 HARV-1
|
||||
137 HARV-11
|
||||
10 LL-67
|
||||
74 LL-TX2
|
||||
138 LL-TSP
|
||||
11 SAIL-10
|
||||
12 ILL-11
|
||||
76 ILL-6500
|
||||
13 CASE-10
|
||||
14 CMU-10
|
||||
15 BURR-6500
|
||||
79 BURR-TEST
|
||||
16 AMES-67
|
||||
144 AMES-TIP
|
||||
145 MITR-TIP
|
||||
18 RADC-645
|
||||
146 RADC-TIP
|
||||
19 NBS-11
|
||||
147 NBS-TIP
|
||||
148 ETAC-TIP
|
||||
21 TINK-418
|
||||
22 MCCL-418
|
||||
23 USC-44
|
||||
151 USC-TIP
|
||||
152 GWC-TIP
|
||||
25 NCAR-7600
|
||||
153 NCAR-TIP
|
||||
158 BBNX-TEST
|
||||
|
||||
|
||||
|
||||
[Page 3]
|
||||
|
||||
RFC #247
|
||||
Attachment 2
|
||||
|
||||
An Implementation Scheme
|
||||
|
||||
If the standard Host names are formed according to the proposed
|
||||
rules, the following implementation scheme, suggested by Steve
|
||||
Crocker, can be used.
|
||||
|
||||
Map <site> into an 8-bit number, S and
|
||||
map <machine> into an 8-bit number, M,
|
||||
where
|
||||
S + M = Network Address.
|
||||
|
||||
S and M can be selected such that specification of <site>
|
||||
alone could cause a default to the "primary" Host at
|
||||
the site. Note that this scheme depends on a unique
|
||||
<site> designator for each IMP.
|
||||
|
||||
Some examples:
|
||||
|
||||
If the "primary" Host at UCLA is the 91, let
|
||||
UCLA -> S = X'41'
|
||||
7 -> M = X'40'
|
||||
91 -> M = X'00'
|
||||
then for
|
||||
UCLA-7, S + M = X'01' = 1 base 10
|
||||
UCLA-91,S + M = X'41' = 65 base 10
|
||||
|
||||
and
|
||||
UCLA alone = X'41' = 65 base 10
|
||||
|
||||
If the primary Host at BBN is TENEX System A, let
|
||||
BBN -> S = X'45'
|
||||
516 -> M = X'40'
|
||||
10A -> M = X'00'
|
||||
10B -> M = X'C0'
|
||||
then for
|
||||
BBN-516, S + M = X'05' = 5 base 10
|
||||
BBN-10A, S + M = X'45' = 69 base 10
|
||||
BBN-10B, S + M = X'85' = 133 base 10
|
||||
|
||||
and
|
||||
BBN alone = X'45' = 69 base 10
|
||||
|
||||
The primary Host for each IMP would be designated by the
|
||||
site and such information disseminated by the NIC.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Page 4]
|
||||
|
3077
libc/dns/rfc1035.txt
Normal file
3077
libc/dns/rfc1035.txt
Normal file
File diff suppressed because it is too large
Load diff
49
libc/dns/sorthoststxt.c
Normal file
49
libc/dns/sorthoststxt.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
|
||||
/**
|
||||
* Compares hostnames in HOSTS.TXT table.
|
||||
* @see dnsnamecmp(), parsehoststxt()
|
||||
*/
|
||||
static int cmphoststxt(const struct HostsTxtEntry *e1,
|
||||
const struct HostsTxtEntry *e2, const char *strings) {
|
||||
if (e1 == e2) return 0;
|
||||
return dnsnamecmp(&strings[e1->name], &strings[e2->name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts entries in HOSTS.TXT table.
|
||||
*
|
||||
* This function enables resolvehoststxt() to be called so hard-coded
|
||||
* hostname lookups take logarithmic time; you can blackhole all the
|
||||
* spam you want, in your /etc/hosts file.
|
||||
*
|
||||
* The sorted order, defined by dnsnamecmp(), also makes it possible to
|
||||
* efficiently search for subdomains, once the initial sort is done.
|
||||
*/
|
||||
void sorthoststxt(struct HostsTxt *ht) {
|
||||
if (ht->entries.p) {
|
||||
qsort_r(ht->entries.p, ht->entries.i, sizeof(*ht->entries.p),
|
||||
(void *)cmphoststxt, ht->strings.p);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue