summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am80
-rw-r--r--src/conntrack.c57
-rw-r--r--src/main.c5
-rw-r--r--src/network.c2
-rw-r--r--src/read_config_lex.l3
-rw-r--r--src/read_config_yy.y280
-rw-r--r--src/run.c23
-rw-r--r--src/vector.c7
8 files changed, 274 insertions, 183 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a1a91a0..352aa37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,7 +11,18 @@ BUILT_SOURCES = read_config_yy.h
sbin_PROGRAMS = conntrack conntrackd nfct
conntrack_SOURCES = conntrack.c
-conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp.la ../extensions/libct_proto_udplite.la ../extensions/libct_proto_icmp.la ../extensions/libct_proto_icmpv6.la ../extensions/libct_proto_sctp.la ../extensions/libct_proto_dccp.la ../extensions/libct_proto_gre.la ../extensions/libct_proto_unknown.la ${LIBNETFILTER_CONNTRACK_LIBS} ${LIBMNL_LIBS} ${LIBNFNETLINK_LIBS}
+conntrack_LDADD = ../extensions/libct_proto_dccp.la \
+ ../extensions/libct_proto_gre.la \
+ ../extensions/libct_proto_icmp.la \
+ ../extensions/libct_proto_icmpv6.la \
+ ../extensions/libct_proto_sctp.la \
+ ../extensions/libct_proto_tcp.la \
+ ../extensions/libct_proto_udp.la \
+ ../extensions/libct_proto_udplite.la \
+ ../extensions/libct_proto_unknown.la \
+ ${LIBMNL_LIBS} \
+ ${LIBNETFILTER_CONNTRACK_LIBS} \
+ ${LIBNFNETLINK_LIBS}
nfct_SOURCES = nfct.c
@@ -35,22 +46,54 @@ if HAVE_CTHELPER
nfct_LDADD += ${LIBNETFILTER_CTHELPER_LIBS}
endif
-conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c queue_tx.c rbtree.c \
- local.c log.c mcast.c udp.c netlink.c vector.c \
- filter.c fds.c event.c process.c origin.c date.c \
- cache.c cache-ct.c cache-exp.c \
- cache_timer.c \
- ctnl.c \
- sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \
- traffic_stats.c stats-mode.c \
- network.c cidr.c \
- build.c parse.c \
- channel.c multichannel.c channel_mcast.c channel_udp.c \
- tcp.c channel_tcp.c \
- external_cache.c external_inject.c \
- internal_cache.c internal_bypass.c \
- read_config_yy.y read_config_lex.l \
- stack.c resync.c
+conntrackd_SOURCES = alarm.c \
+ build.c \
+ cache.c \
+ cache-ct.c \
+ cache-exp.c \
+ cache_timer.c \
+ channel.c \
+ channel_mcast.c \
+ channel_tcp.c \
+ channel_udp.c \
+ cidr.c \
+ ctnl.c \
+ date.c \
+ event.c \
+ external_cache.c \
+ external_inject.c \
+ fds.c \
+ filter.c \
+ hash.c \
+ internal_bypass.c \
+ internal_cache.c \
+ local.c \
+ log.c \
+ main.c \
+ mcast.c \
+ multichannel.c \
+ netlink.c \
+ network.c \
+ origin.c \
+ parse.c \
+ process.c \
+ queue.c \
+ queue_tx.c \
+ rbtree.c \
+ read_config_lex.l \
+ read_config_yy.y \
+ resync.c \
+ run.c \
+ stack.c \
+ stats-mode.c \
+ sync-alarm.c \
+ sync-ftfw.c \
+ sync-mode.c \
+ sync-notrack.c \
+ tcp.c \
+ traffic_stats.c \
+ udp.c \
+ vector.c
if HAVE_CTHELPER
conntrackd_SOURCES += cthelper.c helpers.c utils.c expect.c
@@ -60,9 +103,6 @@ if HAVE_SYSTEMD
conntrackd_SOURCES += systemd.c
endif
-# yacc and lex generate dirty code
-read_config_yy.o read_config_lex.o: AM_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-nested-externs -Wno-undef -Wno-redundant-decls -Wno-sign-compare
-
conntrackd_LDADD = ${LIBMNL_LIBS} ${LIBNETFILTER_CONNTRACK_LIBS} \
${libdl_LIBS} ${LIBNFNETLINK_LIBS}
diff --git a/src/conntrack.c b/src/conntrack.c
index 859a483..0d71352 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -139,6 +139,8 @@ static int alloc_tmpl_objects(struct ct_tmpl *tmpl)
static void free_tmpl_objects(struct ct_tmpl *tmpl)
{
+ if (!tmpl)
+ return;
if (tmpl->ct)
nfct_destroy(tmpl->ct);
if (tmpl->exptuple)
@@ -536,7 +538,7 @@ static const char usage_parameters[] =
"Common parameters and options:\n"
" -s, --src, --orig-src ip\t\tSource address from original direction\n"
" -d, --dst, --orig-dst ip\t\tDestination address from original direction\n"
- " -r, --reply-src ip\t\tSource addres from reply direction\n"
+ " -r, --reply-src ip\t\tSource address from reply direction\n"
" -q, --reply-dst ip\t\tDestination address from reply direction\n"
" -p, --protonum proto\t\tLayer 4 Protocol, eg. 'tcp'\n"
" -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
@@ -761,7 +763,6 @@ static int ct_save_snprintf(char *buf, size_t len,
BUFFER_SIZE(ret, size, len, offset);
break;
default:
- ret = 0;
break;
}
@@ -1769,7 +1770,7 @@ static char *portid2name(pid_t pid, uint32_t portid, unsigned long inode)
continue;
rl = readlink(procname, tmp, sizeof(tmp));
- if (rl <= 0 || rl > (ssize_t)sizeof(tmp))
+ if (rl <= 0 || rl >= (ssize_t)sizeof(tmp))
continue;
tmp[rl] = 0;
@@ -1943,7 +1944,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data)
nfct_snprintf_labels(buf, sizeof(buf), ct, type, op_type, op_flags, labelmap);
done:
- if (nlh->nlmsg_pid) {
+ if (nlh->nlmsg_pid && !(output_mask & _O_XML)) {
char *prog = get_progname(nlh->nlmsg_pid);
if (prog)
@@ -1988,10 +1989,14 @@ static int mnl_nfct_delete_cb(const struct nlmsghdr *nlh, void *data)
res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
IPCTNL_MSG_CT_DELETE, NLM_F_ACK, NULL, ct, NULL);
- if (res < 0)
+ if (res < 0) {
+ /* the entry has vanish in middle of the delete */
+ if (errno == ENOENT)
+ goto done;
exit_error(OTHER_PROBLEM,
"Operation failed: %s",
err2str(errno, CT_DELETE));
+ }
if (output_mask & _O_SAVE) {
ct_save_snprintf(buf, sizeof(buf), ct, labelmap, NFCT_T_DESTROY);
@@ -2183,15 +2188,26 @@ static int mnl_nfct_update_cb(const struct nlmsghdr *nlh, void *data)
if (nfct_cmp(tmp, ct, NFCT_CMP_ALL | NFCT_CMP_MASK))
goto destroy_ok;
- res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
+ res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
+ nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
IPCTNL_MSG_CT_NEW, NLM_F_ACK, NULL, tmp, NULL);
if (res < 0) {
- fprintf(stderr, "Operation failed: %s\n",
- err2str(errno, CT_UPDATE));
+ /* the entry has vanish in middle of the update */
+ if (errno == ENOENT)
+ goto destroy_ok;
+ else if (cmd->options & (CT_OPT_ADD_LABEL | CT_OPT_DEL_LABEL) &&
+ !nfct_attr_is_set(ct, ATTR_CONNLABELS) &&
+ errno == ENOSPC)
+ goto destroy_ok;
+
+ exit_error(OTHER_PROBLEM,
+ "Operation failed: %s",
+ err2str(errno, CT_UPDATE));
}
- res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
- IPCTNL_MSG_CT_GET, NLM_F_ACK,
+ res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
+ nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
+ IPCTNL_MSG_CT_GET, 0,
mnl_nfct_print_cb, tmp, NULL);
if (res < 0) {
/* the entry has vanish in middle of the update */
@@ -2885,7 +2901,7 @@ static int print_stats(const struct ct_cmd *cmd)
fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
fprintf(stderr, exit_msg[cmd->cmd], counter);
if (counter == 0 &&
- !(cmd->command & (CT_LIST | EXP_LIST | CT_ADD)))
+ !(cmd->command & (CT_LIST | EXP_LIST)))
return -1;
}
@@ -3006,8 +3022,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
if (tmpl->filter_status_kernel.mask == 0)
tmpl->filter_status_kernel.mask = status;
- tmpl->mark.value = status;
- tmpl->filter_status_kernel.val = tmpl->mark.value;
+ tmpl->filter_status_kernel.val = status;
tmpl->filter_status_kernel_set = true;
break;
case 'e':
@@ -3218,6 +3233,7 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
struct nfct_mnl_socket *modifier_sock = &_modifier_sock;
struct nfct_mnl_socket *event_sock = &_event_sock;
struct nfct_filter_dump *filter_dump;
+ uint16_t nl_flags = 0;
int res = 0;
switch(cmd->command) {
@@ -3304,14 +3320,15 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
nfct_set_attr(cmd->tmpl.ct, ATTR_CONNLABELS,
xnfct_bitmask_clone(cmd->tmpl.label_modify));
+ if (cmd->command == CT_CREATE)
+ nl_flags = NLM_F_EXCL;
+
res = nfct_mnl_request(sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
IPCTNL_MSG_CT_NEW,
- NLM_F_CREATE | NLM_F_ACK | NLM_F_EXCL,
+ NLM_F_CREATE | NLM_F_ACK | nl_flags,
NULL, cmd->tmpl.ct, NULL);
if (res >= 0)
counter++;
- else if (errno == EEXIST && cmd->command == CT_ADD)
- res = 0;
break;
case EXP_CREATE:
@@ -3376,7 +3393,7 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
case CT_GET:
res = nfct_mnl_request(sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
- IPCTNL_MSG_CT_GET, NLM_F_ACK,
+ IPCTNL_MSG_CT_GET, 0,
mnl_nfct_dump_cb, cmd->tmpl.ct, cmd);
break;
@@ -3479,7 +3496,7 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
strerror(errno));
break;
}
- res = mnl_cb_run(buf, res, 0, 0, event_cb, cmd);
+ mnl_cb_run(buf, res, 0, 0, event_cb, cmd);
}
mnl_socket_close(event_sock->mnl);
break;
@@ -3834,8 +3851,8 @@ int main(int argc, char *argv[])
exit_error(OTHER_PROBLEM, "OOM");
do_parse(cmd, argc, argv);
- do_command_ct(argv[0], cmd, sock);
- res = print_stats(cmd);
+ res = do_command_ct(argv[0], cmd, sock);
+ res |= print_stats(cmd);
free(cmd);
}
nfct_mnl_socket_close(sock);
diff --git a/src/main.c b/src/main.c
index de4773d..c6b2600 100644
--- a/src/main.c
+++ b/src/main.c
@@ -175,7 +175,7 @@ int main(int argc, char *argv[])
}
show_usage(argv[0]);
dlog(LOG_ERR, "Missing config filename");
- break;
+ exit(EXIT_FAILURE);
case 'F':
set_operation_mode(&type, REQUEST, argv);
i = set_action_by_table(i, argc, argv,
@@ -309,8 +309,7 @@ int main(int argc, char *argv[])
default:
show_usage(argv[0]);
dlog(LOG_ERR, "Unknown option: %s", argv[i]);
- return 0;
- break;
+ exit(EXIT_FAILURE);
}
}
diff --git a/src/network.c b/src/network.c
index 13db37c..2560d97 100644
--- a/src/network.c
+++ b/src/network.c
@@ -113,7 +113,7 @@ void nethdr_track_update_seq(uint32_t seq)
STATE_SYNC(last_seq_recv) = seq;
}
-int nethdr_track_is_seq_set()
+int nethdr_track_is_seq_set(void)
{
return local_seq_set;
}
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index 7dc400a..2708432 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -21,6 +21,7 @@
#include <string.h>
+#include "log.h"
#include "conntrackd.h"
#include "read_config_yy.h"
%}
@@ -174,7 +175,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k]
%%
int
-yywrap()
+yywrap(void)
{
return 1;
}
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index 5815d6a..a116b0b 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -31,19 +31,40 @@
#include "cidr.h"
#include "helper.h"
#include "stack.h"
+#include "log.h"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#include <sched.h>
#include <dlfcn.h>
+
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
extern char *yytext;
extern int yylineno;
+int yylex (void);
+int yyerror (const char *msg);
+void yyrestart (FILE *input_file);
+
struct ct_conf conf;
static void __kernel_filter_start(void);
static void __kernel_filter_add_state(int value);
-static void __max_dedicated_links_reached(void);
+
+static struct channel_conf *conf_get_channel(void)
+{
+ if (conf.channel_num >= MULTICHANNEL_MAX) {
+ dlog(LOG_ERR, "too many dedicated links in the configuration "
+ "file (Maximum: %d)", MULTICHANNEL_MAX);
+ exit(EXIT_FAILURE);
+ }
+
+ return &conf.channel[conf.channel_num];
+}
struct stack symbol_stack;
@@ -202,6 +223,8 @@ purge: T_PURGE T_NUMBER
multicast_line : T_MULTICAST '{' multicast_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_MCAST) {
dlog(LOG_ERR, "cannot use `Multicast' with other "
@@ -209,13 +232,15 @@ multicast_line : T_MULTICAST '{' multicast_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_MCAST;
- conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED;
+ channel_conf->channel_type = CHANNEL_MCAST;
+ channel_conf->channel_flags = CHANNEL_F_BUFFERED;
conf.channel_num++;
};
multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_MCAST) {
dlog(LOG_ERR, "cannot use `Multicast' with other "
@@ -223,9 +248,8 @@ multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_MCAST;
- conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT |
- CHANNEL_F_BUFFERED;
+ channel_conf->channel_type = CHANNEL_MCAST;
+ channel_conf->channel_flags = CHANNEL_F_DEFAULT | CHANNEL_F_BUFFERED;
conf.channel_default = conf.channel_num;
conf.channel_num++;
};
@@ -235,15 +259,15 @@ multicast_options :
multicast_option : T_IPV4_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.in)) {
+ if (!inet_aton($2, &channel_conf->u.mcast.in.inet_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
- if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) {
+ if (channel_conf->u.mcast.ipproto == AF_INET6) {
dlog(LOG_WARNING, "your multicast address is IPv4 but "
"is binded to an IPv6 interface? "
"Surely, this is not what you want");
@@ -251,16 +275,15 @@ multicast_option : T_IPV4_ADDR T_IP
}
free($2);
- conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET;
+ channel_conf->u.mcast.ipproto = AF_INET;
};
multicast_option : T_IPV6_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
int err;
- err = inet_pton(AF_INET6, $2,
- &conf.channel[conf.channel_num].u.mcast.in);
+ err = inet_pton(AF_INET6, $2, &channel_conf->u.mcast.in);
if (err == 0) {
dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2);
free($2);
@@ -270,7 +293,7 @@ multicast_option : T_IPV6_ADDR T_IP
exit(EXIT_FAILURE);
}
- if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET) {
+ if (channel_conf->u.mcast.ipproto == AF_INET) {
dlog(LOG_WARNING, "your multicast address is IPv6 but "
"is binded to an IPv4 interface? "
"Surely this is not what you want");
@@ -278,10 +301,10 @@ multicast_option : T_IPV6_ADDR T_IP
break;
}
- conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6;
+ channel_conf->u.mcast.ipproto = AF_INET6;
- if (conf.channel[conf.channel_num].channel_ifname[0] &&
- !conf.channel[conf.channel_num].u.mcast.ifa.interface_index6) {
+ if (channel_conf->channel_ifname[0] &&
+ !channel_conf->u.mcast.ifa.interface_index6) {
unsigned int idx;
idx = if_nametoindex($2);
@@ -291,31 +314,31 @@ multicast_option : T_IPV6_ADDR T_IP
break;
}
- conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx;
- conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6;
+ channel_conf->u.mcast.ifa.interface_index6 = idx;
+ channel_conf->u.mcast.ipproto = AF_INET6;
}
free($2);
};
multicast_option : T_IPV4_IFACE T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.ifa)) {
+ if (!inet_aton($2, &channel_conf->u.mcast.ifa.interface_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
free($2);
- if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) {
+ if (channel_conf->u.mcast.ipproto == AF_INET6) {
dlog(LOG_WARNING, "your multicast interface is IPv4 but "
"is binded to an IPv6 interface? "
"Surely, this is not what you want");
break;
}
- conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET;
+ channel_conf->u.mcast.ipproto = AF_INET;
};
multicast_option : T_IPV6_IFACE T_IP
@@ -326,11 +349,10 @@ multicast_option : T_IPV6_IFACE T_IP
multicast_option : T_IFACE T_STRING
{
+ struct channel_conf *channel_conf = conf_get_channel();
unsigned int idx;
- __max_dedicated_links_reached();
-
- strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ);
+ strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ);
idx = if_nametoindex($2);
if (!idx) {
@@ -339,9 +361,9 @@ multicast_option : T_IFACE T_STRING
break;
}
- if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) {
- conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx;
- conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6;
+ if (channel_conf->u.mcast.ipproto == AF_INET6) {
+ channel_conf->u.mcast.ifa.interface_index6 = idx;
+ channel_conf->u.mcast.ipproto = AF_INET6;
}
free($2);
@@ -349,36 +371,43 @@ multicast_option : T_IFACE T_STRING
multicast_option : T_GROUP T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.mcast.port = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.mcast.port = $2;
};
multicast_option: T_SNDBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.mcast.sndbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.mcast.sndbuf = $2;
};
multicast_option: T_RCVBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.mcast.rcvbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.mcast.rcvbuf = $2;
};
-multicast_option: T_CHECKSUM T_ON
+multicast_option: T_CHECKSUM T_ON
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.mcast.checksum = 0;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.mcast.checksum = 0;
};
multicast_option: T_CHECKSUM T_OFF
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.mcast.checksum = 1;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.mcast.checksum = 1;
};
udp_line : T_UDP '{' udp_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_UDP) {
dlog(LOG_ERR, "cannot use `UDP' with other "
@@ -386,13 +415,15 @@ udp_line : T_UDP '{' udp_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_UDP;
- conf.channel[conf.channel_num].channel_type = CHANNEL_UDP;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED;
+ channel_conf->channel_type = CHANNEL_UDP;
+ channel_conf->channel_flags = CHANNEL_F_BUFFERED;
conf.channel_num++;
};
udp_line : T_UDP T_DEFAULT '{' udp_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_UDP) {
dlog(LOG_ERR, "cannot use `UDP' with other "
@@ -400,9 +431,8 @@ udp_line : T_UDP T_DEFAULT '{' udp_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_UDP;
- conf.channel[conf.channel_num].channel_type = CHANNEL_UDP;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT |
- CHANNEL_F_BUFFERED;
+ channel_conf->channel_type = CHANNEL_UDP;
+ channel_conf->channel_flags = CHANNEL_F_DEFAULT | CHANNEL_F_BUFFERED;
conf.channel_default = conf.channel_num;
conf.channel_num++;
};
@@ -412,24 +442,23 @@ udp_options :
udp_option : T_IPV4_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.server.ipv4)) {
+ if (!inet_aton($2, &channel_conf->u.udp.server.ipv4.inet_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
free($2);
- conf.channel[conf.channel_num].u.udp.ipproto = AF_INET;
+ channel_conf->u.udp.ipproto = AF_INET;
};
udp_option : T_IPV6_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
int err;
- err = inet_pton(AF_INET6, $2,
- &conf.channel[conf.channel_num].u.udp.server.ipv6);
+ err = inet_pton(AF_INET6, $2, &channel_conf->u.udp.server.ipv6);
if (err == 0) {
dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2);
free($2);
@@ -440,29 +469,28 @@ udp_option : T_IPV6_ADDR T_IP
}
free($2);
- conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6;
+ channel_conf->u.udp.ipproto = AF_INET6;
};
udp_option : T_IPV4_DEST_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.client)) {
+ if (!inet_aton($2, &channel_conf->u.udp.client.inet_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
free($2);
- conf.channel[conf.channel_num].u.udp.ipproto = AF_INET;
+ channel_conf->u.udp.ipproto = AF_INET;
};
udp_option : T_IPV6_DEST_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
int err;
- err = inet_pton(AF_INET6, $2,
- &conf.channel[conf.channel_num].u.udp.client);
+ err = inet_pton(AF_INET6, $2, &channel_conf->u.udp.client);
if (err == 0) {
dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2);
free($2);
@@ -473,15 +501,15 @@ udp_option : T_IPV6_DEST_ADDR T_IP
}
free($2);
- conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6;
+ channel_conf->u.udp.ipproto = AF_INET6;
};
udp_option : T_IFACE T_STRING
{
+ struct channel_conf *channel_conf = conf_get_channel();
int idx;
- __max_dedicated_links_reached();
- strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ);
+ strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ);
idx = if_nametoindex($2);
if (!idx) {
@@ -489,43 +517,50 @@ udp_option : T_IFACE T_STRING
free($2);
break;
}
- conf.channel[conf.channel_num].u.udp.server.ipv6.scope_id = idx;
+ channel_conf->u.udp.server.ipv6.scope_id = idx;
free($2);
};
udp_option : T_PORT T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.udp.port = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.udp.port = $2;
};
udp_option: T_SNDBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.udp.sndbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.udp.sndbuf = $2;
};
udp_option: T_RCVBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.udp.rcvbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.udp.rcvbuf = $2;
};
-udp_option: T_CHECKSUM T_ON
+udp_option: T_CHECKSUM T_ON
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.udp.checksum = 0;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.udp.checksum = 0;
};
udp_option: T_CHECKSUM T_OFF
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.udp.checksum = 1;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.udp.checksum = 1;
};
tcp_line : T_TCP '{' tcp_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_TCP) {
dlog(LOG_ERR, "cannot use `TCP' with other "
@@ -533,15 +568,17 @@ tcp_line : T_TCP '{' tcp_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_TCP;
- conf.channel[conf.channel_num].channel_type = CHANNEL_TCP;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED |
- CHANNEL_F_STREAM |
- CHANNEL_F_ERRORS;
+ channel_conf->channel_type = CHANNEL_TCP;
+ channel_conf->channel_flags = CHANNEL_F_BUFFERED |
+ CHANNEL_F_STREAM |
+ CHANNEL_F_ERRORS;
conf.channel_num++;
};
tcp_line : T_TCP T_DEFAULT '{' tcp_options '}'
{
+ struct channel_conf *channel_conf = conf_get_channel();
+
if (conf.channel_type_global != CHANNEL_NONE &&
conf.channel_type_global != CHANNEL_TCP) {
dlog(LOG_ERR, "cannot use `TCP' with other "
@@ -549,11 +586,11 @@ tcp_line : T_TCP T_DEFAULT '{' tcp_options '}'
exit(EXIT_FAILURE);
}
conf.channel_type_global = CHANNEL_TCP;
- conf.channel[conf.channel_num].channel_type = CHANNEL_TCP;
- conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT |
- CHANNEL_F_BUFFERED |
- CHANNEL_F_STREAM |
- CHANNEL_F_ERRORS;
+ channel_conf->channel_type = CHANNEL_TCP;
+ channel_conf->channel_flags = CHANNEL_F_DEFAULT |
+ CHANNEL_F_BUFFERED |
+ CHANNEL_F_STREAM |
+ CHANNEL_F_ERRORS;
conf.channel_default = conf.channel_num;
conf.channel_num++;
};
@@ -563,24 +600,23 @@ tcp_options :
tcp_option : T_IPV4_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.tcp.server.ipv4)) {
+ if (!inet_aton($2, &channel_conf->u.tcp.server.ipv4.inet_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
free($2);
- conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET;
+ channel_conf->u.tcp.ipproto = AF_INET;
};
tcp_option : T_IPV6_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
int err;
- err = inet_pton(AF_INET6, $2,
- &conf.channel[conf.channel_num].u.tcp.server.ipv6);
+ err = inet_pton(AF_INET6, $2, &channel_conf->u.tcp.server.ipv6);
if (err == 0) {
dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2);
free($2);
@@ -591,29 +627,28 @@ tcp_option : T_IPV6_ADDR T_IP
}
free($2);
- conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET6;
+ channel_conf->u.tcp.ipproto = AF_INET6;
};
tcp_option : T_IPV4_DEST_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
- if (!inet_aton($2, &conf.channel[conf.channel_num].u.tcp.client)) {
+ if (!inet_aton($2, &channel_conf->u.tcp.client.inet_addr)) {
dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2);
free($2);
break;
}
free($2);
- conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET;
+ channel_conf->u.tcp.ipproto = AF_INET;
};
tcp_option : T_IPV6_DEST_ADDR T_IP
{
- __max_dedicated_links_reached();
+ struct channel_conf *channel_conf = conf_get_channel();
int err;
- err = inet_pton(AF_INET6, $2,
- &conf.channel[conf.channel_num].u.tcp.client);
+ err = inet_pton(AF_INET6, $2, &channel_conf->u.tcp.client);
if (err == 0) {
dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2);
free($2);
@@ -624,15 +659,15 @@ tcp_option : T_IPV6_DEST_ADDR T_IP
}
free($2);
- conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET6;
+ channel_conf->u.tcp.ipproto = AF_INET6;
};
tcp_option : T_IFACE T_STRING
{
+ struct channel_conf *channel_conf = conf_get_channel();
int idx;
- __max_dedicated_links_reached();
- strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ);
+ strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ);
idx = if_nametoindex($2);
if (!idx) {
@@ -640,44 +675,48 @@ tcp_option : T_IFACE T_STRING
free($2);
break;
}
- conf.channel[conf.channel_num].u.tcp.server.ipv6.scope_id = idx;
+ channel_conf->u.tcp.server.ipv6.scope_id = idx;
free($2);
};
tcp_option : T_PORT T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.tcp.port = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.tcp.port = $2;
};
tcp_option: T_SNDBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.tcp.sndbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.tcp.sndbuf = $2;
};
tcp_option: T_RCVBUFF T_NUMBER
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.tcp.rcvbuf = $2;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.tcp.rcvbuf = $2;
};
-tcp_option: T_CHECKSUM T_ON
+tcp_option: T_CHECKSUM T_ON
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.tcp.checksum = 0;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.tcp.checksum = 0;
};
tcp_option: T_CHECKSUM T_OFF
{
- __max_dedicated_links_reached();
- conf.channel[conf.channel_num].u.tcp.checksum = 1;
+ struct channel_conf *channel_conf = conf_get_channel();
+
+ channel_conf->u.tcp.checksum = 1;
};
tcp_option: T_ERROR_QUEUE_LENGTH T_NUMBER
{
- __max_dedicated_links_reached();
CONFIG(channelc).error_queue_length = $2;
};
@@ -699,12 +738,12 @@ unix_options:
unix_option : T_PATH T_PATH_VAL
{
- if (strlen($2) > UNIX_PATH_MAX) {
+ if (strlen($2) >= UNIX_PATH_MAX) {
dlog(LOG_ERR, "Path is longer than %u characters",
- UNIX_PATH_MAX);
+ UNIX_PATH_MAX - 1);
exit(EXIT_FAILURE);
}
- snprintf(conf.local.path, sizeof(conf.local.path), "%s", $2);
+ strcpy(conf.local.path, $2);
free($2);
};
@@ -1228,7 +1267,7 @@ filter_address_item : T_IPV4_ADDR T_IP
}
}
- if (!inet_aton($2, &ip.ipv4)) {
+ if (!inet_aton($2, (struct in_addr *) &ip.ipv4)) {
dlog(LOG_WARNING, "%s is not a valid IPv4, ignoring", $2);
free($2);
break;
@@ -1670,7 +1709,7 @@ helper_policy_expect_timeout: T_HELPER_EXPECT_TIMEOUT T_NUMBER
%%
int __attribute__((noreturn))
-yyerror(char *msg)
+yyerror(const char *msg)
{
dlog(LOG_ERR, "parsing config file in line (%d), symbol '%s': %s",
yylineno, yytext, msg);
@@ -1701,15 +1740,6 @@ static void __kernel_filter_add_state(int value)
&filter_proto);
}
-static void __max_dedicated_links_reached(void)
-{
- if (conf.channel_num >= MULTICHANNEL_MAX) {
- dlog(LOG_ERR, "too many dedicated links in the configuration "
- "file (Maximum: %d)", MULTICHANNEL_MAX);
- exit(EXIT_FAILURE);
- }
-}
-
int
init_config(char *filename)
{
diff --git a/src/run.c b/src/run.c
index 37a0eb1..b31fff5 100644
--- a/src/run.c
+++ b/src/run.c
@@ -277,6 +277,18 @@ init(void)
}
register_fd(STATE(local).fd, local_cb, NULL, STATE(fds));
+ /* Initialization */
+ if (CONFIG(flags) & (CTD_SYNC_MODE | CTD_STATS_MODE))
+ if (ctnl_init() < 0)
+ return -1;
+
+#ifdef BUILD_CTHELPER
+ if (CONFIG(flags) & CTD_HELPER) {
+ if (cthelper_init() < 0)
+ return -1;
+ }
+#endif
+
/* Signals handling */
sigemptyset(&STATE(block));
sigaddset(&STATE(block), SIGTERM);
@@ -296,17 +308,6 @@ init(void)
if (signal(SIGCHLD, child) == SIG_ERR)
return -1;
- /* Initialization */
- if (CONFIG(flags) & (CTD_SYNC_MODE | CTD_STATS_MODE))
- if (ctnl_init() < 0)
- return -1;
-
-#ifdef BUILD_CTHELPER
- if (CONFIG(flags) & CTD_HELPER) {
- if (cthelper_init() < 0)
- return -1;
- }
-#endif
time(&STATE(stats).daemon_start_time);
dlog(LOG_NOTICE, "initialization completed");
diff --git a/src/vector.c b/src/vector.c
index c81e7ce..92a5436 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -60,13 +60,16 @@ void vector_destroy(struct vector *v)
int vector_add(struct vector *v, void *data)
{
+ void *ptr;
+
if (v->cur_elems >= v->max_elems) {
v->max_elems += DEFAULT_VECTOR_GROWTH;
- v->data = realloc(v->data, v->max_elems * v->size);
- if (v->data == NULL) {
+ ptr = realloc(v->data, v->max_elems * v->size);
+ if (!ptr) {
v->max_elems -= DEFAULT_VECTOR_GROWTH;
return -1;
}
+ v->data = ptr;
}
memcpy(v->data + (v->size * v->cur_elems), data, v->size);
v->cur_elems++;