Add mDNS/Bonjour/Avahi (.local) support for Windows

This commit is contained in:
Jeroen van Rijn
2025-01-27 22:16:24 +01:00
parent 4d3fe34c88
commit d85c2c1ca7
5 changed files with 38 additions and 3 deletions
+3
View File
@@ -95,6 +95,7 @@ Resolve_Error :: enum u32 {
}
DNS_Error :: enum u32 {
None = 0,
Invalid_Hostname_Error = 1,
Invalid_Hosts_Config_Error,
Invalid_Resolv_Config_Error,
@@ -147,6 +148,8 @@ IP6_Loopback :: IP6_Address{0, 0, 0, 0, 0, 0, 0, 1}
IP4_Any := IP4_Address{}
IP6_Any := IP6_Address{}
IP4_mDNS_Broadcast := Endpoint{address=IP4_Address{224, 0, 0, 251}, port=5353}
Endpoint :: struct {
address: Address,
port: int,
+6 -1
View File
@@ -29,9 +29,14 @@ import win "core:sys/windows"
_get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator := context.allocator) -> (records: []DNS_Record, err: DNS_Error) {
context.allocator = allocator
options := win.DNS_QUERY_OPTIONS{}
if strings.has_suffix(hostname, ".local") {
options = {.MULTICAST_ONLY, .MULTICAST_WAIT} // 0x00020500
}
host_cstr := strings.clone_to_cstring(hostname, context.temp_allocator)
rec: ^win.DNS_RECORD
res := win.DnsQuery_UTF8(host_cstr, u16(type), 0, nil, &rec, nil)
res := win.DnsQuery_UTF8(host_cstr, u16(type), options, nil, &rec, nil)
switch u32(res) {
case 0:
+3 -1
View File
@@ -35,6 +35,7 @@ Socket_Option :: enum c.int {
Send_Buffer_Size = c.int(linux.Socket_Option.SNDBUF),
Receive_Timeout = c.int(linux.Socket_Option.RCVTIMEO),
Send_Timeout = c.int(linux.Socket_Option.SNDTIMEO),
Broadcast = c.int(linux.Socket_Option.BROADCAST),
}
// Wrappers and unwrappers for system-native types
@@ -337,7 +338,8 @@ _set_option :: proc(sock: Any_Socket, option: Socket_Option, value: any, loc :=
.Reuse_Address,
.Keep_Alive,
.Out_Of_Bounds_Data_Inline,
.TCP_Nodelay:
.TCP_Nodelay,
.Broadcast:
// TODO: verify whether these are options or not on Linux
// .Broadcast, <-- yes
// .Conditional_Accept,
+1 -1
View File
@@ -5,6 +5,6 @@ foreign import "system:Dnsapi.lib"
@(default_calling_convention="system")
foreign Dnsapi {
DnsQuery_UTF8 :: proc(name: cstring, type: u16, options: DWORD, extra: PVOID, results: ^^DNS_RECORD, reserved: PVOID) -> DNS_STATUS ---
DnsQuery_UTF8 :: proc(name: cstring, type: u16, options: DNS_QUERY_OPTIONS, extra: PVOID, results: ^^DNS_RECORD, reserved: PVOID) -> DNS_STATUS ---
DnsRecordListFree :: proc(list: ^DNS_RECORD, options: DWORD) ---
}
+25
View File
@@ -4576,6 +4576,31 @@ DNS_SRV_DATAA :: struct {
_: WORD, // padding
}
// See https://learn.microsoft.com/en-us/windows/win32/dns/dns-constants
DNS_QUERY_OPTION :: enum DWORD {
ACCEPT_TRUNCATED_RESPONSE = 0,
DNS_QUERY_USE_TCP_ONLY = 1,
NO_RECURSION = 2,
BYPASS_CACHE = 3,
NO_WIRE_QUERY = 4,
NO_LOCAL_NAME = 5,
NO_HOSTS_FILE = 6,
NO_NETBT = 7,
WIRE_ONLY = 8,
RETURN_MESSAGE = 9,
MULTICAST_ONLY = 10,
NO_MULTICAST = 11,
TREAT_AS_FQDN = 12,
ADDRCONFIG = 13,
DUAL_ADDR = 14,
MULTICAST_WAIT = 17,
MULTICAST_VERIFY = 18,
DONT_RESET_TTL_VALUES = 20,
DISABLE_IDN_ENCODING = 21,
APPEND_MULTILABEL = 23,
}
DNS_QUERY_OPTIONS :: bit_set[DNS_QUERY_OPTION; DWORD]
SOCKADDR :: struct {
sa_family: ADDRESS_FAMILY,
sa_data: [14]CHAR,