diff --git a/include/types/server.h b/include/types/server.h index f5aebb11b..c6c581c74 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -96,6 +96,7 @@ enum srv_initaddr { SRV_IADDR_NONE = 1, /* the server won't have any address at start up */ SRV_IADDR_LIBC = 2, /* address set using the libc DNS resolver */ SRV_IADDR_LAST = 3, /* we set the IP address found in state-file for this server */ + SRV_IADDR_IP = 4, /* we set an arbitrary IP address to the server */ }; /* server-state-file version */ @@ -245,6 +246,7 @@ struct server { char *lastaddr; /* the address string provided by the server-state file */ struct dns_resolution *resolution; /* server name resolution */ struct dns_options dns_opts; + struct sockaddr_storage init_addr; /* plain IP address specified on the init-addr line */ unsigned int init_addr_methods; /* initial address setting, 3-bit per method, ends at 0, enough to store 10 entries */ #ifdef USE_OPENSSL diff --git a/src/server.c b/src/server.c index a5876d686..c351707bb 100644 --- a/src/server.c +++ b/src/server.c @@ -1166,6 +1166,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr else if (!strcmp(args[cur_arg], "init-addr")) { char *p, *end; int done; + struct sockaddr_storage sa; newsrv->init_addr_methods = 0; memset(&newsrv->init_addr, 0, sizeof(newsrv->init_addr)); @@ -1176,6 +1177,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr if (*end) *(end++) = 0; + memset(&sa, 0, sizeof(sa)); if (!strcmp(p, "libc")) { done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_LIBC); } @@ -1185,6 +1187,16 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr else if (!strcmp(p, "none")) { done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_NONE); } + else if (str2ip2(p, &sa, 0)) { + if (is_addr(&newsrv->init_addr)) { + Alert("parsing [%s:%d]: '%s' : initial address already specified, cannot add '%s'.\n", + file, linenum, args[cur_arg], p); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + newsrv->init_addr = sa; + done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_IP); + } else { Alert("parsing [%s:%d]: '%s' : unknown init-addr method '%s', supported methods are 'libc', 'last', 'none'.\n", file, linenum, args[cur_arg], p); @@ -3264,6 +3276,14 @@ static int srv_iterate_initaddr(struct server *srv) } return return_code; + case SRV_IADDR_IP: + ipcpy(&srv->init_addr, &srv->addr); + if (return_code) { + Warning("parsing [%s:%d] : 'server %s' : could not resolve address '%s', falling back to configured address.\n", + srv->conf.file, srv->conf.line, srv->id, srv->hostname); + } + return return_code; + default: /* unhandled method */ break; }