Commit Graph

893 Commits

Author SHA1 Message Date
Willy Tarreau
2e10f5a759 MINOR: checks: replace state DISABLED with CONFIGURED and ENABLED
At the moment, health checks and agent checks are tied : no agent
check is emitted if no health check is enabled. Other parameters
are considered in the condition for letting checks run. It will
help us selectively enable checks (agent and regular checks) to be
know whether they're enabled/disabled and configured or not. Now
we can already emit an error when trying to enable an unconfigured
agent.
2013-12-14 16:02:19 +01:00
Willy Tarreau
2c115e5047 MINOR: checks: rename the state flags
The flag CHK_STATE_RUNNING is misleading as one may believe it means
the state is enabled (just like SRV_RUNNING). Let's rename these two
flags CHK_ST_INPROGRESS and CHK_ST_DISABLED.
2013-12-14 16:02:19 +01:00
Willy Tarreau
6aaa1b87cf MINOR: checks: use an enum instead of flags to report a check result
We used to have up to 4 sets of flags which were almost all exclusive
to report a check result. And the names were inherited from the old
server states, adding to the confusion. Let's replace that with an
enum handling only the possible combinations :

   SRV_CHK_UNKNOWN                   => CHK_RES_UNKNOWN
   SRV_CHK_FAILED                    => CHK_RES_FAILED
   SRV_CHK_PASSED                    => CHK_RES_PASSED
   SRV_CHK_PASSED | SRV_CHK_DISABLE  => CHK_RES_CONDPASS
2013-12-14 16:02:19 +01:00
Willy Tarreau
8e85ad5211 REORG: checks: retrieve the check-specific defines from server.h to checks.h
After the move of checks from servers to autonomous checks, we need a
massive cleanup and reordering as it's becoming increasingly difficult
to find the definitions of types and enums.

Nothing was changed, blocks were just moved.
2013-12-14 16:02:18 +01:00
Willy Tarreau
1a53a3af13 MINOR: checks: improve handling of the servers tracking chain
Server tracking uses the same "tracknext" list for servers tracking
another one and for the servers being tracked. This caused an issue
which was fixed by commit f39c71c ([CRITICAL] fix server state tracking:
it was O(n!) instead of O(n)), consisting in ensuring that a server is
being checked before walking down the list, so that we don't propagate
the up/down information via servers being part of the track chain.

But the root cause is the fact that all servers share the same list.
The correct solution consists in having a list head for the tracked
servers and a list of next tracking servers. This simplifies the
propagation logic, especially for the case where status changes might
be passed to individual servers via the CLI.
2013-12-14 16:02:18 +01:00
Thierry FOURNIER
c0e0d7b7cf MEDIUM: map: dynamic manipulation of maps
This patch adds map manipulation commands to the socket interface.

add map <map> <key> <value>
  Add the value <value> in the map <map>, at the entry corresponding to
  the key <key>. This command does not verify if the entry already
  exists.

clear map <map>
  Remove entries from the map <map>

del map <map> <key>
  Delete all the map entries corresponding to the <key> value in the map
  <map>.

set map <map> <key> <value>
  Modify the value corresponding to each key <key> in a map <map>. The
  new value is <value>.

show map [<map>]
  Dump info about map converters. Without argument, the list of all
  available maps are returned. If a <map> is specified, is content is
  dumped.
2013-12-12 15:58:30 +01:00
Thierry FOURNIER
0b2fe4a5cd MINOR: pattern: add support for compiling patterns for lookups
With this patch, patterns can be compiled for two modes :
  - match
  - lookup

The match mode is used for example in ACLs or maps. The lookup mode
is used to lookup a key for pattern maintenance. For example, looking
up a network is different from looking up one address belonging to
this network.

A special case is made for regex. In lookup mode they return the input
regex string and do not compile the regex.
2013-12-12 15:44:02 +01:00
Thierry FOURNIER
799c042daa MINOR: regex: Change the struct containing regex
This change permits to remove the typedef. The original regex structs
are set in haproxy's struct.
2013-12-12 15:42:58 +01:00
Thierry FOURNIER
7148ce6ef4 MEDIUM: pattern: Extract the index process from the pat_parse_*() functions
Now, the pat_parse_*() functions parses the incoming data. The input
"pattern" struct can be preallocated. If the parser needs to add some
buffers, it allocates memory.

