communication

Path: doc/src/communication
Last Update: Fri Oct 13 15:35:37 +0200 2006

Communication and Request Handling

The communication between the individual parts of the dsadmin system (e.g. webfe - admind, admind - admind) is done via a custom request/response - based protocol over TCP connections. The following diagram gives an overview of the request flow and the most important classes involved in it:

Why a Custom Protocol?

On first glance, a custom protocol only means more implementation and testing work compared to a simple drb (distributed ruby) solution. But it offers several key benefits:

  • Since requests and their responses have to be routed, stored (e.g. as part of internal cronjobs) and logged, it‘s just natural to have proper classes for them anyway.
  • It can be quite difficult to properly secure a drb setup against code injection attacks. With a custom protocol, such problems can be easily and effectively prevented.

Requests and Responses

See the documentation for Dsadmin::Request and Dsadmin::Response for details.

One item of note are the "standard" responses defined as constants in Dsadmin::Response. This is currently the closest thing to an authoritative list of response status codes. In the future, this will be specified more formally, but for now the informal list is good enough.

The Network Protocol

As mentioned above, network communication between dsadmin parts uses TCP connections. To keep things simple, there may be only one request/response pair per connection, and each side is required to close its socket for writing as soon as it has sent its data (request or response).

The protocol itself simply consists of YAML - serialized Dsadmin::Request and Dsadmin::Response objects. Since it is unlikely that any third party software will use this protocol to interface with dsadmin in the forseeable future, no formal protocol specification has been written yet. However, the implementation takes care to use only "simple" YAML, i.e. without ruby-specific elements like symbols and raw objects.

Request Processing

As can be seen in the diagram at the top of this document, the central "switchboard" for handling requests is the Dsadmin::Admind::RequestProcessor class. It is responsible for the following:

  • Basic user authentication (verifying that the user exists and the password matches)
  • Verification of sender credentials (if the request comes from another admind instance)
  • Forwarding the request to the proper admind instance (if necessary), including protection against forwarding loops
  • Handing the request over to the proper Dsadmin::Admind::AdmindController (if it can be handled locally)
  • Providing catchall exception handlers to ensure a proper response even on application errors/bugs

The RequestProcessor is designed as a singleton that works safely in a multithreaded environment (typically one thread per request).

Routing

The "target" of a request is determined by its controller and action attributes, specifying the Dsadmin::Admind::AdmindController derivative and its action method respectively. Each AdmindController has a method host_for(action), which returns a list of admind instances that can handle the given action. This information is used by the RequestProcessor to optionally forward the request.

The default implementation in Dsadmin::Admind::AdmindController uses the <on-hosts> info attached to configfile resources and the action -> resource(s) mapping specified via AdmindController‘s resources_for method to automatically determine the correct host.

Request Broadcasting

RequestProcessor also provide a method for broadcasting requests to all admind instances. This is used e.g. at system startup time (for global initialization tasks), for triggering a system-wide shutdown or restart, or for collecting status information on all instances.

Internal Requests

Not all requests originate in the web frontend (or one of the commandline utilities) — some are also generated from within an admind instance. Typically These requests are triggered by the internal task scheduler (Dsadmin::Admind::Cron) or as "nested" requests by an AdmindController action (e.g. /meta/instanceinfo broadcasts a /local/instanceinfo to each admind instance). Such requests do not necessarily contain user authentication information.

Authentication and Security

Dsadmin uses two types of authentication on request: the classical username/password one for authenticating the person triggering the request, and a callerid/auth-token one for authenticating admind instances against each other (especially important for forwarded internal requests).

Since it is assumed that dsadmin will only be deployed in a controlled local network or VPN, all request data (including authentication information) is transmitted in cleartext. If any untrusted party on your network has the capability to sniff network traffic, this is clearly inappropriate. Of course, giving untrusted folks sniffing rights is a symptom of a much larger problem anyway…

See also Dsadmin::Admind::AdmindController and its require_superuser_for, require_internal_for and require_trusted_for methods for some info on access control on the controller/action level.

See also

[Validate]