Proper handling of failing to bind server socket
parent
d1d83d7e7f
commit
618314985d
|
@ -986,8 +986,16 @@ nextpeer:
|
||||||
void Connection::serve(u16 port)
|
void Connection::serve(u16 port)
|
||||||
{
|
{
|
||||||
dout_con<<getDesc()<<" serving at port "<<port<<std::endl;
|
dout_con<<getDesc()<<" serving at port "<<port<<std::endl;
|
||||||
m_socket.Bind(port);
|
try{
|
||||||
m_peer_id = PEER_ID_SERVER;
|
m_socket.Bind(port);
|
||||||
|
m_peer_id = PEER_ID_SERVER;
|
||||||
|
}
|
||||||
|
catch(SocketException &e){
|
||||||
|
// Create event
|
||||||
|
ConnectionEvent e;
|
||||||
|
e.bindFailed();
|
||||||
|
putEvent(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::connect(Address address)
|
void Connection::connect(Address address)
|
||||||
|
@ -1597,6 +1605,9 @@ u32 Connection::Receive(u16 &peer_id, SharedBuffer<u8> &data)
|
||||||
if(m_bc_peerhandler)
|
if(m_bc_peerhandler)
|
||||||
m_bc_peerhandler->deletingPeer(&tmp, e.timeout);
|
m_bc_peerhandler->deletingPeer(&tmp, e.timeout);
|
||||||
continue; }
|
continue; }
|
||||||
|
case CONNEVENT_BIND_FAILED:
|
||||||
|
throw ConnectionBindFailed("Failed to bind socket "
|
||||||
|
"(port already in use?)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw NoIncomingDataException("No incoming data");
|
throw NoIncomingDataException("No incoming data");
|
||||||
|
|
|
@ -59,6 +59,14 @@ public:
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConnectionBindFailed : public BaseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConnectionBindFailed(const char *s):
|
||||||
|
BaseException(s)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/*class ThrottlingException : public BaseException
|
/*class ThrottlingException : public BaseException
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -424,6 +432,7 @@ enum ConnectionEventType{
|
||||||
CONNEVENT_DATA_RECEIVED,
|
CONNEVENT_DATA_RECEIVED,
|
||||||
CONNEVENT_PEER_ADDED,
|
CONNEVENT_PEER_ADDED,
|
||||||
CONNEVENT_PEER_REMOVED,
|
CONNEVENT_PEER_REMOVED,
|
||||||
|
CONNEVENT_BIND_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionEvent
|
struct ConnectionEvent
|
||||||
|
@ -447,6 +456,8 @@ struct ConnectionEvent
|
||||||
return "CONNEVENT_PEER_ADDED";
|
return "CONNEVENT_PEER_ADDED";
|
||||||
case CONNEVENT_PEER_REMOVED:
|
case CONNEVENT_PEER_REMOVED:
|
||||||
return "CONNEVENT_PEER_REMOVED";
|
return "CONNEVENT_PEER_REMOVED";
|
||||||
|
case CONNEVENT_BIND_FAILED:
|
||||||
|
return "CONNEVENT_BIND_FAILED";
|
||||||
}
|
}
|
||||||
return "Invalid ConnectionEvent";
|
return "Invalid ConnectionEvent";
|
||||||
}
|
}
|
||||||
|
@ -470,6 +481,10 @@ struct ConnectionEvent
|
||||||
timeout = timeout_;
|
timeout = timeout_;
|
||||||
address = address_;
|
address = address_;
|
||||||
}
|
}
|
||||||
|
void bindFailed()
|
||||||
|
{
|
||||||
|
type = CONNEVENT_BIND_FAILED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConnectionCommandType{
|
enum ConnectionCommandType{
|
||||||
|
|
|
@ -109,6 +109,10 @@ void * ServerThread::Thread()
|
||||||
{
|
{
|
||||||
infostream<<"Server: PeerNotFoundException"<<std::endl;
|
infostream<<"Server: PeerNotFoundException"<<std::endl;
|
||||||
}
|
}
|
||||||
|
catch(con::ConnectionBindFailed &e)
|
||||||
|
{
|
||||||
|
m_server->setAsyncFatalError(e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END_DEBUG_EXCEPTION_HANDLER(errorstream)
|
END_DEBUG_EXCEPTION_HANDLER(errorstream)
|
||||||
|
@ -837,6 +841,7 @@ Server::Server(
|
||||||
m_path_world(path_world),
|
m_path_world(path_world),
|
||||||
m_path_config(path_config),
|
m_path_config(path_config),
|
||||||
m_gamespec(gamespec),
|
m_gamespec(gamespec),
|
||||||
|
m_async_fatal_error(""),
|
||||||
m_env(NULL),
|
m_env(NULL),
|
||||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||||
m_authmanager(path_world+DIR_DELIM+"auth.txt"),
|
m_authmanager(path_world+DIR_DELIM+"auth.txt"),
|
||||||
|
@ -865,6 +870,9 @@ Server::Server(
|
||||||
m_step_dtime_mutex.Init();
|
m_step_dtime_mutex.Init();
|
||||||
m_step_dtime = 0.0;
|
m_step_dtime = 0.0;
|
||||||
|
|
||||||
|
if(path_world == "")
|
||||||
|
throw ServerError("Supplied empty world path");
|
||||||
|
|
||||||
if(!gamespec.isValid())
|
if(!gamespec.isValid())
|
||||||
throw ServerError("Supplied invalid gamespec");
|
throw ServerError("Supplied invalid gamespec");
|
||||||
|
|
||||||
|
@ -1079,6 +1087,8 @@ Server::~Server()
|
||||||
void Server::start(unsigned short port)
|
void Server::start(unsigned short port)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
infostream<<"Starting server on port "<<port<<"..."<<std::endl;
|
||||||
|
|
||||||
// Stop thread if already running
|
// Stop thread if already running
|
||||||
m_thread.stop();
|
m_thread.stop();
|
||||||
|
|
||||||
|
@ -1128,6 +1138,11 @@ void Server::step(float dtime)
|
||||||
JMutexAutoLock lock(m_step_dtime_mutex);
|
JMutexAutoLock lock(m_step_dtime_mutex);
|
||||||
m_step_dtime += dtime;
|
m_step_dtime += dtime;
|
||||||
}
|
}
|
||||||
|
// Throw if fatal error occurred in thread
|
||||||
|
std::string async_err = m_async_fatal_error.get();
|
||||||
|
if(async_err != ""){
|
||||||
|
throw ServerError(async_err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::AsyncRunStep()
|
void Server::AsyncRunStep()
|
||||||
|
|
|
@ -545,6 +545,11 @@ public:
|
||||||
|
|
||||||
std::string getWorldPath(){ return m_path_world; }
|
std::string getWorldPath(){ return m_path_world; }
|
||||||
|
|
||||||
|
void setAsyncFatalError(const std::string &error)
|
||||||
|
{
|
||||||
|
m_async_fatal_error.set(error);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// con::PeerHandler implementation.
|
// con::PeerHandler implementation.
|
||||||
|
@ -658,6 +663,9 @@ private:
|
||||||
// Equivalent of /usr/share/minetest/server
|
// Equivalent of /usr/share/minetest/server
|
||||||
std::string m_path_share;
|
std::string m_path_share;
|
||||||
|
|
||||||
|
// Thread can set; step() will throw as ServerError
|
||||||
|
MutexedVariable<std::string> m_async_fatal_error;
|
||||||
|
|
||||||
// Some timers
|
// Some timers
|
||||||
float m_liquid_transform_timer;
|
float m_liquid_transform_timer;
|
||||||
float m_print_info_timer;
|
float m_print_info_timer;
|
||||||
|
|
Loading…
Reference in New Issue