Malformed data caused config::error exception to be thrown.

Unfortunately campaignd on catching such an exception had no way to
close the right connection, instead all connections were closed because
the local variable that was supposed to contain connection number wasn't
updated. This is fixed by using boost.exception to attach the necessary
data to config::error objects so it can be used at the catch site.
This commit is contained in:
Sergey Popov 2012-10-04 02:23:15 +00:00
parent 98a9b7ad9d
commit 136f42bd4f
5 changed files with 44 additions and 6 deletions

View File

@ -36,6 +36,7 @@
#include <boost/foreach.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/exception/get_error_info.hpp>
// the fork execute is unix specific only tested on Linux quite sure it won't
// work on Windows not sure which other platforms have a problem with it.
@ -571,9 +572,20 @@ namespace {
LOG_CS << "client disconnect: " << e.message << " " << network::ip_address(e.socket) << "\n";
e.disconnect();
}
} catch(config::error& /*e*/) {
LOG_CS << "error in receiving data...\n";
network::disconnect(sock);
} catch(const config::error& e) {
network::connection err_sock = 0;
network::connection const * err_connection = boost::get_error_info<network::connection_info>(e);
if(err_connection != NULL) {
err_sock = *err_connection;
}
if(err_sock == 0 && sock > 0)
err_sock = sock;
if(err_sock) {
LOG_CS << "client disconnect due to exception: " << e.what() << " " << network::ip_address(*err_connection) << "\n";
network::disconnect(*err_connection);
} else {
throw;
}
}
SDL_Delay(20);

View File

@ -35,6 +35,7 @@
#include <iosfwd>
#include <vector>
#include <boost/variant/variant.hpp>
#include <boost/exception/exception.hpp>
#include "game_errors.hpp"
#include "tstring.hpp"
@ -397,7 +398,7 @@ public:
std::string debug() const;
std::string hash() const;
struct error : public game::error {
struct error : public game::error, public boost::exception {
error(const std::string& message) : game::error(message) {}
};

View File

@ -38,6 +38,9 @@
#include <cstring>
#include <stdexcept>
#include <boost/exception/get_error_info.hpp>
#include <boost/exception/info.hpp>
#include <signal.h>
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
#undef INADDR_ANY
@ -795,7 +798,23 @@ connection receive_data(config& cfg, connection connection_num, bandwidth_in_ptr
{
bandwidth_in = &temp;
}
sock = network_worker_pool::get_received_data(sock,cfg, *bandwidth_in);
try {
sock = network_worker_pool::get_received_data(sock,cfg, *bandwidth_in);
} catch(const config::error& e) {
TCPsocket const * err_sock = boost::get_error_info<tcpsocket_info>(e);
if(err_sock == NULL)
throw;
connection err_connection = 0;
for(connection_map::const_iterator i = connections.begin(); i != connections.end(); ++i) {
if(i->second.sock == *err_sock) {
err_connection = i->first;
}
}
if(err_connection) {
throw e << connection_info(err_connection);
}
throw;
}
if (sock == NULL) {
if (!is_server() && last_ping != 0 && ping_timeout != 0)
{

View File

@ -30,6 +30,7 @@ class config;
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/exception/error_info.hpp>
namespace threading
{
@ -267,6 +268,9 @@ struct error : public game::error
void disconnect();
};
typedef boost::error_info<struct tag_tcpsocket,TCPsocket> tcpsocket_info;
typedef boost::error_info<struct tag_connum,connection> connection_info;
struct statistics
{
statistics() : total(0), current(0), current_max(0) {}

View File

@ -34,6 +34,7 @@
#include "wesconfig.h"
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/exception/info.hpp>
#include <cerrno>
#include <deque>
@ -918,9 +919,10 @@ TCPsocket get_received_data(TCPsocket sock, config& cfg, network::bandwidth_in_p
// throw the error in parent thread
std::string error = (*itor)->config_error;
buffer* buf = *itor;
TCPsocket err_sock = (*itor)->sock;
received_data_queue.erase(itor);
delete buf;
throw config::error(error);
throw config::error(error) << network::tcpsocket_info(err_sock);
} else {
cfg.swap((*itor)->config_buf);
const TCPsocket res = (*itor)->sock;