D-Bus service, forking and shared service name

David Sommerseth dbus at lists.topphemmelig.net
Sun May 28 21:04:00 UTC 2017


On 26/05/17 16:43, Simon McVittie wrote:
> On Fri, 26 May 2017 at 16:14:36 +0200, David Sommerseth wrote:
>> We would prefer to have a unified bus name (net.openvpn) which is used
>> across all our processes.  Each configuration and running tunnel should
>> then have a unique object path, with their own set of methods.
> 
> Sorry, you can't do that. If you think of well-known bus names as being
> like hostnames, and object paths being like HTTP paths, that's close to how
> it works.

Thanks a lot, Simon!  This makes very much sense, and is how I
understood it.

> You can have several web servers trying to implement the same hostname,
> but if you do, you don't get to decide which one handles a request
> from a client - so in practice it doesn't make sense unless they all
> serve the same content. Semi-similarly, you can have several D-Bus
> processes[1] trying to own the same well-known bus name, but they'll
> be in a queue, and only the process at the front of the queue (the
> current owner) actually gets to handle requests from clients.
>
> The closest you can get to this is one of these two approaches:
> 
> * Have objects in the net.openvpn main process that represent the
>   actual tunnels. Clients communicate with those objects. When clients
>   call methods on those objects, the main process implements those
>   methods by calling methods on the individual tunnel processes
>   (effectively it's behaving like a proxy). It could pass
>   requests straight through without understanding them if you
>   want it to, but it would be more common to have it interpret
>   the method calls and have their implementation be implemented
>   in terms of further method calls.
> 
>   Prior art: NetworkManager exposes D-Bus objects for connections, and
>   some of those objects are implemented in terms of calling D-Bus
>   methods on dnsmasq and/or wpasupplicant instances.

Hmmm ... But there's not so much difference between this approach and
the approach below, is it - in regards to the bus name?
dnsmasq/wpasupplicant already have their own unique bus names already.
But this approach makes NetworkManager act as an advanced proxy (kind of
like Varnish), where it will adopt the NM D-Bus "API" to what the
backend expects, or did I miss understand this?

> -or-
> 
> * Wherever you would expect a method in the net.openvpn main process to
>   return an object path, if it might be in a different process, either
>   return a (bus name, object path) pair instead or have a documented
>   rule for deriving a bus name from the object path. Clients are
>   expected to communicate with the actual tunnel process using the
>   given bus name.
> 
>   Prior art: The Telepathy AccountManager creates connections which
>   are in "connection manager" processes distinct from the AccountManager.

So here the "front-ends" are expected to get in touch with the
"AccountManager", where they're told to "connect to this bus/path" for
further operations ... is this correctly understood?


> To get D-Bus access control to work well, you will probably find that
> you want all your service processes (except for perhaps the main one)
> to get in the queue for a special well-known bus name like
> net.openvpn.anytunnel that is not actually intended to be used in
> any method calls. The reason you should probably do that is that it
> can be used in access-control decisions: the dbus-daemon policy language
> understands <allow send_destination="com.example.foo"> to mean
> "allow sending messages to any process that *is in the queue to own*
> the com.example.foo name", not just the process that currently owns
> the name (i.e. is at the front of the queue) like you might expect.

So I'm just thinking aloud, wondering and pondering ...

 - Front-end application (cli/gui user front-ends) connects to a
   "manager" process which owns net.openvpn.  And asks for a particular
   tunnel to be started.

 - The "manager" generates a unique session ID, which it provides to the
   back-end process setting up the tunnel.  In addition it creates a
   session object the front-end needs to use.

 - The back-end sends a response to the "manager" process to a
   SetupComplete method, together with a unique bus name (for example,
   net.openvpn.backend.$PID).  It would reports its unique session ID to
   the "manager", together with bus name/PID,  object path used, etc.

 - The "manager" when getting the "response" back from the back-end,
   sets up a signal watcher on the back-end object path on the
   back-end's unique bus name.  At this point, the front-end is given
   the "managers" object path to this particular session object.

 - The "manager" will now proxy requests from front-ends to the
   back-ends.  When the front-ends does an operation, the "manager"
   ensures the proper back-end gets the request.

 - When the back-end needs the front-end's attention, it sends a signal
   to the "manager" which proxies that signal to the front-end.


Would this work?

One downside I see with this approach is if the "manager" dies - it may
loose overview of all back-end processes.  The back-end processes may
live longer though, but won't be able to reach the front-ends.  This
might be solved by having a "state file" where all running back-end
processes are logged with managers unique session ID, back-ends PID, bus
name and object paths.  When a new "manager" starts up, it can double
check if these logged processes are still active or not and hook back
into them again.  The front-ends would also need to be "reactivated"
somehow; perhaps they would be required to register with the "manager"
process too before being able to start new tunnels?

But I'm wondering if it makes sense if the various front-ends should
just be able connect directly to the back-ends directly - by being given
the busname and object path provided by the back-end.

What are the pros/cons for these alternatives - proxy requests or direct
backend access?

And I know I need to think more carefully about the ACL side of this.
Did I understand you correctly that I with this approach above can have
an ACL saying:

    <allow send_destination="net.openvpn.backends">

which is tied to the "manager" process, that I can restrict the calls
this way?  So the "manager" process may through this access methods and
objects on net.openvpn.backends.$PID?

And would it be possible or clever to have the manager/back-end
communication on the session bus instead of the system bus?  Given that
the back-ends are started by the "manager" process.


-- 
kind regards,

David Sommerseth

-- 
kind regards,

David Sommerseth


More information about the dbus mailing list