ossp-pkg/srpc/BRES
1.1
BASIC RESEARCH AND BRAIN-STORMING
=================================
- Architecture:
- Abstracted Message Passing Library: libamp
- eXtendable Data Serialization Library: libxds
- Simple Remote Procedure Call Library: libsrpc
- The server actually performing the function call has to interpret
the transferred data according to the functions prototype. This may
be done in one of the following ways:
- All functions have the same prototype. The function may then be a
stub calling the actual function. These stubs can be generated
manually or semi-automatically.
- Allow only a finite set of prototypes and switch according to the
function tye, like in eAPI in Apache.
- Build function call dynamically using the Foreign Function Call
library.
- reduce "int foo(int, foo_t *)"
to "rpc_t foo(rpc_t)" mit
rpc_t: void *, size_t
because
o constant function prototype on server-side
(foreign function call problem!)
o only application knows how to convert
complex data structures (foo_t) into
serialized octet-stream
o greater flexibility in data transfer
o rpc library complexity is reduced
(on cost of application complexity)
instead remote procedure call
only message passing
- auditing/logging:
in XDS: nicht noetig
in AMP: 3 levels: in API von MP und in backends und I/O dump
mit Hilfe von Callbacks (L2!)
- message passing / procedure call
sepatered from data serialization
- error semantics:
transaction, ACID
o exactly-once (== 1) bank transaction
o at-least-once (>= 1) muss passieren, mehrfach tut nicht weh (seiteneffekte) SunRPC
o at-most-once (<= 1) logging of not important data, video conferneces
o reduncancy (> 1) data replication (rundancy)
o quatsch (< 1 == 0)
o cachable im Proxy
- flexibility:
o I/O functions overloading (Pth)
o accept+handle, ... application handles
server functionality and can fork, spawn, etc.
- asynchronous vs. synchronous
Ideee: intern immer asynchrouns
aber in API wrapper function
rpc_call == rpc_send+rpc_wait+rpc_result
und auch rpc_abort
trotzdem wird beide male ein timeout vorgesehen
- AMP:
backends
local
shm
pipe
unix socket
network
udp
tcp
ttcp
- Fragmentation?
- entweder AMP high-level aufgrund von backend-infos (MTU!) + Defragnmentierung
- oder error aufgrund backend
- Optimales Backend Protocol:
- server akzepotiert N protocols
- client requested M (<= N) protocols
- library sucht optimalen raus (ev. abhaengig von der Message-Size)
- Backend Protocols:
- eventuell connection caching?
- bei network problems reconnect
- bei idle time shutdown + reconnect later
- AMP:
o optional authentication
o optional packet signing
- AMP+XDS:
o optional encryption
o optional compression
- wo ist encryption und compression?
in beiden mit callbacks vorsehen, da beide
unabhaengig von einander imn Einsatz sein koennen!
- XDS:
o functionality:
encoding
decoding
o Representation Differences
- byte order (little vs. big endian)
- character set (ASCII, Latin-1, Unicode, EBCDIC)
- floating point (IEEEE ...)
o Description:
- self-describing (ASN.1) type+value
- overhead
+ bei decode eine verification machen
- non self-describing
+ no overhead
+ tut nicht weh, da xds_decode() sowieso parameter aufzaehlen muss
o Welche Seite tut was:
- send: into fixed set
recv: from fixed set
+ filter/minitoring moeglich auf netzwerk seite
- eventuell doppleter overhead (C+S:little endian, fixed set: big endian)
- send: nothing, but append own type
recv: into own set if type different
+ no overhead
- no filtering easily possible
o callbacks erlauben encoding/decoding of own data structures/types
o backends:
XDR (SunRPC)
ASN.1 (X.509)
XXX (CORBA)
XML (XML-RPC)
- Firewalls? Sollen die Filtern koennen
Encryption nur von Data, nicht von Meta-Data
- Proxies?
- Sowohl AMP als auch XDR muessen backends von
Application implementieren lassen!
- bei AMP muessen Statistiken verfuegbar sein!
- Rround-Trip-Time
- Datandurchsatz (Throughput)
siehe auch SNMP, Multilink PPP (MP+)
- Denial Of Service auf Server Seite?
- High-Level Library basierende auf AMP:
- Service Location
- Load Balancing
- Fail Over
- IPv6 in AMP unterstuetzen
- Multicasting in AMP unterstuetzen (trivial I/O seitig,
aber muss bei error semantics beruecksichtig werden)
=========================================================================================
Examples:
amp.h:
typedef struct {
void *data;
size_t len;
} amp_data_t;
Server:
#include "amp.h"
#include "xds.h"
#include "pth.h"
amp_data_t foo(void *ctx, amp_data_t in)
{
amp_data_t out;
xds_ctx_t *xds = (xds_ctx_t *)ctx;
int i;
char *cp;
int rv;
xds_decode(xds, in.data, in.len, "%d%s", &i, &cp);
/* i und cp verarbeiten -> rv */
xds_encode(xds, &out, "%d", rv);
return out;
}
amp_server_t *s;
amp_connection_t *c;
xds_ctx_t *xds;
xds = xds_create(XDS_ASN1);
s = amp_server_create();
amp_server_configure(s, AMP_LISTEN, "udp", "server1.de.cw.net", 12345);
amp_server_configure(s, AMP_LISTEN, "tcp", "any" 12345);
amp_server_configure(s, AMP_LISTEN, "unix", 12345);
amp_server_configure(s, AMP_LISTEN, "shm", vp, vplen);
amp_server_configure(s, AMP_ERROR_SEMANTIC, AMP_ATLEASTONCE);
amp_server_configure(s, AMP_IOCB_ACCEPT, pth_accept);
amp_server_configure(s, AMP_IOCB_LISTEN, pth_listen);
amp_server_configure(s, AMP_IOCB_READ, pth_read);
amp_server_configure(s, AMP_IOCB_WRITE, pth_write);
:
amp_server_register(s, "foo", foo, xds);
amp_server_register(s, "bar", bar, NULL);
amp_server_register(s, "baz", baz, NULL);
amp_server_register(s, "quux", quux, NULL);
amp_server_listen(s);
/* synchronous */
amp_server_loop(s);
/* asynchronous */
while ((c = amp_server_accept(s))) {
pth_t *t;
if ((t = pth_spawn(...)) == NULL) {
amp_server_dispatch(c);
}
pth_wait(t);
}
amp_server_unlisten(s);
amp_server_destroy(s);
xds_destroy(xds);
Client:
amp_client_t *c;
amp_connection_t *co;
xds_ctx_t *xds;
amp_data_t in, out;
int i = ...;
char *cp = ...;
int rv;
c = amp_client_create();
xds = xds_create(XDS_ASN1);
amp_client_configure(c, AMP_CONNECT, "udp", "server1.de.cw.net", 12345);
amp_client_configure(c, AMP_CONNECT, "tcp", "server1.de.cw.net", 12345);
co = amp_client_connect(c);
xds_encode(xds, in, "%d%s", i, cp);
out = amp_client_call(co, "foo", in);
xds_decode(xds, out, "%d", &rv);
/* ... rv ... */
amp_client_disconnect(co);
xds_destroy(xds);
amp_client_destroy(c);