diff --git a/docs/scripting.xml b/docs/scripting.xml index 59b787fc3..7ca6014be 100644 --- a/docs/scripting.xml +++ b/docs/scripting.xml @@ -3413,55 +3413,25 @@ also get stored inside the registry. case of a default script scan. The string version is appended, if version detection was enabled. The arguments afterwards are tried to be - interpreted as script categories. This is done via a short Lua function - hard-coded into nse_init.cc called Entry. If you take a look into the script.db you'll see that the Entry lines inside - it are Lua function calls with a table as argument. -The arguments that didn't produce any filenames are then interpreted -as file or directory names themselves. If this also fails, the script scan is aborted. - + interpreted as script categories. This is done via a Lua C function + in nse_init.cc called entry. + Inside script.db, for each category of a script, + there is a call to Entry. If the category was chosen + then the script is loaded. Every argument of + that could not be interpretted as a category + is loaded as a file or directory. If the file or directory could not + be located, then an error is raised and the Script Engine aborts. + + - In the next stage the found files are loaded as chunks, each with - its own environment, having read but not write access to the global - name space and saved inside two globally accessible Lua tables: - hosttests and porttests - depending on the type of script. Because scripts only get loaded once, values stored inside variables during a script's execution against one host or port can be accessed when the same script runs against another target. This can be used to save computation time when a script is run -against multiple targets. See . - - -During this stage scripts are -also are also provided with a default runlevel (1.0), if they -don't specify one themselves and a check is performed whether they -contain an action and a description field. - - - -Using local variables to save data. - -id="persistent locals example" -description="This sample script shows how data can be stored across \ -several invocations of a script against multiple targets" -author="Stoiko Ivanov" -categories = {"safe"} - -require "shortport" -portrule = shortport.portnumber(80) --- we have to declare the variable in the script's global scope --- because if we declare it inside the action it would get redefined --- with each call to the action -local filecontent = nil -require "strbuf" -action= function(host, port) - if(filecontent == nil) then - filecontent = strbuf.new() - for line in io.lines("a_filename_we_want_to_read_from") - filecontent = filecontent .. line - end - end - --rest of the script doing something with the filecontent, we just - --read -end - - + All the .nse files inside a loaded directory are + loaded as files. Each file loaded is exectuted in Lua. If a + portrule is present, then it is saved in the + porttests table with a portrule key and file + closure value. Otherwise, if the script has a hostrule + , then it is saved in the hosttests + in the same manner. + @@ -3475,7 +3445,16 @@ It should be noted that the rules of all chosen scripts are checked against all hosts and their open and open|filtered ports. Therefore it is advisable to leave the rules as simple as possible and to do all the computation inside the action, as a script will only be -executed if it is run against a specific target. After the check those script-target combinations get their own Lua-thread which is anchored in Lua's C-API registry to prevent their garbage collection. These thread_records are afterwards sorted by run level and all script-target combinations of one run level are stored in a list, in order to ensure that scripts with a higher run level are run after those with a lower one. +executed if it is run against a specific target. After the check those script-target combinations +get their own Lua-thread. A +thread running against a host will have only a hostrule passed to the action closure whereas +a thread running against a port will have both a hostrule and portrule passed. Each thread +is stored in a runlevel table with a table of information for the thread. This information +includes the runlevel, target, target port (if applicable), host and port tables +(passed to action), its type (running against a host or port), and its id. When +script scanning begins, these runlevel tables that store the threads will be +passed to mainloop where the real work begins. + @@ -3491,9 +3470,20 @@ executed if it is run against a specific target. After the check those script-ta remote host, is the part of scripts which would consume most time with waiting, this is the point where scripts suspend themselves and let others execute. Each call to some of the functions of the Nsock wrapper - causes the calling script to yield (pause). Once the request is processed by the Nsock library, the + causes the calling script to yield (pause). Once the request is + processed by the Nsock library, the callback causes the script to be pushed from the waiting queue to the running queue, which will eventually let it resume its operation. + The running queue is the runlevel table passed to mainloop + (see nse_main.cc). Mainloop will create a table for waiting scripts + which will have the same form as the running queue. Threads will be + moved back and forth between the tables; when a thread yields, it + is moved to the waiting queue. After all scripts are run in the running + queue, mainloop will place all threads ready to be run in the + running queue. Threads are made "ready" by calling + process_waiting2running. This process of running + threads and moving paused threads to the waiting and running queues is + repeated until no threads exist in the waiting or running queues.