mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-10 18:19:08 +00:00
Fix bug #20205
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:
parent
98a9b7ad9d
commit
136f42bd4f
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/iostreams/filter/gzip.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
|
// 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.
|
// 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";
|
LOG_CS << "client disconnect: " << e.message << " " << network::ip_address(e.socket) << "\n";
|
||||||
e.disconnect();
|
e.disconnect();
|
||||||
}
|
}
|
||||||
} catch(config::error& /*e*/) {
|
} catch(const config::error& e) {
|
||||||
LOG_CS << "error in receiving data...\n";
|
network::connection err_sock = 0;
|
||||||
network::disconnect(sock);
|
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);
|
SDL_Delay(20);
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/variant/variant.hpp>
|
#include <boost/variant/variant.hpp>
|
||||||
|
#include <boost/exception/exception.hpp>
|
||||||
|
|
||||||
#include "game_errors.hpp"
|
#include "game_errors.hpp"
|
||||||
#include "tstring.hpp"
|
#include "tstring.hpp"
|
||||||
@ -397,7 +398,7 @@ public:
|
|||||||
std::string debug() const;
|
std::string debug() const;
|
||||||
std::string hash() 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) {}
|
error(const std::string& message) : game::error(message) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <boost/exception/get_error_info.hpp>
|
||||||
|
#include <boost/exception/info.hpp>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||||
#undef INADDR_ANY
|
#undef INADDR_ANY
|
||||||
@ -795,7 +798,23 @@ connection receive_data(config& cfg, connection connection_num, bandwidth_in_ptr
|
|||||||
{
|
{
|
||||||
bandwidth_in = &temp;
|
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 (sock == NULL) {
|
||||||
if (!is_server() && last_ping != 0 && ping_timeout != 0)
|
if (!is_server() && last_ping != 0 && ping_timeout != 0)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@ class config;
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/exception/error_info.hpp>
|
||||||
|
|
||||||
namespace threading
|
namespace threading
|
||||||
{
|
{
|
||||||
@ -267,6 +268,9 @@ struct error : public game::error
|
|||||||
void disconnect();
|
void disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef boost::error_info<struct tag_tcpsocket,TCPsocket> tcpsocket_info;
|
||||||
|
typedef boost::error_info<struct tag_connum,connection> connection_info;
|
||||||
|
|
||||||
struct statistics
|
struct statistics
|
||||||
{
|
{
|
||||||
statistics() : total(0), current(0), current_max(0) {}
|
statistics() : total(0), current(0), current_max(0) {}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "wesconfig.h"
|
#include "wesconfig.h"
|
||||||
|
|
||||||
#include <boost/iostreams/filter/gzip.hpp>
|
#include <boost/iostreams/filter/gzip.hpp>
|
||||||
|
#include <boost/exception/info.hpp>
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -918,9 +919,10 @@ TCPsocket get_received_data(TCPsocket sock, config& cfg, network::bandwidth_in_p
|
|||||||
// throw the error in parent thread
|
// throw the error in parent thread
|
||||||
std::string error = (*itor)->config_error;
|
std::string error = (*itor)->config_error;
|
||||||
buffer* buf = *itor;
|
buffer* buf = *itor;
|
||||||
|
TCPsocket err_sock = (*itor)->sock;
|
||||||
received_data_queue.erase(itor);
|
received_data_queue.erase(itor);
|
||||||
delete buf;
|
delete buf;
|
||||||
throw config::error(error);
|
throw config::error(error) << network::tcpsocket_info(err_sock);
|
||||||
} else {
|
} else {
|
||||||
cfg.swap((*itor)->config_buf);
|
cfg.swap((*itor)->config_buf);
|
||||||
const TCPsocket res = (*itor)->sock;
|
const TCPsocket res = (*itor)->sock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user