DOC: commit a few old design thoughts files
These ones were design notes and ideas collected during the 1.5
development phase lying on my development machine. There might still
be some value in keeping them for future reference since they mention
certain corner cases.
diff --git a/doc/design-thoughts/binding-possibilities.txt b/doc/design-thoughts/binding-possibilities.txt
new file mode 100644
index 0000000..3f5e432
--- /dev/null
+++ b/doc/design-thoughts/binding-possibilities.txt
@@ -0,0 +1,167 @@
+2013/10/10 - possibilities for setting source and destination addresses
+
+
+When establishing a connection to a remote device, this device is designated
+as a target, which designates an entity defined in the configuration. A same
+target appears only once in a configuration, and multiple targets may share
+the same settings if needed.
+
+The following types of targets are currently supported :
+
+ - listener : all connections with this type of target come from clients ;
+ - server : connections to such targets are for "server" lines ;
+ - peer : connections to such target address "peer" lines in "peers"
+ sections ;
+ - proxy : these targets are used by "dispatch", "option transparent"
+ or "option http_proxy" statements.
+
+A connection might not be reused between two different targets, even if all
+parameters seem similar. One of the reason is that some parameters are specific
+to the target and are not easy or not cheap to compare (eg: bind to interface,
+mss, ...).
+
+A number of source and destination addresses may be set for a given target.
+
+ - listener :
+ - the "from" address:port is set by accept()
+
+ - the "to" address:port is set if conn_get_to_addr() is called
+
+ - peer :
+ - the "from" address:port is not set
+
+ - the "to" address:port is static and dependent only on the peer
+
+ - server :
+ - the "from" address may be set alone when "source" is used with
+ a forced IP address, or when "usesrc clientip" is used.
+
+ - the "from" port may be set only combined with the address when
+ "source" is used with IP:port, IP:port-range or "usesrc client" is
+ used. Note that in this case, both the address and the port may be
+ 0, meaning that the kernel will pick the address or port and that
+ the final value might not match the one explicitly set (eg:
+ important for logging).
+
+ - the "from" address may be forced from a header which implies it
+ may change between two consecutive requests on the same connection.
+
+ - the "to" address and port are set together when connecting to a
+ regular server, or by copying the client's IP address when
+ "server 0.0.0.0" is used. Note that the destination port may be
+ an offset applied to the original destination port.
+
+ - proxy :
+ - the "from" address may be set alone when "source" is used with a
+ forced IP address or when "usesrc clientip" is used.
+
+ - the "from" port may be set only combined with the address when
+ "source" is used with IP:port or with "usesrc client". There is
+ no ip:port range for a proxy as of now. Same comment applies as
+ above when port and/or address are 0.
+
+ - the "from" address may be forced from a header which implies it
+ may change between two consecutive requests on the same connection.
+
+ - the "to" address and port are set together, either by configuration
+ when "dispatch" is used, or dynamically when "transparent" is used
+ (1:1 with client connection) or "option http_proxy" is used, where
+ each client request may lead to a different destination address.
+
+
+At the moment, there are some limits in what might happen between multiple
+concurrent requests to a same target.
+
+ - peers parameter do not change, so no problem.
+
+ - server parameters may change in this way :
+ - a connection may require a source bound to an IP address found in a
+ header, which will fall back to the "source" settings if the address
+ is not found in this header. This means that the source address may
+ switch between a dynamically forced IP address and another forced
+ IP and/or port range.
+
+ - if the element is not found (eg: header), the remaining "forced"
+ source address might very well be empty (unset), so the connection
+ reuse is acceptable when switching in that direction.
+
+ - it is not possible to switch between client and clientip or any of
+ these and hdr_ip() because they're exclusive.
+
+ - using a source address/port belonging to a port range is compatible
+ with connection reuse because there is a single range per target, so
+ switching from a range to another range means we remain in the same
+ range.
+
+ - destination address may currently not change since the only possible
+ case for dynamic destination address setting is the transparent mode,
+ reproducing the client's destination address.
+
+ - proxy parameters may change in this way :
+ - a connection may require a source bound to an IP address found in a
+ header, which will fall back to the "source" settings if the address
+ is not found in this header. This means that the source address may
+ switch between a dynamically forced IP address and another forced
+ IP and/or port range.
+
+ - if the element is not found (eg: header), the remaining "forced"
+ source address might very well be empty (unset), so the connection
+ reuse is acceptable when switching in that direction.
+
+ - it is not possible to switch between client and clientip or any of
+ these and hdr_ip() because they're exclusive.
+
+ - proxies do not support port ranges at the moment.
+
+ - destination address might change in the case where "option http_proxy"
+ is used.
+
+So, for each source element (IP, port), we want to know :
+ - if the element was assigned by static configuration (eg: ":80")
+ - if the element was assigned from a connection-specific value (eg: usesrc clientip)
+ - if the element was assigned from a configuration-specific range (eg: 1024-65535)
+ - if the element was assigned from a request-specific value (eg: hdr_ip(xff))
+ - if the element was not assigned at all
+
+For the destination, we want to know :
+ - if the element was assigned by static configuration (eg: ":80")
+ - if the element was assigned from a connection-specific value (eg: transparent)
+ - if the element was assigned from a request-specific value (eg: http_proxy)
+
+We don't need to store the information about the origin of the dynamic value
+since we have the value itself. So in practice we have :
+ - default value, unknown (not yet checked with getsockname/getpeername)
+ - default value, known (check done)
+ - forced value (known)
+ - forced range (known)
+
+We can't do that on an ip:port basis because the port may be fixed regardless
+of the address and conversely.
+
+So that means :
+
+ enum {
+ CO_ADDR_NONE = 0, /* not set, unknown value */
+ CO_ADDR_KNOWN = 1, /* not set, known value */
+ CO_ADDR_FIXED = 2, /* fixed value, known */
+ CO_ADDR_RANGE = 3, /* from assigned range, known */
+ } conn_addr_values;
+
+ unsigned int new_l3_src_status:2;
+ unsigned int new_l4_src_status:2;
+ unsigned int new_l3_dst_status:2;
+ unsigned int new_l4_dst_status:2;
+
+ unsigned int cur_l3_src_status:2;
+ unsigned int cur_l4_src_status:2;
+ unsigned int cur_l3_dsp_status:2;
+ unsigned int cur_l4_dst_status:2;
+
+ unsigned int new_family:2;
+ unsigned int cur_family:2;
+
+Note: this obsoletes CO_FL_ADDR_FROM_SET and CO_FL_ADDR_TO_SET. These flags
+must be changed to individual l3+l4 checks ORed between old and new values,
+or better, set to cur only which will inherit new.
+
+In the connection, these values may be merged in the same word as err_code.
diff --git a/doc/design-thoughts/connection-reuse.txt b/doc/design-thoughts/connection-reuse.txt
new file mode 100644
index 0000000..0c90eb2
--- /dev/null
+++ b/doc/design-thoughts/connection-reuse.txt
@@ -0,0 +1,139 @@
+2013/10/17 - server connection management and reuse
+
+Current state
+-------------
+
+At the moment, a connection entity is needed to carry any address
+information. This means in the following situations, we need a server
+connection :
+
+- server is elected and the server's destination address is set
+
+- transparent mode is elected and the destination address is set from
+ the incoming connection
+
+- proxy mode is enabled, and the destination's address is set during
+ the parsing of the HTTP request
+
+- connection to the server fails and must be retried on the same
+ server using the same parameters, especially the destination
+ address (SN_ADDR_SET not removed)
+
+
+On the accepting side, we have further requirements :
+
+- allocate a clean connection without a stream interface
+
+- incrementally set the accepted connection's parameters without
+ clearing it, and keep track of what is set (eg: getsockname).
+
+- initialize a stream interface in established mode
+
+- attach the accepted connection to a stream interface
+
+
+This means several things :
+
+- the connection has to be allocated on the fly the first time it is
+ needed to store the source or destination address ;
+
+- the connection has to be attached to the stream interface at this
+ moment ;
+
+- it must be possible to incrementally set some settings on the
+ connection's addresses regardless of the connection's current state
+
+- the connection must not be released across connection retries ;
+
+- it must be possible to clear a connection's parameters for a
+ redispatch without having to detach/attach the connection ;
+
+- we need to allocate a connection without an existing stream interface
+
+So on the accept() side, it looks like this :
+
+ fd = accept();
+ conn = new_conn();
+ get_some_addr_info(&conn->addr);
+ ...
+ si = new_si();
+ si_attach_conn(si, conn);
+ si_set_state(si, SI_ST_EST);
+ ...
+ get_more_addr_info(&conn->addr);
+
+On the connect() side, it looks like this :
+
+ si = new_si();
+ while (!properly_connected) {
+ if (!(conn = si->end)) {
+ conn = new_conn();
+ conn_clear(conn);
+ si_attach_conn(si, conn);
+ }
+ else {
+ if (connected) {
+ f = conn->flags & CO_FL_XPRT_TRACKED;
+ conn->flags &= ~CO_FL_XPRT_TRACKED;
+ conn_close(conn);
+ conn->flags |= f;
+ }
+ if (!correct_dest)
+ conn_clear(conn);
+ }
+ set_some_addr_info(&conn->addr);
+ si_set_state(si, SI_ST_CON);
+ ...
+ set_more_addr_info(&conn->addr);
+ conn->connect();
+ if (must_retry) {
+ close_conn(conn);
+ }
+ }
+
+Note: we need to be able to set the control and transport protocols.
+On outgoing connections, this is set once we know the destination address.
+On incoming connections, this is set the earliest possible (once we know
+the source address).
+
+The problem analysed below was solved on 2013/10/22
+
+| ==> the real requirement is to know whether a connection is still valid or not
+| before deciding to close it. CO_FL_CONNECTED could be enough, though it
+| will not indicate connections that are still waiting for a connect to occur.
+| This combined with CO_FL_WAIT_L4_CONN and CO_FL_WAIT_L6_CONN should be OK.
+|
+| Alternatively, conn->xprt could be used for this, but needs some careful checks
+| (it's used by conn_full_close at least).
+|
+| Right now, conn_xprt_close() checks conn->xprt and sets it to NULL.
+| conn_full_close() also checks conn->xprt and sets it to NULL, except
+| that the check on ctrl is performed within xprt. So conn_xprt_close()
+| followed by conn_full_close() will not close the file descriptor.
+| Note that conn_xprt_close() is never called, maybe we should kill it ?
+|
+| Note: at the moment, it's problematic to leave conn->xprt to NULL before doing
+| xprt_init() because we might end up with a pending file descriptor. Or at
+| least with some transport not de-initialized. We might thus need
+| conn_xprt_close() when conn_xprt_init() fails.
+|
+| The fd should be conditionned by ->ctrl only, and the transport layer by ->xprt.
+|
+| - conn_prepare_ctrl(conn, ctrl)
+| - conn_prepare_xprt(conn, xprt)
+| - conn_prepare_data(conn, data)
+|
+| Note: conn_xprt_init() needs conn->xprt so it's not a problem to set it early.
+|
+| One problem might be with conn_xprt_close() not being able to know if xprt_init()
+| was called or not. That's where it might make sense to only set ->xprt during init.
+| Except that it does not fly with outgoing connections (xprt_init is called after
+| connect()).
+|
+| => currently conn_xprt_close() is only used by ssl_sock.c and decides whether
+| to do something based on ->xprt_ctx which is set by ->init() from xprt_init().
+| So there is nothing to worry about. We just need to restore conn_xprt_close()
+| and rely on ->ctrl to close the fd instead of ->xprt.
+|
+| => we have the same issue with conn_ctrl_close() : when is the fd supposed to be
+| valid ? On outgoing connections, the control is set much before the fd...
diff --git a/doc/design-thoughts/entities-v2.txt b/doc/design-thoughts/entities-v2.txt
new file mode 100644
index 0000000..8c9eb48
--- /dev/null
+++ b/doc/design-thoughts/entities-v2.txt
@@ -0,0 +1,276 @@
+2012/07/05 - Connection layering and sequencing
+
+
+An FD has a state :
+ - CLOSED
+ - READY
+ - ERROR (?)
+ - LISTEN (?)
+
+A connection has a state :
+ - CLOSED
+ - ACCEPTED
+ - CONNECTING
+ - ESTABLISHED
+ - ERROR
+
+A stream interface has a state :
+ - INI, REQ, QUE, TAR, ASS, CON, CER, EST, DIS, CLO
+
+Note that CON and CER might be replaced by EST if the connection state is used
+instead. CON might even be more suited than EST to indicate that a connection
+is known.
+
+
+si_shutw() must do :
+
+ data_shutw()
+ if (shutr) {
+ data_close()
+ ctrl_shutw()
+ ctrl_close()
+ }
+
+si_shutr() must do :
+ data_shutr()
+ if (shutw) {
+ data_close()
+ ctrl_shutr()
+ ctrl_close()
+ }
+
+Each of these steps may fail, in which case the step must be retained and the
+operations postponed in an asynchronous task.
+
+The first asynchronous data_shut() might already fail so it is mandatory to
+save the other side's status with the connection in order to let the async task
+know whether the 3 next steps must be performed.
+
+The connection (or perhaps the FD) needs to know :
+ - the desired close operations : DSHR, DSHW, CSHR, CSHW
+ - the completed close operations : DSHR, DSHW, CSHR, CSHW
+
+
+On the accept() side, we probably need to know :
+ - if a header is expected (eg: accept-proxy)
+ - if this header is still being waited for
+ => maybe both info might be combined into one bit
+
+ - if a data-layer accept() is expected
+ - if a data-layer accept() has been started
+ - if a data-layer accept() has been performed
+ => possibly 2 bits, to indicate the need to free()
+
+On the connect() side, we need to konw :
+ - the desire to send a header (eg: send-proxy)
+ - if this header has been sent
+ => maybe both info might be combined
+
+ - if a data-layer connect() is expected
+ - if a data-layer connect() has been started
+ - if a data-layer connect() has been completed
+ => possibly 2 bits, to indicate the need to free()
+
+On the response side, we also need to know :
+ - the desire to send a header (eg: health check response for monitor-net)
+ - if this header was sent
+ => might be the same as sending a header over a new connection
+
+Note: monitor-net has precedence over proxy proto and data layers. Same for
+ health mode.
+
+For multi-step operations, use 2 bits :
+ 00 = operation not desired, not performed
+ 10 = operation desired, not started
+ 11 = operation desired, started but not completed
+ 01 = operation desired, started and completed
+
+ => X != 00 ==> operation desired
+ X & 01 ==> operation at least started
+ X & 10 ==> operation not completed
+
+Note: no way to store status information for error reporting.
+
+Note2: it would be nice if "tcp-request connection" rules could work at the
+connection level, just after headers ! This means support for tracking stick
+tables, possibly not too much complicated.
+
+
+Proposal for incoming connection sequence :
+
+- accept()
+- if monitor-net matches or if mode health => try to send response
+- if accept-proxy, wait for proxy request
+- if tcp-request connection, process tcp rules and possibly keep the
+ pointer to stick-table
+- if SSL is enabled, switch to SSL handshake
+- then switch to DATA state and instantiate a session
+
+We just need a map of handshake handlers on the connection. They all manage the
+FD status themselves and set the callbacks themselves. If their work succeeds,
+they remove themselves from the list. If it fails, they remain subscribed and
+enable the required polling until they are woken up again or the timeout strikes.
+
+Identified handshake handlers for incoming connections :
+ - HH_HEALTH (tries to send OK and dies)
+ - HH_MONITOR_IN (matches src IP and adds/removes HH_SEND_OK/HH_SEND_HTTP_OK)
+ - HH_SEND_OK (tries to send "OK" and dies)
+ - HH_SEND_HTTP_OK (tries to send "HTTP/1.0 200 OK" and dies)
+ - HH_ACCEPT_PROXY (waits for PROXY line and parses it)
+ - HH_TCP_RULES (processes TCP rules)
+ - HH_SSL_HS (starts SSL handshake)
+ - HH_ACCEPT_SESSION (instanciates a session)
+
+Identified handshake handlers for outgoing connections :
+ - HH_SEND_PROXY (tries to build and send the PROXY line)
+ - HH_SSL_HS (starts SSL handshake)
+
+For the pollers, we could check that handshake handlers are not 0 and decide to
+call a generic connection handshake handler instead of usual callbacks. Problem
+is that pollers don't know connections, they know fds. So entities which manage
+handlers should update change the FD callbacks accordingly.
+
+With a bit of care, we could have :
+ - HH_SEND_LAST_CHUNK (sends the chunk pointed to by a pointer and dies)
+ => merges HEALTH, SEND_OK and SEND_HTTP_OK
+
+It sounds like the ctrl vs data state for the connection are per-direction
+(eg: support an async ctrl shutw while still reading data).
+
+Also support shutr/shutw status at L4/L7.
+
+In practice, what we really need is :
+
+shutdown(conn) =
+ conn.data.shut()
+ conn.ctrl.shut()
+ conn.fd.shut()
+
+close(conn) =
+ conn.data.close()
+ conn.ctrl.close()
+ conn.fd.close()
+
+With SSL over Remote TCP (RTCP + RSSL) to reach the server, we would have :
+
+ HTTP -> RTCP+RSSL connection <-> RTCP+RRAW connection -> TCP+SSL connection
+
+The connection has to be closed at 3 places after a successful response :
+ - DATA (RSSL over RTCP)
+ - CTRL (RTCP to close connection to server)
+ - SOCK (FD to close connection to second process)
+
+Externally, the connection is seen with very few flags :
+ - SHR
+ - SHW
+ - ERR
+
+We don't need a CLOSED flag as a connection must always be detached when it's closed.
+
+The internal status doesn't need to be exposed :
+ - FD allocated (Y/N)
+ - CTRL initialized (Y/N)
+ - CTRL connected (Y/N)
+ - CTRL handlers done (Y/N)
+ - CTRL failed (Y/N)
+ - CTRL shutr (Y/N)
+ - CTRL shutw (Y/N)
+ - DATA initialized (Y/N)
+ - DATA connected (Y/N)
+ - DATA handlers done (Y/N)
+ - DATA failed (Y/N)
+ - DATA shutr (Y/N)
+ - DATA shutw (Y/N)
+
+(note that having flags for operations needing to be completed might be easier)
+--------------
+
+Maybe we need to be able to call conn->fdset() and conn->fdclr() but it sounds
+very unlikely since the only functions manipulating this are in the code of
+the data/ctrl handlers.
+
+FDSET/FDCLR cannot be directly controlled by the stream interface since it also
+depends on the DATA layer (WANT_READ/WANT_WRITE).
+
+But FDSET/FDCLR is probably controlled by who owns the connection (eg: DATA).
+
+Example: an SSL conn relies on an FD. The buffer is full, and wants the conn to
+stop reading. It must not stop the FD itself. It is the read function which
+should notice that it has nothing to do with a read wake-up, which needs to
+disable reading.
+
+Conversely, when calling conn->chk_rcv(), the reader might get a WANT_READ or
+even WANT_WRITE and adjust the FDs accordingly.
+
+------------------------
+
+OK, the problem is simple : we don't manipulate the FD at the right level.
+We should have :
+ ->connect(), ->chk_snd(), ->chk_rcv(), ->shutw(), ->shutr() which are
+ called from the upper layer (buffer)
+ ->recv(), ->send(), called from the lower layer
+
+Note that the SHR is *reported* by lower layer but can be forced by upper
+layer. In this case it's like a delayed abort. The difficulty consists in
+knowing the output data were correctly read. Probably we'd need to drain
+incoming data past the active shutr().
+
+The only four purposes of the top-down shutr() call are :
+ - acknowledge a shut read report : could probably be done better
+ - read timeout => disable reading : it's a delayed abort. We want to
+ report that the buffer is SHR, maybe even the connection, but the
+ FD clearly isn't.
+ - read abort due to error on the other side or desire to close (eg:
+ http-server-close) : delayed abort
+ - complete abort
+
+The active shutr() is problematic as we can't disable reading if we expect some
+exchanges for data acknowledgement. We probably need to drain data only until
+the shutw() has been performed and ACKed.
+
+A connection shut down for read would behave like this :
+
+ 1) bidir exchanges
+
+ 2) shutr() => read_abort_pending=1
+
+ 3) drain input, still send output
+
+ 4) shutw()
+
+ 5) drain input, wait for read0 or ack(shutw)
+
+ 6) close()
+
+--------------------- 2012/07/05 -------------------
+
+Communications must be performed this way :
+
+ connection <-> channel <-> connection
+
+A channel is composed of flags and stats, and may store data in either a buffer
+or a pipe. We need low-layer operations between sockets and buffers or pipes.
+Right now we only support sockets, but later we might support remote sockets
+and maybe pipes or shared memory segments.
+
+So we need :
+
+ - raw_sock_to_buf() => receive raw data from socket into buffer
+ - raw_sock_to_pipe => receive raw data from socket into pipe (splice in)
+ - raw_sock_from_buf() => send raw data from buffer to socket
+ - raw_sock_from_pipe => send raw data from pipe to socket (splice out)
+
+ - ssl_sock_to_buf() => receive ssl data from socket into buffer
+ - ssl_sock_to_pipe => receive ssl data from socket into a pipe (NULL)
+ - ssl_sock_from_buf() => send ssl data from buffer to socket
+ - ssl_sock_from_pipe => send ssl data from pipe to socket (NULL)
+
+These functions should set such status flags :
+
+#define ERR_IN 0x01
+#define ERR_OUT 0x02
+#define SHUT_IN 0x04
+#define SHUT_OUT 0x08
+#define EMPTY_IN 0x10
+#define FULL_OUT 0x20
+
diff --git a/doc/internals/sequence.fig b/doc/internals/sequence.fig
new file mode 100644
index 0000000..295ace7
--- /dev/null
+++ b/doc/internals/sequence.fig
@@ -0,0 +1,123 @@
+#FIG 3.2 Produced by xfig version 3.2.5-alpha5
+Portrait
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+6 900 945 3015 1800
+6 1035 1215 3015 1800
+6 1035 1215 3015 1350
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 1035 1215 1620 1215 1620 1350 1035 1350 1035 1215
+4 0 0 50 -1 12 7 0.0000 4 90 1275 1710 1305 Standard settings\001
+-6
+6 1035 1440 2385 1575
+2 2 0 1 9 11 51 -1 20 0.000 0 0 -1 0 0 5
+ 1035 1440 1620 1440 1620 1575 1035 1575 1035 1440
+4 0 0 50 -1 12 7 0.0000 4 60 675 1710 1530 Rule sets\001
+-6
+6 1035 1665 2790 1800
+2 2 0 1 13 2 52 -1 20 0.000 0 0 -1 0 0 5
+ 1035 1665 1620 1665 1620 1800 1035 1800 1035 1665
+4 0 0 50 -1 12 7 0.0000 4 75 1050 1710 1755 HTTP mode only\001
+-6
+-6
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+ 945 1125 945 1800
+4 0 0 50 -1 17 10 0.0000 4 150 615 900 1080 Captions\001
+-6
+6 450 2250 3510 3195
+4 0 0 50 -1 16 10 0.0000 4 150 2865 450 2385 Each time a poller detects an activity on a\001
+4 0 0 50 -1 16 10 0.0000 4 150 2940 450 2580 listening socket, this sequence is executed.\001
+4 0 0 50 -1 16 10 0.0000 4 150 3000 450 2775 Note that stream_sock_accept() loops until\001
+4 0 0 50 -1 16 10 0.0000 4 150 3030 450 2970 accept() returns an error or tune.maxaccept\001
+4 0 0 50 -1 16 10 0.0000 4 150 1830 450 3165 loops have been executed.\001
+-6
+6 450 3375 3420 4275
+4 0 0 50 -1 16 10 0.0000 4 150 2535 450 3510 Once the session is started, function\001
+4 0 0 50 -1 16 10 0.0000 4 150 2880 450 3705 process_session() will be called once then\001
+4 0 0 50 -1 16 10 0.0000 4 150 2895 450 3900 each time an activity is detected on any of\001
+4 0 0 50 -1 16 10 0.0000 4 150 2955 450 4095 monitored file descriptors belonging to the\001
+4 0 0 50 -1 16 10 0.0000 4 120 555 450 4275 session.\001
+-6
+6 4230 945 6480 1125
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 4230 945 6345 945 6345 1125 4230 1125 4230 945
+4 0 0 50 -1 14 10 0.0000 4 105 2205 4275 1080 rate-limit sessions ?\001
+-6
+6 4455 1620 7065 1800
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 4455 1620 6885 1620 6885 1800 4455 1800 4455 1620
+4 0 0 50 -1 14 10 0.0000 4 135 2520 4521 1755 monitor-net (mode=tcp) ?\001
+-6
+6 4455 1845 7470 2025
+2 2 0 1 9 11 51 -1 20 0.000 0 0 -1 0 0 5
+ 4455 1845 7290 1845 7290 2025 4455 2025 4455 1845
+4 0 0 50 -1 14 10 0.0000 4 135 2940 4500 1980 tcp-request connection {...}\001
+-6
+6 4635 3195 7425 3735
+6 4680 3420 7380 3600
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 4680 3420 7200 3420 7200 3600 4680 3600 4680 3420
+4 0 0 50 -1 14 10 0.0000 4 135 2625 4725 3555 monitor-net (mode=http) ?\001
+-6
+2 2 0 1 13 2 52 -1 20 0.000 0 0 -1 0 0 5
+ 4635 3195 7425 3195 7425 3735 4635 3735 4635 3195
+4 0 0 50 -1 14 10 0.0000 4 135 1575 4725 3330 http_init_txn()\001
+-6
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 6885 1710 7200 1710 7200 675
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 7290 1935 7425 1935 7425 675
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 5850 2340 7650 2340 7650 675
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 7200 3510 7875 3510 7875 675
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2
+ 4140 675 4140 4275
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2
+ 4320 1575 4320 4275
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 5580 1260 6750 1260 6750 675
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2
+ 4545 2700 4545 4050
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 6345 1035 6525 1035 6525 675
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 4635 3825 6030 3825 6030 4005 4635 4005 4635 3825
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3
+ 6030 3915 7875 3915 7875 3510
+2 2 0 1 26 6 51 -1 20 0.000 0 0 -1 0 0 5
+ 4230 720 5895 720 5895 900 4230 900 4230 720
+2 1 0 1 0 7 51 -1 -1 4.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 5895 810 6300 810 6300 675
+4 1 0 51 -1 12 7 0.0000 4 60 375 7515 585 close\001
+4 1 0 51 -1 12 7 0.0000 4 75 1275 6930 2250 not enough memory\001
+4 0 0 51 -1 12 7 1.5708 4 60 1575 8010 2790 return "OK" and close\001
+4 0 0 50 -1 14 10 0.0000 4 135 1365 4275 1305 sock=accept()\001
+4 0 0 50 -1 14 10 0.0000 4 135 1890 4500 2655 frontend_accept(s)\001
+4 0 0 50 -1 14 10 0.0000 4 135 2100 4275 1530 session_accept(sock)\001
+4 0 0 50 -1 14 10 0.0000 4 105 1365 4500 2385 s=new session\001
+4 0 0 50 -1 14 10 0.0000 4 135 1575 4635 2880 prepare logs(s)\001
+4 0 0 50 -1 14 10 0.0000 4 135 2100 4635 3105 prepare socket(sock)\001
+4 0 0 50 -1 14 10 0.0000 4 105 1365 4680 3960 mode=health ?\001
+4 1 0 51 -1 12 7 0.0000 4 60 225 7605 3465 Yes\001
+4 1 0 51 -1 12 7 0.0000 4 60 225 7605 3870 Yes\001
+4 1 0 51 -1 12 7 0.0000 4 60 225 7065 1665 Yes\001
+4 1 0 51 -1 12 7 0.0000 4 75 300 6570 1215 Fail\001
+4 0 0 50 -1 14 10 0.0000 4 120 1680 4500 4230 start session(s)\001
+4 0 0 50 -1 14 10 0.0000 4 105 1785 4275 855 maxconn reached ?\001
+4 1 0 51 -1 12 7 0.0000 4 90 450 6525 585 ignore\001
+4 1 0 51 -1 12 7 0.0000 4 60 225 6120 765 Yes\001
+4 0 0 50 -1 17 12 0.0000 4 210 3000 450 630 Session instantiation sequence\001
+4 0 0 50 -1 14 10 0.0000 4 135 2100 4050 630 stream_sock_accept()\001