35 #include <openvas/misc/network.h> 36 #include <openvas/misc/nvt_categories.h> 37 #include <openvas/misc/internal_com.h> 38 #include <openvas/misc/prefs.h> 39 #include <openvas/base/nvticache.h> 52 #define MAX_PROCESSES 32 54 #undef VERBOSE_LOGGING 56 #undef DEBUG_CONFLICTS 73 static void read_running_processes ();
74 static void update_running_processes ();
77 static int num_running_processes;
78 static int max_running_processes;
79 static int old_max_running_processes;
80 static struct arglist *non_simult_ports_list;
91 process_internal_msg (
int p)
93 int e = 0, bufsz = 0, type = 0;
96 e = internal_recv (processes[p].internal_soc, &buffer, &bufsz, &type);
99 log_write (
"Process %d (OID: %s) seems to have died too early",
100 processes[p].pid, processes[p].plugin->oid);
101 processes[p].
alive = 0;
105 if (type & INTERNAL_COMM_MSG_TYPE_DATA)
107 e = internal_send (processes[p].upstream_soc, buffer, type);
109 else if (type & INTERNAL_COMM_MSG_TYPE_CTRL)
111 if (type & INTERNAL_COMM_CTRL_FINISHED)
113 kill (processes[p].pid, SIGTERM);
114 processes[p].
alive = 0;
118 log_write (
"Received unknown message type %d", type);
131 if (processes[i].pid != 0)
136 ret = waitpid (-1, NULL, WNOHANG);
138 while (ret < 0 && errno == EINTR);
146 update_running_processes (
void)
150 int log_whole = prefs_get_bool (
"log_whole_attack");
152 gettimeofday (&now, NULL);
154 if (num_running_processes == 0)
159 if (processes[i].pid > 0)
162 if (processes[i].alive == 0
163 || (processes[i].timeout > 0
164 && ((now.tv_sec - processes[i].start.tv_sec) >
165 processes[i].timeout)))
169 if (processes[i].alive)
174 log_write (
"%s (pid %d) is slow to finish - killing it",
175 oid, processes[i].pid);
177 msg = g_strdup_printf
178 (
"SERVER <|> ERRMSG <|> %s <|> general/tcp" 179 " <|> NVT timed out after %d seconds." 180 " <|> %s <|> SERVER\n",
181 hostname, processes[i].timeout, oid ?:
"0");
182 internal_send (processes[i].upstream_soc,
183 msg, INTERNAL_COMM_MSG_TYPE_DATA);
187 processes[i].
alive = 0;
191 struct timeval old_now = now;
193 if (now.tv_usec < processes[i].start.tv_usec)
195 processes[i].
start.tv_sec++;
196 now.tv_usec += 1000000;
200 char *name = nvticache_get_filename (oid);
202 (
"%s (%s) [%d] finished its job in %ld.%.3ld seconds",
203 name, oid, processes[i].pid,
204 (
long) (now.tv_sec - processes[i].start.tv_sec),
205 (
long) ((now.tv_usec -
206 processes[i].start.tv_usec) / 1000));
212 e = waitpid (processes[i].pid, NULL, 0);
214 while (e < 0 && errno == EINTR);
217 num_running_processes--;
219 close (processes[i].internal_soc);
220 bzero (&(processes[i]),
sizeof (processes[i]));
240 if (processes[r].pid > 0)
242 struct arglist *common_ports;
247 if (
common (common_ports, non_simult_ports_list))
249 arg_free (common_ports);
252 #ifdef DEBUG_CONFLICT 253 log_write (
"Waiting has been initiated...\n");
254 log_write (
"Ports in common - waiting...");
258 read_running_processes ();
259 update_running_processes ();
262 #ifdef DEBUG_CONFLICT 263 log_write (
"End of the wait - was that long ?\n");
285 read_running_processes (
void)
294 if (num_running_processes == 0)
300 if (processes[i].pid > 0)
302 FD_SET (processes[i].internal_soc, &rd);
303 if (processes[i].internal_soc > max)
312 e = select (max + 1, &rd, NULL, NULL, &tv);
314 while (e < 0 && errno == EINTR);
321 if (processes[i].pid > 0)
324 if (FD_ISSET (processes[i].internal_soc, &rd) != 0)
326 int result = process_internal_msg (i);
330 log_write (
"process_internal_msg for %s returned %d",
331 processes[i].plugin->oid, result);
338 if (flag == 0 && num_running_processes != 0)
339 num_running_processes = 0;
346 struct arglist *preferences = preferences_get ();
347 non_simult_ports_list = arg_get_value (preferences,
"non_simult_ports_list");
349 old_max_running_processes = max_running_processes;
355 (
"max_checks (%d) > MAX_PROCESSES (%d) - modify openvas-scanner/openvassd/pluginlaunch.c",
361 num_running_processes = 0;
362 bzero (&(processes),
sizeof (processes));
368 max_running_processes = 1;
374 max_running_processes = old_max_running_processes;
385 read_running_processes ();
389 if (processes[i].pid > 0)
390 kill (processes[i].pid, SIGTERM);
397 if (processes[i].pid > 0)
399 kill (processes[i].pid, SIGKILL);
400 num_running_processes--;
402 close (processes[i].internal_soc);
403 bzero (&(processes[i]),
sizeof (
struct running));
415 struct host_info *hostinfo, kb_t kb,
char *name)
421 while (num_running_processes >= max_running_processes)
423 read_running_processes ();
424 update_running_processes ();
427 p = next_free_process (plugin);
428 processes[p].
plugin = plugin;
429 processes[p].
timeout = prefs_nvt_timeout (plugin->
oid);
430 if (processes[p].timeout == 0)
431 processes[p].
timeout = nvticache_get_timeout (plugin->
oid);
433 if (processes[p].timeout == 0)
435 int category = nvticache_get_category (plugin->
oid);
436 if (category == ACT_SCANNER)
437 processes[p].
timeout = atoi (prefs_get (
"scanner_plugins_timeout")
440 processes[p].
timeout = atoi (prefs_get (
"plugins_timeout") ?:
"-1");
443 if (socketpair (AF_UNIX, SOCK_STREAM, 0, dsoc) < 0)
445 perror (
"pluginlaunch.c:plugin_launch:socketpair(1) ");
447 gettimeofday (&(processes[p].start), NULL);
449 processes[p].
upstream_soc = arg_get_value_int (globals,
"global_socket");
455 processes[p].
alive = 1;
457 if (processes[p].pid > 0)
458 num_running_processes++;
462 return processes[p].
pid;
475 read_running_processes ();
476 update_running_processes ();
478 while (num_running_processes != 0);
490 if (processes[i].internal_soc)
491 close (processes[i].internal_soc);
501 int num = num_running_processes;
502 while (num && num_running_processes == num)
505 read_running_processes ();
506 update_running_processes ();
int process_alive(pid_t pid)
void pluginlaunch_enable_parrallel_checks(void)
void log_write(const char *str,...)
Write into the logfile / syslog.
struct scheduler_plugin * plugin
struct arglist * requirements_common_ports(struct scheduler_plugin *plugin1, struct scheduler_plugin *plugin2)
Returns <port> if the lists of the required ports between.
#define MAX_PROCESSES
'Hard' limit of the max. number of concurrent plugins per host.
void pluginlaunch_wait_for_free_process(void)
Waits and 'pushes' processes until the number of running processes has changed.
#define PLUGIN_STATUS_DONE
int plugin_launch(struct arglist *globals, struct scheduler_plugin *plugin, struct host_info *hostinfo, kb_t kb, char *name)
Host information, implemented as doubly linked list.
int nasl_plugin_launch(struct arglist *globals, struct host_info *hostinfo, kb_t kb, char *name, const char *oid, int soc)
Launch a NASL plugin.
void pluginlaunch_wait(void)
Waits and 'pushes' processes until num_running_processes is 0.
void pluginlaunch_child_cleanup(void)
Cleanup file descriptors used by the processes array. To be called by the child process running the p...
Structure to represent a process in the sense of a running NVT.
void pluginlaunch_disable_parrallel_checks(void)
void pluginlaunch_stop(int soft_stop)
#define PLUGIN_STATUS_UNRUN
int common(struct arglist *l1, struct arglist *l2)
Returns 1 if the two arglists have a name in common.
int terminate_process(pid_t pid)
int get_max_checks_number(void)
void pluginlaunch_init(const char *host)