Synchronous RPC and Session Types

Norman Feske norman.feske at genode-labs.com
Wed Jun 3 16:41:22 CEST 2020


Hi Sid,

> in our current project, the question of synchronous communications
> between processes comes up quite often. For background, our scenario
> processes numerous parallel requests, which requires, among other
> operations, verifying a signature of a request and signing its
> response. The signature verification and signing operations are
> encapsulated in separate processes. That way they do not need to
> understand the complex message format of requests and responses, but
> only binary hashes and signatures. Therefore, the component
> processing the request must send the input data to the verify or sign
> component and wait for the response before continuing processing.
> In our current solution we use Genode's basic synchronous RPC
> mechanism. This approach has the effect of creating new session types
> when more different functionalities such as verifying or signing are
> added. This seems to be in conflict with the Genode philosophy of
> using only few selected session types. On the other hand, building
> the scenario using the asynchronous report/rom mechanism would lead
> to significantly more complex code to avoid mixing up the many
> requests being processed in parallel.

there is no general answer but a few considerations.

First, your remark about Genode's philosophy is spot-on. Let me cite
myself from Section "Components" of the Genode Foundations book:

  "The versatility of a component-based system does not come from the
   existence of many components alone. Even more important is the
   composability of components. Components can be combined only if their
   interfaces match. To maximize composability, the number of interfaces
   throughout the system should be as low as possible, and all
   interfaces should be largely orthogonal to each other."

[1]
https://genode.org/documentation/genode-foundations/20.05/components/index.html

Therefore, before introducing a new session interface, one should ask
the following questions:

"What if this service had a (*) session interface?" where (*) stands
for the the usual candidates ROM, Report, File_system, Terminal, Block,
and Nic.

  E.g., when we were tempted with introducing a socket session
  interface, we ultimately ended up with modelling the socket API as a
  pseudo-file system, reusing the existing "File_system" session
  interface. This eventually enabled us to use the VFS server
  as multiplexer for the shared use of a single TCP/IP stack.

"Does the designated interface needs to be one interface, or can it be a
combination of multiple simple ones?"

  E.g., when thinking of an encryption component, the most intuitive
  interface may be an RPC interface with an "encrypt" function taking
  the plaintext as argument and producing the ciphertext as result.

  A less intuitive approach would be to model the encryption component
  as a block service that offers two block sessions, one for
  submitting plaintext, and one for picking up ciphertext. This
  approach has the following benefits:

  1. It does not block the caller while computing the encryption
     function.
  2. It can scale better because multiple "block" requests can
     be submitted as a batch at once, using the block number as
     a token to tell them apart.
  3. No session can observe both the plain and ciphertext but only
     one of them. This way, the information flow at the clint side
     can become better separated.
  4. The component works similar to a physical device. That is,
     it could be replaced by a driver for an actual hardware device.

  I have not fully thought it through but the example shows that the
  design space - even when sticking to the existing session interfaces -
  is sometimes larger than it appears at first.

"Could that feature be implemented as a VFS plugin?"

  Recently, the default answer to this question has become YES!
  Implementing protocol-stack functionality as a VFS plugin gives
  two advantages over the implementation of a new server.

  1. The decision of separating functionality out to a separate
     component can be taken at integration time. It is just the
     difference of mounting a VFS plugin locally at an application
     versus mounting it inside a shared VFS server. Performance
     can be traded against the granularity of separation by mere
     reconfiguration.
  2. There is no need to write boiler-place server code. The VFS
     server exists and can be used as is.

  This leads to quite unorthodox results. For example, the font
  renderer used by Sculpt's Leitzentrale GUI is implemented as a
  VFS plugin.

  That said, let me share one note of caution. The VFS-internal
  interfaces are not completely fleshed out yet. They will be undergo
  changes in the next release cycles. There will be no fundamental
  disruption but you should be prepared for the need to adjust VFS
  plugins.

With all these considerations given, we should not be dogmatic. If none
of the existing interfaces fits well, or if the use the existing
interfaces feels highly unnatural, the introduction of a new interface
is totally fine. In the best case, the new interface can one day be
generalized to fill a real gap in the existing options.

After all, correctness is primarily important. And this is best achieved
with simplicity. So if you say that the asynchronous combination of
report and ROM sessions makes you feel uneasy, better take a different
route you feel confident with.

Cheers
Norman


-- 
Dr.-Ing. Norman Feske
Genode Labs

https://www.genode-labs.com · https://genode.org

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth



More information about the users mailing list