aboutsummaryrefslogtreecommitdiffstats
path: root/net/server_epoll.lua
Commit message (Collapse)AuthorAgeFilesLines
* net: refactor sslconfig to not depend on LuaSecJonas Schäfer2022-04-021-0/+6
| | | | | | | | | | | This now requires that the network backend exposes a tls_builder function, which essentially wraps the former util.sslconfig.new() function, passing a factory to create the eventual SSL context. That allows a net.server backend to pick whatever it likes as SSL context factory, as long as it understands the config table passed by the SSL config builder. Heck, a backend could even mock and replace the entire SSL config builder API.
* net: isolate LuaSec-specificsJonas Schäfer2022-04-271-8/+27
| | | | | | | | | | | | | | For this, various accessor functions are now provided directly on the sockets, which reach down into the LuaSec implementation to obtain the information. While this may seem of little gain at first, it hides the implementation detail of the LuaSec+LuaSocket combination that the actual socket and the TLS layer are separate objects. The net gain here is that an alternative implementation does not have to emulate that specific implementation detail and "only" has to expose LuaSec-compatible data structures on the new functions.
* net.server_epoll: Disable verbose mode by defaultKim Alvefur2022-02-121-2/+1
|
* util.id: Adjust entropy levels, with rationalesKim Alvefur2021-12-021-1/+1
| | | | | Modules using ids for logging should not need the now pretty large medium one.
* net.server_epoll: Ensure calls to :write() return somethingKim Alvefur2021-12-061-1/+2
| | | | | | | | | | With opportunistic writes enabled, writes can return what :onwritable() returns, thus :onwritable() should return something sensible at each spot. Should prevent whatever caused > Error writing to connection: (nil) Tho this was probably harmless
* net.server_epoll: Prevent loop attempting to send last data after closeKim Alvefur2021-11-301-0/+1
| | | | | | | | | | | | | | If the connection is closed by the peer, any buffered data is given a last chance to be sent (see f27b9319e0da). If the connection is Really closed, no attempt to write will occur, instead epoll will raise the error flag and :onreadable() will be invoked again, where it will try to :close() again for the same reason, thus looping until the connection somehow gets destroyed. By clearing the _connected flag, the second time it passes :onreadable() it should go directly to :destroy(), breaking the loop. Thanks Link Mauve for reporting
* net.server_epoll: Fix streaming downloads (thanks Menel)Kim Alvefur2021-11-191-1/+1
| | | | | | | | | | ff4e34c448a4 broke the way net.http.server streams downloads from disk because it made writes from the ondrain callback no longer reset the want-write flag, causing the download to halt. Writes from the predrain handler still must not trigger anything but additions to the buffer, since it is about to do all the socket writing already.
* net.server_epoll: Try harder to avoid reentrant opportunistic writesKim Alvefur2021-11-181-1/+4
| | | | | | Opportunistic writes sure do complicate things. This is especially intended to avoid opportunistic_writes from within the onpredrain callback.
* net.server_epoll: Process all queued events from epoll before timersKim Alvefur2021-10-211-2/+4
| | | | | | | Should call timers less frequently when many sockets are waiting for processing. May help under heavy load. Requested by Ge0rG
* net.server_epoll: Prevent starttls on direct TLS connectionsKim Alvefur2021-10-051-0/+1
| | | | | | | | | | This is not a pretty way to signal this... but it is the current API interface:inittls() is a new code path which did not go past the point in interface:starttls() where it set starttls to false, leading mod_tls to offer starttls on direct TLS connections Thanks Martin for discovering.
* net.server_epoll: Separate handling of "closed" from other errorsKim Alvefur2021-09-221-7/+7
| | | | | | The intent is to ensure 'ondisconnect' only gets called once, while giving buffered outgoing data a last chance to be delivered via the :close() path in case the connection was only shutdown in one direction.
* net.server_epoll: Skip attempt to flush write buffer when not connectedKim Alvefur2021-09-221-1/+1
| | | | | | | | Before 22825cb5dcd8 connection attempts that failed (e.g. connection refused) would be immediately destroyed. After, it would schedule another write cycle and then report 'ondisconnect' again when failing. Thanks Martin for reporting
* Merge 0.11->trunkKim Alvefur2021-09-201-0/+18
|\
| * net.server_epoll: Add a hard deadline on shutdown to extra-fix #1670Kim Alvefur2021-09-201-0/+12
| | | | | | | | Should ensure shutdown even if sockets somehow take a very long to get closed.
| * net.server_epoll: Close sockets added after shutdown signal (fixes #1670)Kim Alvefur2021-09-201-0/+6
| | | | | | | | | | This should ensure that sockets get closed even if they are added after the quit signal. Otherwise they may keep the server alive.
* | net.server_epoll: Fix indentation messed up in last mergeKim Alvefur2021-09-171-27/+27
| | | | | | | | Seems to have happened in 6427e2642976, probably because of Meld
* | net.server_epoll: Don't immediately destroy upon getting closed on readKim Alvefur2021-09-151-1/+1
| | | | | | | | | | | | | | | | | | | | Instead try to write any remaining buffered data. If the write attempt also fails with "closed" then there's nothing we can do and the socket is gone. This reverts what appears to be a mistakenly included part of c8aa66595072 Thanks jonas’ for noticing
* | net.server_epoll: Try to make port number related methods saneKim Alvefur2021-09-121-7/+11
| | | | | | | | | | | | | | | | | | Previously it was unclear whether "client port" was the port that the client connected to, or from. I hereby declare that the client port is the source port and the server port is the destination port. Incoming and outgoing connections can be distinguished by looking at the_server reference, which only incoming connections have.
* | net.server_epoll: Prevent removed timers from being readdedKim Alvefur2021-08-311-2/+12
| | | | | | | | | | | | | | | | | | In a case like this the timer would not be readded: addtimer(1, function(t, id) stop(id) return 1 end);
* | Merge 0.11->trunkKim Alvefur2021-08-311-29/+29
|\|
| * net.server_epoll: Fix to preserve ids of readded timersKim Alvefur2021-08-311-2/+2
| | | | | | | | | | | | | | Likely affected rescheduling but have no reports of this. After readding a timer, it would have been issued a new id. Rescheduling would use the previous id, thus not working.
| * net.server_epoll: Fix off-by-one in 2c559953ad41Kim Alvefur2021-01-101-1/+1
| | | | | | | | Thanks tmolitor
* | net.server_epoll: Split, attempt to clarify dirty noise messageKim Alvefur2021-08-161-1/+2
| | | | | | | | | | | | Only relevant because a "dirty" connection (with incoming data in LuaSocket's buffer) does not count as "readable" according to epoll, so special care needs to be taken to keep on processing it.
* | net.server: Add a predrain callaback just before writesKim Alvefur2021-08-161-0/+1
| | | | | | | | | | | | | | | | | | | | Allows sneaking in things in the write buffer just before it's sent to the network stack. For example ack requests, compression flushes or other things that make sense to send after stanzas or other things. This ensures any additional trailing data sent is included in the same write, and possibly the same TCP packet. Other methods used such as timers or nextTick might not have the same effect as it depends on scheduling.
* | net.server_epoll: Improve efficiency of opportunistic writesKim Alvefur2021-08-141-1/+3
| | | | | | | | | | | | | | | | | | Should prevent further opportunistic write attempts after the kernel buffers are full and stops accepting writes. When combined with `keep_buffers = false` it should stop it from repeatedly recreating the buffer table and concatenating it back into a string when there's a lot to write.
* | net.server_epoll: Fix traceback-causing typoKim Alvefur2021-07-181-1/+1
| | | | | | | | | | | | | | Caused "attempt to index a string value (local 'data')", but only if keep_buffers is set to false, which is not the default. Introduced in 917eca7be82b
* | net.server_epoll: Ensure timeouts match epoll flagsKim Alvefur2021-07-171-0/+6
| | | | | | | | | | Read and write timeouts should usually match whether we want to read or write.
* | net.server_epoll: Skip reset of read timeout when not readingKim Alvefur2021-07-171-1/+2
| | | | | | | | Should avoid rare but needless timer interactions
* | net.server_epoll: Reduce timer churn during TLS handshakeKim Alvefur2021-07-171-1/+1
| | | | | | | | | | Instead of removing and readding the timer, keep it and adjust it instead. Should reduce garbage production a bit.
* | net.server_epoll: Use only fatal "write" timeout during TLS negotiationKim Alvefur2021-07-161-3/+3
| | | | | | | | | | | | | | Only real difference between the read and write timeouts is that the former has a callback that allows the higher levels to keep the connection alive, while hitting the later is immediately fatal. We want the later behavior for TLS negotiation.
* | net.server_epoll: Optimize concatenation of exactly 2 buffer chunksKim Alvefur2021-07-161-1/+3
| | | | | | | | | | | | Saves a function call. I forget if I measured this kind of thing but IIRC infix concatenation is faster than a function call up to some number of items, but let's stop at 2 here.
* | net.server_epoll: Avoid allocating a buffer table for single writesKim Alvefur2021-07-161-11/+20
| | | | | | | | | | | | | | writebuffer is now string | { string } Saves the allocation of a buffer table until the second write, which could be rare, especially with opportunistic writes.
* | net.server_epoll: Optionally let go of buffersKim Alvefur2021-07-161-5/+17
| | | | | | | | | | Reusing an already existing buffer table would reduce garbage, but keeping it while idle is a waste.
* | net.server_epoll: Propagate returns from opportunistic writesKim Alvefur2021-07-161-3/+4
| | | | | | | | | | So that if a write ends up writing directly to the socket, it gets the actual return value
* | net.server_epoll: Set minimum wait time to 1ms, matching epollKim Alvefur2021-07-151-1/+1
| | | | | | | | | | | | | | | | | | | | A timeout value less than 0.001 gets turned into zero on the C side, so epoll_wait() returns instantly and essentially busy-loops up to 1ms, e.g. when a timer event ends up scheduled (0, 0.001)ms into the future. Unsure if this has much effect in practice, but it may waste a small amount of CPU time. How much would depend on how often this ends up happening and how fast the CPU gets trough main loop iterations.
* | net.server_epoll: Add setting for disabling the Nagle algorithmKim Alvefur2021-07-141-0/+6
| | | | | | | | Nagle increases latency and is the bane of all networking!
* | net.server_epoll: Support setting keepalive idle timeKim Alvefur2021-07-141-0/+3
| | | | | | | | | | | | | | Activated by setting config.tcp_keepalive to a number, in seconds. Defaults to 2h. Depends on LuaSocket support for this option.
* | net.server_epoll: Add way to enable TCP keeplives on all connectionsKim Alvefur2021-07-141-1/+6
| | | | | | | | | | | | In case one wishes to enable this for all connections, not just c2s (not Direct TLS ones, because LuaSec) and s2s. Unclear what use these are, since they kick in after 2 hours of idle time.
* | net.server_epoll: Add an (empty) method for setting socket optionsKim Alvefur2021-07-141-0/+6
| |
* | net.server_epoll: Log failures to set socket optionsKim Alvefur2021-07-141-2/+8
| | | | | | | | | | | | | | | | | | Good to know if it fails, especially since the return value doesn't seem to be checked anywhere. Since LuaSec-wrapped sockets don't expose the setoption method, this will likely show when mod_c2s tries to enable keepalives on direct tls connections.
* | net.server_epoll: Call onconnect immediately after TLS handshake completionKim Alvefur2021-07-131-1/+2
| | | | | | | | | | | | Skips a roundtrip through the main loop in case client-first data is available already, if not then :onreadable() will set the appropriate timeout.
* | net.server_epoll: Refactor immediate TLS handshake startKim Alvefur2021-07-131-6/+5
| |
* | net.server_epoll: Keep socket registered in epoll trough TLS wrappingKim Alvefur2021-07-131-2/+1
| | | | | | | | | | There's the theory that the socket isn't the same before/after wrap(), but since epoll operates on FD numbers this shouldn't matter.
* | net.server_epoll: Use TLS handshake timeout after initiating handshakeKim Alvefur2021-07-131-1/+3
| | | | | | | | The :init() method sets a different timeout than the TLS related methods.
* | net.server_epoll: Start TLS handshake immediately on newly accepted connectionsKim Alvefur2021-07-131-0/+1
| | | | | | | | | | | | Since TLS is a client-first protocol there is a chance that the ClientHello message is available already. TLS Fast Open and/or the TCP_DEFER_ACCEPT socket option would increase that chance.
* | net.server_epoll: Factor out TLS initialization into a methodKim Alvefur2021-07-131-45/+51
| | | | | | | | | | | | | | | | | | | | | | So there's :startls(), :inittls() and :tlshandshake() :starttls() prepares for plain -> TLS upgrade and ensures that the (unencrypted) write buffer is drained before proceeding. :inittls() wraps the connection and does things like SNI, DANE etc. :tlshandshake() steps the TLS negotiation forward until it completes
* | net.server_epoll: Fix typoKim Alvefur2021-07-131-1/+1
| |
* | net.server_epoll: Prevent stack overflow of opportunistic writesKim Alvefur2021-07-111-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | net.http.files serving a big enough file on a fast enough connection with opportunistic_writes enabled could trigger a stack overflow through repeatedly serving more data that immediately gets sent, draining the buffer and triggering more data to be sent. This also blocked the server on a single task until completion or an error. This change prevents nested opportunistic writes, which should prevent the stack overflow, at the cost of reduced download speed, but this is unlikely to be noticeable outside of Gbit networks. Speed at the cost of blocking other processing is not worth it, especially with the risk of stack overflow.
* | net.server_epoll: Immediately attempt to read from newly accepted connectionsKim Alvefur2021-07-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | This may speed up client-first protocols (e.g. XMPP, HTTP and TLS) when the first client data already arrived by the time we accept() it. If LuaSocket supported TCP_DEFER_ACCEPT we could use that to further increase the chance that there's already data to handle. In case no data has arrived, no harm should be done, :onreadable would simply set the read timeout and we'll get back to it once there is something to handle.
* | net.server_epoll: Separate handling of new incoming and outgoing connectionsKim Alvefur2021-07-081-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | The :init method is more suited for new outgoing connections, which is why it uses the connect_timeout setting. Depending on whether a newly accepted connection is to a Direct TLS port or not, it should be handled differently, and was already. The :starttls method sets up timeouts on its own, so the one set in :init was not needed. Newly accepted plain TCP connections don't need a write timeout set, a read timeout is enough.