Cosmetic changes mostly, removed unused functions.
This commit is contained in:
parent
6fc4b9c19d
commit
0dfa05227e
@ -54,89 +54,154 @@ const char* inet_ntop(int af, const void* src, char* dst, int cnt)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Synchronised<FILE*> STKHost::m_log_file = NULL;
|
||||||
|
|
||||||
FILE* STKHost::m_log_file = NULL;
|
// ============================================================================
|
||||||
pthread_mutex_t STKHost::m_log_mutex;
|
/** Constructor that just initialises this object (esp. opening the packet
|
||||||
|
* log file), but it does not start a listener thread.
|
||||||
void STKHost::logPacket(const NetworkString &ns, bool incoming)
|
*/
|
||||||
|
STKHost::STKHost()
|
||||||
{
|
{
|
||||||
if (m_log_file == NULL)
|
m_host = NULL;
|
||||||
return;
|
m_listening_thread = NULL;
|
||||||
pthread_mutex_lock(&m_log_mutex);
|
m_log_file.setAtomic(NULL);
|
||||||
if (incoming)
|
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||||
fprintf(m_log_file, "[%d\t] <-- ", (int)(StkTime::getRealTime()));
|
if (UserConfigParams::m_packets_log_filename.toString() != "")
|
||||||
else
|
|
||||||
fprintf(m_log_file, "[%d\t] --> ", (int)(StkTime::getRealTime()));
|
|
||||||
for (int i = 0; i < ns.size(); i++)
|
|
||||||
{
|
{
|
||||||
fprintf(m_log_file, "%d.", ns[i]);
|
std::string s = file_manager
|
||||||
}
|
->getUserConfigFile(UserConfigParams::m_packets_log_filename);
|
||||||
fprintf(m_log_file, "\n");
|
m_log_file.setAtomic(fopen(s.c_str(), "w+"));
|
||||||
pthread_mutex_unlock(&m_log_mutex);
|
|
||||||
}
|
}
|
||||||
|
if (!m_log_file.getData())
|
||||||
|
Log::warn("STKHost", "Network packets won't be logged: no file.");
|
||||||
|
} // STKHost
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Destructor. Stops the listening thread, closes the packet log file and
|
||||||
|
* destroys the enet host.
|
||||||
|
*/
|
||||||
|
STKHost::~STKHost()
|
||||||
|
{
|
||||||
|
stopListening();
|
||||||
|
if (m_log_file.getData())
|
||||||
|
{
|
||||||
|
m_log_file.lock();
|
||||||
|
fclose(m_log_file.getData());
|
||||||
|
Log::warn("STKHost", "Packet logging file has been closed.");
|
||||||
|
m_log_file.getData() = NULL;
|
||||||
|
m_log_file.unlock();
|
||||||
|
}
|
||||||
|
if (m_host)
|
||||||
|
{
|
||||||
|
enet_host_destroy(m_host);
|
||||||
|
}
|
||||||
|
} // ~STKHost
|
||||||
|
|
||||||
void* STKHost::receive_data(void* self)
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Log packets into a file
|
||||||
|
* \param ns : The data in the packet
|
||||||
|
* \param incoming : True if the packet comes from a peer.
|
||||||
|
* False if it's sent to a peer.
|
||||||
|
*/
|
||||||
|
void STKHost::logPacket(const NetworkString &ns, bool incoming)
|
||||||
|
{
|
||||||
|
if (m_log_file.getData() == NULL) // read only access, no need to lock
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *arrow = incoming ? "<--" : "-->";
|
||||||
|
|
||||||
|
m_log_file.lock();
|
||||||
|
fprintf(m_log_file.getData(), "[%d\t] %s ",
|
||||||
|
(int)(StkTime::getRealTime()), arrow);
|
||||||
|
|
||||||
|
for (int i = 0; i < ns.size(); i++)
|
||||||
|
{
|
||||||
|
fprintf(m_log_file.getData(), "%d.", ns[i]);
|
||||||
|
}
|
||||||
|
fprintf(m_log_file.getData(), "\n");
|
||||||
|
m_log_file.unlock();
|
||||||
|
} // logPacket
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Starts the listening of events from ENet.
|
||||||
|
* Starts a thread for receiveData that updates it as often as possible.
|
||||||
|
*/
|
||||||
|
void STKHost::startListening()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_exit_mutex); // will let the update function start
|
||||||
|
m_listening_thread = new pthread_t;
|
||||||
|
pthread_create(m_listening_thread, NULL, &STKHost::mainLoop, this);
|
||||||
|
} // startListening
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Stops the listening of events from ENet.
|
||||||
|
* Stops the thread that was receiving events.
|
||||||
|
*/
|
||||||
|
void STKHost::stopListening()
|
||||||
|
{
|
||||||
|
if (m_listening_thread)
|
||||||
|
{
|
||||||
|
// This will stop the update function on its next update
|
||||||
|
pthread_mutex_unlock(&m_exit_mutex);
|
||||||
|
pthread_join(*m_listening_thread, NULL); // wait for the thread to end
|
||||||
|
}
|
||||||
|
} // stopListening
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** \brief Returns true when the thread should stop listening.
|
||||||
|
*/
|
||||||
|
int STKHost::mustStopListening()
|
||||||
|
{
|
||||||
|
switch (pthread_mutex_trylock(&m_exit_mutex)) {
|
||||||
|
case 0: /* if we got the lock, unlock and return 1 (true) */
|
||||||
|
pthread_mutex_unlock(&m_exit_mutex);
|
||||||
|
return 1;
|
||||||
|
case EBUSY: /* return 0 (false) if the mutex was locked */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} // mustStopListening
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Thread function checking if data is received.
|
||||||
|
* This function tries to get data from network low-level functions as
|
||||||
|
* often as possible. When something is received, it generates an
|
||||||
|
* event and passes it to the Network Manager.
|
||||||
|
* \param self : used to pass the ENet host to the function.
|
||||||
|
*/
|
||||||
|
void* STKHost::mainLoop(void* self)
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
STKHost* myself = (STKHost*)(self);
|
STKHost* myself = (STKHost*)(self);
|
||||||
ENetHost* host = myself->m_host;
|
ENetHost* host = myself->m_host;
|
||||||
while (!myself->mustStopListening())
|
while (!myself->mustStopListening())
|
||||||
{
|
{
|
||||||
while (enet_host_service(host, &event, 20) != 0) {
|
while (enet_host_service(host, &event, 20) != 0)
|
||||||
Event* evt = new Event(&event);
|
{
|
||||||
if (evt->type == EVENT_TYPE_MESSAGE)
|
Event* stk_event = new Event(&event);
|
||||||
logPacket(evt->data(), true);
|
if (stk_event->type == EVENT_TYPE_MESSAGE)
|
||||||
|
logPacket(stk_event->data(), true);
|
||||||
if (event.type != ENET_EVENT_TYPE_NONE)
|
if (event.type != ENET_EVENT_TYPE_NONE)
|
||||||
NetworkManager::getInstance()->notifyEvent(evt);
|
NetworkManager::getInstance()->notifyEvent(stk_event);
|
||||||
delete evt;
|
delete stk_event;
|
||||||
}
|
} // while enet_host_service
|
||||||
}
|
} // while !mustStopListening
|
||||||
myself->m_listening = false;
|
|
||||||
free(myself->m_listening_thread);
|
free(myself->m_listening_thread);
|
||||||
myself->m_listening_thread = NULL;
|
myself->m_listening_thread = NULL;
|
||||||
Log::info("STKHost", "Listening has been stopped");
|
Log::info("STKHost", "Listening has been stopped");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
} // mainLoop
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Setups this host as a server.
|
||||||
STKHost::STKHost()
|
* \param address : The IPv4 address of incoming connections.
|
||||||
{
|
* \param port : The port on which the server listens.
|
||||||
m_host = NULL;
|
* \param peer_count : The maximum number of peers.
|
||||||
m_listening_thread = NULL;
|
* \param channel_limit : The maximum number of channels per peer.
|
||||||
m_log_file = NULL;
|
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
|
||||||
pthread_mutex_init(&m_exit_mutex, NULL);
|
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
|
||||||
pthread_mutex_init(&m_log_mutex, NULL);
|
*/
|
||||||
if (UserConfigParams::m_packets_log_filename.toString() != "")
|
|
||||||
{
|
|
||||||
std::string s =
|
|
||||||
file_manager->getUserConfigFile(UserConfigParams::m_packets_log_filename);
|
|
||||||
m_log_file = fopen(s.c_str(), "w+");
|
|
||||||
}
|
|
||||||
if (!m_log_file)
|
|
||||||
Log::warn("STKHost", "Network packets won't be logged: no file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
STKHost::~STKHost()
|
|
||||||
{
|
|
||||||
stopListening();
|
|
||||||
if (m_log_file)
|
|
||||||
{
|
|
||||||
fclose(m_log_file);
|
|
||||||
Log::warn("STKHost", "Packet logging file has been closed.");
|
|
||||||
}
|
|
||||||
if (m_host)
|
|
||||||
{
|
|
||||||
enet_host_destroy(m_host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
|
void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
|
||||||
int channel_limit, uint32_t max_incoming_bandwidth,
|
int channel_limit, uint32_t max_incoming_bandwidth,
|
||||||
uint32_t max_outgoing_bandwidth)
|
uint32_t max_outgoing_bandwidth)
|
||||||
@ -154,15 +219,21 @@ void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
|
|||||||
|
|
||||||
m_host = enet_host_create(addr, peer_count, channel_limit,
|
m_host = enet_host_create(addr, peer_count, channel_limit,
|
||||||
max_incoming_bandwidth, max_outgoing_bandwidth);
|
max_incoming_bandwidth, max_outgoing_bandwidth);
|
||||||
if (m_host == NULL)
|
if (!m_host)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "An error occurred while trying to create an ENet"
|
Log::fatal("STKHost", "An error occurred while trying to create an ENet"
|
||||||
" server host.");
|
" server host.");
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // setupServer
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Setups the host as a client.
|
||||||
|
* In fact there is only one peer connected to this host.
|
||||||
|
* \param peer_count : The maximum number of peers.
|
||||||
|
* \param channel_limit : The maximum number of channels per peer.
|
||||||
|
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
|
||||||
|
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
|
||||||
|
*/
|
||||||
|
|
||||||
void STKHost::setupClient(int peer_count, int channel_limit,
|
void STKHost::setupClient(int peer_count, int channel_limit,
|
||||||
uint32_t max_incoming_bandwidth,
|
uint32_t max_incoming_bandwidth,
|
||||||
@ -170,38 +241,22 @@ void STKHost::setupClient(int peer_count, int channel_limit,
|
|||||||
{
|
{
|
||||||
m_host = enet_host_create(NULL, peer_count, channel_limit,
|
m_host = enet_host_create(NULL, peer_count, channel_limit,
|
||||||
max_incoming_bandwidth, max_outgoing_bandwidth);
|
max_incoming_bandwidth, max_outgoing_bandwidth);
|
||||||
if (m_host == NULL)
|
if (!m_host)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "An error occurred while trying to create an ENet"
|
Log::fatal ("STKHost", "An error occurred while trying to create an "
|
||||||
" client host.");
|
"ENet client host.");
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // setupClient
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Sends a packet whithout ENet adding its headers.
|
||||||
void STKHost::startListening()
|
* This function is used in particular to achieve the STUN protocol.
|
||||||
{
|
* \param data : Data to send.
|
||||||
pthread_mutex_lock(&m_exit_mutex); // will let the update function start
|
* \param length : Length of the sent data.
|
||||||
m_listening_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
* \param dst : Destination of the packet.
|
||||||
pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this);
|
*/
|
||||||
m_listening = true;
|
void STKHost::sendRawPacket(uint8_t* data, int length,
|
||||||
}
|
const TransportAddress& dst)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void STKHost::stopListening()
|
|
||||||
{
|
|
||||||
if(m_listening_thread)
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function on its next update
|
|
||||||
pthread_join(*m_listening_thread, NULL); // wait the thread to end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void STKHost::sendRawPacket(uint8_t* data, int length, const TransportAddress& dst)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in to;
|
struct sockaddr_in to;
|
||||||
int to_len = sizeof(to);
|
int to_len = sizeof(to);
|
||||||
@ -215,54 +270,43 @@ void STKHost::sendRawPacket(uint8_t* data, int length, const TransportAddress& d
|
|||||||
Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str());
|
Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str());
|
||||||
STKHost::logPacket(NetworkString(std::string((char*)(data), length)),
|
STKHost::logPacket(NetworkString(std::string((char*)(data), length)),
|
||||||
false);
|
false);
|
||||||
}
|
} // sendRawPacket
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Receives a packet directly from the network interface.
|
||||||
uint8_t* STKHost::receiveRawPacket()
|
* Receive a packet whithout ENet processing it and returns the
|
||||||
{
|
* sender's ip address and port in the TransportAddress structure.
|
||||||
uint8_t* buffer; // max size needed normally (only used for stun)
|
* \param sender : Stores the transport address of the sender of the
|
||||||
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
|
* received packet.
|
||||||
memset(buffer, 0, 2048);
|
* \return A string containing the data of the received packet.
|
||||||
|
*/
|
||||||
int len = recv(m_host->socket,(char*)buffer,2048, 0);
|
|
||||||
int i = 0;
|
|
||||||
// wait to receive the message because enet sockets are non-blocking
|
|
||||||
while(len < 0)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
len = recv(m_host->socket,(char*)buffer,2048, 0);
|
|
||||||
StkTime::sleep(1);
|
|
||||||
}
|
|
||||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
||||||
{
|
{
|
||||||
uint8_t* buffer; // max size needed normally (only used for stun)
|
const int LEN = 2048;
|
||||||
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
|
// max size needed normally (only used for stun)
|
||||||
memset(buffer, 0, 2048);
|
uint8_t* buffer = new uint8_t[LEN];
|
||||||
|
memset(buffer, 0, LEN);
|
||||||
|
|
||||||
socklen_t from_len;
|
socklen_t from_len;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
from_len = sizeof(addr);
|
from_len = sizeof(addr);
|
||||||
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len);
|
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len );
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// wait to receive the message because enet sockets are non-blocking
|
// wait to receive the message because enet sockets are non-blocking
|
||||||
while(len == -1) // nothing received
|
while(len == -1) // nothing received
|
||||||
{
|
{
|
||||||
i++;
|
|
||||||
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len);
|
|
||||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||||
|
i++;
|
||||||
|
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len );
|
||||||
}
|
}
|
||||||
if (len == SOCKET_ERROR)
|
if (len == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "Problem with the socket. Please contact the dev team.");
|
Log::error("STKHost",
|
||||||
|
"Problem with the socket. Please contact the dev team.");
|
||||||
}
|
}
|
||||||
// we received the data
|
// we received the data
|
||||||
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
|
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
|
||||||
@ -270,69 +314,89 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
|||||||
|
|
||||||
if (addr.sin_family == AF_INET)
|
if (addr.sin_family == AF_INET)
|
||||||
{
|
{
|
||||||
Log::info("STKHost", "IPv4 Address of the sender was %s", sender->toString().c_str());
|
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||||
|
sender->toString().c_str());
|
||||||
}
|
}
|
||||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
} // receiveRawPacket(TransportAddress* sender)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Receives a packet directly from the network interface and
|
||||||
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender, int max_tries)
|
* filter its address.
|
||||||
|
* Receive a packet whithout ENet processing it. Checks that the
|
||||||
|
* sender of the packet is the one that corresponds to the sender
|
||||||
|
* parameter. Does not check the port right now.
|
||||||
|
* \param sender : Transport address of the original sender of the
|
||||||
|
* wanted packet.
|
||||||
|
* \param max_tries : Number of times we try to read data from the
|
||||||
|
* socket. This is aproximately the time we wait in
|
||||||
|
* milliseconds. -1 means eternal tries.
|
||||||
|
* \return A string containing the data of the received packet
|
||||||
|
* matching the sender's ip address.
|
||||||
|
*/
|
||||||
|
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender,
|
||||||
|
int max_tries)
|
||||||
{
|
{
|
||||||
uint8_t* buffer; // max size needed normally (only used for stun)
|
const int LEN = 2048;
|
||||||
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
|
uint8_t* buffer = new uint8_t[LEN];
|
||||||
memset(buffer, 0, 2048);
|
memset(buffer, 0, LEN);
|
||||||
|
|
||||||
socklen_t from_len;
|
socklen_t from_len;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
from_len = sizeof(addr);
|
from_len = sizeof(addr);
|
||||||
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len);
|
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len );
|
||||||
|
|
||||||
int i = 0;
|
int count = 0;
|
||||||
// wait to receive the message because enet sockets are non-blocking
|
// wait to receive the message because enet sockets are non-blocking
|
||||||
while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
|
while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
|
||||||
{
|
{
|
||||||
i++;
|
count++;
|
||||||
if (len>=0)
|
if (len>=0)
|
||||||
{
|
{
|
||||||
Log::info("STKHost", "Message received but the ip address didn't match the expected one.");
|
Log::info("STKHost", "Message received but the ip address didn't "
|
||||||
|
"match the expected one.");
|
||||||
}
|
}
|
||||||
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len);
|
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len);
|
||||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||||
if (i >= max_tries && max_tries != -1)
|
if (count >= max_tries && max_tries != -1)
|
||||||
{
|
{
|
||||||
Log::verbose("STKHost", "No answer from the server on %u.%u.%u.%u:%u", (m_host->address.host&0xff),
|
TransportAddress a(m_host->address);
|
||||||
(m_host->address.host>>8&0xff),
|
Log::verbose("STKHost", "No answer from the server on %s",
|
||||||
(m_host->address.host>>16&0xff),
|
a.toString().c_str());
|
||||||
(m_host->address.host>>24&0xff),
|
|
||||||
(m_host->address.port));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addr.sin_family == AF_INET)
|
if (addr.sin_family == AF_INET)
|
||||||
{
|
{
|
||||||
char s[20];
|
TransportAddress a(addr.sin_addr.s_addr);
|
||||||
inet_ntop(AF_INET, &(addr.sin_addr), s, 20);
|
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||||
Log::info("STKHost", "IPv4 Address of the sender was %s", s);
|
a.toString(false).c_str());
|
||||||
}
|
}
|
||||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
} // receiveRawPacket(const TransportAddress& sender, int max_tries)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Broadcasts a packet to all peers.
|
||||||
|
* \param data : Data to send.
|
||||||
|
*/
|
||||||
void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
|
void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
|
||||||
{
|
{
|
||||||
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
||||||
(reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNSEQUENCED));
|
reliable ? ENET_PACKET_FLAG_RELIABLE
|
||||||
|
: ENET_PACKET_FLAG_UNSEQUENCED);
|
||||||
enet_host_broadcast(m_host, 0, packet);
|
enet_host_broadcast(m_host, 0, packet);
|
||||||
STKHost::logPacket(data, false);
|
STKHost::logPacket(data, false);
|
||||||
}
|
} // broadcastPacket
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Tells if a peer is known.
|
||||||
|
* \return True if the peer is known, false elseway.
|
||||||
|
*/
|
||||||
bool STKHost::peerExists(const TransportAddress& peer)
|
bool STKHost::peerExists(const TransportAddress& peer)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||||
@ -344,10 +408,12 @@ bool STKHost::peerExists(const TransportAddress& peer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
} // peerExists
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Tells if a peer is known and connected.
|
||||||
|
* \return True if the peer is known and connected, false elseway.
|
||||||
|
*/
|
||||||
bool STKHost::isConnectedTo(const TransportAddress& peer)
|
bool STKHost::isConnectedTo(const TransportAddress& peer)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||||
@ -359,22 +425,9 @@ bool STKHost::isConnectedTo(const TransportAddress& peer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
} // isConnectedTo
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int STKHost::mustStopListening()
|
|
||||||
{
|
|
||||||
switch(pthread_mutex_trylock(&m_exit_mutex)) {
|
|
||||||
case 0: /* if we got the lock, unlock and return 1 (true) */
|
|
||||||
pthread_mutex_unlock(&m_exit_mutex);
|
|
||||||
return 1;
|
|
||||||
case EBUSY: /* return 0 (false) if the mutex was locked */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
uint16_t STKHost::getPort() const
|
uint16_t STKHost::getPort() const
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
#ifndef STK_HOST_HPP
|
#ifndef STK_HOST_HPP
|
||||||
#define STK_HOST_HPP
|
#define STK_HOST_HPP
|
||||||
|
|
||||||
#include "network/types.hpp"
|
|
||||||
|
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.hpp"
|
||||||
|
#include "network/types.hpp"
|
||||||
|
#include "utils/synchronised.hpp"
|
||||||
|
|
||||||
// enet.h includes win32.h, which without lean_and_mean includes
|
// enet.h includes win32.h, which without lean_and_mean includes
|
||||||
// winspool.h, which defines MAX_PRIORITY as a macro, which then
|
// winspool.h, which defines MAX_PRIORITY as a macro, which then
|
||||||
@ -47,6 +47,20 @@
|
|||||||
class STKHost
|
class STKHost
|
||||||
{
|
{
|
||||||
friend class STKPeer; // allow direct enet modifications in implementations
|
friend class STKPeer; // allow direct enet modifications in implementations
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** ENet host interfacing sockets. */
|
||||||
|
ENetHost* m_host;
|
||||||
|
|
||||||
|
/** Id of thread listening to enet events. */
|
||||||
|
pthread_t* m_listening_thread;
|
||||||
|
|
||||||
|
/** Mutex used to stop this thread. */
|
||||||
|
pthread_mutex_t m_exit_mutex;
|
||||||
|
|
||||||
|
//** Where to log packets. If NULL for FILE* logging is disabled. */
|
||||||
|
static Synchronised<FILE*> m_log_file;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! \enum HOST_TYPE
|
/*! \enum HOST_TYPE
|
||||||
* \brief Defines three host types for the server.
|
* \brief Defines three host types for the server.
|
||||||
@ -64,109 +78,31 @@ class STKHost
|
|||||||
/*! \brief Destructor */
|
/*! \brief Destructor */
|
||||||
virtual ~STKHost();
|
virtual ~STKHost();
|
||||||
|
|
||||||
/*! \brief Log packets into a file
|
|
||||||
* \param ns : The data in the packet
|
|
||||||
* \param incoming : True if the packet comes from a peer.
|
|
||||||
* False if it's sent to a peer.
|
|
||||||
*/
|
|
||||||
static void logPacket(const NetworkString &ns, bool incoming);
|
static void logPacket(const NetworkString &ns, bool incoming);
|
||||||
|
static void* mainLoop(void* self);
|
||||||
|
|
||||||
/*! \brief Thread function checking if data is received.
|
|
||||||
* This function tries to get data from network low-level functions as
|
|
||||||
* often as possible. When something is received, it generates an
|
|
||||||
* event and passes it to the Network Manager.
|
|
||||||
* \param self : used to pass the ENet host to the function.
|
|
||||||
*/
|
|
||||||
static void* receive_data(void* self);
|
|
||||||
|
|
||||||
/*! \brief Setups the host as a server.
|
|
||||||
* \param address : The IPv4 address of incoming connections.
|
|
||||||
* \param port : The port on which the server listens.
|
|
||||||
* \param peer_count : The maximum number of peers.
|
|
||||||
* \param channel_limit : The maximum number of channels per peer.
|
|
||||||
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
|
|
||||||
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
|
|
||||||
*/
|
|
||||||
void setupServer(uint32_t address, uint16_t port,
|
void setupServer(uint32_t address, uint16_t port,
|
||||||
int peer_count, int channel_limit,
|
int peer_count, int channel_limit,
|
||||||
uint32_t max_incoming_bandwidth,
|
uint32_t max_incoming_bandwidth,
|
||||||
uint32_t max_outgoing_bandwidth);
|
uint32_t max_outgoing_bandwidth);
|
||||||
/*! \brief Setups the host as a client.
|
|
||||||
* In fact there is only one peer connected to this host.
|
|
||||||
* \param peer_count : The maximum number of peers.
|
|
||||||
* \param channel_limit : The maximum number of channels per peer.
|
|
||||||
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
|
|
||||||
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
|
|
||||||
*/
|
|
||||||
void setupClient(int peer_count, int channel_limit,
|
void setupClient(int peer_count, int channel_limit,
|
||||||
uint32_t max_incoming_bandwidth,
|
uint32_t max_incoming_bandwidth,
|
||||||
uint32_t max_outgoing_bandwidth);
|
uint32_t max_outgoing_bandwidth);
|
||||||
|
|
||||||
/*! \brief Starts the listening of events from ENet.
|
|
||||||
* Starts a thread that updates it as often as possible.
|
|
||||||
*/
|
|
||||||
void startListening();
|
void startListening();
|
||||||
/*! \brief Stops the listening of events from ENet.
|
|
||||||
* Stops the thread that was receiving events.
|
|
||||||
*/
|
|
||||||
void stopListening();
|
void stopListening();
|
||||||
|
|
||||||
/*! \brief Sends a packet whithout ENet adding its headers.
|
|
||||||
* This function is used in particular to achieve the STUN protocol.
|
|
||||||
* \param data : Data to send.
|
|
||||||
* \param length : Length of the sent data.
|
|
||||||
* \param dst : Destination of the packet.
|
|
||||||
*/
|
|
||||||
void sendRawPacket(uint8_t* data, int length,
|
void sendRawPacket(uint8_t* data, int length,
|
||||||
const TransportAddress& dst);
|
const TransportAddress& dst);
|
||||||
/*! \brief Receives a packet directly from the network interface.
|
|
||||||
* Receive a packet whithout ENet processing it.
|
|
||||||
* \return A string containing the data of the received packet.
|
|
||||||
*/
|
|
||||||
uint8_t* receiveRawPacket();
|
|
||||||
uint8_t* receiveRawPacket(TransportAddress* sender);
|
uint8_t* receiveRawPacket(TransportAddress* sender);
|
||||||
/*! \brief Receives a packet directly from the network interface and
|
uint8_t* receiveRawPacket(const TransportAddress& sender,
|
||||||
* filter its address.
|
int max_tries = -1);
|
||||||
* Receive a packet whithout ENet processing it. Checks that the
|
void broadcastPacket(const NetworkString& data,
|
||||||
* sender of the packet is the one that corresponds to the sender
|
bool reliable = true);
|
||||||
* parameter. Does not check the port right now.
|
|
||||||
* \param sender : Transport address of the original sender of the
|
|
||||||
* wanted packet.
|
|
||||||
* \param max_tries : Number of times we try to read data from the
|
|
||||||
* socket. This is aproximately the time we wait in milliseconds.
|
|
||||||
* -1 means eternal tries.
|
|
||||||
* \return A string containing the data of the received packet
|
|
||||||
* matching the sender's ip address.
|
|
||||||
*/
|
|
||||||
uint8_t* receiveRawPacket(const TransportAddress& sender, int max_tries = -1);
|
|
||||||
/*! \brief Broadcasts a packet to all peers.
|
|
||||||
* \param data : Data to send.
|
|
||||||
*/
|
|
||||||
void broadcastPacket(const NetworkString& data, bool reliable = true);
|
|
||||||
|
|
||||||
/*! \brief Tells if a peer is known.
|
|
||||||
* \return True if the peer is known, false elseway.
|
|
||||||
*/
|
|
||||||
bool peerExists(const TransportAddress& peer_address);
|
bool peerExists(const TransportAddress& peer_address);
|
||||||
/*! \brief Tells if a peer is known and connected.
|
|
||||||
* \return True if the peer is known and connected, false elseway.
|
|
||||||
*/
|
|
||||||
bool isConnectedTo(const TransportAddress& peer_address);
|
bool isConnectedTo(const TransportAddress& peer_address);
|
||||||
|
|
||||||
/*! \brief Returns true when the thread should stop listening. */
|
|
||||||
int mustStopListening();
|
int mustStopListening();
|
||||||
/*! \brief Returns true when the thread has stopped listening. */
|
|
||||||
bool hasStoppedListening() const { return m_listening; }
|
|
||||||
|
|
||||||
uint32_t getAddress() const { return m_host->address.host; }
|
|
||||||
uint16_t getPort() const;
|
uint16_t getPort() const;
|
||||||
protected:
|
// --------------------------------------------------------------------
|
||||||
ENetHost* m_host; //!< ENet host interfacing sockets.
|
uint32_t getAddress() const { return m_host->address.host; }
|
||||||
pthread_t* m_listening_thread; //!< Thread listening network events.
|
|
||||||
pthread_mutex_t m_exit_mutex; //!< Mutex to kill properly the thread
|
|
||||||
bool m_listening;
|
|
||||||
static FILE* m_log_file; //!< Where to log packets
|
|
||||||
static pthread_mutex_t m_log_mutex; //!< To write in the log only once at a time
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,14 +149,19 @@ public:
|
|||||||
} // operator!=
|
} // operator!=
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns a std::string representing the ip address and port in human
|
/** Returns a std::string representing the ip address and port in human
|
||||||
* readable format. */
|
* readable format.
|
||||||
std::string toString() const
|
* \param show_port True if the port should be shown as well, otherwise
|
||||||
|
* only the ip address will be returned.
|
||||||
|
*/
|
||||||
|
std::string toString(bool show_port = true) const
|
||||||
{
|
{
|
||||||
return
|
std::string s =
|
||||||
StringUtils::insertValues("%d.%d.%d.%d:%d",
|
StringUtils::insertValues("%d.%d.%d.%d",
|
||||||
((m_ip >> 24) & 0xff), ((m_ip >> 16) & 0xff),
|
((m_ip >> 24) & 0xff), ((m_ip >> 16) & 0xff),
|
||||||
((m_ip >> 8) & 0xff), ((m_ip >> 0) & 0xff),
|
((m_ip >> 8) & 0xff), ((m_ip >> 0) & 0xff));
|
||||||
m_port );
|
if (show_port)
|
||||||
|
s += StringUtils::insertValues(":%d", m_port);
|
||||||
|
return s;
|
||||||
} // toString
|
} // toString
|
||||||
}; // TransportAddress
|
}; // TransportAddress
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user