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
1.5.1