From: Baptiste Assmann Date: Mon, 13 Apr 2015 23:13:07 +0000 (+0200) Subject: MEDIUM: server: add support for changing a server's address X-Git-Tag: v1.6-dev2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14e4014a485860892933e7c9ce0fb3c53c659e99;p=thirdparty%2Fhaproxy.git MEDIUM: server: add support for changing a server's address Ability to change a server IP address during HAProxy run time. For now this is provided via function update_server_addr() which currently is not called. A log is emitted on each change. For now we do it inconditionally, but later we'll want to do it only on certain circumstances, which explains why the logging block is enclosed in if(1). --- diff --git a/include/proto/server.h b/include/proto/server.h index a87c8d512d..7e32995732 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -38,6 +38,7 @@ int srv_downtime(const struct server *s); int srv_lastsession(const struct server *s); int srv_getinter(const struct check *check); int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy); +int update_server_addr(struct server *s, void *ip, int ip_sin_family, char *updater); /* increase the number of cumulated connections on the designated server */ static void inline srv_inc_sess_ctr(struct server *s) diff --git a/src/server.c b/src/server.c index ee6b8508da..369dd79ed6 100644 --- a/src/server.c +++ b/src/server.c @@ -1696,6 +1696,72 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr return err_code; } +/* + * update a server's current IP address. + * ip is a pointer to the new IP address, whose address family is ip_sin_family. + * ip is in network format. + * updater is a string which contains an information about the requester of the update. + * updater is used if not NULL. + * + * A log line and a stderr warning message is generated based on server's backend options. + */ +int update_server_addr(struct server *s, void *ip, int ip_sin_family, char *updater) +{ + /* generates a log line and a warning on stderr */ + if (1) { + /* book enough space for both IPv4 and IPv6 */ + char oldip[INET6_ADDRSTRLEN]; + char newip[INET6_ADDRSTRLEN]; + + memset(oldip, '\0', INET6_ADDRSTRLEN); + memset(newip, '\0', INET6_ADDRSTRLEN); + + /* copy old IP address in a string */ + switch (s->addr.ss_family) { + case AF_INET: + inet_ntop(s->addr.ss_family, &((struct sockaddr_in *)&s->addr)->sin_addr, oldip, INET_ADDRSTRLEN); + break; + case AF_INET6: + inet_ntop(s->addr.ss_family, &((struct sockaddr_in6 *)&s->addr)->sin6_addr, oldip, INET6_ADDRSTRLEN); + break; + }; + + /* copy new IP address in a string */ + switch (ip_sin_family) { + case AF_INET: + inet_ntop(ip_sin_family, ip, newip, INET_ADDRSTRLEN); + break; + case AF_INET6: + inet_ntop(ip_sin_family, ip, newip, INET6_ADDRSTRLEN); + break; + }; + + /* save log line into a buffer */ + chunk_printf(&trash, "%s/%s changed its IP from %s to %s by %s", + s->proxy->id, s->id, oldip, newip, updater); + + /* write the buffer on stderr */ + Warning("%s.\n", trash.str); + + /* send a log */ + send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str); + } + + /* save the new IP family */ + s->addr.ss_family = ip_sin_family; + /* save the new IP address */ + switch (ip_sin_family) { + case AF_INET: + ((struct sockaddr_in *)&s->addr)->sin_addr.s_addr = *(uint32_t *)ip; + break; + case AF_INET6: + memcpy(((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr, ip, 16); + break; + }; + + return 0; +} + /* * Local variables: * c-indent-level: 8