cromp_common.h

Go to the documentation of this file.
00001 #ifndef CROMP_COMMON_CLASS
00002 #define CROMP_COMMON_CLASS
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : cromp_common                                                      *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *  Purpose:                                                                   *
00010 *                                                                             *
00011 *    A few common features used by both CROMP clients and servers.            *
00012 *                                                                             *
00013 *******************************************************************************
00014 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
00015 * redistribute it and/or modify it under the terms of the GNU General Public  *
00016 * License as published by the Free Software Foundation; either version 2 of   *
00017 * the License or (at your option) any later version.  This is online at:      *
00018 *     http://www.fsf.org/copyleft/gpl.html                                    *
00019 * Please send any updates to: fred@gruntose.com                               *
00020 \*****************************************************************************/
00021 
00022 #include "dll_cromp.h"
00023 
00024 #include <octopus/octopus.h>
00025 #include <sockets/definitions_sockets.h>
00026 
00027 // forward:
00028 class entity_data_bin;
00029 class infoton;
00030 class infoton_list;
00031 class internet_address;
00032 class machine_uid;
00033 class octopus_request_id;
00034 class RSA_crypto;
00035 class spocket;
00036 
00037 class CROMP_CLASS_STYLE cromp_common : public virtual object_base
00038 {
00039 public:
00040   enum base_constraints {
00041     DEFAULT_MAX_ENTITY_QUEUE = 14 * MEGABYTE
00042       // the default size we allow per each entity.  note that if there are
00043       // many entities and they're all getting full, that multiplies this.
00044   };
00045 
00046   cromp_common(const istring &host, int max_per_ent);
00047     // constructs a normal common object.  open_common() must be invoked before
00048     // this object becomes useful.  the "host" should be the actual TCPIP host
00049     // that this program is running on.  the "max_per_ent" is the maximum
00050     // allowed size (in bytes) of pending items per entity.
00051 
00052   cromp_common(spocket *preexisting, octopus *singleton);
00053     // uses a "preexisting" spocket object for the communications needed here.
00054     // the "singleton" octopus is used instead of our base class for restoring
00055     // any data.  note that "singleton" is not dealt with in the destructor;
00056     // it is considered owned externally.  however, the "preexisting" spocket
00057     // is considered to be owned by this class now.  also note that if a NIL
00058     // "preexisting" socket is passed, then socket creation occurs by the
00059     // normal process.
00060 
00061   virtual ~cromp_common();
00062 
00063   static int default_port();
00064     // returns the default port used by cromp and octopus.  this is not
00065     // appropriate for most derived apps; they should use their own ports.
00066 
00067   IMPLEMENT_CLASS_NAME("cromp_common");
00068 
00069   outcome open_common(const internet_address &where);
00070     // opens the object to begin communication.  this is the first point at
00071     // which the socket is opened.
00072 
00073   outcome close_common();
00074     // shuts down our presence on the network.
00075 
00076   spocket *spock() const;
00077     // allows external access to our socket object.  do not abuse this.
00078     // also keep in mind that in some stages of construction, this can return
00079     // NIL.  do not assume it is non-NIL.
00080 
00081   internet_address other_side() const;
00082     // returns the location that we're connected to, if any.
00083 
00084   virtual outcome add_tentacle(tentacle *to_add, bool filter = false);
00085     // allows customization of the processing that the cromp object performs.
00086 
00087   enum outcomes {
00088     OKAY = common::OKAY,
00089     DISALLOWED = common::DISALLOWED,
00090     BAD_INPUT = common::BAD_INPUT,
00091     NOT_FOUND = common::NOT_FOUND,
00092     TIMED_OUT = common::TIMED_OUT,
00093     GARBAGE = common::GARBAGE,
00094     NO_HANDLER = common::NO_HANDLER,
00095     PARTIAL = common::PARTIAL,
00096     ENCRYPTION_MISMATCH = common::ENCRYPTION_MISMATCH,
00097 
00098     NO_SERVER = communication_commons::NO_SERVER,
00099     NO_CONNECTION = communication_commons::NO_CONNECTION,
00100 
00101     DEFINE_OUTCOME(TOO_FULL, -40, "The request cannot be processed yet")
00102   };
00103 
00104   static const char *outcome_name(const outcome &to_name);
00105 
00106   static istring chew_hostname(const internet_address &addr,
00107           internet_address *resolved = NIL);
00108     // resolves the hostname in "addr" and returns the resolved hostname as
00109     // a machine_uid compact_form().  the "resolved" form of the address is
00110     // also stored if the pointer is non-NIL.
00111 
00112   istring responses_text_form() const;
00113     // returns a textual form of the responses awaiting pickup.
00114 
00115   bool buffer_clog(int clog_point = 1 * MEGABYTE) const;
00116     // returns true if the buffer is bigger than a certain "clog_point".
00117 
00118   outcome pack_and_ship(const infoton &request,
00119           const octopus_request_id &item_id, int max_tries);
00120     // requests a transaction from the other side, specified by the "request".
00121     // the return value is OKAY if the request was successfully sent or it
00122     // will be another outcome that indicates a failure of transmission.
00123     // the "item_id" must be set ahead of time to identify the request and
00124     // sender.  the "max_tries" limits how many times the sending is
00125     // reattempted on failure.
00126 
00127   outcome pack_and_ship(const infoton_list &requests, int max_tries);
00128     // sends a batch of "requests" in one blast.
00129 
00130   outcome retrieve_and_restore(infoton * &item,
00131           const octopus_request_id &req_id, int timeout);
00132     // attempts to pull down data from our spocket and process it back into
00133     // an infoton in "item".   only the specific object for the "req_id"
00134     // will be provided.  if the "timeout" is non-zero, then data will be
00135     // awaited that long.  if "timeout" is zero, the method will return
00136     // immediately if the data is not already available.
00137 
00138   outcome retrieve_and_restore_any(infoton * &item, octopus_request_id &req_id,
00139           int timeout);
00140     // returns the first infoton that becomes available.  the "req_id" is set
00141     // to the identifier from the transaction.  this is useful more for the
00142     // server side than for the client side.
00143 
00144   outcome push_outgoing(int max_tries);
00145     // composes calls to grab_anything and send_buffer into an attempt to
00146     // get all of the data out that is waiting while not ignoring the incoming
00147     // data from the other side.
00148 
00149   void grab_anything(bool wait);
00150     // attempts to locate any data waiting for our socket.  any infotons
00151     // found get stuffed into the requests bin.  this is never needed for
00152     // cromp_clients; the retrieve methods will automatically invoke this
00153     // as appropriate.  if "wait" is true, then a data pause will occur
00154     // on the socket to await data.
00155 
00156   outcome send_buffer();
00157     // pushes out any pending data waiting for the other side.  the returns
00158     // can range the gamut, but OKAY and PARTIAL are both successful outcomes.
00159     // OKAY means that everything was sent successfully (or there was nothing
00160     // to send).  PARTIAL means that not all the data was sent, but some got
00161     // out successfully.  any other errors probably indicate a major problem.
00162 
00163   // these adjust the storage sizes allowed internally.
00164   int max_bytes_per_entity() const;
00165   void max_bytes_per_entity(int max_bytes_per_entity);
00166 
00167   // provides information on the overall number of bytes encountered by all
00168   // cromp clients in this program.  these are only intended for testing
00169   // purposes and might in fact roll over for a busy client app.
00170   static double total_bytes_sent() { return _bytes_sent_total; }
00171   static double total_bytes_received() { return _bytes_received_total; }
00172 
00173   static const int HOSTCHOP;
00174     // this is the number of characters from the host's name that go into the
00175     // octopus identity.  the portion after that many characters is a compacted
00176     // form of the machine_uid.
00177 
00178   static bool decode_host(const istring &coded_host, istring &hostname,
00179            machine_uid &machine);
00180     // takes the "coded_host" from an entity and returns the "hostname" and
00181     // "machine" information that was encoded in it.  those will be gibberish
00182     // unless true is returned.
00183 
00184   octopus *octo() const { return _octopus; }
00185     // returns our octopus support object.  this should always exist when this
00186     // object is constructed properly.
00187 
00188 #ifndef OMIT_CRYPTO_SUPPORT
00189   static const RSA_crypto &localhost_only_key();
00190     // this key should *only* be used for speeding up encryption on the local
00191     // host.  it is generated when the first caller needs it but then is
00192     // a constant key during the program's runtime.  this object can be used
00193     // for initializing services when it is _known_ that they are connecting
00194     // only on the localhost; that's the only place it should be used because
00195     // re-using the key on the network provides less security than using
00196     // the randomized encryption startup in cromp.
00197 #endif
00198 
00199   int pending_sends() const;
00201 
00202   int accumulated_bytes() const;
00204 
00205 protected:
00206   octopus *singleton() const { return _singleton; }
00207     // returns the singleton octopus passed to the constructor earlier.
00208     // this will return NIL if it was not constructed that way.
00209 
00210 private:
00211   spocket *_commlink;  // transceiver for data.
00212   octopus *_octopus;  // main octopus; might be same as singleton.
00213   octopus *_singleton;  // used for dependent cromp server objects.
00214   entity_data_bin *_requests;  // where the incoming requests are stored.
00215   mutex *_accum_lock;  // protects the accumulator and other data below.
00216   time_stamp *_last_data_seen;  // last time we got anything on socket.
00217   byte_array *_accumulator;  // accumulates data for this object.
00218   byte_array *_sendings;  // accumulates outgoing sends when socket is full.
00219   byte_array *_receive_buffer;  // temporary buffer.
00220   byte_array *_still_flat;  // another temporary buffer.
00221   time_stamp *_last_cleanup;  // when we last cleaned out our bin.
00222 
00223   // helps for testing; not used for operation.
00224   static double _bytes_sent_total;
00225   static double _bytes_received_total;
00226 
00227   void snarf_from_socket(bool wait);
00228     // retrieves data waiting on the socket and adds to the accumulator.
00229     // if "wait" is true, then the presence of data is awaited first.
00230 
00231   void process_accumulator();
00232     // chews on the accumulated data to seek any commands that are present.
00233 
00234   void conditional_cleaning();
00235     // flushes out any old items if they haven't been cleaned in a bit.
00236 
00237   outcome retrieve_and_restore_root(bool get_anything, infoton * &item,
00238           octopus_request_id &req_id, int timeout);
00239     // used for both types of retrieval; if "get_anything" is true, then
00240     // any old item will be returned.  if "get_anything" is false, then only
00241     // the item with "req_id" is returned.
00242 };
00243 
00244 #endif
00245 

Generated on Fri Nov 28 04:28:55 2008 for HOOPLE Libraries by  doxygen 1.5.1