MEDIUM: Add parsing of mailers section

As mailer and mailers structures and allow parsing of
a mailers section into those structures.

These structures will subsequently be freed as it is
not yet possible to use reference them in the configuration.

Signed-off-by: Simon Horman <horms@verge.net.au>
This commit is contained in:
Simon Horman 2015-01-30 11:22:58 +09:00 committed by Willy Tarreau
parent e16c1b3f3d
commit 0d16a4011e
4 changed files with 260 additions and 1 deletions

View File

@ -664,7 +664,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocol.o \
src/session.o src/hdr_idx.o src/ev_select.o src/signal.o \
src/acl.o src/sample.o src/memory.o src/freq_ctr.o src/auth.o \
src/compression.o src/payload.o src/hash.o src/pattern.o src/map.o \
src/namespace.o
src/namespace.o src/mailers.o
EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o \
$(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \

65
include/types/mailers.h Normal file
View File

@ -0,0 +1,65 @@
/*
* include/types/mailer.h
* This file defines everything related to mailer.
*
* Copyright 2015 Horms Solutions Ltd., Simon Horman <horms@verge.net.au>
*
* Based on include/types/peers.h
*
* Copyright 2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_EMAIL_ALERT_H
#define _TYPES_EMAIL_ALERT_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct mailer {
char *id;
struct mailers *mailers;
struct {
const char *file; /* file where the section appears */
int line; /* line where the section appears */
} conf; /* config information */
struct sockaddr_storage addr; /* SMTP server address */
struct protocol *proto; /* SMTP server address's protocol */
struct xprt_ops *xprt; /* SMTP server socket operations at transport layer */
void *sock_init_arg; /* socket operations's opaque init argument if needed */
struct mailer *next; /* next mailer in the list */
};
struct mailers {
char *id; /* mailers section name */
struct mailer *mailer_list; /* mailers in this mailers section */
struct {
const char *file; /* file where the section appears */
int line; /* line where the section appears */
} conf; /* config information */
struct mailers *next; /* next mailers section */
int count; /* total number of mailers in this mailers section */
int users; /* number of users of this mailers section */
};
extern struct mailers *mailers;
#endif /* _TYPES_EMAIL_ALERT_H */

View File

@ -48,6 +48,7 @@
#include <types/global.h>
#include <types/obj_type.h>
#include <types/peers.h>
#include <types/mailers.h>
#include <proto/acl.h>
#include <proto/auth.h>
@ -1916,6 +1917,145 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
return err_code;
}
/*
* Parse a line in a <listen>, <frontend>, <backend> or <ruleset> section.
* Returns the error code, 0 if OK, or any combination of :
* - ERR_ABORT: must abort ASAP
* - ERR_FATAL: we can continue parsing but not start the service
* - ERR_WARN: a warning has been emitted
* - ERR_ALERT: an alert has been emitted
* Only the two first ones can stop processing, the two others are just
* indicators.
*/
int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
{
static struct mailers *curmailers = NULL;
struct mailer *newmailer = NULL;
const char *err;
int err_code = 0;
char *errmsg = NULL;
if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
if (!*args[1]) {
Alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
err = invalid_char(args[1]);
if (err) {
Alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
file, linenum, *err, args[0], args[1]);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
/*
* If there are two proxies with the same name only following
* combinations are allowed:
*/
if (strcmp(curmailers->id, args[1]) == 0) {
Warning("Parsing [%s:%d]: mailers '%s' has same name as another mailers (declared at %s:%d).\n",
file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
err_code |= ERR_WARN;
}
}
if ((curmailers = (struct mailers *)calloc(1, sizeof(struct mailers))) == NULL) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
curmailers->next = mailers;
mailers = curmailers;
curmailers->conf.file = strdup(file);
curmailers->conf.line = linenum;
curmailers->id = strdup(args[1]);
}
else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
struct sockaddr_storage *sk;
int port1, port2;
struct protocol *proto;
if (!*args[2]) {
Alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
err = invalid_char(args[1]);
if (err) {
Alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
file, linenum, *err, args[1]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
if ((newmailer = (struct mailer *)calloc(1, sizeof(struct mailer))) == NULL) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
/* the mailers are linked backwards first */
curmailers->count++;
newmailer->next = curmailers->mailer_list;
curmailers->mailer_list = newmailer;
newmailer->mailers = curmailers;
newmailer->conf.file = strdup(file);
newmailer->conf.line = linenum;
newmailer->id = strdup(args[1]);
sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL);
if (!sk) {
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
proto = protocol_by_family(sk->ss_family);
if (!proto || !proto->connect) {
Alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
file, linenum, args[0], args[1]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
if (port1 != port2) {
Alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
file, linenum, args[0], args[1], args[2]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
if (!port1) {
Alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
file, linenum, args[0], args[1], args[2]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
newmailer->addr = *sk;
newmailer->proto = proto;
newmailer->xprt = &raw_sock;
newmailer->sock_init_arg = NULL;
} /* neither "mailer" nor "mailers" */
else if (*args[0] != 0) {
Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
out:
free(errmsg);
return err_code;
}
int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
{
static struct proxy *curproxy = NULL;
@ -5942,6 +6082,7 @@ int readcfgfile(const char *file)
!cfg_register_section("global", cfg_parse_global) ||
!cfg_register_section("userlist", cfg_parse_users) ||
!cfg_register_section("peers", cfg_parse_peers) ||
!cfg_register_section("mailers", cfg_parse_mailers) ||
!cfg_register_section("namespace_list", cfg_parse_netns))
return -1;
@ -7653,6 +7794,42 @@ int check_config_validity()
}
}
if (mailers) {
struct mailers *curmailers = mailers, **last;
struct mailer *m, *mb;
/* Remove all mailers sections which don't have a valid listener.
* This can happen when a mailers section is never referenced.
*/
last = &mailers;
while (*last) {
curmailers = *last;
if (curmailers->users) {
last = &curmailers->next;
continue;
}
Warning("Removing incomplete section 'mailers %s'.\n",
curmailers->id);
m = curmailers->mailer_list;
while (m) {
mb = m->next;
free(m->id);
free(m);
m = mb;
}
/* Destroy and unlink this curmailers section.
* Note: curmailers is backed up into *last.
*/
free(curmailers->id);
curmailers = curmailers->next;
free(*last);
*last = curmailers;
}
}
pool2_hdr_idx = create_pool("hdr_idx",
global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
MEM_F_SHARED);

17
src/mailers.c Normal file
View File

@ -0,0 +1,17 @@
/*
* Mailer management.
*
* Copyright 2015 Horms Solutions Ltd, Simon Horman <horms@verge.net.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#include <stdlib.h>
#include <types/mailers.h>
struct mailers *mailers = NULL;