Outdated egg!
This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.
If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.
[[tags: egg]
bokbok
Description
A secure remote procedure call library for Chicken Scheme.
It supports:
- TCP or UNIX-domain sockets.
- Optional encryption and authentication (with pre-shared keys).
- Multithreading over a single connection: multiple threads may make requests via the same connection, and multiple request handlers can be running at once in their own threads.
- Connections are symmetrical once established: either side may invoke the other side's API at any time, "client" and "server" are just a matter of who sat passively waiting for a connection and who initiated it.
Code repository
The source code for bokbok is hosted in Fossil at http://www.kitten-technologies.co.uk/project/bokbok.
Author
Requirements
Requires the tweetnacl, socket, srfi-27 and matchable eggs.
Quick start
See https://www.kitten-technologies.co.uk/project/bokbok/doc/trunk/bokbok-client.scm and https://www.kitten-technologies.co.uk/project/bokbok/doc/trunk/bokbok-server.scm for a demo client and server.
API reference
[procedure] (passphrase->key passphrase-string)Converts an arbitrary passphrase string into a key object that can be used as an argument to open-connection! or returned from a server's username->key callback.
[procedure] (open-connection! address username key request-handler close-handler)Opens a connection, returning a connection object.
address can be in any of the following forms:
- "HOSTNAME:PORT" or (tcp HOSTNAME PORT) for a TCP connection
- "PATH/TO/SOCKET" or (unix "PATH/TO/SOCKET") for a UNIX domain connection
username and key will be used to authenticate and encrypt the connection; the server can't accept the connection unless the key matches what it expects for that username. So if you or the server have not got the right key, the connection will fail.
For an unencrypted and unauthenticated insecure connection, set username and key to #f.
request-handler is a callback that will be invoked (in a thread) for any requests that come from the server. It will be applied to two arguments: the connection object itself and the request received from the server. Its return value will be taken as the response to the request and sent back to the server. Any errors raised in the request-handler will be sent back to the server.
close-handler is a callback that will be invoked (in a thread) if the connection is closed by the server. It will be applied to a single argument, the connection object.
open-connection returns the connection object.
[procedure] (connection? con)Returns #t if and only if the argument is a connection object.
[procedure] (connection-user con)Returns the username of the connection, or #f if it's an insecure connection.
[procedure] (connection-addr con)Returns the address of the other end of the connection.
[procedure] (close-connection! con)Closes a connection.
[procedure] (request! con message)Sends the message (an arbitrary sexpr) as a request to the other end of the connection, and blocks waiting for a response. This is thread-safe - multiple threads may call request! on the same connection in parallel, and although the connection is blocked while a request is being sent or a response received, it is not blocked while a request is being processed at the other end, and responses may come back in a different order to the requests sent.
If the request fails for networky reasons, a suitable error is raised; if the request handler at the far end fails, a remote error is raised.
[procedure] (remote-error? error)Returns #t if and only if the error is a remote error.
[procedure] (remote-error-message error)Returns a string describing what went wrong at the other end of the connection.
[procedure] (start-server bind-addr backlog user->key open-handler request-handler close-handler)Starts a bokbok server in a thread, and returns a server object.
bind-addr is the address to bind to, either (unix PATH) for a Unix-domain socket or (tcp ADDRESS PORT) for a TCP socket. An ADDRESS of #f causes it to bind on all available addresses.
backlog is the listen backlog. This is a slightly mysterious tuning parameter that can matter in highly-loaded systems. Try using 10.
user->key, if provided, is a callback closure invoked to authenticate and authorize encrypted connections. It is passed a username string, and must return a key object that matches the key object used by the client when opening the connection. Attach it to whatever passes for a database of users on the server. It should return #f for an unrecognised or otherwise not allowed to connect username. If #f is provided, then the server listens for insecure connections.
open-handler is a callback closure invoked whenever a new connection is made to the server. It is applied to the connection object.
request-handler is a callback closure invoked whenever the client sends a request to the server on any connection, as explained above under open-connection.
close-handler is a callback closure invoked when the client closes a connection. It is applied to the connection object.
[procedure] (stop-server! server)Asks the server to stop.
[procedure] (wait-until-server-stopped server)Blocks until the server has stopped.