OUTDATED

IPC for OpenSync?

This page will give you a short overview about why IPC in opensync is needed and how it is planed to be implemented

Why IPC?

There are several reasons for using IPC:

  • Some plugins can only be synchronized if they own the process. Examples for this are evo 1.4, kde and mozilla/thunderbird/sunbird
  • By using and IPC we can circumvent licensing problems if a commercial plugin and GPL plugin would be used at the same time
  • There might be use cases where a IPC is needed (for example if the member is on a different pc)

How it is going to be implemented

The IPC should have the following features:

  • As transparent as possible
  • platform independent
  • Able to locate the ipc end if it was started before

Based on these need we decided to go with named pipes. The implementation will look like this:

The IPC will sit between opensync and the plugin and catch all calls from opensync to the plugin and redirect them over the ipc. This is done by loading a special IPC plugin. This plugin will establish the IPC connection in its initialize function. Once the connection is established it will redirect all function calls to the plugin. This is done by saving the context that is normally sent to the plugin together with a unique ID. The ID is then used in the ipc call and has to be used to answer the call. The remote side receive the call and generates a new context which is associated with the ID it received. Once the context gets answered the remote side sends an answer. Then the ipc plugin picks up the stored context and answers it.

The call looks like this:

---plugin call from opensync ---> ipc plugin stores context --- ipc call ---> remote side generates context --- real plugin calll ---> plugin

The answer is like this:

<---context gets answered --- ipc plugin retrievs context <--- ipc answer ---- remote side receives context answer <---- plugin answers --- plugin

A IPC call and answer would look like this

struct ipc_call {
uint32_t ID;
uint8_t command;
data;
}

The data above is then used to marshal objects that are required to be sent: The following objects need to be marshalled:

  • OSyncChange for getting and committing changes
  • OSyncError for receiving error messages
  • OSyncMember for getting and setting slow-sync. There will be a transparent OSyncMember on the remote side which will forward all sets/gets to the opensync process
  • OSyncGroup. same as OSyncMember

Note that there is a limitation:

Only "plain" changes can be sent over the IPC. a plain change is a format which is basically a string. so a vcard would be plain while a xmlDoc * would not be. Formats which are not plain but need to be sent anyways need to provide marshal/demarshal functions.

Locating

Some plugins may require locating the remote end. One example would be the thunderbird plugin, where the remote end (which is started by thunderbird) is started before opensync. To be able to locate this remote end, the plugin can provide their own ipc plugin which overwrites the default ipc plugin. This ipc plugin would then have a mechanism for locating/activating the remote end. This custom ipc plugin would only need to provide the intialize/finalize functions since the other function calls are intercepted by the opensync ipc mechanism.