Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#15 server process crashes on large SOAP response

closed-fixed
None
5
2009-10-16
2009-08-07
David Torrey
No

There is a hard memory limit defined in upnpsoap.c of 1MB for the SOAP response. This is reached for large collections, and causes an error message:

[2009/08/07 12:15:48] upnpsoap.c:511: error: UPnP SOAP response is getting too big! [1338 returned]

followed by a segfault and crash of the entire process.

I'm not familiar enough with the UPnP protocols to know whether this is a server bug, client bug (asking for too much at once?) or protocol flaw, but I can reproduce it at will by navigating to the "All Music" folder, for example. The immediate bug seems to be the call to sqlite3_exec() on line 945 of upnpsoap.c, and the resulting calls to the callback function (where the error message is produced). There does not seem to be a failsafe to actually stop the response building and work out an alternative, so the query results happily blaze past the end of passed_args->resp.

Playing with the hard limit would delay the problem, but I'm thinking there must be some way to break up large responses in this situation. OTOH, to reproduce the problem without requiring a large collection of files, one could drop that limit to, say, 10kB, and likely get the same results.

As a short-term workaround, to truncate the search without crashing, the attached patch may be useful. Oddly, on my NAS, it seems to actually catch all the tracks somehow. Slowly.

Fair warning on running it in debug mode, though. That's one heck of a packet :)

Thanks,
Dave

Discussion

  • David Torrey
    David Torrey
    2009-08-07

    fix callback() in upnpsoap.c to avoid segfault

     
    Attachments
  • Justin Maggard
    Justin Maggard
    2009-08-07

    Ah, good catch! What client are you using? Every client I've seen asks for no more than 1,000 results at a time.

     
  • David Torrey
    David Torrey
    2009-08-07

    Heh... to be fair, that's why I'm not sure what the root cause was. I'm using 'djmount' to test because I'm not on the same network as the server right now, so that allows command-line-based testing. For better or worse, it seemed to be prefetching listings as I cd'd around the tree. I can see asking for a large list, but was surprised it would ask/respond with an attempt to fit it into a single chunk.

    I don't have a hardware client, but will test rhythmbox when I get home. That might behave better, but at least now it's not crashing.

    Dave

     
  • Justin Maggard
    Justin Maggard
    2009-08-07

    • assigned_to: nobody --> jmaggard
    • status: open --> open-fixed
     
  • Justin Maggard
    Justin Maggard
    2009-08-07

    Well that was definitely a bug. Don't know what I was thinking when I wrote that code. :) I've checked in code to realloc if the response size gets too large, and to gracefully abort the SQL exec activity if it gets too large. On my own testing with djmount, it looks like even if we (or ushare) return a proper huge list, djmount won't display it unless the response is under 1MB (well, I didn't try in very granular increments, but 1MB worked, 2MB didn't). So I set the default max response size to 1MB, and we'll just return an incomplete result set if gets larger than that. Please let me know if the fix doesn't work for you.

     
  • David Torrey
    David Torrey
    2009-08-09

    With the changes in CVS to date, the process no longer crashes. Djmount seems to be content, but rhythmbox can't get a track listing. The minidlna error log is similar: for both clients, it complains that the UPnP SOAP response was cut short a couple times, but for rhythmbox, those messages are followed by lots of "HTTP Connection closed inexpectedly" lines from upnphttp.c:828. I'm wondering if something is missing a request size from the client, since I would have expected rhythmbox to request a more reasonable chunk of the listings.

    Dave

     
  • Justin Maggard
    Justin Maggard
    2009-08-10

    The Rhythmbox DLNA plugin doesn't seem to work very well. From my testing using the Fedora 11 packages, it doesn't limit requests (like djmount), and it doesn't even work with responses that contain a duration with a period. So when MiniDLNA returns metadata for a song as something like "duration=00:03:50.135", it can't handle it. As a test I modified /usr/lib/rhythmbox/plugins/upnp_coherence/UpnpSource.py and changed line 135:
    seconds = int(h)*3600 + int(m)*60 + int(s)
    to
    seconds = int(h)*3600 + int(m)*60 + int(float(s))
    , and Rhythmbox was then able to display the track listing.

     
  • Justin Maggard
    Justin Maggard
    2009-10-16

    • status: open-fixed --> closed-fixed