theopolis
registerExtension method on the daemon's socket to inform the daemon of what tables, config plugins, logger plugins, etc, the extension has.
2. Request the daemon's CLI and configuration options, and configure them locally, assign itself a UUID as determined by the daemon, randomly.
3. Start its own Thrift server to handle async requests from the daemon.
All requests from daemon -> extension use the extension's Thrift server.
All requests from extension -> daemon use the daemon's Thrift server. In this case only the daemon needs to be multi-threaded. It's nice to have them both support multiple concurrent API calls though and in practice that's how they're implemented in C++. Other language bindings can do whatever they like.
For communication from daemon to extensions they will follow: https://github.com/facebook/osquery/blob/master/osquery/extensions/extensions.cpp#L650 this code. Most things in osquery are wrapped in a "plugin API" and the daemon will keep track or the origin or plugins. If a plugin is provided by an extension then the call is eventually funneled into that method.