The function pattern_register() runs the call to the parser, process
the key indexation and associate the "sample_storage" used by maps.
2013-12-12 15:42:11 +01:00
Thierry FOURNIER
e3ded59706 MEDIUM: acl: Last patch change the output type
This patch remove the compatibility check from the input type and the
match method. Now, it checks if a casts from the input type to output
type exists and the pattern_exec_match() function apply casts before
each pattern matching.
2013-12-12 15:42:11 +01:00
Thierry FOURNIER
cc0e0b3dbb MINOR: pattern: Each pattern sets the expected input type
This is used later for increasing the compability with incoming
sample types. When multiple compatible types are supported, one
is arbitrarily used (eg: UINT).
2013-12-12 11:07:33 +01:00
Willy Tarreau
9ba813cd69 CLEANUP: check: server port is unsigned
Baptiste Assmann reported some confusing printf() output of the server
port since it's declared signed. Better turn it to unsigned.

There's no need to backport this, it's only used in 16-bit places.
2013-12-10 23:32:30 +01:00
Willy Tarreau
2d400bb931 MINOR: stream_interface: add reporting of ressouce allocation errors
SSL and keep-alive will need to be able to fail on allocation errors,
and the stream interface did not allow to report such a cause. The flag
will then be "RC" as already documented.
2013-12-09 17:12:18 +01:00
Willy Tarreau
05efc0f33a DIET/MINOR: task: reduce struct task size by 8 bytes
Just by reordering the struct task, we could shrink it by 8 bytes from
120 to 112 bytes. A careful reordering allowed each part to be located
closer to the hot parts it's used with, resulting in another performance
increase of about 0.5%.
2013-12-09 16:06:22 +01:00
Willy Tarreau
5735d7e2a2 MINOR: http: use an enum for the auth method in http_auth_data
This method now takes a single byte, with 7 bytes left to be used
after it. No savings were gained but at least now we have an enum.
2013-12-09 16:06:22 +01:00
Willy Tarreau
3770f23a3a MINOR: http: switch the http state to an enum
This reduces its size which is not reused by anything else. However it
will significantly improve the debugger's output since we'll now get
real state values.

The default case had to be enabled in the parsers because gcc tries
to optimize the switch/case and noticed some values were missing from
the enums and emitted a warning.
2013-12-09 16:06:22 +01:00
Willy Tarreau
c8987b3664 DIET/MINOR: http: reduce the size of struct http_txn by 8 bytes
Here again we had some oversized and misaligned entries. The method
and the status don't need 4 bytes each, and there was a hole after
the status that does not exist anymore. That's 8 additional bytes
saved from http_txn and as much for the session.

Also some fields were slightly moved to present better memory access
patterns resulting in a steady 0.5% performance increase.
2013-12-09 16:06:22 +01:00
Willy Tarreau
721854f0ac DIET/MINOR: stream-int: rearrange a few fields in struct stream_interface to save 8 bytes
The current and previous states are now packed enums instead of ints. This will
also help in gdb. The flags have been turned to 16-bit instead of 32 since only
10 are used. This resulted in saving 8 bytes per streamm interface, or 16 per
session.
2013-12-09 16:06:21 +01:00
Willy Tarreau
2518db4bfa DIET/MINOR: session: reduce the struct session size by 8 bytes
Move uniq_id upper to fill a hole and kill one. Another hole remains
after store_count.
2013-12-09 16:06:21 +01:00
Willy Tarreau
8379c17adf DIET/MINOR: proxy: rearrange a few fields in struct proxy to save 16 bytes
Turn the proxy state to a packed enum (1 char), same for the proxy mode,
and store the capabitilies as a char. These 3 ints can now fill the hole
after obj_type and save 8 bytes in the proxy struct. Moving the maxconn
value just after, which is frequently accessed and was in a block of 3
ints saved another 8 bytes.
2013-12-09 16:06:21 +01:00
Willy Tarreau
f6502c5062 DIET/MINOR: listener: rearrange a few fields in struct listener to save 16 bytes
Pack the listener state to 1 char, store it as an enum instead of an
int (more gdb-friendly), and move a few fields around to fill holes.

