dbus first impressions

Havoc Pennington hp at redhat.com
Tue Sep 7 03:52:07 UTC 2004


On Mon, 2004-09-06 at 14:42 -0700, Don Park wrote:
> I feel dbus's role is to provide an RPC mechanism that has a flexable
> access policy mechanism.

It's a bit more complex than that, some of the other goals include:
 - be optimized for local rather than network IPC
 - be close to compatible with DCOP

> Ive read through the dbus specification at
> http://freedesktop.org/Software/dbus/doc/dbus-specification.html
> and i have a couple questions & comments.

The start of http://freedesktop.org/Software/dbus/doc/dbus-tutorial.html
is a decent overview also. The specification is kind of out of sync with
the code, unfortunately.

> why have a little endian, big endian flag? wouldnt it be simpler to
> standardize on one bit ordering (like tcp/ip does?)

Ah, the question *everyone* asks. The normal case here is IPC on a
single machine, so using network byte order seems a little wasteful.
If you're already fooling with a binary protocol you may as well 
do byte swapping, since it's a fairly complex undertaking to begin with.

> the auth mechanism section refers to SASL many times but doesnt come out
> and say it uses a SASL library. in fact somewhere it says libxml is the
> only dependency. is an external SASL library used?

SASL library usage wouldn't belong in the protocol specification, that's
an implementation detail. We don't use a SASL lib in the current
implementation but it would be nice to do so.

> The auth section also says "All bytes must be in the ASCII character set."
> " the protocol is ASCII-only." yet there is the while bit about sending a
> NULL character. that pretty much eliminates fakeing the protocol with a
> telnet client, which i thought was one of the advantages of using an ASCII
> protocol. Why is this initial NULL byte there?

On some old Unices, to send user/group credentials you have to send a
byte. The nul byte is this byte. I don't remember why it's nul rather
than 'a' or something, maybe there's no reason.

> At first, it looks like a Service name and Message name is all thats
> needed to send a message. In the spec it names service
> org.freenetworks.Peer.Ping, which looks like a good candidate for a
> simple, no-arguments service to try from dbus-send. It looks like Ping is
> the message name and org.freenetworks.Peer is the service name.
> 
> "dbus-send org.freenetworks.Peer.Ping" was my intuition (without reading
> the man page) and it fails miserably. Upon reading the dbus-send manpage
> there is a --dest for the service name and the first real parameter is the
> object name. The spec could say more about the object name.
> 
> In the dbus-send man page example,
> 
>   dbus-send --dest='org.freedesktop.ExampleService'        \
>                    /org/freedesktop/sample/object/name              \
>                    org.freedesktop.ExampleInterface.ExampleMethod   \
>                    int32:47 string:'hello world' double:65.32
> 
> the service name is already specified - why does the message name have to
> include the service name again?

You have:

 1) services - these are names that are associated with a process
 2) objects - these are names associated with some part of a process, 
    perhaps an object in an OO language
 3) interfaces - these are sets of methods an object can support,
    or you could think of them as "types" for objects
 4) methods - methods you can invoke on an object

You could think of a service as the name of a socket; an object name as
a C++ object reference; an interface as a C++ pure virtual class; a
method as a C++ method.

> Onto the "Message Bus Overview":
> the service field is most confusing. "When the message bus receives a
> message, if the SERVICE field is absent, the message is taken to be a
> standard peer-to-peer message and interpreted by the message bus itself."
> how do i know what messages the 'message bus itself' can handle? is it
> really that command that the message bus itself gives a response to a
> message that every message sent needs this flag?

See:
http://freedesktop.org/Software/dbus/doc/dbus-tutorial.html

If there's no service, then the message is for the bus, rather than to
be routed by the bus. For example in any 1-to-1 connection you can send
a ping, so you can also ping the bus.

> "Messages may also be broadcast  by sending them to the special service
> org.freedesktop.DBus.Broadcast. Broadcast messages are sent to all
> applications with message matching rules that match the message."

This is no longer accurate, now you broadcast a message by giving it the
special type SIGNAL.

> i read this to mean the application doing the sending needs to
> know who is in the group.

No, the matching rules are kept by the bus, not the app doing the
sending.

> Rather than having "secondary owners" for a service, the service could
> have multiple simultaneous owners in a publish-subscribe style setup. Then
> as the print driver I could send one message to org.gnome.printqueue and
> dbus could send the message to each person listening to that serice. The
> service would go away when the last subscriber leaves the service.

The service names are not used for publish-subscribe. Rather, they are
used to invoke methods on objects. So if I want to send a message to
"THE print queue" I send to org.freedesktop.PrintQueue. If I want to
send a message to "anyone who cares about my new print job" then I
broadcast a signal.

Imagine I specify that any print daemon creates a
socket /var/run/print_daemon and specify a protocol that socket will
speak. That is the same thing we're doing with
org.freedesktop.PrintQueue.

> what is the reason for base service names? do service names have to be an
> extesion of the base service name (without the : of course)? if not, then
> how are services associated with a base service name? which means, how are
> objects (service names) associated with applications (base service names)?

You can think of service names as hostnames ("www.gnome.org") and base
service names as IP addresses ("192.168.0.1"). Not a perfect analogy,
but the point is you need a unique ID for every application (base
service name) and then you need well-known names for "the application
that..." e.g. "the application that provides print services" =
org.freedesktop.PrintQueue

A base service name is associated with a well-known service name when
the application with the base service name comes to own the service.

> in the service activation section, the description file looks like a
> windows .ini file. Why isnt it XML like the other configuration files?

Because the .desktop format is already pretty widely used by GNOME/KDE
for this sort of thing.

> Finally, in the "Message Bus Messages", it looks like not enaugh
> information is given to actually call the method. according to dbus-send I
> need to know the service name, the object path, and the method name. What
> I see is the service name, and a function prototype which Im not sure how
> to map into a method name.

Right, this part of the spec has not been updated to reflect the
addition of object paths. Object paths are sort of redundant in the case
of a well-known service, because you are going to also use a well-known
object path. In other words for something like the print queue there's a
global singleton object. So specifying org.freedesktop.PrintQueue and 
also /org/freedesktop/print_queue is kind of redundant and annoying.

When the service path will not be "the same" as the object path is when
you have dynamically created objects.

Anyway, the object path for the org.freedesktop.DBus messages is 
/org/freedesktop/DBus which is a singleton object.

I think we need to draw a diagram and have some examples extending the
tutorial a bit more, and maybe add some "rationale" footnotes to the
protocol spec... not to mention syncing the protocol spec with
reality ;-)

Havoc




More information about the dbus mailing list