mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-17 00:26:44 -04:00
Add timeout support to packet waiting
This commit is contained in:
parent
25625b44af
commit
1e8fe35905
@ -104,6 +104,14 @@ int64_t listen(size_t socket_fd, bool listen);
|
|||||||
*/
|
*/
|
||||||
int64_t wait_for_packet(char* buffer, size_t socket_fd);
|
int64_t wait_for_packet(char* buffer, size_t socket_fd);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Wait for a packet, for some time
|
||||||
|
* \param socket_fd The file descriptor of the packet
|
||||||
|
* \param ms The maximum time, in milliseconds, to wait for a packet
|
||||||
|
* \return the packet index
|
||||||
|
*/
|
||||||
|
int64_t wait_for_packet(char* buffer, size_t socket_fd, size_t ms);
|
||||||
|
|
||||||
} // end of network namespace
|
} // end of network namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -264,3 +264,37 @@ int64_t network::wait_for_packet(char* buffer, size_t socket_fd){
|
|||||||
|
|
||||||
return packet.index;
|
return packet.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t network::wait_for_packet(char* buffer, size_t socket_fd, size_t ms){
|
||||||
|
if(!scheduler::has_socket(socket_fd)){
|
||||||
|
return -std::ERROR_SOCKET_INVALID_FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& socket = scheduler::get_socket(socket_fd);
|
||||||
|
|
||||||
|
if(!socket.listen){
|
||||||
|
return -std::ERROR_SOCKET_NOT_LISTEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
logging::logf(logging::log_level::TRACE, "network: %u wait for packet on socket %u\n", scheduler::get_pid(), socket_fd);
|
||||||
|
|
||||||
|
if(socket.listen_packets.empty()){
|
||||||
|
if(!ms){
|
||||||
|
return -std::ERROR_SOCKET_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!socket.listen_queue.sleep(ms)){
|
||||||
|
return -std::ERROR_SOCKET_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = socket.listen_packets.pop();
|
||||||
|
std::copy_n(packet.payload, packet.payload_size, buffer);
|
||||||
|
|
||||||
|
// The memory was allocated as a copy by the decoding process, it is safe to remove it here
|
||||||
|
delete[] packet.payload;
|
||||||
|
|
||||||
|
logging::logf(logging::log_level::TRACE, "network: %u received packet on socket %u\n", scheduler::get_pid(), socket_fd);
|
||||||
|
|
||||||
|
return packet.index;
|
||||||
|
}
|
||||||
|
@ -390,6 +390,17 @@ void sc_wait_for_packet(interrupt::syscall_regs* regs){
|
|||||||
regs->rbx = reinterpret_cast<size_t>(user_buffer);
|
regs->rbx = reinterpret_cast<size_t>(user_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sc_wait_for_packet_ms(interrupt::syscall_regs* regs){
|
||||||
|
auto socket_fd = regs->rbx;
|
||||||
|
auto user_buffer = reinterpret_cast<char*>(regs->rcx);
|
||||||
|
auto ms = regs->rdx;
|
||||||
|
|
||||||
|
auto index = network::wait_for_packet(user_buffer, socket_fd, ms);
|
||||||
|
|
||||||
|
regs->rax = index;
|
||||||
|
regs->rbx = reinterpret_cast<size_t>(user_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
} //End of anonymous namespace
|
} //End of anonymous namespace
|
||||||
|
|
||||||
void system_call_entry(interrupt::syscall_regs* regs){
|
void system_call_entry(interrupt::syscall_regs* regs){
|
||||||
@ -629,6 +640,10 @@ void system_call_entry(interrupt::syscall_regs* regs){
|
|||||||
sc_wait_for_packet(regs);
|
sc_wait_for_packet(regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x3006:
|
||||||
|
sc_wait_for_packet_ms(regs);
|
||||||
|
break;
|
||||||
|
|
||||||
// Special system calls
|
// Special system calls
|
||||||
|
|
||||||
case 0x6666:
|
case 0x6666:
|
||||||
|
@ -71,20 +71,24 @@ int main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = tlib::wait_for_packet(*socket);
|
auto p = tlib::wait_for_packet(*socket, 2000);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
tlib::printf("ping: wait_for_packet error: %s\n", std::error_message(p.error()));
|
if(p.error() == std::ERROR_SOCKET_TIMEOUT){
|
||||||
return 1;
|
tlib::printf("%s unreachable\n", ip.c_str());
|
||||||
}
|
} else {
|
||||||
|
tlib::printf("ping: wait_for_packet error: %s\n", std::error_message(p.error()));
|
||||||
auto* icmp_header = reinterpret_cast<tlib::icmp::header*>(p->payload + p->index);
|
return 1;
|
||||||
|
}
|
||||||
auto command_type = static_cast<tlib::icmp::type>(icmp_header->type);
|
|
||||||
|
|
||||||
if(command_type == tlib::icmp::type::ECHO_REPLY){
|
|
||||||
tlib::printf("Reply received from %s\n", ip.c_str());
|
|
||||||
} else {
|
} else {
|
||||||
tlib::printf("Unhandled command type received\n");
|
auto* icmp_header = reinterpret_cast<tlib::icmp::header*>(p->payload + p->index);
|
||||||
|
|
||||||
|
auto command_type = static_cast<tlib::icmp::type>(icmp_header->type);
|
||||||
|
|
||||||
|
if(command_type == tlib::icmp::type::ECHO_REPLY){
|
||||||
|
tlib::printf("Reply received from %s\n", ip.c_str());
|
||||||
|
} else {
|
||||||
|
tlib::printf("Unhandled command type received\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tlib::release_packet(*p);
|
tlib::release_packet(*p);
|
||||||
|
@ -30,6 +30,7 @@ std::expected<packet> prepare_packet(size_t socket_fd, void* desc);
|
|||||||
std::expected<void> finalize_packet(size_t socket_fd, packet p);
|
std::expected<void> finalize_packet(size_t socket_fd, packet p);
|
||||||
std::expected<void> listen(size_t socket_fd, bool l);
|
std::expected<void> listen(size_t socket_fd, bool l);
|
||||||
std::expected<packet> wait_for_packet(size_t socket_fd);
|
std::expected<packet> wait_for_packet(size_t socket_fd);
|
||||||
|
std::expected<packet> wait_for_packet(size_t socket_fd, size_t ms);
|
||||||
void release_packet(packet& packet);
|
void release_packet(packet& packet);
|
||||||
|
|
||||||
} // end of namespace tlib
|
} // end of namespace tlib
|
||||||
|
@ -103,6 +103,27 @@ std::expected<tlib::packet> tlib::wait_for_packet(size_t socket_fd){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::expected<tlib::packet> tlib::wait_for_packet(size_t socket_fd, size_t ms){
|
||||||
|
auto buffer = malloc(2048);
|
||||||
|
|
||||||
|
int64_t code;
|
||||||
|
uint64_t payload;
|
||||||
|
asm volatile("mov rax, 0x3006; mov rbx, %[socket]; mov rcx, %[buffer]; mov rdx, %[ms]; int 50; mov %[code], rax; mov %[payload], rbx;"
|
||||||
|
: [payload] "=m" (payload), [code] "=m" (code)
|
||||||
|
: [socket] "g" (socket_fd), [buffer] "g" (reinterpret_cast<size_t>(buffer)), [ms] "g" (ms)
|
||||||
|
: "rax", "rbx", "rcx");
|
||||||
|
|
||||||
|
if(code < 0){
|
||||||
|
free(buffer);
|
||||||
|
return std::make_expected_from_error<packet, size_t>(-code);
|
||||||
|
} else {
|
||||||
|
tlib::packet p;
|
||||||
|
p.index = code;
|
||||||
|
p.payload = reinterpret_cast<char*>(payload);
|
||||||
|
return std::make_expected<packet>(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tlib::release_packet(packet& packet){
|
void tlib::release_packet(packet& packet){
|
||||||
if(packet.payload){
|
if(packet.payload){
|
||||||
free(packet.payload);
|
free(packet.payload);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user