mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-09 04:22:04 -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<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 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
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -367,6 +367,9 @@ std::expected<void> network::send(socket_fd_t socket_fd, const char* buffer, siz
|
||||
case network::socket_protocol::TCP:
|
||||
return network::tcp::send(target_buffer, socket, buffer, n);
|
||||
|
||||
case network::socket_protocol::UDP:
|
||||
return network::udp::send(target_buffer, socket, buffer, n);
|
||||
|
||||
default:
|
||||
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) {
|
||||
case network::socket_protocol::UDP:
|
||||
return network::udp::receive(buffer, socket, n);
|
||||
|
||||
case network::socket_protocol::TCP:
|
||||
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) {
|
||||
case network::socket_protocol::UDP:
|
||||
return network::udp::receive(buffer, socket, n, ms);
|
||||
|
||||
case network::socket_protocol::TCP:
|
||||
return network::tcp::receive(buffer, socket, n, ms);
|
||||
|
||||
|
@ -184,3 +184,93 @@ std::expected<void> network::udp::client_unbind(network::socket& sock){
|
||||
|
||||
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);
|
||||
if (!status) {
|
||||
_bound = false;
|
||||
if (status) {
|
||||
_bound = true;
|
||||
} else {
|
||||
_bound = false;
|
||||
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);
|
||||
if (!status) {
|
||||
_bound = false;
|
||||
if (status) {
|
||||
_bound = true;
|
||||
} else {
|
||||
error_code = status.error();
|
||||
_bound = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,6 +372,7 @@ void tlib::socket::connect(tlib::ip::address server, size_t port) {
|
||||
_connected = true;
|
||||
} else {
|
||||
error_code = status.error();
|
||||
_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user