The <nice> field can only be -1024..1024 so it was stored as a signed
short and completes well with obj_type and li_state.

Doing this has reduced the struct listener from 376 to 360 bytes (4.2%).
2013-12-09 16:06:21 +01:00
Willy Tarreau
ad5281ca04 DIET/MINOR: connection: rearrange a few fields to save 8 bytes in the struct
By moving the error code to 8 bits the send_proxy_ofs to 16 bits, and
moving them just after the obj_type, we can save 8 bytes in the struct
connection, down from 328 to 320.
2013-12-09 16:06:15 +01:00
Willy Tarreau
939478d04d DIET/MINOR: obj: pack the obj_type enum to 8 bits
Taking 32-bit in each struct just to store an obj_type is a waste
considering the very small amount of possible values. Let's force
it to be as small as possible (1 char) and we'll be able to move
some structs around to save some space.
2013-12-09 16:06:08 +01:00
Willy Tarreau
0a23bcb8be MAJOR: stream-interface: dynamically allocate the applet context
From now on, a call to stream_int_register_handler() causes a call
to si_alloc_appctx() and returns an initialized appctx for the
current stream interface. If one was previously allocated, it is
released. If the stream interface was attached to a connection, it
is released as well.

The appctx are allocated from the same pools as the connections, because
they're substantially smaller in size, and we can't have both a connection
and an appctx on an interface at any moment.

In case of memory shortage, the call may return NULL, which is already
handled by all consumers of stream_int_register_handler().

The field appctx was removed from the stream interface since we only
rely on the endpoint now. On 32-bit, the stream_interface size went down
from 108 to 44 bytes. On 64-bit, it went down from 144 to 64 bytes. This
represents a memory saving of 160 bytes per session.

It seems that a later improvement could be to move the call to
stream_int_register_handler() to session.c for most cases.
2013-12-09 15:40:23 +01:00
Willy Tarreau
57cd3e46b9 MEDIUM: connection: merge the send_proxy and local_send_proxy calls
We used to have two very similar functions for sending a PROXY protocol
line header. The reason is that the default one relies on the stream
interface to retrieve the other end's address, while the "local" one
performs a local address lookup and sends that instead (used by health
checks).

Now that the send_proxy_ofs is stored in the connection and not the
stream interface, we can make the local_send_proxy rely on it and
support partial sends. This also simplifies the code by removing the
local_send_proxy function, making health checks use send_proxy_ofs,
resulting in the removal of the CO_FL_LOCAL_SPROXY flag, and the
associated test in the connection handler. The other flag,
CO_FL_SI_SEND_PROXY was renamed without the "SI" part so that it
is clear that it is not dedicated anymore to a usage with a stream
interface.
2013-12-09 15:40:23 +01:00
Willy Tarreau
b8020cefed MEDIUM: connection: move the send_proxy offset to the connection
Till now the send_proxy_ofs field remained in the stream interface,
but since the dynamic allocation of the connection, it makes a lot
of sense to move that into the connection instead of the stream
interface, since it will not be statically allocated for each
session.

Also, it turns out that moving it to the connection fils an alignment
hole on 64 bit architectures so it does not consume more memory, and
removing it from the stream interface was an opportunity to correctly
reorder fields and reduce the stream interface's size from 160 to 144
bytes (-10%). This is 32 bytes saved per session.
2013-12-09 15:40:23 +01:00
Willy Tarreau
32e3c6a607 MAJOR: stream interface: dynamically allocate the outgoing connection
The outgoing connection is now allocated dynamically upon the first attempt
to touch the connection's source or destination address. If this allocation
fails, we fail on SN_ERR_RESOURCE.

As we didn't use si->conn anymore, it was removed. The endpoints are released
upon session_free(), on the error path, and upon a new transaction. That way
we are able to carry the existing server's address across retries.

The stream interfaces are not initialized anymore before session_complete(),
so we could even think about allocating them dynamically as well, though
that would not provide much savings.

The session initialization now makes use of conn_new()/conn_free(). This
slightly simplifies the code and makes it more logical. The connection
initialization code is now shorter by about 120 bytes because it's done
at once, allowing the compiler to remove all redundant initializations.

