Bugfix Submissions and Feedback

Sep 20, 2010 at 7:21 AM

There's a bug when Srv objects get cloned and then it tries to parse them again. In the WriteTo() function the so called "Useless data" which is the length of the Srv is not written to the buffer. It should be something like this:

public class Srv : ResponseData
    {
        public override void WriteTo(System.IO.BinaryWriter writer)
        {
            // Assume a length of 8 although if we're reading it we don't care
            writer.Write(new byte[] { 0, 8 });
            writer.Write(Message.ToBytes(Priority));
            writer.Write(Message.ToBytes(Weight));
            writer.Write(Message.ToBytes(Port));
            Target.WriteTo(writer);
        }

Additionally in BonjourServiceResolver.cs there's an issue where MergeServices may get called from multiple threads at the same time. This causes an InvalidOperationException because the services collection is modified while being enumerated. It's not the most ideal solution, but technically you can just throw a lock (this.services) around the whole function without any problems.

And finally I see you're using ExclusiveAddressUse = true in Server.cs, however, I believe what you're really wanting is:
udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);


If you add that in there then you can have multiple programs running your library at the same time. Otherwise you'll get exceptions about the port already being used.

Overall it seems to be a pretty damn good solution. I'm using it to implement DNS SD capabilities for IP camera discovery at work and I think I'm pretty much done with the code in the maybe two hours I've been using the library. If I find any more issues during testing I'll be sure to let you know.

Sep 20, 2010 at 7:31 AM

Thank you for posting corrections. This project seems to be abandoned so I think it would be best that you take it over and publish a new library.

Coordinator
Sep 20, 2010 at 8:09 AM

Hi,

Thanks a lot for your code. I'll have a look.

@grJubei, the project is not abandonned. Even if it's true I did not make any upgrade for a long time, I am still working on it. I am working on implementing Upnp, which is not an easy piece of SD... More specific, for now, I am working on DLNA implementation.

Sep 20, 2010 at 8:14 AM
neonp wrote:

the project is not abandonned. I am working on implementing Upnp, which is not an easy piece of SD... More specific, for now, I am working on DLNA implementation.

I'm sorry I was under the wrong impression. DLNA, is that proprietary or is it an open standard? i.e. Does one have to pay to get the spec?

Coordinator
Sep 20, 2010 at 8:17 AM

To get DLNA certified, you need to pay, but dlna is based on Upnp-video and upnp-audio, which are free. To make DLNA work, I sniff DLNA frames when requesting a Windows Media Player. I also was able to find a spec, but I do not remember where.

Sep 20, 2010 at 3:14 PM

Good to know the project is still active. I don't really know much about Bonjour so I wouldn't really be too much help. However, any bugfixes and feedback I can provide I'll be glad to help. I also have a proprietary UPnP library. It's not a full implementation, but some of it may be useful. I also have a GENA implementation too if you'll be needing GENA for your UPnP library.

Sep 23, 2010 at 2:31 AM

Alright one more suggestion. It looks like there's potential for a couple exceptions that could be avoided in BonjourServiceResolver. The first one is that again the services collection could change while dispose is looping through it. I would simply recommend calling client.Stop() before stopping the services which would avoid that entirely. In addition it's possible although typically unlikely that maybe you created a BonjourServiceResolver, but a user never initiated the action that would call Resolve() in which case client would be null and you would get a NullReferenceException in Dispose(). I would suggest changing Dispose to be like the following:

        public void Dispose()
        {
            if (client != null)
                client.Stop();

            foreach (IService service in services)
                service.Stop();
        }