Bug 94085 - dbus_connection_open not returning shared connections if the address does not include "guid"
Summary: dbus_connection_open not returning shared connections if the address does not...
Status: RESOLVED MOVED
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: 1.10
Hardware: All Linux (All)
: medium normal
Assignee: D-Bus Maintainers
QA Contact: D-Bus Maintainers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-02-10 23:03 UTC by missa
Modified: 2018-10-12 21:26 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
dbus-test.c (1.03 KB, text/plain)
2016-02-10 23:03 UTC, missa
Details
Add a regression test for connection re-use (7.24 KB, patch)
2016-02-11 14:11 UTC, Simon McVittie
Details | Splinter Review

Description missa 2016-02-10 23:03:55 UTC
Created attachment 121657 [details]
dbus-test.c

It seems dbus_connection_open() is not returning shared connections. It is not clear if there is some miss configuration or some bug.

The issue can be seen easily. Every call to dbus_connection_open() returns a different pointer and refcount of 2 (1 for application and 1 for libdbus).

After some time the system is crashing because the connections are maxed out. There are dbus_connection_unref() calls but this doesn't free the shared connections and since we are getting a new connection every time, it is easy to max them out.
We checked the resources usage and the number of FDs, sockets and memory increase with every call.

After some investigation, dbus_bus_get() seems to always return the same pointer with refcount incremented as expected. FDs, sockets, memory seem not impacted.