The si_attach_applet() function now takes care of first detaching the
existing endpoint, and it is called from stream_int_register_handler(),
so we can safely remove the calls to si_release_endpoint() in the
application code around this call.

A call to si_detach() was made upon stream_int_unregister_handler() to
ensure we always free the allocated connection if one was allocated in
parallel to setting an applet (eg: detect HTTP proxy while proceeding
with stats maybe).
2013-12-09 15:40:23 +01:00
Willy Tarreau
f79c8171b2 MAJOR: connection: add two new flags to indicate readiness of control/transport
Currently the control and transport layers of a connection are supposed
to be initialized when their respective pointers are not NULL. This will
not work anymore when we plan to reuse connections, because there is an
asymmetry between the accept() side and the connect() side :

  - on accept() side, the fd is set first, then the ctrl layer then the
    transport layer ; upon error, they must be undone in the reverse order,
    then the FD must be closed. The FD must not be deleted if the control
    layer was not yet initialized ;

  - on the connect() side, the fd is set last and there is no reliable way
    to know if it has been initialized or not. In practice it's initialized
    to -1 first but this is hackish and supposes that local FDs only will
    be used forever. Also, there are even less solutions for keeping trace
    of the transport layer's state.

Also it is possible to support delayed close() when something (eg: logs)
tracks some information requiring the transport and/or control layers,
making it even more difficult to clean them.

So the proposed solution is to add two flags to the connection :

  - CO_FL_CTRL_READY is set when the control layer is initialized (fd_insert)
    and cleared after it's released (fd_delete).

  - CO_FL_XPRT_READY is set when the control layer is initialized (xprt->init)
    and cleared after it's released (xprt->close).

The functions have been adapted to rely on this and not on the pointers
anymore. conn_xprt_close() was unused and dangerous : it did not close
the control layer (eg: the socket itself) but still marks the transport
layer as closed, preventing any future call to conn_full_close() from
finishing the job.

The problem comes from conn_full_close() in fact. It needs to close the
xprt and ctrl layers independantly. After that we're still having an issue :
we don't know based on ->ctrl alone whether the fd was registered or not.
For this we use the two new flags CO_FL_XPRT_READY and CO_FL_CTRL_READY. We
now rely on this and not on conn->xprt nor conn->ctrl anymore to decide what
remains to be done on the connection.

In order not to miss some flag assignments, we introduce conn_ctrl_init()
to initialize the control layer, register the fd using fd_insert() and set
the flag, and conn_ctrl_close() which unregisters the fd and removes the
flag, but only if the transport layer was closed.

Similarly, at the transport layer, conn_xprt_init() calls ->init and sets
the flag, while conn_xprt_close() checks the flag, calls ->close and clears
the flag, regardless xprt_ctx or xprt_st. This also ensures that the ->init
and the ->close functions are called only once each and in the correct order.
Note that conn_xprt_close() does nothing if the transport layer is still
tracked.

conn_full_close() now simply calls conn_xprt_close() then conn_full_close()
in turn, which do nothing if CO_FL_XPRT_TRACKED is set.

In order to handle the error path, we also provide conn_force_close() which
ignores CO_FL_XPRT_TRACKED and closes the transport and the control layers
in turns. All relevant instances of fd_delete() have been replaced with
conn_force_close(). Now we always know what state the connection is in and
we can expect to split its initialization.
2013-12-09 15:40:23 +01:00
Willy Tarreau
f8a49eab4f MEDIUM: session: attach incoming connection to target on embryonic sessions
In order to reduce the dependency over stream-interfaces, we now
attach the incoming connection to the embryonic session's target
instead of the stream-interface's connection. This means we won't
need to initialize stream interfaces anymore after we implement
dynamic connection allocation. The session's target is reset to
NULL after the session has been converted to a complete session.
2013-12-09 15:40:22 +01:00
Willy Tarreau
b363a1f469 MAJOR: stream-int: stop using si->conn and use si->end instead
The connection will only remain there as a pre-allocated entity whose
goal is to be placed in ->end when establishing an outgoing connection.
All connection initialization can be made on this connection, but all
information retrieved should be applied to the end point only.

