GSoC: Documentation #1
This commit is contained in:
parent
120a7f558e
commit
f9263e00c1
5 changed files with 174 additions and 3 deletions
17
libs/lucid-http/docs/OVERVIEW
Normal file
17
libs/lucid-http/docs/OVERVIEW
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
LuCId HTTP/1.1 Server Slave
|
||||||
|
|
||||||
|
*** Abstract ***
|
||||||
|
The LuCId HTTP-Server Slave is an HTTP/1.1 implementation for the LuCId
|
||||||
|
superserver loosely based on the LuCI HTTP stack. It supports keep-alive,
|
||||||
|
pipelining, basic authentication, kernel-mode file transfer (sendfile()
|
||||||
|
through nixio), address and hostname based virtual hosts, custom 404 pages,
|
||||||
|
E-Tags, conditional headers, directory indexing and partial file transfers.
|
||||||
|
|
||||||
|
|
||||||
|
*** Workflow ***
|
||||||
|
After receiving an incoming connection from LuCId, the slave parses the request
|
||||||
|
and prepares the environment for the acion handler. After that the virtual host
|
||||||
|
will be dispatched and the request will be passed on to the respective handler.
|
||||||
|
The handler will enforce access restrictions if configured and then returns a
|
||||||
|
status code a set of response headers, as well as a content resource that will
|
||||||
|
be sent to the user.
|
19
libs/lucid-rpc/docs/OVERVIEW
Normal file
19
libs/lucid-rpc/docs/OVERVIEW
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
LuCId JSON-RPC Server Slave
|
||||||
|
|
||||||
|
*** Abstract ***
|
||||||
|
The LuCId JSON-RPC server slave implements the JSON-RPC 1.0 and 2.0 protocol
|
||||||
|
to allow efficient light-weight remote procedure calling.
|
||||||
|
It provides notification support and several unofficial protocol extensions such
|
||||||
|
as:
|
||||||
|
* Close notifications
|
||||||
|
* Raw TCP switching to transfer BLOBs efficiently
|
||||||
|
* Client notification
|
||||||
|
|
||||||
|
|
||||||
|
*** Workflow ***
|
||||||
|
After receiving an incoming connection from LuCId, the slave analyses the
|
||||||
|
request and passes it to the matching handler. The handler will enforce
|
||||||
|
access restriction and deserialize the payload data and invokes the assigned
|
||||||
|
Lua function in a protected way. In case of a success the handler will serialize
|
||||||
|
the response and send it to the client - otherwise a detailed error message
|
||||||
|
will be returned.
|
75
libs/lucid/docs/OVERVIEW
Normal file
75
libs/lucid/docs/OVERVIEW
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
LuCId Network Superserver in Lua
|
||||||
|
|
||||||
|
*** Abstract ***
|
||||||
|
LuCId is a network superserver written in Lua based on the nixio POSIX library.
|
||||||
|
It supports IPv4, IPv6, TLS, asynchronous and synchronous IO and can be extended
|
||||||
|
to handle any kind of IO events on file descriptors. LuCId is also able to
|
||||||
|
generate RSA private keys and self-signed certificates on demand if the px5g
|
||||||
|
keymaster library is available. Both nixio and px5g are libraries created
|
||||||
|
by the LuCI developers.
|
||||||
|
|
||||||
|
|
||||||
|
*** Configuration ***
|
||||||
|
LuCId uses the UCI Universal Configuration Interface as configuration backend.
|
||||||
|
|
||||||
|
There are 4 types of configuration sections and one named section defined:
|
||||||
|
The main section of type "lucid" defines the basic framework parameters of LuCId
|
||||||
|
These include:
|
||||||
|
* pollinterval: Internal polling interval
|
||||||
|
* threadlimit: Overall maximum number of child processes
|
||||||
|
* daemonize: Whether to daemonize at startup
|
||||||
|
* debug: Whether to enable debug output in syslog
|
||||||
|
|
||||||
|
|
||||||
|
The "tcpserver" section type provides the framework for TCP servers:
|
||||||
|
Parameters:
|
||||||
|
* entrypoint: Lua module entrypoint (provides a prepare_daemon function)
|
||||||
|
|
||||||
|
The "daemon" sections define instances of servers.
|
||||||
|
Parameters may include:
|
||||||
|
* slave: Server slave
|
||||||
|
* publisher: Publishers to be served by this daemon
|
||||||
|
* enabled: Flag (0/1) whether this daemon should be started
|
||||||
|
* address: List of ports / addresses to be bound too, if applicable
|
||||||
|
* encryption: Flag (disabled/enabled) whether to enforce encryption
|
||||||
|
* tls: Reference to the TLS configuration section to use
|
||||||
|
|
||||||
|
The "...Publisher" sections define services to be published through daemons.
|
||||||
|
Publishers definitions should be daemon and protocol independent whenever
|
||||||
|
possible. Publishers should also implement access restrictions for certain
|
||||||
|
network interfaces and for specified UNIX user accounts.
|
||||||
|
Publishers usually define but are not required to use the following Parameters:
|
||||||
|
* name: Published Name
|
||||||
|
* physical: Physical source path
|
||||||
|
* virtual: Virtual resource path
|
||||||
|
* domain: Any kind of domain or realm specification
|
||||||
|
* read: ACL containing entities allowed to read the given resource
|
||||||
|
* write: -"-
|
||||||
|
* exec: -"-
|
||||||
|
|
||||||
|
The "tls" sections describe TLS security specifications for TCP servers.
|
||||||
|
Parameters:
|
||||||
|
* key: Private Key file
|
||||||
|
* cert: Certificate file
|
||||||
|
* type: Type of certificate and key files (pem, asn1)
|
||||||
|
* generate: Flag (0/1) to determine whether LuCId should generate
|
||||||
|
keys and self-signed certificates if the certificate is not available and
|
||||||
|
the px5g RSA Keymaster is available
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** Workflow ***
|
||||||
|
In the preparation phase LuCId loads its configuration using the specification
|
||||||
|
given above and prepares its servers, daemons and publishers. It also allocates
|
||||||
|
resources such as binding sockets or preparing encryption credentials.
|
||||||
|
If everything could be setup correctly LuCId will daemonize - if requested. If
|
||||||
|
any errors occur in the preparation phase, LuCId will write to the system logger
|
||||||
|
and exit.
|
||||||
|
|
||||||
|
After daemonizing the main process is responsible for keeping a list of
|
||||||
|
file descriptors that LuCId is polling regularly to handle incoming data events.
|
||||||
|
Data events are for example new TCP connection attempts which could cause the
|
||||||
|
superserver to fork a new process and invoke a registered handler.
|
||||||
|
|
||||||
|
Whenever a sub-process is about to be generate LuCId checks if given resource
|
||||||
|
limits are still met.
|
|
@ -41,7 +41,7 @@ local UCINAME = UCINAME
|
||||||
local SSTATE = "/tmp/.lucid_store"
|
local SSTATE = "/tmp/.lucid_store"
|
||||||
|
|
||||||
|
|
||||||
|
--- Starts a new LuCId superprocess.
|
||||||
function start()
|
function start()
|
||||||
prepare()
|
prepare()
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ function start()
|
||||||
run()
|
run()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Stops any running LuCId superprocess.
|
||||||
function stop()
|
function stop()
|
||||||
local pid = tonumber(state:get(UCINAME, "main", "pid"))
|
local pid = tonumber(state:get(UCINAME, "main", "pid"))
|
||||||
if pid then
|
if pid then
|
||||||
|
@ -68,6 +69,7 @@ function stop()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Prepares the slaves, daemons and publishers, allocate resources.
|
||||||
function prepare()
|
function prepare()
|
||||||
local debug = tonumber((cursor:get(UCINAME, "main", "debug")))
|
local debug = tonumber((cursor:get(UCINAME, "main", "debug")))
|
||||||
|
|
||||||
|
@ -104,6 +106,8 @@ function prepare()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Run the superprocess if prepared before.
|
||||||
|
-- This main function of LuCId will wait for events on given file descriptors.
|
||||||
function run()
|
function run()
|
||||||
local pollint = tonumber((cursor:get(UCINAME, "main", "pollinterval")))
|
local pollint = tonumber((cursor:get(UCINAME, "main", "pollinterval")))
|
||||||
|
|
||||||
|
@ -136,11 +140,20 @@ function run()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a file descriptor for the main loop and associate handler functions.
|
||||||
|
-- @param polle Table containing: {fd = FILE DESCRIPTOR, events = POLL EVENTS,
|
||||||
|
-- handler = EVENT HANDLER CALLBACK}
|
||||||
|
-- @see unregister_pollfd
|
||||||
|
-- @return boolean status
|
||||||
function register_pollfd(polle)
|
function register_pollfd(polle)
|
||||||
pollt[#pollt+1] = polle
|
pollt[#pollt+1] = polle
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Unregister a file desciptor and associate handler from the main loop.
|
||||||
|
-- @param polle Poll descriptor
|
||||||
|
-- @see register_pollfd
|
||||||
|
-- @return boolean status
|
||||||
function unregister_pollfd(polle)
|
function unregister_pollfd(polle)
|
||||||
for k, v in ipairs(pollt) do
|
for k, v in ipairs(pollt) do
|
||||||
if v == polle then
|
if v == polle then
|
||||||
|
@ -151,6 +164,8 @@ function unregister_pollfd(polle)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Close all registered file descriptors from main loop.
|
||||||
|
-- This is useful for forked child processes.
|
||||||
function close_pollfds()
|
function close_pollfds()
|
||||||
for k, v in ipairs(pollt) do
|
for k, v in ipairs(pollt) do
|
||||||
if v.fd and v.fd.close then
|
if v.fd and v.fd.close then
|
||||||
|
@ -159,11 +174,19 @@ function close_pollfds()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register a tick function that will be called at each cycle of the main loop.
|
||||||
|
-- @param cb Callback
|
||||||
|
-- @see unregister_tick
|
||||||
|
-- @return boolean status
|
||||||
function register_tick(cb)
|
function register_tick(cb)
|
||||||
tickt[#tickt+1] = cb
|
tickt[#tickt+1] = cb
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Unregister a tick function from the main loop.
|
||||||
|
-- @param cb Callback
|
||||||
|
-- @see register_tick
|
||||||
|
-- @return boolean status
|
||||||
function unregister_tick(cb)
|
function unregister_tick(cb)
|
||||||
for k, v in ipairs(tickt) do
|
for k, v in ipairs(tickt) do
|
||||||
if v == cb then
|
if v == cb then
|
||||||
|
@ -174,10 +197,14 @@ function unregister_tick(cb)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a new child process from a Lua function and assign a destructor.
|
||||||
|
-- @param threadcb main function of the new process
|
||||||
|
-- @param waitcb destructor callback
|
||||||
|
-- @return process identifier or nil, error code, error message
|
||||||
function create_process(threadcb, waitcb)
|
function create_process(threadcb, waitcb)
|
||||||
local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
|
local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
|
||||||
if threadlimit and tcount >= threadlimit then
|
if threadlimit and tcount >= threadlimit then
|
||||||
nixio.syslog("warning", "Unable to create thread: process limit reached")
|
nixio.syslog("warning", "Cannot create thread: process limit reached")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local pid, code, err = nixio.fork()
|
local pid, code, err = nixio.fork()
|
||||||
|
@ -193,6 +220,9 @@ function create_process(threadcb, waitcb)
|
||||||
return pid, code, err
|
return pid, code, err
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Prepare a daemon from a given configuration table.
|
||||||
|
-- @param config Configuration data.
|
||||||
|
-- @return boolean status or nil, error code, error message
|
||||||
function prepare_daemon(config)
|
function prepare_daemon(config)
|
||||||
nixio.syslog("info", "Preparing daemon " .. config[".name"])
|
nixio.syslog("info", "Preparing daemon " .. config[".name"])
|
||||||
local modname = cursor:get(UCINAME, config.slave)
|
local modname = cursor:get(UCINAME, config.slave)
|
||||||
|
@ -210,6 +240,9 @@ function prepare_daemon(config)
|
||||||
return module.prepare_daemon(config, _M)
|
return module.prepare_daemon(config, _M)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Prepare a slave.
|
||||||
|
-- @param name slave name
|
||||||
|
-- @return table containing slave module and configuration or nil, error message
|
||||||
function prepare_slave(name)
|
function prepare_slave(name)
|
||||||
local slave = slaves[name]
|
local slave = slaves[name]
|
||||||
if not slave then
|
if not slave then
|
||||||
|
@ -228,16 +261,24 @@ function prepare_slave(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return a list of available network interfaces on the host.
|
||||||
|
-- @return table returned by nixio.getifaddrs()
|
||||||
function get_interfaces()
|
function get_interfaces()
|
||||||
return ifaddrs
|
return ifaddrs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Revoke process privileges.
|
||||||
|
-- @param user new user name or uid
|
||||||
|
-- @param group new group name or gid
|
||||||
|
-- @return boolean status or nil, error code, error message
|
||||||
function revoke_privileges(user, group)
|
function revoke_privileges(user, group)
|
||||||
if nixio.getuid() == 0 then
|
if nixio.getuid() == 0 then
|
||||||
return nixio.setgid(group) and nixio.setuid(user)
|
return nixio.setgid(group) and nixio.setuid(user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return a secure UCI cursor.
|
||||||
|
-- @return UCI cursor
|
||||||
function securestate()
|
function securestate()
|
||||||
local stat = nixio.fs.stat(SSTATE) or {}
|
local stat = nixio.fs.stat(SSTATE) or {}
|
||||||
local uid = nixio.getuid()
|
local uid = nixio.getuid()
|
||||||
|
@ -253,6 +294,8 @@ function securestate()
|
||||||
return uci.cursor(nil, SSTATE)
|
return uci.cursor(nil, SSTATE)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Daemonize the process.
|
||||||
|
-- @return boolean status or nil, error code, error message
|
||||||
function daemonize()
|
function daemonize()
|
||||||
if nixio.getppid() == 1 then
|
if nixio.getppid() == 1 then
|
||||||
return
|
return
|
||||||
|
|
|
@ -28,7 +28,10 @@ local UCINAME = lucid.UCINAME
|
||||||
|
|
||||||
local tcpsockets = {}
|
local tcpsockets = {}
|
||||||
|
|
||||||
|
--- Prepare a daemon and allocate its resources. (superserver callback)
|
||||||
|
-- @param config configuration table
|
||||||
|
-- @param server LuCId basemodule
|
||||||
|
-- @return binary data
|
||||||
function prepare_daemon(config, server)
|
function prepare_daemon(config, server)
|
||||||
nixio.syslog("info", "Preparing TCP-Daemon " .. config[".name"])
|
nixio.syslog("info", "Preparing TCP-Daemon " .. config[".name"])
|
||||||
if type(config.address) ~= "table" then
|
if type(config.address) ~= "table" then
|
||||||
|
@ -104,6 +107,9 @@ function prepare_daemon(config, server)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Accept a new TCP connection. (server callback)
|
||||||
|
-- @param polle Poll descriptor
|
||||||
|
-- @return handler process id or nil, error code, error message
|
||||||
function accept(polle)
|
function accept(polle)
|
||||||
local socket, host, port = polle.fd:accept()
|
local socket, host, port = polle.fd:accept()
|
||||||
if not socket then
|
if not socket then
|
||||||
|
@ -133,6 +139,13 @@ function accept(polle)
|
||||||
return unpack(stat)
|
return unpack(stat)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Prepare a TCP server socket.
|
||||||
|
-- @param family protocol family ["inetany", "inet6", "inet"]
|
||||||
|
-- @param host host
|
||||||
|
-- @param port port
|
||||||
|
-- @param opts table of socket options
|
||||||
|
-- @param backlog socket backlog
|
||||||
|
-- @return socket, final socket family
|
||||||
function prepare_socket(family, host, port, opts, backlog)
|
function prepare_socket(family, host, port, opts, backlog)
|
||||||
nixio.syslog("info", "Preparing socket for port " .. port)
|
nixio.syslog("info", "Preparing socket for port " .. port)
|
||||||
backlog = backlog or 1024
|
backlog = backlog or 1024
|
||||||
|
@ -171,6 +184,10 @@ function prepare_socket(family, host, port, opts, backlog)
|
||||||
return socket, family
|
return socket, family
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Prepare a TLS server context and load keys and certificates.
|
||||||
|
-- May invoke px5g to create keys and certificate on demand if available.
|
||||||
|
-- @param tlskey TLS configuration identifier
|
||||||
|
-- @return TLS server conext or nil
|
||||||
function prepare_tls(tlskey)
|
function prepare_tls(tlskey)
|
||||||
local tls
|
local tls
|
||||||
if tlskey and cursor:get(UCINAME, tlskey) then
|
if tlskey and cursor:get(UCINAME, tlskey) then
|
||||||
|
|
Loading…
Reference in a new issue