dns_unix.odin 2.2 KB

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