feisty meow concerns codebase  2.140
cromp_common.h
Go to the documentation of this file.
1 #ifndef CROMP_COMMON_CLASS
2 #define CROMP_COMMON_CLASS
3 
4 /*
5 * Name : cromp_common
6 * Author : Chris Koeritz
7 *******************************************************************************
8 * Copyright (c) 2000-$now By Author. This program is free software; you can *
9 * redistribute it and/or modify it under the terms of the GNU General Public *
10 * License as published by the Free Software Foundation; either version 2 of *
11 * the License or (at your option) any later version. This is online at: *
12 * http://www.fsf.org/copyleft/gpl.html *
13 * Please send any updates to: fred@gruntose.com *
14 \*****************************************************************************/
15 
16 #include <crypto/rsa_crypto.h>
17 #include <octopus/octopus.h>
18 #include <octopus/entity_defs.h>
20 #include <octopus/infoton.h>
22 #include <sockets/machine_uid.h>
23 #include <sockets/spocket.h>
24 #include <sockets/tcpip_stack.h>
25 
26 namespace cromp {
27 
30 
34 
35 class cromp_common : public virtual basis::root_object
36 {
37 public:
38  cromp_common(const basis::astring &host, int max_per_ent);
39  // constructs a normal common object. open_common() must be invoked before
40  // this object becomes useful. the "host" should be the actual TCPIP host
41  // that this program is running on. the "max_per_ent" is the maximum
42  // allowed size (in bytes) of pending items per entity.
43 
45  // uses a "preexisting" spocket object for the communications needed here.
46  // the "singleton" octopus is used instead of our base class for restoring
47  // any data. note that "singleton" is not dealt with in the destructor;
48  // it is considered owned externally. however, the "preexisting" spocket
49  // is considered to be owned by this class now. also note that if a NULL_POINTER
50  // "preexisting" socket is passed, then socket creation occurs by the
51  // normal process.
52 
53  virtual ~cromp_common();
54 
55  static int default_port();
56  // returns the default port used by cromp and octopus. this is not
57  // appropriate for most derived apps; they should use their own ports.
58 
59  DEFINE_CLASS_NAME("cromp_common");
60 
62  // opens the object to begin communication. this is the first point at
63  // which the socket is opened.
64 
66  // shuts down our presence on the network.
67 
68  sockets::spocket *spock() const;
69  // allows external access to our socket object. do not abuse this.
70  // also keep in mind that in some stages of construction, this can return
71  // NULL_POINTER. do not assume it is non-null.
72 
74  // returns the location that we're connected to, if any.
75 
76  virtual basis::outcome add_tentacle(octopi::tentacle *to_add, bool filter = false);
77  // allows customization of the processing that the cromp object performs.
78 
79  enum outcomes {
80  OKAY = basis::common::OKAY,
81  DISALLOWED = basis::common::DISALLOWED,
82  BAD_INPUT = basis::common::BAD_INPUT,
83  NOT_FOUND = basis::common::NOT_FOUND,
84  TIMED_OUT = basis::common::TIMED_OUT,
85  GARBAGE = basis::common::GARBAGE,
86  NO_HANDLER = basis::common::NO_HANDLER,
87  PARTIAL = basis::common::PARTIAL,
88  ENCRYPTION_MISMATCH = basis::common::ENCRYPTION_MISMATCH,
89 
90  NO_SERVER = sockets::communication_commons::NO_SERVER,
91  NO_CONNECTION = sockets::communication_commons::NO_CONNECTION,
92 
93  DEFINE_OUTCOME(TOO_FULL, -40, "The request cannot be processed yet")
94  };
95 
96  static const char *outcome_name(const basis::outcome &to_name);
97 
100  // resolves the hostname in "addr" and returns the resolved hostname as
101  // a machine_uid compact_form(). the "resolved" form of the address is
102  // also stored if the pointer is non-null.
103 
105  // returns a textual form of the responses awaiting pickup.
106 
107  bool buffer_clog(int clog_point = 1 * basis::MEGABYTE) const;
108  // returns true if the buffer is bigger than a certain "clog_point".
109 
111  const octopi::octopus_request_id &item_id, int max_tries);
112  // requests a transaction from the other side, specified by the "request".
113  // the return value is OKAY if the request was successfully sent or it
114  // will be another outcome that indicates a failure of transmission.
115  // the "item_id" must be set ahead of time to identify the request and
116  // sender. the "max_tries" limits how many times the sending is
117  // reattempted on failure.
118 
119  basis::outcome pack_and_ship(const octopi::infoton_list &requests, int max_tries);
120  // sends a batch of "requests" in one blast.
121 
123  const octopi::octopus_request_id &req_id, int timeout);
124  // attempts to pull down data from our spocket and process it back into
125  // an infoton in "item". only the specific object for the "req_id"
126  // will be provided. if the "timeout" is non-zero, then data will be
127  // awaited that long. if "timeout" is zero, the method will return
128  // immediately if the data is not already available.
129 
131  int timeout);
132  // returns the first infoton that becomes available. the "req_id" is set
133  // to the identifier from the transaction. this is useful more for the
134  // server side than for the client side.
135 
136  basis::outcome push_outgoing(int max_tries);
137  // composes calls to grab_anything and send_buffer into an attempt to
138  // get all of the data out that is waiting while not ignoring the incoming
139  // data from the other side.
140 
141  void grab_anything(bool wait);
142  // attempts to locate any data waiting for our socket. any infotons
143  // found get stuffed into the requests bin. this is never needed for
144  // cromp_clients; the retrieve methods will automatically invoke this
145  // as appropriate. if "wait" is true, then a data pause will occur
146  // on the socket to await data.
147 
149  // pushes out any pending data waiting for the other side. the returns
150  // can range the gamut, but OKAY and PARTIAL are both successful outcomes.
151  // OKAY means that everything was sent successfully (or there was nothing
152  // to send). PARTIAL means that not all the data was sent, but some got
153  // out successfully. any other errors probably indicate a major problem.
154 
155  // these adjust the storage sizes allowed internally.
156  int max_bytes_per_entity() const;
158 
159  // provides information on the overall number of bytes encountered by all
160  // cromp clients in this program. these are only intended for testing
161  // purposes and might in fact roll over for a busy client app.
162  static double total_bytes_sent() { return _bytes_sent_total; }
163  static double total_bytes_received() { return _bytes_received_total; }
164 
165  static const int HOSTCHOP;
166  // this is the number of characters from the host's name that go into the
167  // octopus identity. the portion after that many characters is a compacted
168  // form of the machine_uid.
169 
170  static bool decode_host(const basis::astring &coded_host, basis::astring &hostname,
171  sockets::machine_uid &machine);
172  // takes the "coded_host" from an entity and returns the "hostname" and
173  // "machine" information that was encoded in it. those will be gibberish
174  // unless true is returned.
175 
176  octopi::octopus *octo() const { return _octopus; }
177  // returns our octopus support object. this should always exist when this
178  // object is constructed properly.
179 
181  // this key should *only* be used for speeding up encryption on the local
182  // host. it is generated when the first caller needs it but then is
183  // a constant key during the program's runtime. this object can be used
184  // for initializing services when it is _known_ that they are connecting
185  // only on the localhost; that's the only place it should be used because
186  // re-using the key on the network provides less security than using
187  // the randomized encryption startup in cromp.
188 
189  int pending_sends() const;
191 
192  int accumulated_bytes() const;
194 
195 protected:
196  octopi::octopus *singleton() const { return _singleton; }
197  // returns the singleton octopus passed to the constructor earlier.
198  // this will return NULL_POINTER if it was not constructed that way.
199 
200 private:
201  sockets::spocket *_commlink; // transceiver for data.
202  octopi::octopus *_octopus; // main octopus; might be same as singleton.
203  octopi::octopus *_singleton; // used for dependent cromp server objects.
204  octopi::entity_data_bin *_requests; // where the incoming requests are stored.
205  basis::mutex *_accum_lock; // protects the accumulator and other data below.
206  timely::time_stamp *_last_data_seen; // last time we got anything on socket.
207  basis::byte_array *_accumulator; // accumulates data for this object.
208  basis::byte_array *_sendings; // accumulates outgoing sends when socket is full.
209  basis::byte_array *_receive_buffer; // temporary buffer.
210  basis::byte_array *_still_flat; // another temporary buffer.
211  timely::time_stamp *_last_cleanup; // when we last cleaned out our bin.
212 
213  // helps for testing; not used for operation.
214  static double _bytes_sent_total;
215  static double _bytes_received_total;
216 
217  void snarf_from_socket(bool wait);
218  // retrieves data waiting on the socket and adds to the accumulator.
219  // if "wait" is true, then the presence of data is awaited first.
220 
221  void process_accumulator();
222  // chews on the accumulated data to seek any commands that are present.
223 
224  void conditional_cleaning();
225  // flushes out any old items if they haven't been cleaned in a bit.
226 
227  basis::outcome retrieve_and_restore_root(bool get_anything, octopi::infoton * &item,
228  octopi::octopus_request_id &req_id, int timeout);
229  // used for both types of retrieval; if "get_anything" is true, then
230  // any old item will be returned. if "get_anything" is false, then only
231  // the item with "req_id" is returned.
232 };
233 
234 } //namespace.
235 
236 #endif
237 
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
A very common template for a dynamic array of bytes.
Definition: byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition: outcome.h:31
A few common features used by both CROMP clients and servers.
Definition: cromp_common.h:36
DEFINE_CLASS_NAME("cromp_common")
static double total_bytes_sent()
Definition: cromp_common.h:162
static const char * outcome_name(const basis::outcome &to_name)
octopi::octopus * octo() const
Definition: cromp_common.h:176
static const int HOSTCHOP
Definition: cromp_common.h:165
bool buffer_clog(int clog_point=1 *basis::MEGABYTE) const
basis::outcome open_common(const sockets::internet_address &where)
basis::outcome push_outgoing(int max_tries)
sockets::spocket * spock() const
cromp_common(const basis::astring &host, int max_per_ent)
basis::outcome retrieve_and_restore(octopi::infoton *&item, const octopi::octopus_request_id &req_id, int timeout)
basis::outcome close_common()
static double total_bytes_received()
Definition: cromp_common.h:163
int accumulated_bytes() const
returns the number of bytes pending processing from the other side.
basis::outcome pack_and_ship(const octopi::infoton &request, const octopi::octopus_request_id &item_id, int max_tries)
sockets::internet_address other_side() const
static int default_port()
basis::outcome retrieve_and_restore_any(octopi::infoton *&item, octopi::octopus_request_id &req_id, int timeout)
static basis::astring chew_hostname(const sockets::internet_address &addr, sockets::internet_address *resolved=NULL_POINTER)
octopi::octopus * singleton() const
Definition: cromp_common.h:196
int max_bytes_per_entity() const
basis::astring responses_text_form() const
static bool decode_host(const basis::astring &coded_host, basis::astring &hostname, sockets::machine_uid &machine)
int pending_sends() const
returns the number of bytes still unsent.
virtual basis::outcome add_tentacle(octopi::tentacle *to_add, bool filter=false)
basis::outcome send_buffer()
void grab_anything(bool wait)
static const crypto::rsa_crypto & localhost_only_key()
Supports public key encryption and decryption.
Definition: rsa_crypto.h:33
Stores a set of infotons grouped by the entity that owns them.
a list of pending requests and who made them.
Definition: entity_defs.h:181
An infoton is an individual request parcel with accompanying information.
Definition: infoton.h:32
Identifies requests made on an octopus by users.
Definition: entity_defs.h:114
Octopus is a design pattern for generalized request processing systems.
Definition: octopus.h:47
Manages a service within an octopus by processing certain infotons.
Definition: tentacle.h:36
this type of address describes a destination out on the internet.
Abstraction for a higher-level BSD socket that is platform independent.
Definition: spocket.h:40
Represents a point in time relative to the operating system startup time.
Definition: time_stamp.h:38
#define NULL_POINTER
The value representing a pointer to nothing.
Definition: definitions.h:32
const int MEGABYTE
Number of bytes in a megabyte.
Definition: definitions.h:135
const int DEFAULT_MAX_ENTITY_QUEUE
the default size we allow per each entity.
Definition: cromp_common.h:28
#define DEFINE_OUTCOME(NAME, CURRENT_VALUE, INFO_STRING)
Provides a way to define auto-generated outcome values.
Definition: outcome.h:80