aboutsummaryrefslogtreecommitdiff
path: root/core/net/dns_unix.odin
diff options
context:
space:
mode:
authorColin Davidson <colrdavidson@gmail.com>2023-03-01 07:58:30 -0800
committerColin Davidson <colrdavidson@gmail.com>2023-03-01 07:58:30 -0800
commit28f7f572473c4e97ccd6133bb4f5fa6f45505530 (patch)
tree0bd159c24c617df409f72b0ec75daa086372e94d /core/net/dns_unix.odin
parent3567c006e6683d989805c078db48a95a901d9e72 (diff)
manually start merging core_net
Diffstat (limited to 'core/net/dns_unix.odin')
-rw-r--r--core/net/dns_unix.odin83
1 files changed, 83 insertions, 0 deletions
diff --git a/core/net/dns_unix.odin b/core/net/dns_unix.odin
new file mode 100644
index 000000000..7f57927fd
--- /dev/null
+++ b/core/net/dns_unix.odin
@@ -0,0 +1,83 @@
+//+build linux, darwin, freebsd, openbsd, !windows
+/*
+ Copyright 2022 Tetralux <tetraluxonpc@gmail.com>
+ Copyright 2022 Colin Davidson <colrdavidson@gmail.com>
+ Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
+ Made available under Odin's BSD-3 license.
+
+ List of contributors:
+ Tetralux: Initial implementation
+ Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
+ Jeroen van Rijn: Cross platform unification, code style, documentation
+*/
+
+/*
+ Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
+ For other protocols and their features, see subdirectories of this package.
+*/
+package net
+
+import "core:strings"
+
+get_dns_records_unix :: proc(hostname: string, type: DNS_Record_Type, allocator := context.allocator) -> (records: []DNS_Record, err: DNS_Error) {
+ context.allocator = allocator
+
+ if type != .SRV {
+ // NOTE(tetra): 'hostname' can contain underscores when querying SRV records
+ ok := validate_hostname(hostname)
+ if !ok {
+ return nil, .Invalid_Hostname_Error
+ }
+ }
+
+ name_servers, resolve_ok := load_resolv_conf(dns_configuration.resolv_conf)
+ defer delete(name_servers)
+ if !resolve_ok {
+ return nil, .Invalid_Resolv_Config_Error
+ }
+ if len(name_servers) == 0 {
+ return
+ }
+
+ hosts, hosts_ok := load_hosts(dns_configuration.hosts_file)
+ defer delete(hosts)
+ if !hosts_ok {
+ return nil, .Invalid_Hosts_Config_Error
+ }
+ if len(hosts) == 0 {
+ return
+ }
+
+ host_overrides := make([dynamic]DNS_Record)
+ for host in hosts {
+ if strings.compare(host.name, hostname) != 0 {
+ continue
+ }
+
+ if type == .IP4 && family_from_address(host.addr) == .IP4 {
+ record := DNS_Record_IP4{
+ base = {
+ record_name = strings.clone(hostname),
+ ttl_seconds = 0,
+ },
+ address = host.addr.(IP4_Address),
+ }
+ append(&host_overrides, record)
+ } else if type == .IP6 && family_from_address(host.addr) == .IP6 {
+ record := DNS_Record_IP6{
+ base = {
+ record_name = strings.clone(hostname),
+ ttl_seconds = 0,
+ },
+ address = host.addr.(IP6_Address),
+ }
+ append(&host_overrides, record)
+ }
+ }
+
+ if len(host_overrides) > 0 {
+ return host_overrides[:], nil
+ }
+
+ return get_dns_records_from_nameservers(hostname, type, name_servers, host_overrides[:])
+}