mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-26 14:42:21 +00:00
MEDIUM: server: make server_set_inetaddr() updater serializable
server_set_inetaddr() updater argument is a simple char * string containing infos about the caller responsible for the update. In this patch, we try to make this argument serializable, that is, make it so that we can easily export it without having to keep the original pointer passed by the caller or having to work with strings of variable lengths. This was a prerequisite for exposing more updater information through SERVER_INETADDR event (upcoming patch). Static strings were simply mapped to a fixed ID that can be converted back to a string when needed using server_inetaddr_updater_by_to_str(). One special case one made for the SERVER_INETADDR_UPDATER_DNS_RESOLVER updater since in this case the updater hint has to be generated from the corresponding resolver id / nameserver id combination. This was achieved by saving the nameserver id within the updater struct. Knowing that the resolver id can be guessed from the server struct directly, it was not exposed through the updater struct. This patch depends on: - "MINOR: resolvers: add unique numeric id to nameservers" No functional change should be expected.
This commit is contained in:
parent
2f6120d6d4
commit
3ac79b504a
@ -154,8 +154,9 @@ struct dns_nameserver {
|
||||
|
||||
/* mixed dns and resolver counters, we will have to split them */
|
||||
struct dns_counters {
|
||||
char *id;
|
||||
char *pid;
|
||||
char *id; /* nameserver id */
|
||||
char *pid; /* parent resolver id */
|
||||
unsigned int ns_puid; /* nameserver numerical id (ns->puid) */
|
||||
long long sent; /* - queries sent */
|
||||
long long snd_error; /* - sending errors */
|
||||
union {
|
||||
|
@ -612,6 +612,49 @@ struct server_inetaddr {
|
||||
} port;
|
||||
};
|
||||
|
||||
/* struct to store informations about server's addr / port updater in
|
||||
* INET context
|
||||
*/
|
||||
enum server_inetaddr_updater_by {
|
||||
SERVER_INETADDR_UPDATER_BY_NONE = 0,
|
||||
SERVER_INETADDR_UPDATER_BY_CLI,
|
||||
SERVER_INETADDR_UPDATER_BY_LUA,
|
||||
SERVER_INETADDR_UPDATER_BY_DNS_AR,
|
||||
SERVER_INETADDR_UPDATER_BY_DNS_CACHE,
|
||||
SERVER_INETADDR_UPDATER_BY_DNS_RESOLVER,
|
||||
/* changes here must be reflected in SERVER_INETADDR_UPDATER_*
|
||||
* helper macros and in server_inetaddr_updater_by_to_str() func
|
||||
*/
|
||||
};
|
||||
struct server_inetaddr_updater {
|
||||
enum server_inetaddr_updater_by by; // by identifier (unique)
|
||||
union {
|
||||
struct {
|
||||
unsigned int ns_id; // nameserver id responsible for the update
|
||||
} dns_resolver; // SERVER_INETADDR_UPDATER_DNS_RESOLVER specific infos
|
||||
}; // per updater's additional ctx
|
||||
};
|
||||
#define SERVER_INETADDR_UPDATER_NONE \
|
||||
(struct server_inetaddr_updater){ .by = SERVER_INETADDR_UPDATER_BY_NONE }
|
||||
|
||||
#define SERVER_INETADDR_UPDATER_CLI \
|
||||
(struct server_inetaddr_updater){ .by = SERVER_INETADDR_UPDATER_BY_CLI }
|
||||
|
||||
#define SERVER_INETADDR_UPDATER_LUA \
|
||||
(struct server_inetaddr_updater){ .by = SERVER_INETADDR_UPDATER_BY_LUA }
|
||||
|
||||
#define SERVER_INETADDR_UPDATER_DNS_AR \
|
||||
(struct server_inetaddr_updater){ .by = SERVER_INETADDR_UPDATER_BY_DNS_AR }
|
||||
|
||||
#define SERVER_INETADDR_UPDATER_DNS_CACHE \
|
||||
(struct server_inetaddr_updater){ .by = SERVER_INETADDR_UPDATER_BY_DNS_CACHE }
|
||||
|
||||
#define SERVER_INETADDR_UPDATER_DNS_RESOLVER(_ns_id) \
|
||||
(struct server_inetaddr_updater){ \
|
||||
.by = SERVER_INETADDR_UPDATER_BY_DNS_RESOLVER, \
|
||||
.dns_resolver.ns_id = _ns_id, \
|
||||
}
|
||||
|
||||
/* data provided to EVENT_HDL_SUB_SERVER_INETADDR handlers through
|
||||
* event_hdl facility
|
||||
*
|
||||
|
@ -47,12 +47,13 @@ int srv_lastsession(const struct server *s);
|
||||
int srv_getinter(const struct check *check);
|
||||
void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl);
|
||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_flags);
|
||||
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater);
|
||||
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server_inetaddr_updater updater);
|
||||
int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err);
|
||||
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, const char *updater, struct buffer *msg);
|
||||
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, const char *updater);
|
||||
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater, struct buffer *msg);
|
||||
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater);
|
||||
void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr);
|
||||
const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater);
|
||||
const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, struct server_inetaddr_updater updater);
|
||||
const char *server_inetaddr_updater_by_to_str(enum server_inetaddr_updater_by by);
|
||||
const char *srv_update_check_addr_port(struct server *s, const char *addr, const char *port);
|
||||
const char *srv_update_agent_addr_port(struct server *s, const char *addr, const char *port);
|
||||
struct server *server_find_by_id(struct proxy *bk, int id);
|
||||
|
@ -1513,7 +1513,7 @@ int hlua_server_set_addr(lua_State *L)
|
||||
port = NULL;
|
||||
|
||||
HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
|
||||
err = srv_update_addr_port(srv, addr, port, "Lua script");
|
||||
err = srv_update_addr_port(srv, addr, port, SERVER_INETADDR_UPDATER_LUA);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
if (!err)
|
||||
lua_pushnil(L);
|
||||
|
@ -847,10 +847,10 @@ srv_found:
|
||||
|
||||
switch (item->ar_item->type) {
|
||||
case DNS_RTYPE_A:
|
||||
srv_update_addr(srv, &item->ar_item->data.in4.sin_addr, AF_INET, "DNS additional record");
|
||||
srv_update_addr(srv, &item->ar_item->data.in4.sin_addr, AF_INET, SERVER_INETADDR_UPDATER_DNS_AR);
|
||||
break;
|
||||
case DNS_RTYPE_AAAA:
|
||||
srv_update_addr(srv, &item->ar_item->data.in6.sin6_addr, AF_INET6, "DNS additional record");
|
||||
srv_update_addr(srv, &item->ar_item->data.in6.sin6_addr, AF_INET6, SERVER_INETADDR_UPDATER_DNS_AR);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2811,6 +2811,7 @@ int resolv_allocate_counters(struct list *stat_modules)
|
||||
if (strcmp(mod->name, "resolvers") == 0) {
|
||||
ns->counters = (struct dns_counters *)ns->extra_counters->data + mod->counters_off[COUNTERS_RSLV];
|
||||
ns->counters->id = ns->id;
|
||||
ns->counters->ns_puid = ns->puid;
|
||||
ns->counters->pid = resolvers->id;
|
||||
}
|
||||
}
|
||||
|
86
src/server.c
86
src/server.c
@ -3719,6 +3719,66 @@ void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr)
|
||||
inetaddr->port.map = mapports;
|
||||
}
|
||||
|
||||
/* get human readable name for server_inetaddr_updater .by struct member
|
||||
*/
|
||||
const char *server_inetaddr_updater_by_to_str(enum server_inetaddr_updater_by by)
|
||||
{
|
||||
switch (by) {
|
||||
case SERVER_INETADDR_UPDATER_BY_CLI:
|
||||
return "stats socket command";
|
||||
case SERVER_INETADDR_UPDATER_BY_LUA:
|
||||
return "Lua script";
|
||||
case SERVER_INETADDR_UPDATER_BY_DNS_AR:
|
||||
return "DNS additional record";
|
||||
case SERVER_INETADDR_UPDATER_BY_DNS_CACHE:
|
||||
return "DNS cache";
|
||||
case SERVER_INETADDR_UPDATER_BY_DNS_RESOLVER:
|
||||
return "DNS resolver";
|
||||
default:
|
||||
/* unknown, don't mention updater */
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* append inetaddr updater info to chunk <out>
|
||||
*/
|
||||
static void _srv_append_inetaddr_updater_info(struct buffer *out,
|
||||
struct server *s,
|
||||
struct server_inetaddr_updater updater)
|
||||
{
|
||||
switch (updater.by) {
|
||||
case SERVER_INETADDR_UPDATER_BY_DNS_RESOLVER:
|
||||
/* we need to report the resolver/nameserver id which is
|
||||
* responsible for the update
|
||||
*/
|
||||
{
|
||||
struct resolvers *r = s->resolvers;
|
||||
struct dns_nameserver *ns;
|
||||
|
||||
/* we already know that the update comes from the
|
||||
* resolver section linked to the server, but we
|
||||
* need to find out which nameserver handled the dns
|
||||
* query
|
||||
*/
|
||||
BUG_ON(!r);
|
||||
ns = find_nameserver_by_resolvers_and_id(r, updater.dns_resolver.ns_id);
|
||||
BUG_ON(!ns);
|
||||
chunk_appendf(out, " by '%s/%s'", r->id, ns->id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
const char *by_name;
|
||||
|
||||
by_name = server_inetaddr_updater_by_to_str(updater.by);
|
||||
if (by_name)
|
||||
chunk_appendf(out, " by '%s'", by_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* server_set_inetaddr() helper */
|
||||
static void _addr_to_str(int family, const void *addr, char *addr_str, size_t len)
|
||||
{
|
||||
@ -3784,7 +3844,7 @@ static int _inetaddr_addr_cmp(const struct server_inetaddr *inetaddr, const stru
|
||||
*/
|
||||
int server_set_inetaddr(struct server *s,
|
||||
const struct server_inetaddr *inetaddr,
|
||||
const char *updater, struct buffer *msg)
|
||||
struct server_inetaddr_updater updater, struct buffer *msg)
|
||||
{
|
||||
union {
|
||||
struct event_hdl_cb_data_server_inetaddr addr;
|
||||
@ -3893,8 +3953,8 @@ int server_set_inetaddr(struct server *s,
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (ret && msg && updater)
|
||||
chunk_appendf(msg, " by '%s'", updater);
|
||||
if (ret && msg && updater.by != SERVER_INETADDR_UPDATER_BY_NONE)
|
||||
_srv_append_inetaddr_updater_info(msg, s, updater);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3906,7 +3966,7 @@ int server_set_inetaddr(struct server *s,
|
||||
*/
|
||||
int server_set_inetaddr_warn(struct server *s,
|
||||
const struct server_inetaddr *inetaddr,
|
||||
const char *updater)
|
||||
struct server_inetaddr_updater updater)
|
||||
{
|
||||
struct buffer *msg = get_trash_chunk();
|
||||
int ret;
|
||||
@ -3935,7 +3995,7 @@ int server_set_inetaddr_warn(struct server *s,
|
||||
*
|
||||
* Must be called with the server lock held.
|
||||
*/
|
||||
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater)
|
||||
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server_inetaddr_updater updater)
|
||||
{
|
||||
struct server_inetaddr inetaddr;
|
||||
|
||||
@ -4061,8 +4121,8 @@ out:
|
||||
/*
|
||||
* This function update a server's addr and port only for AF_INET and AF_INET6 families.
|
||||
*
|
||||
* Caller can pass its name through <updater> to get it integrated in the response message
|
||||
* returned by the function.
|
||||
* Caller can pass its info through <updater> to get it integrated in the response
|
||||
* message returned by the function.
|
||||
*
|
||||
* The function first does the following, in that order:
|
||||
* - checks that don't switch from/to a family other than AF_INET and AF_INET6
|
||||
@ -4071,7 +4131,8 @@ out:
|
||||
*
|
||||
* Must be called with the server lock held.
|
||||
*/
|
||||
const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater)
|
||||
const char *srv_update_addr_port(struct server *s, const char *addr, const char *port,
|
||||
struct server_inetaddr_updater updater)
|
||||
{
|
||||
struct sockaddr_storage sa;
|
||||
struct server_inetaddr inetaddr;
|
||||
@ -4300,7 +4361,6 @@ int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
|
||||
void *serverip, *firstip;
|
||||
short server_sin_family, firstip_sin_family;
|
||||
int ret;
|
||||
struct buffer *chk = get_trash_chunk();
|
||||
int has_no_ip = 0;
|
||||
|
||||
s = objt_server(requester->owner);
|
||||
@ -4375,11 +4435,11 @@ int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
|
||||
if (counters) {
|
||||
counters->app.resolver.update++;
|
||||
/* save the first ip we found */
|
||||
chunk_printf(chk, "%s/%s", counters->pid, counters->id);
|
||||
srv_update_addr(s, firstip, firstip_sin_family,
|
||||
SERVER_INETADDR_UPDATER_DNS_RESOLVER(counters->ns_puid));
|
||||
}
|
||||
else
|
||||
chunk_printf(chk, "DNS cache");
|
||||
srv_update_addr(s, firstip, firstip_sin_family, (char *) chk->area);
|
||||
srv_update_addr(s, firstip, firstip_sin_family, SERVER_INETADDR_UPDATER_DNS_CACHE);
|
||||
|
||||
update_status:
|
||||
if (!snr_update_srv_status(s, has_no_ip) && has_no_ip)
|
||||
@ -5005,7 +5065,7 @@ static int cli_parse_set_server(char **args, char *payload, struct appctx *appct
|
||||
port = args[6];
|
||||
}
|
||||
HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
|
||||
warning = srv_update_addr_port(sv, addr, port, "stats socket command");
|
||||
warning = srv_update_addr_port(sv, addr, port, SERVER_INETADDR_UPDATER_CLI);
|
||||
if (warning)
|
||||
cli_msg(appctx, LOG_WARNING, warning);
|
||||
srv_clr_admin_flag(sv, SRV_ADMF_RMAINT);
|
||||
|
Loading…
Reference in New Issue
Block a user