This change is huge because there were many users of si->conn. Now the
only users are those who initialize the new connection. The difficulty
appears in a few places such as backend.c, proto_http.c, peers.c where
si->conn is used to hold the connection's target address before assigning
the connection to the stream interface. This is why we have to keep
si->conn for now. A future improvement might consist in dynamically
allocating the connection when it is needed.
2013-12-09 15:40:22 +01:00
Willy Tarreau
4a59f2f954 MAJOR: stream interface: remove the ->release function pointer
Since last commit, we now have a pointer to the applet in the
applet context. So we don't need the si->release function pointer
anymore, it can be extracted from applet->applet.release. At many
places, the ->release function was still tested for real connections
while it is only limited to applets, so most of them were simply
removed. For the remaining valid uses, a new inline function
si_applet_release() was added to simplify the check and the call.
2013-12-09 15:40:22 +01:00
Willy Tarreau
48099c7a07 MEDIUM: stream-interface: set the pointer to the applet into the applet context
In preparation for a later move of all the applet context outside of the
stream interface, we'll need to have access to the applet itself from the
context. Let's have a pointer to it inside the context.
2013-12-09 15:40:22 +01:00
Willy Tarreau
7d67d7b9e5 MINOR: stream-int: add a new pointer to the end point
The end point will correspond to either an applet context or a connection,
depending on the object type. For now the pointer remains null.
2013-12-09 15:40:22 +01:00
Willy Tarreau
9b6c2c721e MINOR: stream-int: rename ->applet to ->appctx
Since this is the applet context, call it ->appctx to avoid the confusion
with the pointer to the applet. Many places were changed but it's only a
renaming.
2013-12-09 15:40:22 +01:00
Willy Tarreau
0788f47cc1 MINOR: obj: introduce a new type appctx
The object type was added to "struct appctx". The purpose will be
to identify an appctx when the applet context is detached from the
stream interface. For now, it's still attached, so this patch only
adds the new type and does not replace its use.
2013-12-09 15:40:22 +01:00
Willy Tarreau
452d3bb0c4 MINOR: stream-interface: move the applet context to its own struct
In preparation of making the applet context dynamically allocatable,
we create a "struct appctx". Nothing else was changed, it's the same
struct as the one which was in the stream interface.
2013-12-09 15:40:22 +01:00
Willy Tarreau
f4acee332b MEDIUM: stream interface: move the peers' ptr into the applet context
A long time ago when peers were introduced, there was no applet nor
applet context. Applet contexts were introduced but the peers still
did not make use of them and the "ptr" pointer remains present in
every stream interface in addition to the other contexts.

Simply move this pointer to its own location in the context.

Note that this pointer is still a void* because its type and contents
varies depending on the peers session state. Probably that this could
be cleaned up in the future given that all other contexts already store
much more than a single pointer.
2013-12-09 15:40:22 +01:00
Willy Tarreau
51c2184755 MINOR: connection: add a field to store an object type
This will soon be used to differenciate connections from applet
contexts. Object type "connection" has also been added.
2013-12-09 15:40:22 +01:00
Willy Tarreau
66337a0784 MINOR: obj: provide a safe and an unsafe access to pointed objects
Most of the times, the caller of objt_<type>(ptr) will know that <ptr>
is valid and of the correct type (eg: in an "if" condition). Let's provide
an unsafe variant that does not perform the check again for these usages.
The new functions are called "__objt_<type>".
2013-12-09 15:40:22 +01:00
Willy Tarreau
6fe1541285 MINOR: stream-int: make the shutr/shutw functions void
This is to be more consistent with the other functions. The only
reason why these functions used to return a value was to let the
caller adjust polling by itself, but now their only callers were
the si_shutr()/si_shutw() inline functions. Now these functions
do not depend anymore on the connection.

These connection variant of these functions now call
conn_data_stop_recv()/conn_data_stop_send() before returning order
not to require a return code anymore. The applet version does not
need this at all.
2013-12-09 15:40:22 +01:00
Willy Tarreau
8b3d7dfd7c MEDIUM: stream-int: split the shutr/shutw functions between applet and conn
These functions induce a lot of ifs everywhere because they consider two
different cases, one which is where the connection exists and has a file
descriptor, and the other one which is the default case where at most an
applet has to be notified.

