diff --git a/ChangeLog b/ChangeLog index f5666fb..a8f1aaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,37 @@ Version 1.6.7 ******************************************************************************* +2010-06-10 Marcelo Jimenez + SF Bug Tracker [ 3007407 ] Service traversal issue in AdvertiseAndReply() + Submitted: Chuck Thomason ( cyt4 ) - 2010-05-26 15:07:39 UTC + + When the UPnP server is started, one alive message is broadcast for each + service in each device. It appears that libupnp's implementation of the + alive message generation does not correctly navigate the XML description + document when locating the services. This can result in the wrong UDN + being used in the alive message sent for a service. + + In my specific case (see attached XML), the root EchoSTB device contains + no services, but its embedded MediaServer device contains 2 services. + When the existing libupnp code traverses the EchoSTB device in the XML, + it searches the global list of serviceLists within the document instead + of searching for a serviceList that is its direct child node. The + ContentDirectory and ConnectionManager services are then announced with + the UDN of EchoSTB1 (the root device) instead of with the UDN of + MediaServer, which is actually their parent device. + + I discovered this behavior using libupnp-1.6.6. I have generated a patch + against branch-1.6.x that corrects the XML navigation such that all + services are traversed from their parent device, which results in the + correct UDN being sent in the alive message for each service. I built + from branch-1.6.x without this patch, tested, and confirmed that the + issue still exists as I observed it in libupnp-1.6.6. I then built + from branch-1.6.x with this patch, tested, and confirmed that the + issue was resolved. + + Thanks, + Chuck Thomason + 2010-05-07 Marcelo Jimenez SF Bug Tracker [ 2995758 ] libupnp 1.6.6, wrong bind when reuseaddr is 1. @@ -17,7 +48,6 @@ Version 1.6.7 2010-03-27 Nick Leverton Subscription auto-renewals copy the renewal time from old subscription. - 2010-03-27 Marcelo Jimenez Backport of svn revision 527: * Added API to ithread, created the following functions: diff --git a/THANKS b/THANKS index 9c4e654..73eab8e 100644 --- a/THANKS +++ b/THANKS @@ -16,6 +16,7 @@ exempt of errors. - Chaos - Charles Nepveu (cnepveu) - Chris Pickel +- Chuck Thomason (cyt4) - Craig Nelson - David Maass - Emil Ljungdahl diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index b7e302a..6e31908 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -96,6 +96,8 @@ struct SSDPSockArray { * Returns: int * UPNP_E_SUCCESS if successful else appropriate error ***************************************************************************/ +static const char *SERVICELIST_STR = "serviceList"; + int AdvertiseAndReply( IN int AdFlag, IN UpnpDevice_Handle Hnd, @@ -280,9 +282,22 @@ int AdvertiseAndReply( UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Sending service Advertisement\n"); - tmpNode = ixmlNodeList_item(SInfo->ServiceList, i); - if (!tmpNode) continue; + /* Correct service traversal such that each device's serviceList + * is directly traversed as a child of its parent device. This + * ensures that the service's alive message uses the UDN of + * the parent device. */ + tmpNode = ixmlNode_getFirstChild(tmpNode); + while (tmpNode) { + dbgStr = ixmlNode_getNodeName(tmpNode); + if (!strncmp(dbgStr, SERVICELIST_STR, sizeof(SERVICELIST_STR))) { + break; + } + tmpNode = ixmlNode_getNextSibling(tmpNode); + } ixmlNodeList_free(nodeList); + if (!tmpNode) { + continue; + } nodeList = ixmlElement_getElementsByTagName( (IXML_Element *)tmpNode, "service"); if (!nodeList) {