diff --git a/secure/inetd/inetd_base.c b/secure/inetd/inetd_base.c
new file mode 100644
index 0000000..7ec6c28
--- /dev/null
+++ b/secure/inetd/inetd_base.c
@@ -0,0 +1,1272 @@
+/*
+
+   //TODO: implement retries
+ */
+
+#define protected public
+
+#pragma strict_types, save_types, rtt_checks, pedantic
+#pragma no_clone, no_shadow
+
+#include <tls.h>
+#include <config.h>
+#include <driver_info.h>
+#include <lpctypes.h>
+#include <strings.h>
+
+// data structures
+struct host_s {
+    string name;
+    string key;
+    string ip;
+    int port;
+    int last_contact;
+    int first_contact;
+    int reputation;
+    string *services;
+    int im_version;
+    int ncttl;
+    int mtu;
+    mapping received;
+};
+
+struct fragment_s {
+    string header;
+    string buf;
+};
+
+struct packet_s {
+    int id;
+    int timestamp;
+    int pversion;
+    int pflags;
+    struct fragment_s *fragments;
+    string peername;
+    mapping data;
+    string buf;
+};
+
+struct service_s {
+    string name;
+    string obname;
+    string fun;
+    closure recv_cb;
+};
+
+struct request_s {
+    int id;
+    struct packet_s packet;
+    closure callback;
+    int timeout;
+};
+
+// Prototypes & Defines
+protected void init();
+void ping_many_muds(string *muds);
+protected int calc_ncttl(struct host_s p);
+protected void send_helo(string name);
+
+// mud-compatibility layer - might implement efuns with lfuns if not available
+// on the specific mud.
+inherit __DIR__"inetd_compat";
+
+// Mapping of known peers with their names as keys.
+mapping peers = ([]);
+
+// our own offered services
+mapping services = ([]);
+
+// our own host_s structure - it also contains our _private_ key.
+struct host_s self = (<host_s>);
+
+// reset counter for housekeeping
+int reset_counter;
+
+nosave int last_packet_id = 0;
+nosave mapping requests = ([]);
+
+// Minimum protocol version to accept (default 0)
+int min_protocol_version = 0;
+
+// *** lfuns in this section might be re-defined to suit the individual muds.
+protected void debug_msg(string msg, int severity)
+{
+  write(msg);
+}
+
+protected void set_user()
+{
+  seteuid(getuid());
+}
+
+protected void save_me()
+{
+}
+
+protected int restore_me()
+{
+}
+
+protected void export_peer_list(mapping list)
+{
+}
+
+// *** end of mud-specific lfuns ***
+
+private string *sys_fields = ({HOST, NAME, PACKET, UDP_PORT, SYSTEM, VERSION,
+                               FLAGS, SIGNATURE,
+                               PACKET_LOSS, RESPONSE_TIME});
+
+// *** public interface
+public void register_service(string name, string fun)
+{
+  struct service_s serv;
+
+  closure cl = symbol_function(fun, previous_object());
+  if (!cl)
+    raise_error("register_service(): function not public.\n");
+
+  if (member(services, name))
+    serv = services[name];
+  else
+    serv = (<service_s>);
+
+  serv->name = name;
+  serv->obname = object_name(previous_object());
+  serv->fun = fun;
+  serv->recv_cb = cl;
+  services[name] = serv;
+  self->services = m_indices(services);
+  debug_msg(sprintf("Service registered: %O\n",serv),40);
+}
+
+public void unregister_service(string name)
+{
+  struct service_s serv = services[name];
+  if (!structp(serv))
+    return;
+  // wenn von aussen gerufen, nur registriertes Objekt selber.
+  if (extern_call() && serv->obname != object_name(previous_object()))
+    raise_error("Service can only be unregistered by service object.\n");
+  m_delete(services, name);
+  self->services = m_indices(services);
+  debug_msg(sprintf("Service unregistered: %s\n",name),40);
+}
+
+public string *QueryPeerList()
+{
+  return m_indices(peers);
+}
+
+// TODO: remove, for debug only
+public struct host_s QueryPeer(string name)
+{
+  return peers[name];
+}
+
+public string PeerName()
+{
+  return self->name;
+}
+
+// **************** internal implementation ***********************
+
+
+protected void configure_host(struct host_s new_self)
+{
+  new_self->first_contact = time();
+  new_self->last_contact = time();
+  new_self->reputation = __INT_MAX__;
+  new_self->ncttl = __INT_MAX__;
+  //if (!sizeof(new_self->services))
+  //  raise_error("Illegal to configure peer without services!\n");
+  if(new_self->key)
+    new_self->im_version=2500;
+  else
+    new_self->im_version=2000;
+  if (new_self->mtu < 1024)
+    raise_error("The minimum UDP length (MTU) must >= 1024 bytes!\n");
+  // ok, uebernehmen
+  self = new_self;
+  debug_msg(sprintf("localhost configured: %O\n",self),30);
+}
+
+// Updates (or adds a new) peer.
+protected struct host_s add_new_peer(struct host_s p)
+{
+  // TODO: validate
+  // This must not happen, the caller must check for existence to prevent
+  // hijacking peer names...
+  if (member(peers, p->name))
+    raise_error("Attempt to add existing peer!\n");
+  if (p->mtu < 1024) p->mtu = 1024;
+  p->received = ([]);
+  peers[p->name] = p;
+  debug_msg(sprintf("new peer added: %O\n",p),50);
+  return p;
+}
+
+// Updates (or adds a new) peer.
+protected void update_peer(struct host_s p)
+{
+  //TODO validate
+  struct host_s old = peers[p->name];
+  if (!old)
+    peers[p->name] = p;
+  else
+  {
+    // we always keep some data...
+    old->key = p->key;
+    old->ip = p->ip;
+    old->port = p->port;
+    if (p->last_contact > old->last_contact)
+        old->last_contact = p->last_contact;
+    if (p->first_contact < old->first_contact)
+        old->first_contact = p->first_contact;
+    old->services=p->services;
+    old->reputation = p->reputation;
+    old->im_version = p->im_version;
+    if (p->mtu >= 1024) old->mtu = p->mtu;
+    old->ncttl = p->ncttl;
+    // keep packet fragments, don't update received.
+    debug_msg(sprintf("peer updated: %O\n",self),50);
+  }
+}
+
+// remove a peer from the known peer list
+protected void kill_peer(string name)
+{
+  m_delete(peers, name);
+  debug_msg(sprintf("peer deleteted: %s\n",name),50);
+}
+
+// Update last_contact value to current time.
+protected void touch_peer(string name)
+{
+  struct host_s p = peers[name];
+  if (p)
+    p->last_contact = time();
+}
+
+// imports old style host lists. Should only be done once.
+public int import_host_list(string file) {
+
+  int res;
+  mixed data = (read_file(file));
+  if (!data) {
+    debug_msg("*Error in reading host file: " + file +"\n\n", 100);
+    return 0;
+  }
+
+  data = old_explode(data, "\n");
+
+  foreach(string line: data)
+  {
+    if (line == "" || line[0] == '#')
+      continue;
+    mixed fields = old_explode(line, HOSTFILE_DEL);
+    if (sizeof(fields) < 5) {
+      debug_msg(sprintf(
+            "*Parse error in hosts file: %s, Line: %s\n", file, line), 100);
+      continue;
+    }
+
+    struct host_s p = (<host_s>);
+    p->name = lower_case(fields[HOSTLIST_NAME]);
+    // skip already known peers
+    if (member(peers, p->name))
+      continue; // mud already in list
+
+    p->services = old_explode(fields[HOSTLIST_LOCAL_COMMANDS],HOSTFILE_DEL2);
+    if (member(p->services,"*") != -1)
+        p->services = p->services - ({ "*" }) + DEFAULT_COMMANDS;
+    p->ip = fields[HOSTLIST_IP];
+    p->port = to_int(fields[HOSTLIST_UDP_PORT]);
+    // we fake first and last contact, otherwise it would be expired if not online.
+    p->first_contact = time();
+    p->last_contact = time();
+    p->mtu = 1024;
+    p->ncttl = calc_ncttl(p);
+
+    add_new_peer(p);
+    ++res;
+  }
+  debug_msg(sprintf("old-stype host list imported: %s, %d new peers\n",
+                    file,res),50);
+  return res;
+}
+
+
+protected void init()
+{
+  if (!self)
+    raise_error("Can't init/startup without configuration!\n");
+
+  // Register the core services. Must be callother for previous_object being
+  // ourself
+  this_object()->register_service(PING, "recv_ping");
+  this_object()->register_service(QUERY, "recv_query");
+  this_object()->register_service(REPLY, "recv_reply");
+  this_object()->register_service(HELO, "recv_helo");
+  debug_msg(sprintf("init() performed, pinging known peers.\n"),30);
+  ping_many_muds(m_indices(peers));
+}
+
+protected string encode(mixed v)
+{
+  switch(typeof(v))
+  {
+    case T_NUMBER:
+      return to_string(v);
+    case T_STRING:
+      return "$"+v;
+    default:
+      // convert into a string representation - hopefully the receiver
+      // knows what to do with it.
+      return sprintf("$%Q",v);
+  }
+}
+
+#define SIGLENGTH 32+4 // length of signature including "$S:|"
+
+protected void sign_fragment(struct fragment_s f)
+{
+  if (self->key)
+  {
+    f->header=sprintf("%s$S:%s|", f->header,
+                      hmac(TLS_HASH_SHA512, self->name, f->buf));
+    debug_msg(sprintf("signed fragment: %s, %s.\n",f->header,f->buf),90);
+  }
+  else
+    f->header="";
+}
+
+
+// creates a packet structure with fragments to send (can be only one, if the
+// packet does not need to be split).
+protected struct packet_s packetize(struct host_s dest, mapping data)
+{
+  // some field names in the packet are reserved and must not be used by
+  // users, they are added by the inetd.
+  if (sizeof(data & sys_fields))
+    raise_error(sprintf(
+          "Data must not contain reserved system fields: %O.\n",
+          data & sys_fields));
+
+  // create packet structure
+  struct packet_s packet = (<packet_s>
+                            id: ++last_packet_id, timestamp: time(),
+                            pversion: self->im_version, pflags: 0,
+                            fragments: 0, peername: 0, data: data, buf: 0);
+
+  // add the system fields (NAME, V, F must be the first fields!)
+  // the ID field is special, because maybe the packet is an answer to a
+  // request. In this case, we must keep the original ID
+  if (!member(data, ID))
+    data[ID] = packet->id;
+  else
+  {
+    if (data[REQUEST] != REPLY)
+        raise_error(sprintf("ID only permitted in reply packets!"));
+  }
+  // NAME is added below
+  data[UDP_PORT] = self->port;
+
+  // create an array of fields (key:value pairs)
+  string data_field;
+  string *  fields = allocate(sizeof(data)+3);
+  fields[0] = sprintf("NAME:%s", self->name);
+  fields[1] = sprintf("V:%d", packet->pversion);
+  fields[2] = sprintf("F:%d", packet->pflags);
+  int cindex = 3;
+  foreach(string key, mixed val : data)
+  {
+    // the DATA field must be added last, so remember its encoded string.
+    // Also, it is not checked for reserved characters
+    if (key == DATA)
+      data_field = sprintf("%s:%s", encode(DATA), encode(val));
+    else
+    {
+      if (!stringp(key) || !sizeof(key))
+        raise_error(sprintf("send((): Illegal field name %.30O in data "
+                            "payload.\n",key));
+      string ekey = encode(key);
+      string eval = encode(val);
+      // check key and value strings for reserved characters
+      if (regmatch(ekey,"[|:]") || regmatch(eval, "[|:]"))
+        raise_error(sprintf("send(): Field name or value contains reserved "
+                            "character: %.50s,%.50s\n", ekey, eval));
+      fields[cindex] = sprintf("%s:%s",ekey,eval);
+      ++cindex;
+    }
+  }
+  // add the DATA field if existing
+  if (data_field)
+    fields[cindex] = data_field;
+
+  // write the string buffer
+  packet->buf = implode(fields, "|");
+
+  // now split into fragments if packet too large for one.
+  int mtu = min(self->mtu, dest->mtu);
+  if ((mtu - SIGLENGTH - sizeof(packet->buf)) < 0)
+  {
+    // multiple fragments, each starting with
+    // PKT:peername:packet-id:packet-number/total-packets|
+    // fsize is the maximum payload length per fragment.
+    string fheader = sprintf("PKT:%s:%d:", self->name, packet->id);
+    int fsize = mtu - SIGLENGTH - sizeof(fheader)
+                - 8; // sizeof("nnn/mmm|")
+    string buffer = packet->buf;
+    int fcount = sizeof(buffer) / fsize;
+    // if there is a modulo left, we need one additional fragment
+    if (sizeof(buffer) % fsize)
+      ++fcount;
+    if (fcount > 999)    // too many fragments?
+      raise_error("packet too long to send.\n");
+    // allocate the complete fragment array.
+    packet->fragments = allocate(fcount);
+    foreach(int i: fcount)
+    {
+      struct fragment_s f = (<fragment_s>
+                     header:sprintf("%s%d/%d|",fheader,i+1,fcount),
+                     buf: buffer[i*fsize .. min((i+1)*fsize, sizeof(buffer))-1]
+          );
+      sign_fragment(f);
+      packet->fragments[i] = f;
+      debug_msg(sprintf("Created fragment %d/%d\n", i,fcount),90);
+    }
+  }
+  else
+  {
+    // one fragment, and the fragment header will be empty.
+    struct fragment_s f = (<fragment_s> header: "",
+                           buf: packet->buf);
+    sign_fragment(f);
+    packet->fragments = ({f});
+    debug_msg(sprintf("Created fragment 1/1\n"),90);
+  }
+  return packet;
+}
+
+// encodes the mapping data into a packet and sends it to <dest>. The
+// key-value pairs of <data> are converted into intermud fields. The keys must
+// be strings and only the DATA field can contain : or |.
+// Also, <data> must not contain any reserved field names.
+// If the caller expects an answer, <cb> must contain a calleable closure. In
+// this case, the inetd remembers the request. When the answer arrives, the
+// callback <cb> is called with the request id (int) and a mapping (the answer
+// packet) as arguments. The return value of send() is in this case the
+// request id used for storage.
+// <= 0 for error, > 0 for success.
+public int send(string dest, mapping data, closure cb)
+{
+  if (!sizeof(data))
+    raise_error("Illegal sending empty packets.");
+  if (!sizeof(dest))
+    raise_error("Can't send without destination: %O.\n");
+  // find peer data. If not found, abort and tell the caller
+  struct host_s peer = peers[dest];
+  if (!structp(peer))
+    return -1;
+
+  if (member(peer->services, data[REQUEST]) == -1)
+    raise_error("Remote host doesn't offer service "+
+                data[REQUEST] + ".\n");
+
+  // then packetize the data, i.e. create packet structure, encode into buffer
+  // and split into fragments as needed and sign fragments.
+  // There will be at least one fragment structure.
+  struct packet_s packet = packetize(peer, data);
+
+  // loop over all fragments and send them
+  foreach(struct fragment_s f : packet->fragments)
+  {
+    debug_msg(sprintf("%O <- %.500O\n",peer->ip, f->header + f->buf), 100);
+    // TODO: error handling
+    send_udp(peer->ip, peer->port, f->header + f->buf);
+  }
+  // delete the buffer
+  packet->buf = 0;
+  // delete the fragments until we support re-transmission of fragments
+  packet->fragments = 0;
+
+  // we keep the original data for reference, if storing the request.
+
+  // if an answer is expected, there is a callback closure. Then we store the
+  // request with a timeout of 120s.
+  if (cb)
+  {
+    struct request_s r = (<request_s> packet->id, packet, cb, time()+120);
+    requests[r->id] = r;
+    debug_msg(sprintf("Answer expected, request stored\n"),80);
+  }
+
+  return packet->id;
+}
+
+// like send(), but sends to all peers offering the service <service>. But
+// limited to peers we had contact with in the last 24h.
+public int broadcast(string service, mapping data, closure cb)
+{
+  if (!service)
+    raise_error("No service given!\n");
+  if (!sizeof(data))
+    raise_error("Illegal sending empty packets.");
+//TODO: check if we could send the same packet to all peers, instead of
+//packetizing for each peer as well.
+  int ret;
+  int tlc_cutoff = time() - 86400;
+  foreach(string dest, struct host_s peer : peers)
+  {
+    if (peer->last_contact >= tlc_cutoff
+        && member(peer->service, service) != -1)
+    {
+      send(dest, data, cb);
+      ++ret;
+    }
+  }
+  return ret;
+}
+
+protected string|int decode(string arg)
+{
+    if (sizeof(arg) && arg[0] == '$')
+        return arg[1..];
+    if (to_string(to_int(arg)) == arg)
+        return to_int(arg);
+
+    return arg;
+}
+
+// must be validated before. Parses the packet buffer into the given packet
+// structure and returns it. In case of errors (e.g. malformed packets), 0 is
+// returned.
+protected struct packet_s parse_packet(struct packet_s packet)
+{
+  string *fields = explode(packet->buf, "|");
+  // The DATA field may contain any number of | which don't signify a field.
+  // Therefore counting | over-estimates the number of fields. To prevent
+  // excessive memory allocation, we limit the allocation to 32 fields. The
+  // mapping may still grow if there are really more fields.
+  packet->data = m_allocate(min(sizeof(fields),32));
+  int cindex;
+  while (cindex < sizeof(fields))
+  {
+    string header, info;
+    /// DATA fields can be denoted by a preceeding blank field :-/
+    if (!sizeof(fields[cindex]))
+    {
+      ++cindex;
+      header = DATA;
+      //Test for illegal packet length (no DATA)
+      if (cindex >= sizeof(fields))
+        return 0;
+      // take the first "field" of DATA (the rest is added below)
+      info = fields[cindex];
+    }
+    else if (sscanf(fields[cindex], "%s:%s", header, info) != 2)
+      return 0;
+    header = decode(header);
+    if (header == DATA)
+    {
+      // add the rest of the packet and combine back into one string if
+      // necessary
+      if (cindex < sizeof(fields)-1)
+        info = implode(({info}) + fields[cindex+1 ..], "|");
+      // and we have finished after decoding info
+      cindex = sizeof(fields);
+    }
+    packet->data[header] = decode(info);
+    ++cindex;
+  }
+  // only allow printable characters for these fields.
+  response[SENDER] =
+             regreplace(response[SENDER],"[:^print:]|\n","",1);
+  response[NAME] =
+             regreplace(response[NAME],"[:^print:]|\n","",1);
+  response[RECIPIENT] =
+             regreplace(response[RECIPIENT],"[:^print:]|\n","",1);
+
+  return packet;
+}
+
+protected void defragment_packet(struct packet_s p)
+{
+  if (sizeof(p->fragments))
+  {
+    p->buf = "";
+    foreach(struct fragment_s f : p->fragments)
+    {
+      p->buf += f->buf;
+    }
+    p->fragments = 0;
+  }
+}
+
+protected int validate_signature(string signature, string buf, struct host_s src)
+{
+  if (!src->key)
+    return 0;
+  // TODO: debug purpose
+  return 1;
+}
+
+// returns a packet_s or 0 for invalid or incomplete (!) packet. In both
+// cases, the caller should not do anything. In case of incomplete packets,
+// the fragment will be stored, if it was valid.
+protected struct packet_s validate_fragment(string buffer, struct host_s sender)
+{
+  string signature, pname;
+  int packetid, fragno, totalfrags, version, flags;
+  struct packet_s packet;
+  struct fragment_s f;
+
+  if (sizeof(buffer) > MAX_UDP_LENGTH)
+    return 0;
+
+  if (sscanf(buffer, "S:%s|NAME:%s|V:%d|$F:%d|%~s",
+             signature, pname, version, flags) == 5)
+  {
+    // non-fragmented v2.5+ packet
+    debug_msg(sprintf("Received v2.5+ packet.\n"),90);
+    pname = lower_case(pname);
+    packet = (<packet_s> timestamp: time(), pversion: version,
+              pflags: (flags & ~FL_VALID_SIGNATURE),
+              buf: buffer[strstr(buffer,"|")+1..]
+             );
+    debug_msg(sprintf("Received v2.5+ packet from %s.\n",pname),90);
+    sender = peers[pname];
+    // if we don't know the sender yet, we create a new peer with its name.
+    // The ip and port will be updated during parsing.
+    if (!sender)
+    {
+      sender = add_new_peer( (<host_s> name: pname,
+                          first_contact: time(),
+                          last_contact: time(),
+                          mtu: 1024,
+                          im_version : version,
+                          received: m_allocate(5)
+                         ));
+      // but if we can't create one, we discard the packet
+      if (!sender)
+        return 0;
+    }
+    packet->peername = pname;
+    // try to check the packet signature and record the result, if
+    // successful.
+    if (validate_signature(signature, packet->buf, sender))
+    {
+      packet->pflags |= FL_VALID_SIGNATURE;
+    }
+  }
+  else if (sscanf(buffer, "PKT:%.1s:%d:%d/%d|%~s",
+                  pname, packetid, fragno, totalfrags) == 5)
+  {
+    // this is a fragmented packet
+    // we at least check if the info about fragmentation is sane.
+    if (totalfrags > 999 || fragno > totalfrags
+        || totalfrags < 1 || fragno < 1)
+      return 0;
+
+    pname=lower_case(pname);
+
+    // is it even a IM 2.5+ packet? (want to avoid copying the buffer,
+    // therefore this approach)
+    if (sscanf(buffer, "PKT:%.1~s:%~d:%~d/%~d|$S:%.10s|%~s",
+               signature) == 6)
+    {
+      // create fragment (we know, there are at least two |)
+      int first_pipe = strstr(buffer,"|");
+      int sig_end = strstr(buffer, "|", first_pipe+1);
+      f = (<fragment_s> header: buffer[0..first_pipe],
+                      buf: buffer[sig_end+1 ..]
+          );
+      debug_msg(sprintf("Received v2.5+ packet %d, fragment %d/%d from %s.\n"
+                ,packetid, fragno, totalfrags, pname),90);
+    }
+    else
+    {
+      // create fragment (we know, there is at least one |)
+      debug_msg(sprintf("Received v2 packet %d, fragment %d/%d from %s.\n"
+                ,packetid, fragno, totalfrags, pname),90);
+      int header_end = strstr(buffer, "|");
+      f = (<fragment_s> header: buffer[0..header_end],
+                      buf: buffer[header_end+1 ..]
+          );
+    }
+
+    // get the sender
+    sender = peers[pname];
+    // if we don't know the sender yet, we create a new peer with its name.
+    // The ip and port will be updated during parsing, when the packet is
+    // complete.
+    if (!sender)
+    {
+      // if we can't create one, we discard the fragment
+      sender = add_new_peer( (<host_s> name: pname,
+                          first_contact: time(),
+                          last_contact: time(),
+                          mtu: 1024,
+                          received: m_allocate(5)
+                         ));
+      if (!sender)
+        return 0;
+    }
+    // did we already received a fragment? - get its packet
+    packet = sender->received[packetid];
+    // if not create new packet structure and add it to the receive queue of
+    // the peer
+    if (!packet)
+    {
+      packet = (<packet_s> id : packetid, timestamp: time(),
+                peername: pname,
+                fragments : allocate(totalfrags, 0)
+               );
+      m_add(sender->received, packetid, packet);
+    }
+
+    // now we can also check the signature, if there is one.
+    if (signature &&
+        validate_signature(signature, f->header+f->buf, sender))
+    {
+         packet->pflags |= FL_VALID_SIGNATURE;
+    }
+    else
+    {
+      // if there is no valid signature, but we received a fragment of this
+      // packet with valid signature, we discard the fragment.
+      if (packet->pflags & FL_VALID_SIGNATURE)
+      {
+        debug_msg(sprintf("Received fragment %d with invalid signature in "
+                          "signed packet %d from %s. Discarding fragment.\n"
+                          ,fragno, packetid, pname),40);
+        return 0;
+      }
+    }
+
+    // add fragment to its slot - if we receive a fragment twice, the last one
+    // arriving wins.
+    packet->fragments[fragno] = f;
+    // if not all fragments are received, we end processing here and wait for
+    // more.
+    if (member(packet->fragments, 0))
+      return 0;
+  }
+  else
+  {
+    // we assume a non-fragmented legacy packet, no real validation
+    // possible.
+    packet = (<packet_s> timestamp: time(),
+              buf: buffer
+             );
+
+    debug_msg(sprintf("Received v2 packet.\n"),90);
+  }
+  // at this point we have a complete packet - but we may have to defragment
+  // it yet.
+  if (packet->fragments)
+  {
+    defragment_packet(packet);
+    // and remove it from the receive queue of the sender (note, if we have
+    // fragments in the packet, we also have a valid sender at this point)
+    m_delete(sender->received, packet->id);
+    // and check for versions and flags - will be there for IM 2.5+ packets.
+    // Note: if the sender claims a version < 2000 here, this is also fine.
+    // If not there, we assume IM 2/Zebedee.
+    if (sscanf(buffer, "NAME:%~s|V:%d|$F:%d|%~s",
+               version, flags) == 4)
+    {
+      packet->pversion = version;
+      // store flags, but do not set the FL_VALID_SIGNATURE flag ;-)
+      packet->pflags |= (flags & ~FL_VALID_SIGNATURE);
+    }
+    else
+      packet->pversion = 2000;
+  }
+
+  // if the packet has a version >= 2500, it must be signed. If not, we
+  // discard it.
+  if (packet->pversion >= 2500
+      && !(packet->pflags & FL_VALID_SIGNATURE))
+  {
+    // But there is one exception: if we don't have a key for the
+    // peer yet, we accept the packet anyway. This is needed to receive its
+    // public key, which we are going to ask them (soon).
+    if (sender->key)
+    {
+      debug_msg(sprintf("Received unsigned packet from v2.5+ peer with "
+                        "key. Discarding."),40);
+      return 0; // key, but no valid signature - discard it.
+    }
+  }
+
+  // Maybe we accept only packets conforming to a specific protocol version
+  // (or newer). This can be used to accept only signated packets.
+  // also we don't accept protocol version older than we already saw for this
+  // peer to prevent downgrade attacks
+  if (packet->pversion < min_protocol_version)
+    return 0;
+
+  return packet;
+}
+
+/* Check wether a UDP request was valid. Is done after validating and parsing
+ * the packet (and all its fragments).
+ * Logs are made and "host" information is updated as appropriate.
+ * Arguments: Decoded UDP packet (struct packet_s)
+ *            sending peer (struct host_s)
+ * Returns:   0 for valid packets, an erro  r string otherwise.
+ */
+string validate_request(struct packet_s p, struct host_s sender)
+{
+  // If we have no peername, it was a legacy packet. Try to find the NAME in
+  // the packet payload.
+  if (!p->peername)
+  {
+    if(!member(p->data, NAME))
+      return "Name of sending peer not given.\n";
+    p->peername = lower_case(p->data[NAME]);
+  }
+
+  if (p->peername == self->name)
+    return "Someone tried to fake ourself!\n";
+
+  // if needed, check the payload for the ID. The ID may be absent...
+  if (!p->id)
+    p->id = p->data[ID];
+  // ... unless this is a reply to a request. And also, a reply can only be
+  // valid, when know about the initial request sent by us.
+  struct request_s req;
+  if (p->data[REQUEST] == REPLY)
+  {
+    if (!p->id)
+      return "Reply packet without packet ID.\n";
+    // and we take note of the request while we are at it, in case we need it.
+    req = requests[p->id];
+    if (!structp(req))
+      return "Reply packet without request.\n";
+  }
+
+  // if we still have no sender (legacy non-fragmented packets), we finally
+  // create one, because we know the sender by name now.
+  sender = peers[p->peername];
+  if (!sender)
+  {
+    // but if we can't create one, we discard the request
+    sender = add_new_peer( (<host_s> name: p->peername,
+                        first_contact: time(),
+                        last_contact: time(),
+                        mtu: 1024,
+                        received: m_allocate(3),
+                       ));
+    if (!sender)
+      return "New peer, but peer list too full.\n";
+  }
+
+  // we don't accept protocol version older than we already saw for this
+  // peer to prevent downgrade attacks.
+  if (p->pversion < sender->im_version)
+    return "Downgraded peer intermud version.";
+  else
+    sender->im_version = p->pversion;
+
+  // if we have a packet with version >= 2500 and no key for the peer
+  // yet, we ask them by sending a HELO packet (which also transmits our
+  // public key).
+  // Note: if we have a packet with version >= 2500, no valid signature, but
+  // already a key for the peer, validate_fragment() would already have
+  // discarded the packet/fragment and we would not be here.
+  // Of course, don't HELO, if this is a helo.
+  if (p->pversion >= 2500 && !sender->key
+      && p->data[REQUEST] != HELO)
+  {
+    // also don't HELO, if this is a response to a HELO...
+    if (!req || req->packet->data[REQUEST] != HELO)
+      send_helo(p->peername);
+  }
+
+  // Note: HELO packets or HELO reponses in packets without valid signature
+  // can't survive until here if we know a key for the peer. Therefore, we
+  // don't have to validate that specifically.
+
+  // TODO: e.g. some requests are allowed only in signed packets.
+
+  return 0; // request ok!
+}
+
+// processes the received packet or fragment. Must be called from the
+// function called by the mudlib master in this object.
+protected void process_fragment(string host, string msg, int hostport)
+{
+  // Catch if someone tries to fake ourself.
+  if (host == self->ip && hostport == self->port)
+    return;
+  debug_msg(sprintf("Received packet from %s:%d.\n",
+                    host, hostport), 100);
+  // First (try to) validate the received fragment (or packet).
+  struct host_s sender;
+  struct packet_s p = validate_fragment(msg, &sender);
+  // If we got a packet structure, the packet is complete and all the
+  // fragments were valid. If not, the packet is either invalid (and to be
+  // discarded) or not complete yet. In both cases, processing ends here.
+  if (!p)
+    return;
+
+  // first parse the packet into a mapping. And again, when not successful,
+  // 0 will be returned.
+  p = parse_packet(p);
+  if (!p)
+    return;
+
+  // record sending host data, may be important for validating the request.
+  p->data[HOST] = host;
+  p->data[UDP_PORT] = hostport;
+
+  debug_msg(sprintf("Packet valid and complete.\n"), 90);
+
+  // Validate the request...
+  string reason = validate_request(p, &sender);
+  if (reason)
+  {
+    debug_msg("validate_request(): discarding request: "+reason+"\n", 30);
+    return; //discard
+  }
+  sender->last_contact = time();
+  // if we received the packet from a host/port combination that is different
+  // from the one we know for this peers, we update the ip address and port.
+  // Note: if the packet was signed, the origin is proved by now. If not...
+  // well... We believe it now.
+  if (sender->ip != host || sender->port != hostport)
+  {
+    debug_msg(sprintf("Updating address of peer %s from %s:%d to %s:%d.\n",
+                      sender->name, sender->ip, sender->port,
+                      host, hostport), 40);
+    sender->ip = host;
+    sender->port = hostport;
+  }
+
+  touch_peer(sender->name);
+
+  // then execute/forward it.
+  struct service_s srv = services[p->data[REQUEST]];
+  if (srv)
+  {
+    if (!srv->recv_cb)
+   {
+      srv->recv_cb = symbol_function(srv->fun, find_object(srv->obname));
+      if (!srv->recv_cb)
+      {
+        // If no callable, the service is unregistered.
+        unregister_service(srv->name);
+        return;
+      }
+    }
+    funcall(srv->recv_cb, p->data);
+  }
+  else
+    // unknown service. Discard for now. //TODO:: send reply
+    return;
+
+} // process_fragment()
+
+
+// returns an increase in reputation (may be 0),
+// may be overloaded in inheritees.
+protected int auto_promote_peer(struct host_s p)
+{
+  // only if we heard from that peer in the last day.
+  if (p->last_contact + 86400 < time())
+    return 0;
+  // TODO: decide if auto-promotion above n should be tied to having a key.
+  if (p->reputation < 1
+      && p->first_contact < time() - 7*86400)
+    return 1;
+  if (p->reputation < 2
+      && p->first_contact < time() - 30*86400)
+    return 1;
+  if (p->reputation < 3
+      && p->first_contact < time() - 12*30*86400)
+    return 1;
+
+  return 0;
+}
+
+// Calculate the not-connected-time-to-live depending on the reputation. May
+// be overloaded in inheritees.
+protected int calc_ncttl(struct host_s p)
+{
+  switch(p->reputation)
+  {
+    case 0:
+      return 3*86400;
+    case 1:
+      return 14*86400;
+    case 2:
+      return 3*30*86400;
+    case 3:
+      return 6*30*86400;
+    default:
+      return 12*30*86400;
+  }
+}
+
+// checks if a peer should be expired (forgotten) and deletes it from our
+// known peer list if necessary.
+protected int check_and_delete_peer(struct host_s peer)
+{
+  if (peer->last_contact + peer->ncttl < time())
+  {
+    m_delete(peers, peer->name);
+  }
+}
+
+void reset()
+{
+  set_next_reset(600);
+  // housekeeping of peer list every 60 resets (6h).
+  reset_counter = ++reset_counter % 60;
+
+  // expire stale requests
+  foreach(int id, struct request_s r : requests)
+  {
+    if (r->timeout < time())
+    {
+      // in case of timeouts we call the callback, but with no data
+      funcall(r->callback, id, r->packet->data, 0);
+      m_delete(requests, id);
+    }
+  }
+
+  // peer housekeeping: increse reputation, expire peers
+  // expire fragments in all peers
+  foreach(string name, struct host_s peer : peers)
+  {
+    // should we do housekeeping of peer list?
+    if (!reset_counter)
+    {
+      // first check if peer should be expired, because we had no contact for an
+      // extended time.
+      if (check_and_delete_peer(peer))
+        continue;
+      // check if the reputation of a peer can be auto-promoted
+      peer->reputation += auto_promote_peer(peer);
+      peer->ncttl = calc_ncttl(peer);
+    }
+
+    if (!mappingp(peer->received) || !sizeof(peer->received))
+      continue;
+
+    // check all incomplete fragments
+    foreach(int id, struct packet_s pack : peer->received)
+    {
+      if (pack->timestamp + 120 < time())
+        m_delete(peer->received, id);
+      //TODO: send info to sender?
+    }
+  }
+}
+
+// *** Core services every implementation must have.
+
+// we received a reply to one of our pings
+protected void recv_ping_reply(int id, mapping request, mapping response)
+{
+  //TODO: what should we do?
+}
+
+// we received a ping request
+protected void recv_ping(mapping data)
+{
+  send(data[NAME], ([ID: data[ID], REQUEST:REPLY,
+                     DATA: self->name +" is alive!\n"]), 0);
+}
+
+// sends a ping request to a peer
+protected void send_ping(string mud)
+{
+  send(mud, ([ REQUEST: PING ]), #'recv_ping_reply);
+}
+
+// We received a reply for one of our QUERY requests.
+protected void recv_query_reply(int id, mapping request, mapping response)
+{
+  //TODO: what do we do with the information?
+}
+
+// send a query request asking for <prop>
+public void send_query(string name, string prop)
+{
+  if (!stringp(name) || !stringp(prop))
+    return;
+  send(name, ([REQUEST: QUERY, DATA: prop,
+               SENDER: getuid(previous_object()) ]), #'recv_query_reply);
+}
+
+// we received a reply request.
+protected void recv_query(mapping data)
+{
+  mapping ret;
+  switch(data[DATA])
+  {
+    case "commands":
+      ret = ([DATA: implode(self->services, ":") ]);
+      break;
+    case "email":
+      ret = ([DATA: EMAIL]);
+      break;
+    case "hosts":
+      string tmp="";
+      foreach(struct host_s p : peers)
+      {
+        tmp += p->name + ":" + p->ip + ":" + p->port
+               + ":" + implode(p->services, ",") + ":" +
+               implode(p->services, ",") + "\n";
+      }
+      ret = ([DATA: trim(tmp, TRIM_RIGHT, "\n") ]);
+      break;
+    case "inetd":
+    case "version":
+      ret = ([DATA: self->im_version ]);
+      break;
+    case "list":
+      ret = ([DATA: "commands,email,hosts,inetd,version,mud_port" ]);
+      break;
+    case "mud_port":
+      ret = ([DATA: query_mud_port() ]);
+      break;
+    case "time":
+      ret = ([DATA: time()]);
+      break;
+    default:
+      return; // Just ignore request for the time being.
+  }
+  ret[REQUEST] = REPLY;
+  ret[RECIPIENT] = data[SENDER];
+  ret[ID] = data[ID];
+  ret["QUERY"] = data[DATA];  //TODO: this is not right, right?
+
+  send(data[NAME], ret, 0);
+}
+
+// Called, when we receive a reply of OUR HELO request.
+protected void recv_helo_reply(int id, mapping request, mapping response)
+{
+  struct host_s peer = peers[response[NAME]];
+  // if we already have a key for the peer, we accept data and answer only if
+  // the packet was correctly signed. Although the check should be redundant,
+  // because then the packet should have been discarded earlier. But for this,
+  // better safe, than sorry.
+  if (peer->key
+      && !(response[FLAGS] & FL_VALID_SIGNATURE))
+    raise_error("Unexpected unsigned packed from "
+                + peer->name + ".\n");
+
+  mapping theirinfo = json_parse(response[DATA]);
+  // yes - this is a way to update a key... Sending a HELO packet signed
+  // with the old key
+  peer->key = response["pkey"];
+  if (response["mtu"] >= 1024)
+    peer->mtu = min(response["mtu"], MAX_UDP_LENGTH);
+  if (pointerp(data["services"]))
+    peer->services = data["services"];
+}
+
+// we received a HELO packet, send back our info.
+protected void recv_helo(mapping data)
+{
+  struct host_s peer = peers[data[NAME]];
+  // if we already have a key for the peer, we accept data and answer only if
+  // the packet was correctly signed. Although the check should be redundant,
+  // because then the packet should have been discarded earlier. But for this,
+  // better safe, than sorry.
+  if (peer->key
+      && !(data[FLAGS] & FL_VALID_SIGNATURE))
+    raise_error("Unexpected unsigned packed from "
+                + peer->name + ".\n");
+
+  mapping theirinfo = json_parse(data[DATA]);
+  // yes - this is a way to update a key... Sending a HELO packet signed
+  // with the old key
+  peer->key = theirinfo["pkey"];
+  if (theirinfo["mtu"] >= 1024)
+    peer->mtu = min(theirinfo["mtu"], MAX_UDP_LENGTH);
+  if (pointerp(theirinfo["services"]))
+    peer->services = theirinfo["services"];
+
+  mapping ourinfo = (["mtu": self->mtu, "pkey": self->key,
+                      "services": self->services ]);
+  send(data[NAME], ([ID: data[ID], REQUEST:REPLY,
+                     DATA: json_serialize(ourinfo) ]), 0 );
+}
+
+// send a HELO packet.
+protected void send_helo(string name)
+{
+  mapping ourinfo = (["mtu": self->mtu, "pkey": self->key,
+                      "services": self->services]);
+  send(name, ([REQUEST:HELO,
+                     DATA: json_serialize(ourinfo) ]), #'recv_helo_reply );
+}
+
+// We received some reply for one of our requests - find our initial request
+// and forward the data to the callback.
+protected void recv_reply(mapping data)
+{
+  // validate_request ensured that we have the initial request.
+  int pid = data[ID];
+  debug_msg(sprintf("Received answer for request %d\n",pid),90);
+  struct request_s req = requests[pid];
+  m_delete(requests, pid);
+  funcall(req->callback, pid, req->packet->data, data);
+}
+
+/*
+ * Make a PING request to all muds in the "hosts" mapping to set
+ * HOSTLIST_STATUS information.
+ * But don't ping all muds at once, because that may overflow the callout
+ * table during mud startup, when hundreds of objects make callouts.
+ */
+void ping_many_muds(string *muds)
+{
+  if (!pointerp(muds))
+    muds=m_indices(peers);
+  if (!sizeof(muds))
+    return;
+  string *part;
+  if (sizeof(muds) > 9)
+    part=muds[0..9];
+  else
+    part=muds;
+  foreach(string mud: part)
+    send_ping(mud);
+  muds -= part;
+  if (sizeof(muds))
+    call_out(#'ping_many_muds, 4, muds);
+}
+
+protected void create()
+{
+  if (object_name(this_object()) == __FILE__[0..<3])
+  {
+    set_next_reset(-1);
+    return;
+  }
+  set_user();
+  restore_me();
+  init();
+}
+
+protected void create_super()
+{
+  set_next_reset(-1);
+}
+
+int remove(int silent)
+{
+  reset();
+  save_me();
+  destruct(this_object());
+  return 1;
+}
+
