Skip to content

Commit 8cb7002

Browse files
author
Alexandre jublot
committed
merge: hotfix/serverDestructioBroadcast into dev
2 parents 7bffcf9 + 73845b4 commit 8cb7002

8 files changed

Lines changed: 434 additions & 4 deletions

File tree

src/src/tcp/ClientConnection.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "polymorph/network/dto/SessionTransferRequestDto.hpp"
1818
#include "polymorph/network/dto/SessionTransferResponseDto.hpp"
1919
#include "tcp/ServerImpl.hpp"
20+
#include "polymorph/network/dto/DisconnectionDto.hpp"
2021

2122

2223
polymorph::network::tcp::ClientConnection::ClientConnection(asio::ip::tcp::socket socket, SessionStore &sessionStore, std::weak_ptr<IConnectionPool> pool, ServerImpl &packetHandler)
@@ -32,6 +33,8 @@ void polymorph::network::tcp::ClientConnection::start()
3233

3334
void polymorph::network::tcp::ClientConnection::send(std::vector<std::byte> data, std::function<void(const PacketHeader &, const std::vector <std::byte> &)> callback)
3435
{
36+
if (_stopped)
37+
return;
3538
std::unique_lock<std::mutex> lock(_sendQueueMutex);
3639

3740
_sendQueue.emplace(std::move(data), std::move(callback));
@@ -88,8 +91,11 @@ void polymorph::network::tcp::ClientConnection::_doReceive()
8891
while (_receiveBuffer.size() > sizeof(PacketHeader) ) {
8992
auto header = SerializerTrait<PacketHeader>::deserialize(_receiveBuffer);
9093
if (_receiveBuffer.size() >= sizeof(PacketHeader) + header.pSize) {
91-
if (!_determinePacket(header, _receiveBuffer))
94+
if (!_determinePacket(header, _receiveBuffer)) {
95+
_packetHandler.declareReceivingDone();
96+
_stopped = true;
9297
return;
98+
}
9399
_receiveBuffer.erase(_receiveBuffer.begin(), _receiveBuffer.begin() + sizeof(PacketHeader) + header.pSize);
94100
} else
95101
break;
@@ -147,9 +153,11 @@ bool polymorph::network::tcp::ClientConnection::_determinePacket(const polymorph
147153
} else if (header.opId == SessionTransferRequestDto::opId) {
148154
_handleSessionTransferPacket(header, bytes);
149155
return true;
150-
} else {
156+
} else if (header.opId == DisconnectionDto::opId) {
157+
_broadcastReceivedPacket(header, bytes);
158+
return false;
159+
} else
151160
return _broadcastReceivedPacket(header, bytes);
152-
}
153161
}
154162

155163
bool polymorph::network::tcp::ClientConnection::isConnected()

src/src/tcp/ClientImpl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ void polymorph::network::tcp::ClientImpl::_doReceive()
123123
auto header = SerializerTrait<PacketHeader>::deserialize(_receiveBuffer);
124124
if (_receiveBuffer.size() >= sizeof(PacketHeader) + header.pSize) {
125125
APacketHandler::packetReceived(header, _receiveBuffer);
126+
if (header.opId == DisconnectionDto::opId) {
127+
_stopping = true;
128+
_receiveInProgress = false;
129+
return;
130+
}
126131
_receiveBuffer.erase(_receiveBuffer.begin(), _receiveBuffer.begin() + sizeof(PacketHeader) + header.pSize);
127132
} else
128133
break;
@@ -158,6 +163,8 @@ void polymorph::network::tcp::ClientImpl::_send(polymorph::network::OpId opId, c
158163
std::cerr << "Trying to send a packet before client is connected" << std::endl;
159164
return;
160165
}
166+
if (_stopping)
167+
return;
161168
++_currentPacketId;
162169
PacketHeader header{};
163170
header.pId = _currentPacketId;

src/src/tcp/ServerImpl.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "tcp/ServerImpl.hpp"
1010
#include "tcp/ClientConnection.hpp"
11+
#include "polymorph/network/dto/DisconnectionDto.hpp"
1112

