summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_router.c (unfollow)
AgeCommit message (Collapse)AuthorFilesLines
2023-08-10Wasm: Register a new WebAssembly language module type.Andrew Clayton1-0/+1
This is the first patch in adding WebAssembly language module support. This just adds a new NXT_APP_WASM type, required by subsequent commits. Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-08-10Index initialise the nxt_app_msg_prefix array.Andrew Clayton1-6/+6
This makes it much more clear what's what. This is in preparation for adding WebAssembly language module support. Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-05-08NJS: supported loadable modules.Zhidao HONG1-5/+153
2023-04-25Allow to remove the version string in HTTP responses.Andrew Clayton1-0/+8
Normally Unit responds to HTTP requests by including a header like Server: Unit/1.30.0 however it can sometimes be beneficial to withhold the version information and in this case just respond with Server: Unit This patch adds a new "settings.http" boolean option called server_version, which defaults to true, in which case the full version information is sent. However this can be set to false, e.g "settings": { "http": { "server_version": false } }, in which case Unit responds without the version information as the latter example above shows. Link: <https://www.ietf.org/rfc/rfc9110.html#section-10.2.4> Closes: <https://github.com/nginx/unit/issues/158> Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-03-21HTTP: added route logging.Alejandro Colomar1-0/+6
- Configuration: added "/config/settings/http/log_route". Type: bool Default: false This adds configurability to the error log. It allows enabling and disabling logs related to how the router performs selection of the routes. - HTTP: logging request line. Log level: [notice] The request line is essential to understand which logs correspond to which request when reading the logs. - HTTP: logging route that's been discarded. Log level: [info] - HTTP: logging route whose action is selected. Log level: [notice] - HTTP: logging when "fallback" action is taken. Log level: [notice] Closes: <https://github.com/nginx/unit/issues/758> Link: <https://github.com/nginx/unit/pull/824> Link: <https://github.com/nginx/unit/pull/839> Suggested-by: Timo Stark <t.stark@nginx.com> Suggested-by: Mark L Wood-Patrick <mwoodpatrick@gmail.com> Suggested-by: Liam Crilly <liam@nginx.com> Tested-by: Liam Crilly <liam@nginx.com> Acked-by: Artem Konev <a.konev@f5.com> Cc: Andrew Clayton <a.clayton@nginx.com> Cc: Andrei Zeliankou <zelenkov@nginx.com> Reviewed-by: Zhidao Hong <z.hong@f5.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
2023-03-17Socket: Remove Unix domain listen sockets upon reconfigure.Andrew Clayton1-3/+38
Currently when using Unix domain sockets for requests, if unit is reconfigured then it will fail if it tries to bind(2) again to a Unix domain socket with something like 2023/02/25 19:15:50 [alert] 35274#35274 bind(\"unix:/tmp/unit.sock\") failed (98: Address already in use) When closing such a socket we really need to unlink(2) it. However that presents a problem in that when running as root, while the main process runs as root and creates the socket, it's the router process, that runs as an unprivileged user, e.g nobody, that closes the socket and would thus remove it, but couldn't due to not having permission, even if the socket is mode 0666, you need write permissions on the containing directory to remove a file. There are several options to solve this, all with varying degrees of complexity and utility. 1) Give the user who the router process runs as write permission to the directory containing the listen sockets. These can then be unlink(2)'d from the router process. Simple and would work, but perhaps not the most elegant. 2) Using capabilities(7). The router process could temporarily attain the CAP_DAC_OVERRIDE capability, unlink(7) the socket, then relinquish the capability until required again. These are Linux specific (other systems may have similar mechanisms which would be extra work to support). There is also a, albeit small, window where the router process is running with elevated privileges. 3) Have the main process do the unlink(2), it is after all the process that created the socket. This is what this commit implements. We create a new port IPC message type of NXT_PORT_MSG_SOCKET_UNLINK, that is used by the router process to notify the main process about a Unix domain socket to unlink(2). Upon doing a reconfigure the router process will call nxt_router_listen_socket_release() which will close the socket, we extend this function in the case of non-abstract Unix domain sockets, so that it will send a message to the main process containing a copy of the nxt_sockaddr_t structure that will contain the filename of the socket. In the main process the handler that we have defined, nxt_main_port_socket_unlink_handler(), for this message type will run and allow us to look for the socket in question in the listen_sockets array and remove it and unlink(2) the socket. This then allows the reconfigure to work if it tries to bind(2) again to a socket that previously existed. Link: <https://github.com/nginx/unit/issues/669> Link: <https://github.com/nginx/unit/pull/735> Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-03-14Router: More accurately allocate request buffer memory.Andrew Clayton1-2/+2
In nxt_router_prepare_msg() we create a buffer (nxt_unit_request_t *req) that gets sent to an application process that contains details about a client request. This buffer was always a little larger than needed due to allocating space for the remote address _and_ port and the local address _and_ port. We also allocate space for the local port separately. ->{local,remote}->length includes the port number and ':' and also the '[]' for IPv6. E.g [2001:db8::1]:8080 ->{local,remote}->address_length represents the length of the unadorned IP address. E.g 2001:db8::1 Update the buffer size so that we only allocate what is actually needed. Suggested-by: Zhidao HONG <z.hong@f5.com> Cc: Zhidao HONG <z.hong@f5.com> Reviewed-by: Zhidao HONG <z.hong@f5.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-03-10Router: Fix allocation of request buffer sent to application.Andrew Clayton1-0/+1
This fixes an issue reported by @Peter2121 on GitHub. In nxt_router_prepare_msg() we create a buffer (nxt_unit_request_t *req) that gets sent to an application process that contains details about a client request. The req structure comprises various members with the final member being an array (specified as a flexible array member, with its actual length denoted by the req->fields_count member) of nxt_unit_field_t's. These structures specify the length and offset for the various request headers name/value pairs which are stored after some request metadata that is stored immediately after this array of structs as individual nul terminated strings. After this we have the body content data (if any). So it looks a little like (gdb) x /64bs 0x7f38c976e060 0x7f38c976e060: "\353\346\244\t\006" <-- First nxt_unit_field_t 0x7f38c976e066: "" 0x7f38c976e067: "" 0x7f38c976e068: "T\001" 0x7f38c976e06b: "" 0x7f38c976e06c: "Z\001" 0x7f38c976e06f: "" ... 0x7f38c976e170: "\362#\244\v$" <-- Last nxt_unit_field_t 0x7f38c976e176: "" 0x7f38c976e177: "" 0x7f38c976e178: "\342\002" 0x7f38c976e17b: "" 0x7f38c976e17c: "\352\002" 0x7f38c976e17f: "" 0x7f38c976e180: "POST" <-- Start of request metadata 0x7f38c976e185: "HTTP/1.1" 0x7f38c976e18e: "unix:" 0x7f38c976e194: "unix:/dev/shm/842.sock" 0x7f38c976e1ab: "" 0x7f38c976e1ac: "fedora" 0x7f38c976e1b3: "/842.php" 0x7f38c976e1bc: "HTTP_HOST" <-- Start of header fields 0x7f38c976e1c6: "fedora" 0x7f38c976e1cd: "HTTP_X_FORWARDED_PROTO" 0x7f38c976e1e4: "https" ... 0x7f38c976e45a: "HTTP_COOKIE" 0x7f38c976e466: "PHPSESSID=8apkg25r9s9vju3pi085i21eh4" 0x7f38c976e48b: "public_form=sended" <-- Body content Well that's how things are supposed to look! When using Unix domain sockets what we actually got looked like ... 0x7f6141f3445a: "HTTP_COOKIE" 0x7f6141f34466: "PHPSESSID=uo5b2nu9buijkc89jotbgmd60vpublic_form=sended" Here, the body content (from a POST for example) has been appended straight onto the end of the last header field value. In this case corrupting the PHP session cookie. The body content would still be found by the application as its offset into this buffer is correct. This problem was actually caused by a0327445 ("PHP: allowed to specify URLs without a trailing '/'.") which added an extra item into this request buffer specifying the port number that unit is listening on that handled this request. Unfortunately when I wrote that patch I didn't increase the size of this request buffer to accommodate it. When using normal TCP sockets we actually end up allocating more space than required for this buffer, we track the end of this buffer up to where the body content would go and so we have a few spare bytes between the nul byte of the last field header value and the start of the body content. When using Unix domain sockets, they have no associated port number and thus the port number has a length of 0 bytes, but we still write a '\0' in there using up a byte that we didn't account for, this causes us to loose the nul byte of the last header fields value causing the body data to be appended to the last header field value. The fix is simple, account for the local port length, we also add 1 to it, this covers the nul byte, even if there is no port as with Unix domain sockets. Closes: <https://github.com/nginx/unit/issues/842> Fixes: a0327445 ("PHP: allowed to specify URLs without a trailing '/'.") Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2023-01-30NJS: adding the missing vm destruction.Zhidao HONG1-0/+6
This commit fixed the njs memory leak happened in the config validation, updating and http requests.
2023-01-30NJS: adding the missing vm destruction.Zhidao HONG1-0/+6
This commit fixed the njs memory leak happened in the config validation, updating and http requests.
2022-11-22NJS: added http request prototype.Zhidao HONG1-0/+4
2022-11-20Basic njs support.Zhidao HONG1-1/+6
2022-11-20Var: separating nxt_tstr_t from nxt_var_t.Zhidao HONG1-2/+2
It's for the introduction of njs support. For each option that supports native variable and JS template literals introduced next, it's unified as template string. No functional changes.
2022-11-02PHP: allowed to specify URLs without a trailing '/'.Andrew Clayton1-0/+6
Both @lucatacconi & @mwoodpatrick reported what appears to be the same issue on GitHub. Namely that when using the PHP language module and trying to access a URL that is a directory but without specifying the trailing '/', they were getting a '503 Service Unavailable' error. Note: This is when _not_ using the 'script' option. E.g with the following config { "listeners": { "[::1]:8080": { "pass": "applications/php" } }, "applications": { "php": { "type": "php", "root": "/var/tmp/unit-php" } } } and with a directory path of /var/tmp/unit-php/foo containing an index.php, you would see the following $ curl http://localhost/foo <title>Error 503</title> Error 503 However $ curl http://localhost/foo/ would work and serve up the index.php This commit fixes the above so you get the desired behaviour without specifying the trailing '/' by doing the following 1] If the URL doesn't end in .php and doesn't have a trailing '/' then check if the requested path is a directory. 2) If it is a directory then create a 301 re-direct pointing to it. This matches the behaviour of the likes of nginx, Apache and lighttpd. This also matches the behaviour of the "share" action in Unit. This doesn't effect the behaviour of the 'script' option which bypasses the nxt_php_dynamic_request() function. This also adds a couple of tests to test/test_php_application.py to ensure this continues to work. Closes: <https://github.com/nginx/unit/issues/717> Closes: <https://github.com/nginx/unit/issues/753> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2022-10-03Renamed a couple of members of nxt_unit_request_t.Andrew Clayton1-2/+2
This is a preparatory patch that renames the 'local' and 'local_length' members of the nxt_unit_request_t structure to 'local_addr' and 'local_addr_length' in preparation for the adding of 'local_port' and 'local_port_length' members. Suggested-by: Zhidao HONG <z.hong@f5.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2022-08-29Status: added requests count.Zhidao HONG1-0/+1
2022-08-29Implemented basic statistics API.Valentin Bartenev1-0/+81
2022-07-14Log: split access log from nxt_router.c.Zhidao HONG1-435/+8
No functional changes.
2022-07-14Var: dynamic variables support.Zhidao HONG1-0/+5
This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
2022-06-20Router: forwared header replacement.Zhidao HONG1-30/+77
2022-06-20Router: introduced nxt_http_forward_t.Zhidao HONG1-22/+17
This makes the replacement of forwarded request header like client_ip and protocol more generic. It's a prerequirement for protocol replacement. No functional changes.
2022-06-20Router: refactored nxt_router_conf_create().Zhidao HONG1-30/+30
No functional changes.
2022-06-07Removing unused tracking fields and functions.Max Romanov1-1/+0
The message tracking is unused since 1d84b9e4b459 commit. This fixes the issue found by Coverity (CID 376263).
2022-06-07Router: removed unused code in nxt_router_conf_error().Zhidao HONG1-6/+0
No functional changes.
2022-04-26Removed special cases for non-NXT_CONF_VALUE_ARRAY.Alejandro Colomar1-17/+7
The previous commit added more generic APIs for handling NXT_CONF_VALUE_ARRAY and non-NXT_CONF_VALUE_ARRAY together. Modify calling code to remove special cases for arrays and non-arrays, taking special care that the path for non arrays is logically equivalent to the previous special cased code. Use the now-generic array code only.
2021-11-25Fixing access_log structure reference counting.Max Romanov1-4/+26
The reference to the access_log structure is stored in the current nxt_router_conf_t and the global nxt_router_t. When the reference is copied, the reference counter should be adjusted accordingly. This closes #593 issue on GitHub.
2021-11-25Fixing access_log structure reference counting.Max Romanov1-4/+26
The reference to the access_log structure is stored in the current nxt_router_conf_t and the global nxt_router_t. When the reference is copied, the reference counter should be adjusted accordingly. This closes #593 issue on GitHub.
2021-11-24Sending shared port to application prototype.Max Romanov1-43/+18
Application process started with shared port (and queue) already configured. But still waits for PORT_ACK message from router to start request processing (so-called "ready state"). Waiting for router confirmation is necessary. Otherwise, the application may produce response and send it to router before the router have the information about the application process. This is a subject of further optimizations.
2021-11-09Introducing application prototype processes.Tiago Natel de Moura1-68/+211
2021-11-05HTTP: removed surplus check for r->args is not NULL.Zhidao HONG1-2/+2
2021-10-28Moving request limit control to libunit.Max Romanov1-50/+5
Introducting application graceful stop. For now only used when application process reach request limit value. This closes #585 issue on GitHub.
2021-10-28Adding explicit app reference to nxt_router_app_port_release().Max Romanov1-11/+8
port->app field is not thread safe and should be used in main thread only. To release port after request processing, application reference should be obtained from corresponding request descriptor.
2021-08-17Added TLS session tickets support.Andrey Suvorov1-0/+4
2021-08-12Introduced the generic API nxt_buf_dummy_completion().Zhidao HONG1-11/+3
No functional changes.
2021-08-12Router: client IP address replacement.Oisin Canty1-1/+85
This commit introduces the replacement of the client address based on the value of a specified HTTP header. This is intended for use when Unit is placed behind a reverse proxy like nginx or a CDN. You must specify the source addresses of the trusted proxies. This can be accomplished with any valid IP pattern supported by Unit's match block: ["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"] The feature is configured per listener. The client address replacement functionality only operates when there is a source IP match and the specified header is present. Typically this would be an 'X-Forwarded-For' header. { "listeners": { "127.0.0.1:8080": { "client_ip": { "header": "X-Forwarded-For", "source": [ "10.0.0.0/8" ] }, "pass": "applications/my_app" }, } } If a request occurs and Unit receives a header like below: "X-Forwarded-For: 84.123.23.23" By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8. If Unit runs behind consecutive reverse proxies and receives a header similar to the following: "X-Forwarded-For: 84.123.23.23, 10.0.0.254" You will need to enable "recursive" checking, which walks the header from last address to first and chooses the first non-trusted address it finds. { "listeners": { "127.0.0.1:8080": { "client_ip": { "header": "X-Forwarded-For", "source": [ "10.0.0.0/8" ] "recursive": true, }, "pass": "applications/my_app" }, } } If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254 is also a trusted address so the client address will be replaced with 84.123.23.23. If all IP addresses in the header are trusted, the client address is set to the first address in the header: If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1", the client address will be replaced with 10.0.0.3.
2021-07-29Application restart introduced.Max Romanov1-41/+178
When processing a restart request, the router sends a QUIT message to all existing processes of the application. Then, a new shared application port is created to ensure that new requests won't be handled by the old processes of the application.
2021-07-24Router: split nxt_http_app_conf_t from nxt_http_action_t.Zhidao HONG1-9/+38
No functional changes.
2021-07-23Router: split nxt_http_static_conf_t from nxt_http_action_t.Zhidao HONG1-5/+5
No functional changes.
2021-07-21Enabling configure TLS sessions.Andrey Suvorov1-12/+36
To support TLS sessions, Unit uses the OpenSSL built-in session cache; the cache_size option defines the number sessions to store. To disable the feather, the option must be zero.
2021-07-19Router: fixing assertion on app thread port handle.Max Romanov1-8/+10
A new application thread port message can be processed in the router after the application is removed from the router. Assertion for this case is replaced by a condition to store the new thread port until receiving the stop notification from the application process.
2021-07-01Fixing multiple TLS-enabled listeners initialization.Max Romanov1-6/+5
Because of the incorrect 'last' field assignment, multiple listeners with a TLS certificate did not initialize properly, which caused a router crash while establishing a connection. Test with multiple TLS listeners added. The issue was introduced in the c548e46fe516 commit. This closes #561 issue on GitHub.
2021-05-26Enabling SSL_CTX configuration by using SSL_CONF_cmd().Andrey Suvorov1-52/+38
To perform various configuration operations on SSL_CTX, OpenSSL provides SSL_CONF_cmd(). Specifically, to configure ciphers for a listener, "CipherString" and "Ciphersuites" file commands are used: https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html This feature can be configured in the "tls/conf_commands" section.
2021-05-26Fixing crash during TLS connection shutdown.Andrey Suvorov1-0/+1
A crash was caused by an incorrect timer handler nxt_h1p_idle_timeout() if SSL_shutdown() returned SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE. The flag SSL_RECEIVED_SHUTDOWN is used to avoid getting SSL_ERROR_WANT_READ, so the server won't wait for a close notification from a client. For SSL_ERROR_WANT_WRITE, a correct timer handler is set up.
2021-05-25Fixing racing condition on listen socket close in router (v2).Max Romanov1-5/+5
This patch fixes a possible race between the nxt_router_conf_wait() and nxt_router_listen_socket_release() function calls and improves the 7f1b2eaa2d58 commit fix.
2021-05-17Fixing a crash after applying the wrong TLS configuration.Andrey Suvorov1-3/+3
When an invalid TLS configuration is applied (such as the conf_commands feature), nxt_cert_store_get() creates a buffer to send a certificate request to the main process and adds its default completion handler to an asynchronous queue to free the allocated buffer. However, if configuration fails, nxt_router_conf_error() removes the memory pool used to allocate the buffer, causing a crash when the completion handler is dispatched. Assertion "src/nxt_buf.c:208 assertion failed: data == b->parent" is triggered when is NXT_DEBUG enabled in the configure script. This patch uses a reference counter to retain the memory pool and redefines the completion handler to free the buffer before releasing the memory pool.
2021-05-17Fixing racing condition on listen socket close in router.Max Romanov1-10/+14
Listen socket is actually closed in the instant timer handler. This patch moves the "configuration has been applied" notification to the timer handler to avoid a situation when the user gets the response from the controller, but the listen socket is still open in the router.
2021-04-22Router: grouped app and share fields in nxt_http_action_t.Zhidao HONG1-1/+1
This is a prerequisite for further introduction of openat2() features. No functional changes.
2021-03-25Releasing shm buffers for large body requests.Max Romanov1-11/+4
This fixes memory and shm file descriptor leakage that occurred when a large request body was passed via shared memory. The leakage was caught with the "test_settings_body_buffer_size" test. The main condition is the "body_buffer_size" value exceeding 10 Mb (a shm segment). Thus, the router was forced to split the body into several shm segments, but these buffers were not freed because of dummy completion handlers.
2021-03-24Added ability to configure multiple certificates on a listener.Andrey Suvorov1-30/+93
The certificate is selected by matching the arriving SNI to the common name and the alternatives names. If no certificate matches the name, the first bundle in the array is chosen.
2021-03-02Fixing warnings on Solaris.Max Romanov1-1/+1
pthread_t on Solaris is an integer type with size not equal to pointer size. To avoid warnings, type casts to and from pointer needs to be done via uintptr_t type. This change originally proposed by Juraj Lutter <juraj@lutter.sk>.