dns_unix.odin 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //+build linux, darwin, freebsd
  2. package net
  3. /*
  4. Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
  5. For other protocols and their features, see subdirectories of this package.
  6. */
  7. /*
  8. Copyright 2022 Tetralux <[email protected]>
  9. Copyright 2022 Colin Davidson <[email protected]>
  10. Copyright 2022 Jeroen van Rijn <[email protected]>.
  11. Copyright 2024 Feoramund <[email protected]>.
  12. Made available under Odin's BSD-3 license.
  13. List of contributors:
  14. Tetralux: Initial implementation
  15. Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
  16. Jeroen van Rijn: Cross platform unification, code style, documentation
  17. Feoramund: FreeBSD platform code
  18. */
  19. import "core:strings"
  20. @(private)
  21. _get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator := context.allocator) -> (records: []DNS_Record, err: DNS_Error) {
  22. context.allocator = allocator
  23. if type != .SRV {
  24. // NOTE(tetra): 'hostname' can contain underscores when querying SRV records
  25. ok := validate_hostname(hostname)
  26. if !ok {
  27. return nil, .Invalid_Hostname_Error
  28. }
  29. }
  30. name_servers, resolve_ok := load_resolv_conf(dns_configuration.resolv_conf)
  31. defer delete(name_servers)
  32. if !resolve_ok {
  33. return nil, .Invalid_Resolv_Config_Error
  34. }
  35. if len(name_servers) == 0 {
  36. return
  37. }
  38. hosts, hosts_ok := load_hosts(dns_configuration.hosts_file)
  39. defer delete(hosts)
  40. if !hosts_ok {
  41. return nil, .Invalid_Hosts_Config_Error
  42. }
  43. host_overrides := make([dynamic]DNS_Record)
  44. for host in hosts {
  45. if strings.compare(host.name, hostname) != 0 {
  46. continue
  47. }
  48. if type == .IP4 && family_from_address(host.addr) == .IP4 {
  49. record := DNS_Record_IP4{
  50. base = {
  51. record_name = strings.clone(hostname),
  52. ttl_seconds = 0,
  53. },
  54. address = host.addr.(IP4_Address),
  55. }
  56. append(&host_overrides, record)
  57. } else if type == .IP6 && family_from_address(host.addr) == .IP6 {
  58. record := DNS_Record_IP6{
  59. base = {
  60. record_name = strings.clone(hostname),
  61. ttl_seconds = 0,
  62. },
  63. address = host.addr.(IP6_Address),
  64. }
  65. append(&host_overrides, record)
  66. }
  67. }
  68. if len(host_overrides) > 0 {
  69. return host_overrides[:], nil
  70. }
  71. return get_dns_records_from_nameservers(hostname, type, name_servers, host_overrides[:])
  72. }