1213
std::unique_ptr<polymorph::network::tcp::Server> polymorph::network::tcp::Server::create(std::uint16_t port)
1314
{
@@ -40,6 +41,26 @@ void polymorph::network::tcp::ServerImpl::_doAccept()
4041

4142
polymorph::network::tcp::ServerImpl::~ServerImpl()
4243
{
44+
polymorph::network::DisconnectionDto dto;
45+
std::vector<std::future<void>> futures;
46+
std::vector<std::shared_ptr<std::promise<void>>> promises;
47+
48+
for (auto &connection : _connectionPool->getConnections()) {
49+
auto promise = std::make_shared<std::promise<void>>();
50+
futures.push_back(promise->get_future());
51+
promises.emplace_back(promise);
52+
53+
auto sId = connection->getSessionId();
54+
55+
sendTo<polymorph::network::DisconnectionDto>(polymorph::network::DisconnectionDto::opId, dto, sId, [promise](const PacketHeader &header, const polymorph::network::DisconnectionDto &payload) {
56+
promise->set_value();
57+
return true;
58+
});
59+
}
60+
61+
for (auto &future : futures) {
62+
future.wait_for(std::chrono::milliseconds(500));
63+
}
4364
if (!_context.stopped())
4465
_context.stop();
4566
while (isSending() || isReceiving()) {

src/src/udp/ServerImpl.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <iostream>
9+
#include <future>
910
#include "udp/ServerImpl.hpp"
1011
#include "polymorph/network/dto/ConnectionDto.hpp"
1112
#include "authorizationKey.hpp"
@@ -211,8 +212,27 @@ void polymorph::network::udp::ServerImpl::_send(polymorph::network::OpId opId, c
211212

212213
polymorph::network::udp::ServerImpl::~ServerImpl()
213214
{
215+
polymorph::network::DisconnectionDto dto;
216+
std::vector<std::future<void>> futures;
217+
std::vector<std::shared_ptr<std::promise<void>>> promises;
218+
219+
for (auto &connection : _sessionStore.allUdpSessions()) {
220+
auto promise = std::make_shared<std::promise<void>>();
221+
futures.push_back(promise->get_future());
222+
promises.emplace_back(promise);
223+
224+
sendTo<polymorph::network::DisconnectionDto>(polymorph::network::DisconnectionDto::opId, dto, connection, [promise](const PacketHeader &header, const polymorph::network::DisconnectionDto &payload) {
225+
promise->set_value();
226+
return true;
227+
});
228+
}
229+
230+
for (auto &future : futures) {
231+
future.wait_for(std::chrono::milliseconds(500));
232+
}
214233
if (!_context.stopped())
215234
_context.stop();
216-
while(isWriteInProgress() || isReceiveInProgress())
235+
while(isWriteInProgress() || isReceiveInProgress()) {
217236
std::this_thread::sleep_for(std::chrono::milliseconds(1));
237+
}
218238
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
** EPITECH PROJECT, 2022
3+
** SimpleHandshake.cpp
4+
** File description:
5+
** SimpleHandshake.cpp
6+
*/
7+
8+
#include <gtest/gtest.h>
9+
#include <thread>
10+
#include "polymorph/network/tcp/Server.hpp"
11+
#include "polymorph/network/tcp/Client.hpp"
12+
#include "../utils.hpp"
13+
#include "polymorph/network/dto/DisconnectionDto.hpp"
14+
15+
TEST(tcpE2E, ClientPrematureDisconnect)
16+
{
17+
//checks
18+
std::uint16_t input_data = 42;
19+
std::uint16_t output_data = 0;
20+
std::atomic<bool> receivedDisconnect(false);
21+
22+
using namespace polymorph::network;
23+
using namespace polymorph::network::tcp;
24+
25+
// Server Setup
26+
auto server = Server::create(4242);
27+
server->start();
28+
server->registerReceiveHandler<std::uint16_t>(10, [&output_data](const PacketHeader &, uint16_t payload) {
29+
output_data = payload;
30+
return true;
31+
});
32+
server->registerReceiveHandler<DisconnectionDto>(DisconnectionDto::opId, [&receivedDisconnect](const PacketHeader &, const DisconnectionDto &) {
33+
receivedDisconnect = true;
34+
return true;
35+
});
36+
37+
{
38+
// Client Setup
39+
auto client = Client::create("127.0.0.1", 4242);
40+
41+
// Client Infos
42+
SessionId id;
43+
bool connected = false;
44+
45+
client->connect([&id, &connected](bool authorized, SessionId sId) {
46+
connected = authorized;
47+
id = sId;
48+
});
49+
50+
PNL_WAIT_COND_LOOP(!connected, PNL_TIME_OUT, 5)
51+
ASSERT_TRUE(connected);
52+
client->send(10, input_data);
53+
PNL_WAIT(PNL_TIME_OUT)
54+
ASSERT_EQ(input_data, output_data);
55+
}
56+
57+
std::this_thread::sleep_for(std::chrono::milliseconds(500));
58+
}
59+
60+
61+
#ifdef PNL_CLIENT_TEST
62+
#if PNL_CLIENT_TEST == 1
63+
TEST(tcpE2E, SafetyClientSend)
64+
{
65+
//checks
66+
std::uint32_t input_data = 4294967295;
67+
std::uint32_t output_data = 0;
68+
69+
using namespace polymorph::network;
70+
using namespace polymorph::network::tcp;
71+
72+
// Client Setup
73+
SessionStore serverStore;
74+
Client client("127.0.0.1", 4242, serverStore);
75+
76+
// Client Infos
77+
SessionId id;
78+
bool connected = false;
79+
80+
client.connect([&id, &connected](bool authorized, SessionId sId) {
81+
connected = authorized;
82+
id = sId;
83+
});
84+
85+
PNL_WAIT_COND_LOOP(!connected, PNL_TIME_OUT, 5)
86+
ASSERT_TRUE(connected);
87+
client.send(2, input_data);
88+
PNL_WAIT_COND(input_data != output_data, PNL_TIME_OUT)
89+
ASSERT_EQ(input_data, output_data);
90+
}
91+
#endif
92+
#endif
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
** EPITECH PROJECT, 2022
3+
** SimpleHandshake.cpp
4+
** File description:
5+
** SimpleHandshake.cpp
6+
*/
7+
8+
#include <gtest/gtest.h>
9+
#include <thread>
10+
#include "polymorph/network/tcp/Server.hpp"
11+
#include "polymorph/network/tcp/Client.hpp"
12+
#include "../utils.hpp"
13+
#include "polymorph/network/dto/DisconnectionDto.hpp"
14+
15+
TEST(tcpE2E, ServerPrematureDisconnect)
16+
{
17+
//checks
18+
std::uint16_t input_data = 42;
19+
std::uint16_t output_data = 0;
20+
std::atomic<bool> receivedDisconnect(false);
21+
22+
using namespace polymorph::network;
23+
using namespace polymorph::network::tcp;
24+
25+
std::unique_ptr<Client> client;
26+
27+
{
28+
// Server Setup
29+
auto server = Server::create(4242);
30+
server->start();
31+
server->registerReceiveHandler<std::uint16_t>(10, [&output_data](const PacketHeader &, uint16_t payload) {
32+
output_data = payload;
33+
return true;
34+
});
35+
server->registerReceiveHandler<DisconnectionDto>(DisconnectionDto::opId,
36+
[&receivedDisconnect](const PacketHeader &,
37+
const DisconnectionDto &) {
38+
receivedDisconnect = true;
39+
return true;
40+
});
41+
42+
// Client Setup
43+
client = Client::create("127.0.0.1", 4242);
44+
45+
// Client Infos
46+
SessionId id;
47+
bool connected = false;
48+
49+
client->connect([&id, &connected](bool authorized, SessionId sId) {
50+
connected = authorized;
51+
id = sId;
52+
});
53+
54+
PNL_WAIT_COND_LOOP(!connected, PNL_TIME_OUT, 5)
55+
ASSERT_TRUE(connected);
56+
}
57+
58+
client->send(10, input_data);
59+
PNL_WAIT(PNL_TIME_OUT)
60+
ASSERT_NE(input_data, output_data);
61+
62+
std::this_thread::sleep_for(std::chrono::milliseconds(500));
63+
}
64+
65+
66+
#ifdef PNL_CLIENT_TEST
67+
#if PNL_CLIENT_TEST == 1
68+
TEST(tcpE2E, SafetyClientSend)
69+
{
70+
//checks
71+
std::uint32_t input_data = 4294967295;
72+
std::uint32_t output_data = 0;
73+
74+
using namespace polymorph::network;
75+
using namespace polymorph::network::tcp;
76+
77+
// Client Setup
78+
SessionStore serverStore;
79+
Client client("127.0.0.1", 4242, serverStore);
80+
81+
// Client Infos
82+
SessionId id;
83+
bool connected = false;
84+
85+
client.connect([&id, &connected](bool authorized, SessionId sId) {
86+
connected = authorized;
87+
id = sId;
88+
});
89+
90+
PNL_WAIT_COND_LOOP(!connected, PNL_TIME_OUT, 5)
91+
ASSERT_TRUE(connected);
92+
client.send(2, input_data);
93+
PNL_WAIT_COND(input_data != output_data, PNL_TIME_OUT)
94+
ASSERT_EQ(input_data, output_data);
95+
}
96+
#endif
97+
#endif

0 commit comments

Comments
 (0)