00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "network.hpp"
00022 #include "network_manager_ana.hpp"
00023
00024 #include "global.hpp"
00025
00026 #include "config.hpp"
00027
00028 #include "gettext.hpp"
00029 #include "log.hpp"
00030 #include "serialization/string_utils.hpp"
00031 #include "serialization/parser.hpp"
00032 #include "thread.hpp"
00033 #include "util.hpp"
00034
00035 #include "filesystem.hpp"
00036
00037 #include <cerrno>
00038 #include <queue>
00039 #include <iomanip>
00040 #include <set>
00041 #include <cstring>
00042
00043 #include <signal.h>
00044 #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
00045 #undef INADDR_ANY
00046 #undef INADDR_BROADCAST
00047 #undef INADDR_NONE
00048 #include <windows.h>
00049 #else
00050 #include <sys/types.h>
00051 #include <sys/socket.h>
00052 #include <netinet/in.h>
00053 #include <netinet/tcp.h>
00054 #ifdef __BEOS__
00055 #include <socket.h>
00056 #else
00057 #include <fcntl.h>
00058 #endif
00059 #define SOCKET int
00060 #endif
00061
00062 static lg::log_domain log_network("network");
00063 #define DBG_NW LOG_STREAM(debug, log_network)
00064 #define LOG_NW LOG_STREAM(info, log_network)
00065 #define WRN_NW LOG_STREAM(warn, log_network)
00066 #define ERR_NW LOG_STREAM(err, log_network)
00067
00068 namespace
00069 {
00070 ana_network_manager ana_manager;
00071 network::bandwidth_in_ptr global_bandwidth_in_ptr( new network::bandwidth_in(4) );
00072
00073
00074 size_t instances_using_the_network_module( 0 );
00075 }
00076
00077 namespace network {
00078
00079
00080
00081
00082
00083
00084 unsigned int ping_timeout = 0;
00085
00086 connection_stats::connection_stats(int sent, int received, int connected_at)
00087 : bytes_sent(sent), bytes_received(received), time_connected(0 - connected_at)
00088
00089 {
00090 }
00091
00092 connection_stats get_connection_stats(connection connection_num)
00093 {
00094 const ana::stats* stats = ana_manager.get_stats( connection_num );
00095
00096 if ( stats == NULL )
00097 throw std::runtime_error("Invalid connection ID to get stats from.");
00098 else
00099 return connection_stats( stats->bytes_out(),
00100 stats->bytes_in(),
00101 stats->uptime() );
00102 }
00103
00104 error::error(const std::string& msg, connection sock) : game::error(msg), socket(sock)
00105 {
00106 }
00107
00108 void error::disconnect()
00109 {
00110 }
00111
00112
00113 void enable_connection_through_proxy()
00114 {
00115 ana_manager.enable_connection_through_proxy();
00116 }
00117 void set_proxy_address ( const std::string& address )
00118 {
00119 ana_manager.set_proxy_address( address );
00120 }
00121
00122 void set_proxy_port ( const std::string& port )
00123 {
00124 ana_manager.set_proxy_port( port );
00125 }
00126
00127 void set_proxy_user ( const std::string& user )
00128 {
00129 ana_manager.set_proxy_user( user );
00130 }
00131
00132 void set_proxy_password( const std::string& password )
00133 {
00134 ana_manager.set_proxy_password( password );
00135 }
00136
00137
00138
00139 pending_statistics get_pending_stats()
00140 {
00141
00142 pending_statistics result;
00143
00144 result.npending_sends = 0;
00145 result.nbytes_pending_sends = 0;
00146
00147 return result;
00148 }
00149
00150 manager::manager(size_t , size_t ) : free_(true)
00151 {
00152 ++instances_using_the_network_module;
00153 }
00154
00155 manager::~manager()
00156 {
00157 if ( --instances_using_the_network_module == 0 )
00158 ana_manager.close_connections_and_cleanup();
00159 }
00160
00161 void set_raw_data_only()
00162 {
00163 }
00164
00165 server_manager::server_manager(int port, CREATE_SERVER create_server)
00166 : free_(false),
00167 connection_(0)
00168 {
00169 if ( create_server != NO_SERVER )
00170 {
00171 ana::net_id server_id = ana_manager.create_server( );
00172 ana_manager.run_server( server_id, port);
00173 }
00174 }
00175
00176 server_manager::~server_manager()
00177 {
00178 }
00179
00180 void server_manager::stop()
00181 {
00182 throw std::runtime_error("TODO:Not implemented stop");
00183 }
00184
00185 bool server_manager::is_running() const
00186 {
00187 throw std::runtime_error("TODO:Not implemented is_running");
00188 }
00189
00190 size_t nconnections()
00191 {
00192 return ana_manager.number_of_connections();
00193 }
00194
00195 bool is_server()
00196 {
00197 throw std::runtime_error("TODO:Not implemented is_server");
00198 }
00199
00200 connection connect(const std::string& host, int port)
00201 {
00202 return ana_manager.create_client_and_connect( host, port );
00203 }
00204
00205 connection connect(const std::string& host, int port, threading::waiter& )
00206 {
00207 return connect(host,port);
00208 }
00209
00210 connection accept_connection()
00211 {
00212 return ana_manager.new_connection_id();
00213 }
00214
00215 bool disconnect(connection handle)
00216 {
00217 return ana_manager.disconnect( handle );
00218 }
00219
00220 void queue_disconnect(network::connection handle )
00221 {
00222 ana_manager.disconnect( handle );
00223 }
00224
00225 connection receive_data(config& cfg,
00226 connection connection_num,
00227 unsigned int timeout,
00228 bandwidth_in_ptr* bandwidth_in)
00229 {
00230 ana_manager.throw_if_pending_disconnection();
00231
00232
00233 if ( bandwidth_in != NULL )
00234 *bandwidth_in = global_bandwidth_in_ptr;
00235
00236 network::connection read_id = ana_manager.read_from( connection_num, cfg, timeout );
00237
00238
00239
00240 return read_id;
00241 }
00242
00243 connection receive_data(config& cfg,
00244 connection connection_num,
00245 bandwidth_in_ptr* bandwidth_in)
00246 {
00247
00248 return receive_data(cfg,connection_num, static_cast<unsigned>(0), bandwidth_in);
00249 }
00250
00251 connection receive_data(std::vector<char>& buf, bandwidth_in_ptr* bandwidth_in)
00252 {
00253 ana_manager.throw_if_pending_disconnection();
00254
00255
00256 if ( bandwidth_in != NULL )
00257 *bandwidth_in = global_bandwidth_in_ptr;
00258
00259 return ana_manager.read_from_all( buf );
00260 }
00261
00262
00263 void add_bandwidth_out(const std::string& , size_t )
00264 {
00265
00266 }
00267
00268 void add_bandwidth_in(const std::string& , size_t )
00269 {
00270
00271 }
00272
00273
00274 std::string get_bandwidth_stats_all()
00275 {
00276
00277 const char* packet_type = "network";
00278
00279 const size_t field_width = 8;
00280 const size_t packet_width = 8;
00281 const size_t bytes_width = 8;
00282
00283 const ana::stats* stats = ana_manager.get_stats( );
00284
00285 std::stringstream ss;
00286 ss << " " << std::setw(field_width) << packet_type << "| "
00287 << std::setw(packet_width)<< stats->packets_out()<< "| "
00288 << std::setw(bytes_width) << stats->bytes_out() /1024 << "| "
00289 << std::setw(packet_width)<< stats->packets_in()<< "| "
00290 << std::setw(bytes_width) << stats->bytes_in() /1024 << "\n";
00291
00292 return ss.str();
00293 }
00294
00295 std::string get_bandwidth_stats()
00296 {
00297
00298 const char* packet_type = "network";
00299
00300 const size_t field_width = 8;
00301 const size_t packet_width = 8;
00302 const size_t bytes_width = 8;
00303
00304 const ana::stats* stats = ana_manager.get_stats( 0, ana::HOURS );
00305
00306
00307 std::stringstream ss;
00308 ss << " " << std::setw(field_width) << packet_type << "| "
00309 << std::setw(packet_width)<< stats->packets_out()<< "| "
00310 << std::setw(bytes_width) << stats->bytes_out() /1024 << "| "
00311 << std::setw(packet_width)<< stats->packets_in()<< "| "
00312 << std::setw(bytes_width) << stats->bytes_in() /1024 << "\n";
00313
00314 return ss.str();
00315 }
00316
00317 std::string get_bandwidth_stats(int )
00318 {
00319 return std::string("");
00320 }
00321
00322 bandwidth_in::~bandwidth_in()
00323 {
00324 }
00325
00326 void send_file(const std::string& ,
00327 connection ,
00328 const std::string& )
00329 {
00330 throw std::runtime_error("TODO:Not implemented send_file");
00331 }
00332
00333 size_t send_data(const config& cfg,
00334 connection connection_num,
00335 const std::string& )
00336 {
00337 if(cfg.empty())
00338 return 0;
00339
00340 if( connection_num == 0 )
00341 return ana_manager.send_all( cfg );
00342 else
00343 return ana_manager.send( connection_num, cfg );
00344 }
00345
00346 void send_raw_data(const char* buf,
00347 int len,
00348 connection connection_num,
00349 const std::string& )
00350 {
00351 ana_manager.send_raw_data( buf, size_t( len ), connection_num );
00352 }
00353
00354 void process_send_queue(connection, size_t)
00355 {
00356 ana_manager.throw_if_pending_disconnection();
00357 }
00358
00359 void send_data_all_except(const config& cfg,
00360 connection connection_num,
00361 const std::string& )
00362 {
00363 ana_manager.send_all_except(cfg, connection_num);
00364 }
00365
00366 std::string ip_address(connection connection_num)
00367 {
00368 return ana_manager.ip_address( connection_num );
00369 }
00370
00371 statistics get_send_stats(connection handle)
00372 {
00373 return ana_manager.get_send_stats( handle );
00374 }
00375
00376 statistics get_receive_stats(connection handle)
00377 {
00378 return ana_manager.get_receive_stats( handle );
00379 }
00380 }