00001 #ifndef CROMP_SERVER_CLASS 00002 #define CROMP_SERVER_CLASS 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : cromp_server * 00007 * Author : Chris Koeritz * 00008 * * 00009 * Purpose: * 00010 * * 00011 * Services request commands from CROMP clients. Derived objects supply * 00012 * the specific services that a CROMP server implements by providing a set * 00013 * of tentacles that handle the requests. These are added directly to the * 00014 * server's octopus base class. * 00015 * * 00016 ******************************************************************************* 00017 * Copyright (c) 2000-$now By Author. This program is free software; you can * 00018 * redistribute it and/or modify it under the terms of the GNU General Public * 00019 * License as published by the Free Software Foundation; either version 2 of * 00020 * the License or (at your option) any later version. This is online at: * 00021 * http://www.fsf.org/copyleft/gpl.html * 00022 * Please send any updates to: fred@gruntose.com * 00023 \*****************************************************************************/ 00024 00025 #include "cromp_common.h" 00026 00027 #include <octopus/octopus.h> 00028 #include <processes/ethread.h> 00029 #include <timely/time_stamp.h> 00030 #include <sockets/internet_address.h> 00031 00032 #include <tentacles/encryption_tentacle.h> 00033 #include <tentacles/login_tentacle.h> 00034 #include <processes/thread_cabinet.h> 00035 00036 namespace cromp { 00037 00038 // forward. 00039 class client_dropping_thread; 00040 class connection_management_thread; 00041 class cromp_client_list; 00042 class cromp_client_record; 00043 class cromp_security; 00044 class cromp_transaction; 00045 00046 class cromp_server : public cromp_common 00047 { 00048 public: 00049 cromp_server(const sockets::internet_address &where, 00050 int accepting_threads = DEFAULT_ACCEPTERS(), 00051 bool instantaneous = true, 00052 int max_per_entity = DEFAULT_MAX_ENTITY_QUEUE); 00053 // creates a server that will open servers on the location "where". the 00054 // number of connections that can be simultaneously handled is passed in 00055 // "accepting_threads". if the "instantaneous" parameter is true, then 00056 // any infotons that need to be handled will be passed to the octopus for 00057 // immediate handling rather than being handled later on a thread. 00058 00059 virtual ~cromp_server(); 00060 00061 DEFINE_CLASS_NAME("cromp_server"); 00062 00063 int clients() const; // returns number of active clients. 00064 00065 static sockets::internet_address any_address(int port); 00066 // returns an internet_address that should work on any interface that a 00067 // host has. 00068 00069 sockets::internet_address location() const; 00070 // returns the network location where this server is supposed to reside, 00071 // passed in the constructor. 00072 00073 bool instantaneous() const { return _instantaneous; } 00074 // reports whether this server uses immediate handling or delayed handling. 00075 00076 bool enabled() const { return _enabled; } 00077 // reports whether this server has been cranked up or not yet. 00078 00079 basis::outcome enable_servers(bool encrypt, cromp_security *security = NIL); 00080 // this must be called after construction to start up the object before it 00081 // will accept client requests. if "encrypt" is on, then packets will 00082 // be encrypted and no unencrypted packets will be allowed. if the 00083 // "security" is passed as NIL, then a default security manager is created 00084 // and used. otherwise, the specified "security" object is used and will 00085 // _not_ be destroyed when this object goes away. 00086 00087 void disable_servers(); 00088 // shuts down the server sockets that this object owns and disables the 00089 // operation of this object overall. the next step is destruction. 00090 00091 bool find_entity(const octopi::octopus_entity &id, sockets::internet_address &found); 00092 // given an "id" that is currently connected, find the network address 00093 // where it originated and put it in "found". true is returned if the 00094 // entity was located. 00095 00096 bool disconnect_entity(const octopi::octopus_entity &id); 00098 00099 basis::outcome send_to_client(const octopi::octopus_request_id &id, octopi::infoton *data); 00100 // blasts a command back to the client identified by the _entity member in 00101 // the "id". this allows the controlling object of the server object to 00102 // asynchronously inject data into the client's incoming stream. the 00103 // client had better know what's going on or this will just lead to 00104 // ignored data that eventually gets trashed. 00105 00106 basis::outcome get_from_client(const octopi::octopus_request_id &id, octopi::infoton * &data, 00107 int timeout); 00108 // attempts to locate a command with the request "id". if it is found 00109 // within the timeout period, then "data" is set to the command. the 00110 // "data" pointer must be deleted after use. 00111 00112 // basis::outcome get_any_from_client(const octopi::octopus_entity &ent, octopi::infoton * &data, 00113 // int timeout); 00114 // attempts to grab any waiting package for the entity "ent". 00115 00116 bool get_sizes(const octopi::octopus_entity &id, int &items, int &bytes); 00117 // promoted from our octopus' entity_data_bin in order to provide some 00118 // accounting of what is stored for the "id". 00119 00120 basis::astring responses_text_form() const; 00121 // returns a printout of the responses being held here. 00122 00123 static int DEFAULT_ACCEPTERS(); 00124 // the default number of listening threads. 00125 00126 // internal use only... 00127 00128 void look_for_clients(processes::ethread &requester); 00129 // meant to be called by an arbitrary number of threads that can block 00130 // on accepting a new client. control flow will not return from this 00131 // method until the thread's cancel() method has been called. 00132 00133 void drop_dead_clients(); 00134 // called by a thread to manage dead or dying connections. 00135 00136 bool encrypting() const { return !!_encrypt_arm; } 00137 // true if this object is encrypting transmissions. 00138 00139 octopi::infoton *wrap_infoton(octopi::infoton * &request, const octopi::octopus_entity &ent); 00140 // when we're encrypting, this turns "request" into an encryption_wrapper. 00141 // if NIL is returned, then nothing needed to happen to the "request". 00142 00143 private: 00144 cromp_client_list *_clients; // the active set of clients. 00145 processes::thread_cabinet *_accepters; // the list of accepting threads. 00146 basis::mutex *_list_lock; // protects our lists. 00147 timely::time_stamp *_next_droppage; // times cleanup for dead clients. 00148 bool _instantaneous; // true if the octopus gets driven hard. 00149 sockets::internet_address *_where; // where does the server live. 00150 int _accepting_threads; // the number of accepters we keep going. 00151 client_dropping_thread *_dropper; // cleans our lists. 00152 bool _enabled; // records if this is running or not. 00153 octopi::encryption_tentacle *_encrypt_arm; // the handler for encryption. 00154 cromp_security *_default_security; // used in lieu of other provider. 00155 octopi::login_tentacle *_security_arm; // handles security for the logins. 00156 00157 basis::outcome accept_one_client(bool wait); 00158 // tries to get just one accepted client. if "wait" is true, then the 00159 // routine will pause until the socket accept returns. 00160 }; 00161 00162 } //namespace. 00163 00164 #endif 00165 00166
1.6.3