00001 #ifndef CONNECTION_TABLE_CLASS 00002 #define CONNECTION_TABLE_CLASS 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : connection_table * 00007 * Author : Chris Koeritz * 00008 * * 00009 * Purpose: * 00010 * * 00011 * Manages a list of virtual connections. * 00012 * * 00013 ******************************************************************************* 00014 * Copyright (c) 1992-$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 "connections_dll.h" 00023 00024 // forward. 00025 class connection; 00026 class conntab_hash; 00027 00028 class CONNECTIONS_CLASS_STYLE connection_table 00029 { 00030 public: 00031 connection_table(int heartbeats_count, int freshness_period, 00032 int ghost_period); 00033 // creates a table that manages a set of connections. "heartbeat_count" is 00034 // the number of times a refresh of the connection is attempted (without 00035 // getting a response) before marking the connection dead. the 00036 // "freshness_period" is how long (ms) a connection goes between heartbeat 00037 // checks. "ghost_period" is how long (ms) the connection lingers in the 00038 // table before really getting whacked. the "diagnostic" is used as the 00039 // target for problem complaints. 00040 00041 virtual ~connection_table(); 00042 00043 IMPLEMENT_CLASS_NAME("connection_table"); 00044 00045 enum sides { LOCAL_LINK, REMOTE_LINK, LOCAL_REAL }; 00046 // a simple enum where local represents something on this machine and 00047 // remote means something on another machine. 00048 00049 bool live(const connection_id &conn_id); 00050 // returns true if the "conn_id" is a live connection. 00051 00052 bool connected(const connection_id &conn_id); 00053 // returns true if the connection with "conn_id" is currently active. 00054 00055 connection_id add(const connection &to_add); 00056 // places a new connection in the connection table and returns the 00057 // connection id stored in "to_add" on success. this id must be allocated 00058 // prior to calling add(). it is a nasty error if the host and id already 00059 // exist; an invalid connection_id is returned in that case. 00060 00061 connection_id update(const connection &to_update); 00062 // locates a connection by the connection id in "to_update" and 00063 // copies all information from "to_update" into it. 00064 00065 bool find(const connection_id &conn_id, connection &to_fill); 00066 // finds the connection for the "conn_id". the return value 00067 // is true if the search succeeded. 00068 00069 bool zap(const connection_id &conn_id); 00070 // removes a connection "conn_id" from the list. true is returned if the 00071 // connection id was deleted. this does not actually completely trash the 00072 // connection; it merely marks it as dead. the connection will be 00073 // destroyed at a later time but is effectively dead. 00074 00075 bool transport_connected(const transport_id &tran_id); 00076 // returns true if the linked or real transport that has "tran_id" has any 00077 // active connections. if the transport is real, then the result is 00078 // true if any linked transports using that real transport are connected. 00079 00080 int count_users(const transport_id &real_id, 00081 const transport_id &ignored_link_id, int low_level_id, int level); 00082 // returns the number of connections using the "low_level_id" at the 00083 // specified "level" for the real transport with "real_id" and ignores 00084 // the "ignored_link_id" in this count. 00085 00086 connection_id find_linked(sides side, const transport_id &tran_id); 00087 // returns the connection id in use by the linked transport with an 00088 // id of "tran_id". since a linked transport can only have one connection, 00089 // the id is a unique key for the connection. the "side" tells whether to 00090 // match the local or remote transport id. 00091 00092 connection_id find_low_level(network_address::address_type type, 00093 int low_level_id, int level = 0); 00094 // looks for a connection of the "type" specified that has the 00095 // "low_level_id". this is needed for translating from a low level 00096 // protocol id to one of our transports. the connection id for that 00097 // low level id is returned. the "level" is used to index into the 00098 // low level id array. currently zero and one are supported as indices. 00099 00100 connection_id find_destination(const transport_id &real_id, 00101 const network_address &destination); 00102 // finds the connection id for a linked transport that is hooked up to 00103 // the "real_id" and has the "destination". 00104 00105 transport_id socket_to_real_transport(network_address::address_type type, 00106 int socket, transport_id &linked_id); 00107 // converts a socket number to the real transport that's managing it. 00108 // if the socket is also associated with a link, then the id is returned 00109 // in "linked_id". 00110 00111 connection_id find_state(const transport_id &real_id, 00112 connection::states to_find, int low_level); 00113 // locates the first connection that uses the "real_id" and is in the 00114 // state "to_find". if the "low_level" is a normal number, only the 00115 // connection with the state "to_find" and the primary low-level id of 00116 // "low_level" will match. if "low_level" is zero, then only connections 00117 // that have no primary low-level id yet will match. if "low_level" is 00118 // negative, then any connection in the right state will match. 00119 00120 int get_low_level_id(const transport_id &real_id, int level); 00121 // finds a live and connected connection that has the "real_id" and 00122 // returns the low-level unique_id at the "level" specified. 00123 00124 void clear_dead(); 00125 // removes all connections that are marked as dead and that have had their 00126 // time stamp expire. 00127 00128 bool reset_time(const connection_id &conn_id); 00129 bool kabump(const connection_id &conn_id) { return reset_time(conn_id); } 00130 // resets the time_stamp associated with the "conn_id" indicating that 00131 // something has occurred recently to make us think it's still a live 00132 // connection. 00133 00134 bool record_request(const connection_id &conn_id); 00135 bool made_request(const connection_id &conn_id) 00136 { return record_request(conn_id); } 00137 // increments the missed heartbeats parameter on the occasion of a 00138 // heartbeat request. the number missed can be reset with "reset_time". 00139 00140 heartbeat liveness(const connection_id &conn_id); 00141 bool set_liveness(const connection_id &conn_id, 00142 const heartbeat &new_liveness); 00143 // allow the heartbeat for the connection to be mangled. 00144 00145 void show_connections(istring &output, int indentation = 0, 00146 bool alive_only = false); 00147 // prints a list of the active connections to the debugging window at 00148 // "handle". if "alive_only" is true, then only the live connections are 00149 // shown. 00150 00151 int connections() const; 00152 // returns the current number of connections in the table. 00153 00154 connection::states get_conn_state(const transport_id &tran_id); 00155 // returns the current state of the connection for the transport 00156 // with "tran_id". 00157 00158 bool set_conn_state(const transport_id &tran_id, connection::states state); 00159 // sets the connection "state" for the transport with "tran_id". true is 00160 // returned if the "tran_id" was found successfully and modified. 00161 00162 int set_conn_states(const transport_id &real_id, connection::states state); 00163 // sets all transports linked to the "real_id" to the "state" specified. 00164 // the number of connections processed is returned. 00165 00166 bool owns_connection(const connection_id &conn_id, 00167 const transport_id &link_id); 00168 // returns true if the connection "conn_id" is owned by the linked 00169 // transport with the specified "link_id". 00170 00171 int connections_on_primary(const transport_id &real_id, 00172 const transport_id &ignored_link_id, int primary_id); 00173 // looks up the number of connections on the real_transport_id "real_id" 00174 // that use the "primary_id" as their primary low-level id. this ignores 00175 // any reference to the "ignored_link_id", since that's the object that's 00176 // going away. 00177 00178 void complain_missing_connection(const connection_id &conn_id, 00179 const istring &where) const; 00180 // used to decry the non-finding of a connection. "conn_id" is the 00181 // connection that could not be found and "where" is the location inside 00182 // the program where it was supposed to be found. 00183 00184 int_set find_related_conns(int low_level_primary, int real_transport); 00185 // returns the set of connection ids that have "low_level_primary" as their 00186 // PRIMARY low level id and "real_transport" as their real transport's id. 00187 00188 int_set find_live_reals(); 00189 // returns a list of all the valid real transport ids, based on the set 00190 // of connections that are alive. 00191 00192 connection_id find_dupe(int real_transport, int low_level_primary, 00193 const network_address &sender, int other_side_transport); 00194 // returns the first connection id found that matches all of these 00195 // parameters. this is vital to check when allowing a connection to be 00196 // made since a prolonged connection attempt could build up some redundant 00197 // connection intro packets. 00198 00199 private: 00200 conntab_hash *_connection_list; // repository for connection info. 00201 mutex *_connlock; // protects access to the list of connections. 00202 00203 // constructor parameters: see docs above. 00204 int _heartbeats_until_expiration; 00205 int _freshness_period, _ghost_period; 00206 }; 00207 00209 00210 // a macro that complains (to the log) when a connection cannot be found. 00211 #define CONNECTION_COMPLAINT(id, conn_table) { \ 00212 FUNCTION(func); \ 00213 conn_table.complain_missing_connection(id, function_name); \ 00214 } 00215 00216 // locates a connection by its "conn_id". the "conn_table" must be a valid 00217 // connection_table object. after using the macro, a new bool variable named 00218 // "conn_found" will be true if the connection was found. not finding the 00219 // connection causes a complaint to be emitted. 00220 #define GET_CONN_ENTRY(conn_table, conn_id) \ 00221 connection conn_entry; \ 00222 bool conn_found = true; /* optimistic at first. */ \ 00223 if (!conn_table.find(conn_id, conn_entry)) { \ 00224 CONNECTION_COMPLAINT(conn_id, conn_table); \ 00225 conn_found = false; /* pessimism prevails. */ \ 00226 } 00227 00228 #endif 00229
1.5.1