In a former life I was a programmer, and given my abundance of free time lately, some of the old habits have begun to reassert themselves. I was always curious about Mono but could only spend some time with it in the professional world. Now, with more free time, I can tinker with it as a hobbyist and this has allowed me to examine aspects of Mono I never encountered before, like Mono.Zeroconf.
Mono.Zeroconf allows a .NET programmer to utilize Zero Configuration Networking in their application with minimal fuss. I wanted to integrate this library into a little application I wanted to build. The application would announce its presence via Mono.Zeroconf and wait for subscribing clients to connect to it.
From reading the documentation, Mono.Zeroconf looked perfect. It even works in Windows as long as you have Bonjour installed. Mono.Zeroconf is currently at release 0.90 so I expected some bugs. But I quickly found a fairly big bug in the library.
Its briefly addressed in the Known Workarounds section of the Mono.Zeroconf page. There, you see discussion of the Port property defined in the Mono.Zeroconf API. An additional property UPort was created to address issues in Mono.Zeroconf versions prior to 0.90. There however is a bug in the Bonjour implementation of Mono.Zeroconf.
It appears the new UPort property as implemented in Mono.Zeroconf.Providers.Bonjour.Services.UPort has a bug. When I attempted to run sample code that came with Mono.Zeroconf, any attempts to register a Bonjour service failed. After some debugging, I noticed the Port and UPort properties were set to 0. After further investigation, I saw the underlying code in Mono.Zeroconf.Providers.Bonjour.Services was incorrect.
I’m not the first to notice this. The Mono bug tracker suggests bugs 529363 and 502560 are already filed on this issue. I wasn’t sure about the solution offered in the description for bug 502560, but I found another solution on the Mono mailing list that looked more promising. It is contained in a thread from Casey Marshall that included a patch to fix this bug. His description of the problem is as follows:
The endian conversion in the property Mono.Zeroconf.Providers.Bonjour.Service.UPort is wrong; casting between an int and a ushort doesn't do the right thing — NetworkToHostOrder will shift the low bytes into the high bytes, but casting that to a ushort discards the high bytes.
The last patch he submitted to the mailing list that addressed big endian architectures was unfortunately also broken. Specifically, the setter for UPort was incorrect. The fixed code is as follows:
public ushort UPort
{
get
{
if( BitConverter.IsLittleEndian )
{
return (ushort)( ( ( port & 0x00FF ) << 8 ) | ( ( port & 0xFF00 ) >> 8 ) );
}
return port;
}
set
{
if( BitConverter.IsLittleEndian )
{
port = (ushort)( ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 ) );
}
else
{
port = value;
}
}
}
This looks to be a better solution than is listed in Bug 502560. But as far as I could tell, neither the fix proposed in the bug report nor the patch from Casey Marshall appears to be in the code repository. It looks like I’ll have to figure out how to get this fix committed to Mono.Zeroconf. But now the first few lines of my application appear to work. Progress!
0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.