Attached is a simple program tested on x86 ubuntu that shows this behavior.
Comment 1 Simon McVittie 2016-02-11 13:32:14 UTC
(In reply to missa from comment #0)
> After some investigation, dbus_bus_get() seems to always return the same
> pointer with refcount incremented as expected.

If you are connecting to the standard system or session bus, I would recommend using dbus_bus_get() - that's what it's there for.

If your application requires a connection to a custom bus or peer-to-peer server specified by its address, then dbus_connection_open() is the correct function to be using, and you are correct to think that

    for (...)
      {
        conn = dbus_connection_open (address, &error);
        dbus_connection_unref (conn);
      }

should return the same pointer repeatedly.

You could work around this bug by calling dbus_connection_open() (or dbus_connection_open_private()) once, and storing the resulting pointer in your own global or static variable. That's essentially what libdbus has to do for dbus_bus_get(), and what it's meant to do for dbus_connection_open() (but from your report it seems that the latter doesn't work correctly).

I suspect that the reason nobody previously reported this is that most libdbus users use dbus_bus_get(), and in use-cases that need to connect to a specified address (for example the Tubes APIs in Telepathy), the implementer usually doesn't want the connection-sharing behaviour and will use dbus_connection_open_private().
Comment 2 Simon McVittie 2016-02-11 14:09:04 UTC
(In reply to Simon McVittie from comment #1)
> (but from your report it seems that the latter doesn't work correctly)

I couldn't reproduce this with the current stable release of libdbus (1.10.6 from the Debian package libdbus-1-3 version 1.10.6-1), after changing the value of "n" to be getenv ("DBUS_SESSION_BUS_ADDRESS") so your test program works on systems other than your own. I get the same connection repeatedly, with a refcount that goes up every time, or stays at 2 if I uncomment the dbus_connection_unref() call.

(In reply to missa from comment #0)
> tested on x86 ubuntu

What does "x86 ubuntu" mean? i386 or x86_64? Which version of Ubuntu? Which version of libdbus-1-3?
Comment 3 Simon McVittie 2016-02-11 14:11:12 UTC
Created attachment 121673 [details] [review]
Add a regression test for connection re-use

Loosely based on loopback.c. This was an attempt to reproduce bug 94085.
Comment 4 missa 2016-02-11 16:06:50 UTC
We do have a custom bus.
The issue is first reported on ARM with libdbus 1.6.4
We reproduced on latest ubuntu 15.10-desktop-amd64 x86_64.

missa@ubuntu:~/Desktop/dbus$ uname -a
Linux ubuntu 4.2.0-27-generic #32-Ubuntu SMP Fri Jan 22 04:49:08 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
missa@ubuntu:~/Desktop/dbus$ dbus-daemon --version
D-Bus Message Bus Daemon 1.10.0
Copyright (C) 2002, 2003 Red Hat, Inc., CodeFactory AB, and others
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I tried to change "n" as you suggested but we get the same results:

Trial 0
conn ptr 0xc77df0 refcount 2
Trial 1
conn ptr 0xc78a20 refcount 2
Trial 2
conn ptr 0xc79650 refcount 2
Trial 3
conn ptr 0xc7a280 refcount 2
Trial 4
conn ptr 0xc7b1d0 refcount 2
Trial 5
conn ptr 0xc7be00 refcount 2
Trial 6
conn ptr 0xc7ca30 refcount 2
Trial 7
conn ptr 0xc7d660 refcount 2
Trial 8
conn ptr 0xc7e290 refcount 2
Trial 9
conn ptr 0xc7eec0 refcount 2
Comment 5 missa 2016-02-11 16:23:05 UTC
Using this library:
ls -l /usr/lib/x86_64-linux-gnu/libdbus-1.so
lrwxrwxrwx 1 root root 41 Sep  1 10:01 /usr/lib/x86_64-linux-gnu/libdbus-1.so -> /lib/x86_64-linux-gnu/libdbus-1.so.3.14.3
Comment 6 Simon McVittie 2016-02-12 08:08:12 UTC
Thanks, I can reproduce this on Ubuntu with libdbus-1-3 version 1.10.0-1ubuntu1. (When reporting bugs in Debian or Ubuntu packages, please use "dpkg -s libdbus-1-3" or "dpkg-query -W libdbus-1-3" to find the exact version number.)

The difference appears to be in the Ubuntu-specific script that starts the session dbus-daemon via Upstart: it produces a DBUS_SESSION_BUS_ADDRESS that does not include the 'guid' parameter. The same thing happens with dbus started by a systemd user session, for which the value is something like "unix:path=/run/user/1000/bus". However, it does not happen under "dbus-run-session ./dbus-test", which creates a temporary bus address and gives it to dbus-test; that address does include the guid.

For your custom bus, if you obtained the address from the DBusServer:

    /* if using a DBusServer directly */
    const char *address = dbus_server_get_address (server);
    DBusConnection *shared_conn = dbus_connection_open (address, &error);

    # if using dbus-daemon
    dbus-daemon --print-address=1 > address.txt
    # or a higher fd if stdout is in use for something else
    dbus-daemon --print-address=5 5> address.txt
    # or from C/C++ code, use the fd of a pipe, like in
    # tools/dbus-run-session.c and  test/test-utils-glib.c

then it would contain the guid and dbus_connection_open() would work as intended.

dbus_connection_open() uses the guid to identify what is "the same" connection, because in principle there could be address types for which connecting to the same string address results in a connection to a logically different bus. You might think that this can be fixed by using simple string comparison of addresses when deciding what is "the same bus", but that just makes the problem rarer, and does not eliminate it. For example, these addresses:

    tcp:host=localhost,port=1234
    tcp:port=1234,host=localhost
    tcp:port=1234,host=127.0.0.1

are all equivalent (on an IPv4 system), but a simple string comparison would not reflect this.

I think we should deprecate dbus_connection_open(), add a note about this limitation to its documentation, and recommend that anyone wanting to cache private connections uses their own global or static variable (Comment #1).
Comment 7 missa 2016-02-12 23:47:17 UTC
Thanks for your input!
I guess the only way is to get it using the --print-address.
These details about guid are useful for the API documentation for dbus_connection_open(). Maybe the API should also fail if a guid is not supplied. Otherwise, users will leak resources and get unexpected outputs.
Comment 8 GitLab Migration User 2018-10-12 21:26:30 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/dbus/dbus/issues/144.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.