mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-10 13:04:53 -04:00
Enhance UDP support
This commit is contained in:
parent
28dc3fff33
commit
683e17f3d0
@ -61,6 +61,11 @@ std::expected<void> finalize_packet(network::interface_descriptor& interface, ne
|
|||||||
std::expected<size_t> client_bind(network::socket& socket, size_t server_port, network::ip::address server);
|
std::expected<size_t> client_bind(network::socket& socket, size_t server_port, network::ip::address server);
|
||||||
std::expected<void> client_unbind(network::socket& socket);
|
std::expected<void> client_unbind(network::socket& socket);
|
||||||
|
|
||||||
|
std::expected<size_t> receive(char* buffer, network::socket& socket, size_t n);
|
||||||
|
std::expected<size_t> receive(char* buffer, network::socket& socket, size_t n, size_t ms);
|
||||||
|
|
||||||
|
std::expected<void> send(char* target_buffer, network::socket& socket, const char* buffer, size_t n);
|
||||||
|
|
||||||
} // end of upd namespace
|
} // end of upd namespace
|
||||||
|
|
||||||
} // end of network namespace
|
} // end of network namespace
|
||||||
|
@ -274,12 +274,12 @@ std::expected<network::socket_fd_t> network::open(network::socket_domain domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the socket protocol is valid
|
// Make sure the socket protocol is valid
|
||||||
if(protocol != socket_protocol::ICMP && protocol != socket_protocol::DNS && protocol != socket_protocol::TCP){
|
if(protocol != socket_protocol::ICMP && protocol != socket_protocol::DNS && protocol != socket_protocol::TCP && protocol != socket_protocol::UDP){
|
||||||
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_PROTOCOL);
|
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_PROTOCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the socket protocol is valid for the given socket type
|
// Make sure the socket protocol is valid for the given socket type
|
||||||
if(type == socket_type::DGRAM && !(protocol == socket_protocol::DNS)){
|
if(type == socket_type::DGRAM && !(protocol == socket_protocol::DNS || protocol == socket_protocol::UDP)){
|
||||||
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE_PROTOCOL);
|
return std::make_expected_from_error<network::socket_fd_t>(std::ERROR_SOCKET_INVALID_TYPE_PROTOCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,6 +367,9 @@ std::expected<void> network::send(socket_fd_t socket_fd, const char* buffer, siz
|
|||||||
case network::socket_protocol::TCP:
|
case network::socket_protocol::TCP:
|
||||||
return network::tcp::send(target_buffer, socket, buffer, n);
|
return network::tcp::send(target_buffer, socket, buffer, n);
|
||||||
|
|
||||||
|
case network::socket_protocol::UDP:
|
||||||
|
return network::udp::send(target_buffer, socket, buffer, n);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return std::make_unexpected<void>(std::ERROR_SOCKET_UNIMPLEMENTED);
|
return std::make_unexpected<void>(std::ERROR_SOCKET_UNIMPLEMENTED);
|
||||||
}
|
}
|
||||||
@ -388,6 +391,9 @@ std::expected<size_t> network::receive(socket_fd_t socket_fd, char* buffer, size
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (socket.protocol) {
|
switch (socket.protocol) {
|
||||||
|
case network::socket_protocol::UDP:
|
||||||
|
return network::udp::receive(buffer, socket, n);
|
||||||
|
|
||||||
case network::socket_protocol::TCP:
|
case network::socket_protocol::TCP:
|
||||||
return network::tcp::receive(buffer, socket, n);
|
return network::tcp::receive(buffer, socket, n);
|
||||||
|
|
||||||
@ -412,6 +418,9 @@ std::expected<size_t> network::receive(socket_fd_t socket_fd, char* buffer, size
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (socket.protocol) {
|
switch (socket.protocol) {
|
||||||
|
case network::socket_protocol::UDP:
|
||||||
|
return network::udp::receive(buffer, socket, n, ms);
|
||||||
|
|
||||||
case network::socket_protocol::TCP:
|
case network::socket_protocol::TCP:
|
||||||
return network::tcp::receive(buffer, socket, n, ms);
|
return network::tcp::receive(buffer, socket, n, ms);
|
||||||
|
|
||||||
|
@ -184,3 +184,93 @@ std::expected<void> network::udp::client_unbind(network::socket& sock){
|
|||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::expected<void> network::udp::send(char* target_buffer, network::socket& socket, const char* buffer, size_t n){
|
||||||
|
auto& connection = socket.get_connection_data<udp_connection>();
|
||||||
|
|
||||||
|
// Make sure stream sockets are connected
|
||||||
|
if(!connection.connected){
|
||||||
|
return std::make_unexpected<void>(std::ERROR_SOCKET_NOT_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
network::udp::packet_descriptor desc{n};
|
||||||
|
auto packet = user_prepare_packet(target_buffer, socket, &desc);
|
||||||
|
|
||||||
|
if (packet) {
|
||||||
|
for(size_t i = 0; i < n; ++i){
|
||||||
|
packet->payload[packet->index + i] = buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto target_ip = connection.server_address;
|
||||||
|
auto& interface = network::select_interface(target_ip);
|
||||||
|
return network::udp::finalize_packet(interface, *packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unexpected<void>(packet.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::expected<size_t> network::udp::receive(char* buffer, network::socket& socket, size_t n){
|
||||||
|
auto& connection = socket.get_connection_data<udp_connection>();
|
||||||
|
|
||||||
|
// Make sure stream sockets are connected
|
||||||
|
if(!connection.connected){
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_SOCKET_NOT_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(socket.listen_packets.empty()){
|
||||||
|
socket.listen_queue.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = socket.listen_packets.pop();
|
||||||
|
|
||||||
|
auto* udp_header = reinterpret_cast<network::udp::header*>(packet.payload + packet.tag(2));
|
||||||
|
auto payload_len = switch_endian_16(udp_header->length);
|
||||||
|
|
||||||
|
if(payload_len > n){
|
||||||
|
delete[] packet.payload;
|
||||||
|
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_BUFFER_SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy_n(packet.payload + packet.index, payload_len, buffer);
|
||||||
|
|
||||||
|
delete[] packet.payload;
|
||||||
|
|
||||||
|
return payload_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::expected<size_t> network::udp::receive(char* buffer, network::socket& socket, size_t n, size_t ms){
|
||||||
|
auto& connection = socket.get_connection_data<udp_connection>();
|
||||||
|
|
||||||
|
// Make sure stream sockets are connected
|
||||||
|
if(!connection.connected){
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_SOCKET_NOT_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(socket.listen_packets.empty()){
|
||||||
|
if(!ms){
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_SOCKET_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!socket.listen_queue.wait_for(ms)){
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_SOCKET_TIMEOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = socket.listen_packets.pop();
|
||||||
|
|
||||||
|
auto* udp_header = reinterpret_cast<network::udp::header*>(packet.payload + packet.tag(2));
|
||||||
|
auto payload_len = switch_endian_16(udp_header->length);
|
||||||
|
|
||||||
|
if(payload_len > n){
|
||||||
|
delete[] packet.payload;
|
||||||
|
|
||||||
|
return std::make_unexpected<size_t>(std::ERROR_BUFFER_SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy_n(packet.payload + packet.index, payload_len, buffer);
|
||||||
|
|
||||||
|
delete[] packet.payload;
|
||||||
|
|
||||||
|
return payload_len;
|
||||||
|
}
|
||||||
|
@ -322,9 +322,10 @@ void tlib::socket::client_bind(tlib::ip::address server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto status = tlib::client_bind(fd, server);
|
auto status = tlib::client_bind(fd, server);
|
||||||
if (!status) {
|
if (status) {
|
||||||
_bound = false;
|
_bound = true;
|
||||||
} else {
|
} else {
|
||||||
|
_bound = false;
|
||||||
error_code = status.error();
|
error_code = status.error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,10 +336,11 @@ void tlib::socket::client_bind(tlib::ip::address server, size_t port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto status = tlib::client_bind(fd, server, port);
|
auto status = tlib::client_bind(fd, server, port);
|
||||||
if (!status) {
|
if (status) {
|
||||||
_bound = false;
|
_bound = true;
|
||||||
} else {
|
} else {
|
||||||
error_code = status.error();
|
error_code = status.error();
|
||||||
|
_bound = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +372,7 @@ void tlib::socket::connect(tlib::ip::address server, size_t port) {
|
|||||||
_connected = true;
|
_connected = true;
|
||||||
} else {
|
} else {
|
||||||
error_code = status.error();
|
error_code = status.error();
|
||||||
|
_connected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user