cleaning way of stopping the listening thread (now uses a mutex locked/unlocked) Fixed some other bugs.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13633 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
074ef2237d
commit
ff8fda6219
@ -161,7 +161,6 @@ void ConnectToServer::asynchronousUpdate()
|
|||||||
{
|
{
|
||||||
// just send a broadcast packet, the client will know our ip address and will connect
|
// just send a broadcast packet, the client will know our ip address and will connect
|
||||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||||
NetworkManager::getInstance()->setManualSocketsMode(true);
|
|
||||||
TransportAddress sender;
|
TransportAddress sender;
|
||||||
Log::info("ConnectToServer", "Waiting broadcast message.");
|
Log::info("ConnectToServer", "Waiting broadcast message.");
|
||||||
const uint8_t* received_data = host->receiveRawPacket(&sender); // get the sender
|
const uint8_t* received_data = host->receiveRawPacket(&sender); // get the sender
|
||||||
@ -173,9 +172,11 @@ void ConnectToServer::asynchronousUpdate()
|
|||||||
// just check if the ip is ours : if so, then just use localhost (127.0.0.1)
|
// just check if the ip is ours : if so, then just use localhost (127.0.0.1)
|
||||||
struct ifaddrs *ifap, *ifa;
|
struct ifaddrs *ifap, *ifa;
|
||||||
struct sockaddr_in *sa;
|
struct sockaddr_in *sa;
|
||||||
getifaddrs (&ifap);
|
getifaddrs (&ifap); // get the info
|
||||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||||
if (ifa->ifa_addr->sa_family==AF_INET) {
|
{
|
||||||
|
if (ifa->ifa_addr->sa_family==AF_INET)
|
||||||
|
{
|
||||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||||
if (turnEndianness(sa->sin_addr.s_addr) == sender.ip) // this interface is ours
|
if (turnEndianness(sa->sin_addr.s_addr) == sender.ip) // this interface is ours
|
||||||
sender.ip = 0x7f000001; // 127.0.0.1
|
sender.ip = 0x7f000001; // 127.0.0.1
|
||||||
@ -220,7 +221,6 @@ void ConnectToServer::asynchronousUpdate()
|
|||||||
m_server_address = sender;
|
m_server_address = sender;
|
||||||
m_state = CONNECTING;
|
m_state = CONNECTING;
|
||||||
}
|
}
|
||||||
NetworkManager::getInstance()->setManualSocketsMode(false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -125,8 +125,9 @@ void GetPublicAddress::asynchronousUpdate()
|
|||||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(p->ai_addr);
|
struct sockaddr_in* current_interface = (struct sockaddr_in*)(p->ai_addr);
|
||||||
|
|
||||||
m_stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
m_stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
||||||
NetworkManager::getInstance()->setManualSocketsMode(true);
|
m_transaction_host = new STKHost();
|
||||||
NetworkManager::getInstance()->getHost()->sendRawPacket(bytes, 20, TransportAddress(m_stun_server_ip, 3478));
|
m_transaction_host->setupClient(1,1,0,0);
|
||||||
|
m_transaction_host->sendRawPacket(bytes, 20, TransportAddress(m_stun_server_ip, 3478));
|
||||||
m_state = TEST_SENT;
|
m_state = TEST_SENT;
|
||||||
|
|
||||||
freeaddrinfo(res); // free the linked list
|
freeaddrinfo(res); // free the linked list
|
||||||
@ -137,7 +138,7 @@ void GetPublicAddress::asynchronousUpdate()
|
|||||||
}
|
}
|
||||||
if (m_state == TEST_SENT)
|
if (m_state == TEST_SENT)
|
||||||
{
|
{
|
||||||
uint8_t* data = NetworkManager::getInstance()->getHost()->receiveRawPacket(TransportAddress(m_stun_server_ip, 3478), 2000);
|
uint8_t* data = m_transaction_host->receiveRawPacket(TransportAddress(m_stun_server_ip, 3478), 2000);
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
m_state = NOTHING_DONE; // will send the test again to an other server
|
m_state = NOTHING_DONE; // will send the test again to an other server
|
||||||
@ -220,7 +221,6 @@ void GetPublicAddress::asynchronousUpdate()
|
|||||||
{
|
{
|
||||||
Log::debug("GetPublicAddress", "The public address has been found : %i.%i.%i.%i:%i", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port);
|
Log::debug("GetPublicAddress", "The public address has been found : %i.%i.%i.%i:%i", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port);
|
||||||
m_state = ADDRESS_KNOWN;
|
m_state = ADDRESS_KNOWN;
|
||||||
NetworkManager::getInstance()->setManualSocketsMode(false);
|
|
||||||
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
||||||
addr->ip = address;
|
addr->ip = address;
|
||||||
addr->port = port;
|
addr->port = port;
|
||||||
|
@ -45,6 +45,7 @@ class GetPublicAddress : public Protocol
|
|||||||
uint32_t m_stun_tansaction_id[3];
|
uint32_t m_stun_tansaction_id[3];
|
||||||
static const uint32_t m_stun_magic_cookie = 0x2112A442;
|
static const uint32_t m_stun_magic_cookie = 0x2112A442;
|
||||||
uint32_t m_stun_server_ip;
|
uint32_t m_stun_server_ip;
|
||||||
|
STKHost* m_transaction_host;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GET_PUBLIC_ADDRESS_HPP
|
#endif // GET_PUBLIC_ADDRESS_HPP
|
||||||
|
@ -37,8 +37,9 @@
|
|||||||
void* STKHost::receive_data(void* self)
|
void* STKHost::receive_data(void* self)
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
ENetHost* host = (((STKHost*)(self))->m_host);
|
STKHost* myself = (STKHost*)(self);
|
||||||
while (1)
|
ENetHost* host = myself->m_host;
|
||||||
|
while (!myself->mustStopListening())
|
||||||
{
|
{
|
||||||
while (enet_host_service(host, &event, 20) != 0) {
|
while (enet_host_service(host, &event, 20) != 0) {
|
||||||
Event* evt = new Event(&event);
|
Event* evt = new Event(&event);
|
||||||
@ -47,6 +48,9 @@ void* STKHost::receive_data(void* self)
|
|||||||
delete evt;
|
delete evt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
myself->m_listening = false;
|
||||||
|
delete myself->m_listening_thread;
|
||||||
|
myself->m_listening_thread = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,18 +60,14 @@ STKHost::STKHost()
|
|||||||
{
|
{
|
||||||
m_host = NULL;
|
m_host = NULL;
|
||||||
m_listening_thread = NULL;
|
m_listening_thread = NULL;
|
||||||
|
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
STKHost::~STKHost()
|
STKHost::~STKHost()
|
||||||
{
|
{
|
||||||
if (m_listening_thread)
|
stopListening();
|
||||||
{
|
|
||||||
pthread_cancel(*m_listening_thread);//, SIGKILL); with kill
|
|
||||||
delete m_listening_thread;
|
|
||||||
m_listening_thread = NULL;
|
|
||||||
}
|
|
||||||
if (m_host)
|
if (m_host)
|
||||||
{
|
{
|
||||||
enet_host_destroy(m_host);
|
enet_host_destroy(m_host);
|
||||||
@ -84,6 +84,13 @@ void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
|
|||||||
addr->host = address;
|
addr->host = address;
|
||||||
addr->port = port;
|
addr->port = port;
|
||||||
|
|
||||||
|
#ifdef WIN32/*
|
||||||
|
addr->host = 0;
|
||||||
|
addr->host += ((unsigned int)(192)<<0); // 192.168.0.11
|
||||||
|
addr->host += ((unsigned int)(168)<<8); // 192.168.0.11
|
||||||
|
addr->host += ((unsigned int)(11)<<24); // 192.168.0.11*/
|
||||||
|
#endif
|
||||||
|
|
||||||
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 == NULL)
|
||||||
@ -114,8 +121,10 @@ void STKHost::setupClient(int peer_count, int channel_limit,
|
|||||||
|
|
||||||
void STKHost::startListening()
|
void STKHost::startListening()
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&m_exit_mutex); // will let the update function start
|
||||||
m_listening_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
m_listening_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||||
pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this);
|
pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this);
|
||||||
|
m_listening = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -124,8 +133,7 @@ void STKHost::stopListening()
|
|||||||
{
|
{
|
||||||
if(m_listening_thread)
|
if(m_listening_thread)
|
||||||
{
|
{
|
||||||
pthread_cancel(*m_listening_thread);
|
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function
|
||||||
m_listening_thread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,12 +190,16 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
|||||||
|
|
||||||
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 < 0)
|
while(len == -1) // nothing received
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len);
|
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len);
|
||||||
Time::sleep(1); // wait 1 millisecond between two checks
|
Time::sleep(1); // wait 1 millisecond between two checks
|
||||||
}
|
}
|
||||||
|
if (len == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
Log::error("STKHost", "Problem with the socket. Please contact the dev team.");
|
||||||
|
}
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *) (&addr);
|
struct sockaddr_in *sin = (struct sockaddr_in *) (&addr);
|
||||||
// we received the data
|
// we received the data
|
||||||
sender->ip = turnEndianness((uint32_t)(sin->sin_addr.s_addr));
|
sender->ip = turnEndianness((uint32_t)(sin->sin_addr.s_addr));
|
||||||
@ -211,32 +223,40 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress sender, int max_tries)
|
|||||||
memset(buffer, 0, 2048);
|
memset(buffer, 0, 2048);
|
||||||
|
|
||||||
socklen_t from_len;
|
socklen_t from_len;
|
||||||
struct sockaddr addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
from_len = sizeof(addr);
|
from_len = sizeof(addr);
|
||||||
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len);
|
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 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 < 0 || (
|
while(len < 0 || addr.sin_addr.s_addr == sender.ip)
|
||||||
(uint8_t)(addr.sa_data[2]) != (sender.ip>>24&0xff)
|
|
||||||
&& (uint8_t)(addr.sa_data[3]) != (sender.ip>>16&0xff)
|
|
||||||
&& (uint8_t)(addr.sa_data[4]) != (sender.ip>>8&0xff)
|
|
||||||
&& (uint8_t)(addr.sa_data[5]) != (sender.ip&0xff)))
|
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len);
|
if (len>=0)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
uint32_t addr1 = addr.sin_addr.s_addr;
|
||||||
|
uint32_t addr2 = sender.ip;
|
||||||
|
uint32_t addr3 = ntohl(addr1);
|
||||||
|
uint32_t addr4 = ntohl(addr2);
|
||||||
Time::sleep(1); // wait 1 millisecond between two checks
|
Time::sleep(1); // wait 1 millisecond between two checks
|
||||||
if (i >= max_tries && max_tries != -1)
|
if (i >= max_tries && max_tries != -1)
|
||||||
{
|
{
|
||||||
Log::verbose("STKHost", "No answer from the server.");
|
Log::verbose("STKHost", "No answer from the server on %u.%u.%u.%u:%u", (m_host->address.host&0xff),
|
||||||
|
(m_host->address.host>>8&0xff),
|
||||||
|
(m_host->address.host>>16&0xff),
|
||||||
|
(m_host->address.host>>24&0xff),
|
||||||
|
(m_host->address.port));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addr.sa_family == AF_INET)
|
if (addr.sin_family == AF_INET)
|
||||||
{
|
{
|
||||||
char s[20];
|
char s[20];
|
||||||
inet_ntop(AF_INET, &(((struct sockaddr_in *)&addr)->sin_addr), s, 20);
|
inet_ntop(AF_INET, &(addr.sin_addr), s, 20);
|
||||||
Log::info("STKHost", "IPv4 Address of the sender was %s", s);
|
Log::info("STKHost", "IPv4 Address of the sender was %s", s);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -281,3 +301,17 @@ bool STKHost::isConnectedTo(TransportAddress peer)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
@ -140,9 +140,16 @@ class STKHost
|
|||||||
* \return True if the peer is known and connected, false elseway.
|
* \return True if the peer is known and connected, false elseway.
|
||||||
*/
|
*/
|
||||||
bool isConnectedTo(TransportAddress peer_address);
|
bool isConnectedTo(TransportAddress peer_address);
|
||||||
|
|
||||||
|
/*! \brief Returns true when the thread should stop listening. */
|
||||||
|
int mustStopListening();
|
||||||
|
/*! \brief Returns true when the thread has stopped listening. */
|
||||||
|
bool hasStoppedListening() { return m_listening; }
|
||||||
protected:
|
protected:
|
||||||
ENetHost* m_host; //!< ENet host interfacing sockets.
|
ENetHost* m_host; //!< ENet host interfacing sockets.
|
||||||
pthread_t* m_listening_thread; //!< Thread listening network events.
|
pthread_t* m_listening_thread; //!< Thread listening network events.
|
||||||
|
pthread_mutex_t m_exit_mutex; //!< Mutex to kill properly the thread
|
||||||
|
bool m_listening;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user