Let's have them in si_ops and automatically decide which one to use.

The connection shutdown sequence has been slightly simplified, and we
now clear the flags at the end.

Also we remove SHUTR_NOW after a shutw with nolinger, as it's cleaner
not to keep it.
2013-12-09 15:40:22 +01:00
Willy Tarreau
9f68148321 MEDIUM: peers: don't rely on conn->xprt_ctx anymore
We make the peers code use applet->ptr instead of conn->xprt_ctx to
store the pointer to the current peer. That way it does not depend
on a connection anymore.
2013-12-09 15:40:21 +01:00
Willy Tarreau
a94d2d7653 MEDIUM: stats: don't use conn->xprt_st anymore
We're trying to move the applets out of the struct connection. So
let's remove the dependence on xprt_st and introduce si->applet.st2
to store the missing contextual data instead.
2013-12-09 15:40:21 +01:00
Willy Tarreau
08382955fe CLEANUP: stream_interface: remove unused field err_loc
This field was still fed with a pointer to the server that caught an
error but was not used anymore. Let's remove it.
2013-12-09 15:40:21 +01:00
Willy Tarreau
37e340ce4b BUG/MEDIUM: stick: completely remove the unused flag from the store entries
The store[] array in the session holds a flag which probably aimed to
differenciate store entries learned from the request from those learned
from the response, and allowing responses to overwrite only the request
ones (eg: have a server set a response cookie which overwrites the request
one).

But this flag is set when a response data is stored, and is never cleared.
So in practice, haproxy always runs with this flag set, meaning that
responses prevent themselves from overriding the request data.

It is desirable anyway to keep the ability not to override data, because
the override is performed only based on the table and not on the key, so
that would mean that it would be impossible to retrieve two different
keys to store into a same table. For example, if a client sets a cookie
and a server another one, both need to be updated in the table in the
proper order. This is especially true when multiple keys may be tracked
on each side into the same table (eg: list of IP addresses in a header).

So the correct fix which also maintains the current behaviour consists in
simply removing this flag and never try to optimize for the overwrite case.

This fix also has the benefit of significantly reducing the session size,
by 64 bytes due to alignment issues caused by this flag!

The bug has been there forever (since 1.4-dev7), so a backport to 1.4
would be appropriate.
2013-12-06 23:14:53 +01:00
Willy Tarreau
98aec9ff47 BUG/MINOR: checks: tcp-check actions are enums, not flags
In recent commit 5ecb77f (MEDIUM: checks: add send/expect tcp based check),
bitfields were mistakenly used at some places for the actions. Fortunately,
the only two actions right now are 1 and 2 so they don't share any bit in
common and the bug has no impact.

No backport is needed.
2013-12-06 16:16:41 +01:00
Baptiste Assmann
5ecb77f4c7 MEDIUM: checks: add send/expect tcp based check
This is a generic health check which can be used to match a
banner or send a request and analyse a server response.
It works in a send/expect ways and many exchange can be done between
HAProxy and a server to decide the server status, making HAProxy able to
speak the server's protocol.

It can send arbitrary regular or binary strings and match content as a
regular or binary string or a regex.

Signed-off-by: Baptiste Assmann <bedis9@gmail.com>
2013-12-06 11:50:47 +01:00
Thierry FOURNIER
0ffe78cfe3 MEDIUM: map: merge identical maps
This patch permits to use the same struct pattern for two indentical maps.
This permits to preserve memory, and permits to update only one
"struct pattern" when the dynamic map update is supported.
2013-12-06 11:40:53 +01:00
Thierry FOURNIER
275db69c07 BUG/MINOR: map: The map list was declared in the map.h file
This bug is harmless and post-dev19, it does not require any backport.
2013-12-06 11:37:28 +01:00
Thierry FOURNIER
d18cd0f110 MEDIUM: http: The redirect strings follows the log format rules.
We handle "http-request redirect" with a log-format string now, but we
leave "redirect" unaffected.

Note that the control of the special "/" case is move from the runtime
execution to the configuration parsing. If the format rule list is
empty, the build_logline() function does nothing.
2013-12-02 23:31:33 +01:00