From: Oleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) Date: Tue, 18 Jul 2023 08:04:08 +0000 (+0000) Subject: Pull request #3913: Fix descriptor polling for non-Linux kernels X-Git-Tag: 3.1.67.0~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0820f24b9b7b723ef96a7cf7071f57b6e418f136;p=thirdparty%2Fsnort3.git Pull request #3913: Fix descriptor polling for non-Linux kernels Merge in SNORT/snort3 from ~OSHUMEIK/snort3:cntrl_shell_detach to master Squashed commit of the following: commit a52fea2e2f3a957ae0e052b968343c36cdefdc29 Author: Oleksii Shumeiko Date: Wed Jul 12 15:27:09 2023 +0300 control: follow code style and formatting commit 509e22428a6863396128b7cab018a9901fd378d8 Author: Oleksii Shumeiko Date: Wed Jul 12 15:22:14 2023 +0300 control: fix descriptor polling implementation (POSIX) --- diff --git a/src/control/control.cc b/src/control/control.cc index df47773c7..0204e82ac 100644 --- a/src/control/control.cc +++ b/src/control/control.cc @@ -78,33 +78,35 @@ void ControlConn::configure() const ModuleManager::load_commands(shell); } -void ControlConn::log_command(const std::string& command, bool log) +void ControlConn::log_command(const std::string& command, bool log) { - if(command.empty()) + if (command.empty()) return; - + auto it = std::find(log_exclusion_list.begin(), log_exclusion_list.end(), command); - if (log) + if (log) { - if (it != log_exclusion_list.end()) + if (it != log_exclusion_list.end()) log_exclusion_list.erase(it); - } else + } + else { - if (it == log_exclusion_list.end()) + if (it == log_exclusion_list.end()) log_exclusion_list.push_back(command); } } bool ControlConn::loggable(const std::string& command) { - if(log_exclusion_list.empty() or command.empty()) + if (log_exclusion_list.empty() or command.empty()) return true; - - for (const auto& m : log_exclusion_list) + + for (const auto& m : log_exclusion_list) { if (command.find(m) != std::string::npos) return false; } + return true; } @@ -122,13 +124,14 @@ int ControlConn::read_commands() while ((nl = strchr(p, '\n')) != nullptr) { next_command.append(buf, nl - p); - if(loggable(next_command)) + if (loggable(next_command)) LogMessage("Control: received command, %s\n", next_command.c_str()); pending_commands.push(std::move(next_command)); next_command.clear(); p = nl + 1; commands_found++; } + if (*p != '\0') next_command.append(p); else if (local) @@ -145,14 +148,19 @@ int ControlConn::read_commands() ErrorMessage("Error reading from control descriptor: %s\n", get_error(errno)); return -1; } + if (n == 0 && commands_found == 0) return -1; + touch(); + return commands_found; } void ControlConn::set_user_network_policy() -{ shell->set_user_network_policy(); } +{ + shell->set_user_network_policy(); +} int ControlConn::execute_commands() { @@ -214,8 +222,10 @@ bool ControlConn::respond(const char* format, va_list& ap) { char buf[STD_BUF]; int response_len = vsnprintf(buf, sizeof(buf), format, ap); + if (response_len < 0 || response_len == sizeof(buf)) return false; + buf[response_len] = '\0'; int bytes_written = 0; @@ -233,7 +243,9 @@ bool ControlConn::respond(const char* format, va_list& ap) else bytes_written += n; } + touch(); + return true; } diff --git a/src/control/control_mgmt.cc b/src/control/control_mgmt.cc index f9629eef8..5c3aed10e 100644 --- a/src/control/control_mgmt.cc +++ b/src/control/control_mgmt.cc @@ -56,7 +56,9 @@ static std::unordered_map controls; #define READY 1 #define DEAD 2 -struct FdEvents{ + +struct FdEvents +{ int fd; unsigned flag; }; @@ -214,21 +216,24 @@ static bool poll_control_fds(FdEvents ready[MAX_CONTROL_FDS], unsigned& nready) ErrorMessage("Failed to poll control descriptors: %s\n", get_error(errno)); return false; } - nready = ret; - for (unsigned i = 0; i < ret; i++) + nready = 0; + for (int i = 0; i < npfds; i++) { struct pollfd* pfd = &pfds[i]; int fd = pfd->fd; - ready[i].fd = fd; - ready[i].flag = 0; + ready[nready].fd = fd; + ready[nready].flag = 0; if (pfd->revents & (POLLHUP | POLLERR | POLLNVAL)) { if (pfd->revents & (POLLERR | POLLNVAL)) ErrorMessage("Failed to poll control descriptor %d!\n", fd); - ready[i].flag |= DEAD; + ready[nready].flag |= DEAD; } if (pfd->revents & POLLIN) - ready[i].flag |= READY; + ready[nready].flag |= READY; + + if (ready[nready].flag) + ++nready; } return true; }