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