Fix udp address resolve (#624)
* тест для udp + фикс udp * fix udp addresses resolve * update SocketUdpConnection::connect * update SocketUdpServer::sendTo * update udp test * revert * test * test * test * test * test * test? * update test * cleanup * cleanup * update test * update * revert * cleanup * update test * update test * update * fix test * additional error handling * update Network.cpp * update Network.cpp 2 * fix the test * cleanup Network.cpp * revert network_tcp.lua extra changes --------- Co-authored-by: Xertis <118364459+Xertis@users.noreply.github.com>
This commit is contained in:
parent
370c95c14f
commit
3a40162f1e
@ -1,5 +1,5 @@
|
|||||||
for i=1,3 do
|
for i=1,3 do
|
||||||
print(string.format("iteration %s", i + 1))
|
print(string.format("iteration %s", i))
|
||||||
local text = ""
|
local text = ""
|
||||||
local complete = false
|
local complete = false
|
||||||
|
|
||||||
|
|||||||
35
dev/tests/network_udp.lua
Normal file
35
dev/tests/network_udp.lua
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
math.randomseed(43172)
|
||||||
|
for i = 1, 15 do
|
||||||
|
debug.log(string.format("iteration %s", i))
|
||||||
|
local complete = false
|
||||||
|
|
||||||
|
local server = network.udp_open(8645 + i, function (address, port, data, srv)
|
||||||
|
debug.log(string.format("server received %s byte(s) from %s:%s", #data, address, port))
|
||||||
|
srv:send(address, port, "pong")
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.tick()
|
||||||
|
network.udp_connect("localhost", 8645 + i, function (data)
|
||||||
|
debug.log(string.format("client received %s byte(s) from server", #data))
|
||||||
|
complete = true
|
||||||
|
end, function (socket)
|
||||||
|
debug.log("udp socket opened")
|
||||||
|
start_coroutine(function()
|
||||||
|
debug.log("udp data-sender started")
|
||||||
|
for k = 1, 15 do
|
||||||
|
local payload = ""
|
||||||
|
for j = 1, 16 do
|
||||||
|
payload = payload .. math.random(0, 9)
|
||||||
|
end
|
||||||
|
socket:send(payload)
|
||||||
|
debug.log(string.format("sent packet %s (%s bytes)", k, #payload))
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
app.sleep_until(function () return complete end, nil, 5)
|
||||||
|
socket:close()
|
||||||
|
end, "udp-data-sender")
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.sleep_until(function () return complete end, nil, 5)
|
||||||
|
server:close()
|
||||||
|
end
|
||||||
@ -144,7 +144,11 @@ network.udp_connect = function (address, port, datagramHandler, openCallback)
|
|||||||
socket.id = network.__connect_udp(address, port)
|
socket.id = network.__connect_udp(address, port)
|
||||||
|
|
||||||
_udp_client_datagram_callbacks[socket.id] = datagramHandler
|
_udp_client_datagram_callbacks[socket.id] = datagramHandler
|
||||||
_udp_client_open_callbacks[socket.id] = openCallback
|
if openCallback then
|
||||||
|
_udp_client_open_callbacks[socket.id] = function()
|
||||||
|
openCallback(socket)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return socket
|
return socket
|
||||||
end
|
end
|
||||||
@ -254,9 +258,15 @@ network.__process_events = function()
|
|||||||
end
|
end
|
||||||
elseif etype == DATAGRAM then
|
elseif etype == DATAGRAM then
|
||||||
if side == ON_CLIENT then
|
if side == ON_CLIENT then
|
||||||
_udp_client_datagram_callbacks[cid](data)
|
local callback = _udp_client_datagram_callbacks[cid]
|
||||||
|
if callback then
|
||||||
|
callback(data)
|
||||||
|
end
|
||||||
elseif side == ON_SERVER then
|
elseif side == ON_SERVER then
|
||||||
_udp_server_callbacks[sid](addr, port, data)
|
local callback = _udp_server_callbacks[sid]
|
||||||
|
if callback then
|
||||||
|
callback(addr, port, data)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
elseif etype == RESPONSE then
|
elseif etype == RESPONSE then
|
||||||
if event[2] / 100 == 2 then
|
if event[2] / 100 == 2 then
|
||||||
|
|||||||
@ -620,6 +620,26 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static sockaddr_in resolve_address_dgram(const std::string& address, int port) {
|
||||||
|
sockaddr_in serverAddr{};
|
||||||
|
addrinfo hints {};
|
||||||
|
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
|
addrinfo* addrinfo = nullptr;
|
||||||
|
if (int res = getaddrinfo(
|
||||||
|
address.c_str(), nullptr, &hints, &addrinfo
|
||||||
|
)) {
|
||||||
|
throw std::runtime_error(gai_strerror(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(&serverAddr, addrinfo->ai_addr, sizeof(sockaddr_in));
|
||||||
|
serverAddr.sin_port = htons(port);
|
||||||
|
freeaddrinfo(addrinfo);
|
||||||
|
return serverAddr;
|
||||||
|
}
|
||||||
|
|
||||||
class SocketUdpConnection : public UdpConnection {
|
class SocketUdpConnection : public UdpConnection {
|
||||||
u64id_t id;
|
u64id_t id;
|
||||||
SOCKET descriptor;
|
SOCKET descriptor;
|
||||||
@ -652,13 +672,7 @@ public:
|
|||||||
throw std::runtime_error("could not create udp socket");
|
throw std::runtime_error("could not create udp socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in serverAddr{};
|
sockaddr_in serverAddr = resolve_address_dgram(address, port);
|
||||||
serverAddr.sin_family = AF_INET;
|
|
||||||
if (inet_pton(AF_INET, address.c_str(), &serverAddr.sin_addr) <= 0) {
|
|
||||||
closesocket(descriptor);
|
|
||||||
throw std::runtime_error("invalid udp address: " + address);
|
|
||||||
}
|
|
||||||
serverAddr.sin_port = htons(port);
|
|
||||||
|
|
||||||
if (::connect(descriptor, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
|
if (::connect(descriptor, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
|
||||||
auto err = handle_socket_error("udp connect failed");
|
auto err = handle_socket_error("udp connect failed");
|
||||||
@ -683,6 +697,7 @@ public:
|
|||||||
while (open) {
|
while (open) {
|
||||||
int size = recv(descriptor, buffer.data(), buffer.size(), 0);
|
int size = recv(descriptor, buffer.data(), buffer.size(), 0);
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
|
logger.error() <<id <<"udp connection " << id << handle_socket_error(" recv error").what();
|
||||||
if (!open) break;
|
if (!open) break;
|
||||||
closesocket(descriptor);
|
closesocket(descriptor);
|
||||||
state = ConnectionState::CLOSED;
|
state = ConnectionState::CLOSED;
|
||||||
@ -697,11 +712,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int send(const char* buffer, size_t length) override {
|
int send(const char* buffer, size_t length) override {
|
||||||
int len = sendto(descriptor, buffer, length, 0,
|
int len = ::send(descriptor, buffer, length, 0);
|
||||||
(sockaddr*)&addr, sizeof(addr));
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
auto err = handle_socket_error(" send failed");
|
||||||
closesocket(descriptor);
|
closesocket(descriptor);
|
||||||
state = ConnectionState::CLOSED;
|
state = ConnectionState::CLOSED;
|
||||||
|
logger.error() << "udp connection " << id << err.what();
|
||||||
} else totalUpload += len;
|
} else totalUpload += len;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@ -710,6 +726,7 @@ public:
|
|||||||
void close(bool discardAll=false) override {
|
void close(bool discardAll=false) override {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
open = false;
|
open = false;
|
||||||
|
logger.info() << "closing udp connection "<< id;
|
||||||
|
|
||||||
if (state != ConnectionState::CLOSED) {
|
if (state != ConnectionState::CLOSED) {
|
||||||
shutdown(descriptor, 2);
|
shutdown(descriptor, 2);
|
||||||
@ -789,13 +806,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendTo(const std::string& addr, int port, const char* buffer, size_t length) override {
|
void sendTo(const std::string& addr, int port, const char* buffer, size_t length) override {
|
||||||
sockaddr_in client{};
|
sockaddr_in client = resolve_address_dgram(addr, port);
|
||||||
client.sin_family = AF_INET;
|
if (sendto(descriptor, buffer, length, 0,
|
||||||
inet_pton(AF_INET, addr.c_str(), &client.sin_addr);
|
reinterpret_cast<sockaddr*>(&client), sizeof(client)) < 0) {
|
||||||
client.sin_port = htons(port);
|
logger.error() << handle_socket_error("sendto").what();
|
||||||
|
}
|
||||||
sendto(descriptor, buffer, length, 0,
|
|
||||||
reinterpret_cast<sockaddr*>(&client), sizeof(client));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() override {
|
void close() override {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user