Pārlūkot izejas kodu

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

Jeroen van Rijn 7 mēneši atpakaļ
vecāks
revīzija
d85c2c1ca7

+ 3 - 0
core/net/common.odin

@@ -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
core/net/dns_windows.odin

@@ -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
core/net/socket_linux.odin

@@ -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
core/sys/windows/dnsapi.odin

@@ -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 - 0
core/sys/windows/types.odin

@@ -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,