} 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
*
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);
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)
{
*/
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;
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;
}
*/
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;
*
* 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;
/*
* 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
*
* 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;
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);
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)
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);