brutella/hap

dnssd Name Conflict Resolution results in HTTP Bad Request

geekman opened this issue · 0 comments

Actually I'm not sure if I should file this in dnssd or hap, but I think the issue is unique to hap, so it's filed here.

When dnssd detects that a hostname is in use, it then tries to pick a different name by appending a space & number "%s %d", which is probably what iOS does too:

https://github.com/brutella/dnssd/blob/8574d113aa9e847409d25d90ac0ba1e0512f601c/probe.go#L76-L86

In doing so, the hostname now contains a space and HomeKit encodes the space as \032 in the Host: header which results in an invalid hostname under HTTP, so the http parser replies with an error. Related issue #9.

There's already an attempt to avoid spaces by replacing the server/accessory name before passing it to dnssd, but in this case the spaces were added by dnssd:

hap/server.go

Lines 509 to 519 in 1a3e48c

stripped := strings.Replace(s.a.Info.Name.Value(), " ", "_", -1)
cfg := dnssd.Config{
Name: removeAccentsFromString(stripped),
Type: "_hap._tcp",
Domain: "local",
Host: strings.Replace(s.uuid, ":", "", -1), // use the id (without the colons) to get unique hostnames
Text: s.txtRecords(),
Port: s.port,
Ifaces: s.Ifaces,
}

I'm not sure that iOS will fix this issue anytime soon (or at all), so maybe hap/dnssd should try to avoid generating such names. Maybe dnssd could defer to the caller (hap, in this case) for conflict resolution strategies, where it could send back "-" + random_hex_str instead of using " %d".