diff --git a/src/filter.c b/src/filter.c index ae99d32..40e67ba 100644 --- a/src/filter.c +++ b/src/filter.c @@ -2436,8 +2436,8 @@ int filter_commands(struct worker_t *self, struct client_t *c, const char *s, in int i, argc; /* skip over the #filter in the beginning of the command */ - len -= 7; - s += 7; + len -= 6; + s += 6; if ( *s == '?' && len == 1 ) { /* Query current filters */ diff --git a/src/incoming.c b/src/incoming.c index 963b8c9..393d703 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -667,8 +667,9 @@ int incoming_uplinksim_handler(struct worker_t *self, struct client_t *c, int l4 /* filter adjunct commands ? */ /* TODO: is some client sending "# filter" instead? Should accept maybe? */ /* Yes, aprssrvr accept #kjhflawhiawuhglawuhfilter too - as long as it has filter in the end. */ - if (strncasecmp(s, "#filter", 7) == 0) - return filter_commands(self, c, s, len); + char *filtercmd = strstr(s, "filter"); + if (filtercmd) + return filter_commands(self, c, filtercmd, len - (filtercmd - s)); return 0; } @@ -715,8 +716,9 @@ int incoming_handler(struct worker_t *self, struct client_t *c, int l4proto, cha if (l4proto != IPPROTO_UDP) { /* filter adjunct commands ? */ /* TODO: check if the socket type allows filter commands! */ - if (strncasecmp(s, "#filter", 7) == 0) - return filter_commands(self, c, s, len); + char *filtercmd = strstr(s, "filter"); + if (filtercmd) + return filter_commands(self, c, filtercmd, len - (filtercmd - s)); hlog(LOG_DEBUG, "#-in: '%.*s'", len, s); } diff --git a/src/login.c b/src/login.c index 7488600..7b00c54 100644 --- a/src/login.c +++ b/src/login.c @@ -140,7 +140,10 @@ int login_handler(struct worker_t *self, struct client_t *c, int l4proto, char * } - } else if (strcasecmp(argv[i], "filter") == 0) { + } else if (strstr(argv[i], "filter")) { + /* Follows javaaprssrvr's example - any command having 'filter' in the + * end is OK. + */ if (!(c->flags & CLFLAGS_USERFILTEROK)) { return client_printf(self, c, "# No user-specified filters on this port\r\n"); } diff --git a/tests/t/30filter-cmd.t b/tests/t/30filter-cmd.t new file mode 100644 index 0000000..76c5e89 --- /dev/null +++ b/tests/t/30filter-cmd.t @@ -0,0 +1,104 @@ +# +# Filter command testing +# +# Filter can be set either by a "server adjunct command" in the login: +# user pass vers filter +# +# or with a #command in the incoming stream: +# "# filter " +# "#filter " +# "#alfhilawuehflwieuhffilter " +# +# Yes, the command can be prefixed with anything, even in the "user" +# command. +# + +use Test; +BEGIN { plan tests => 6 + 1 + 2 + 2 + 2 + 3 }; +use runproduct; +use istest; +use Ham::APRS::IS; +use Time::HiRes qw(sleep); + +my $p = new runproduct('basic'); + +ok(defined $p, 1, "Failed to initialize product runner"); +ok($p->start(), 1, "Failed to start product"); + +my $login = "N5CAL-1"; +my $server_call = "TESTING"; +my $i_tx = new Ham::APRS::IS("localhost:55580", $login); +ok(defined $i_tx, 1, "Failed to initialize Ham::APRS::IS"); + +# First filter is for uncompressed packet, second for compressed, +# third for mic-e, fourth for prefix filter test. +# The first and last one also test upper-case letters as filter keys. +my $i_rx = new Ham::APRS::IS("localhost:55580", "N5CAL-2", + 'filter' => 'p/OH'); +ok(defined $i_rx, 1, "Failed to initialize Ham::APRS::IS"); + +my $ret; +$ret = $i_tx->connect('retryuntil' => 8); +ok($ret, 1, "Failed to connect to the server: " . $i_tx->{'error'}); + +$ret = $i_rx->connect('retryuntil' => 8); +ok($ret, 1, "Failed to connect to the server: " . $i_rx->{'error'}); + +# do the actual tests +my($tx, $rx, $helper); + +# check that the initial p/ filter works +$tx = $rx = "OH2SRC>APRS,qAR,$login:>should pass"; +istest::txrx(\&ok, $i_tx, $i_rx, $tx, $rx); + +# change filter +$i_rx->sendline("#filter p/N/K"); +sleep(0.2); + +# check that the new filter is applied +$tx = "OH2SRC>APRS,qAR,$login:>should drop"; +$helper = "K2SRC>APRS,qAR,$login:>should pass"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +$tx = "OH2SRC>APRS,qAR,$login:>should drop2"; +$helper = "N2SRC>APRS,qAR,$login:>should pass2"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +# change filter, with some spaces +$i_rx->sendline("# filter p/N/K "); +sleep(0.2); + +# check that the new filter is applied +$tx = "OH2SRC>APRS,qAR,$login:>should drop3"; +$helper = "K2SRC>APRS,qAR,$login:>should pass3"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +$tx = "OH2SRC>APRS,qAR,$login:>should drop4"; +$helper = "N2SRC>APRS,qAR,$login:>should pass4"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +# change filter, with some rubbish in front +$i_rx->sendline("#blaablaaanxauyg3iuyq2gfilter p/OG/OF/OH"); +sleep(0.2); + +# check that the new filter is applied +$tx = "K2SRC>APRS,qAR,$login:>should drop5"; +$helper = "OH2SRC>APRS,qAR,$login:>should pass5"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +$tx = "N2SRC>APRS,qAR,$login:>should drop6"; +$helper = "OH2SRC>APRS,qAR,$login:>should pass6"; +istest::should_drop(\&ok, $i_tx, $i_rx, $tx, $helper); + +# disconnect + +$ret = $i_rx->disconnect(); +ok($ret, 1, "Failed to disconnect from the server: " . $i_rx->{'error'}); + +$ret = $i_tx->disconnect(); +ok($ret, 1, "Failed to disconnect from the server: " . $i_tx->{'error'}); + +# stop + +ok($p->stop(), 1, "Failed to stop product"); + diff --git a/tests/t/30parser-filter.t b/tests/t/30parser-filter.t index 5b72a8d..b405253 100644 --- a/tests/t/30parser-filter.t +++ b/tests/t/30parser-filter.t @@ -7,6 +7,8 @@ # the positions in these packets, and also quickly try out the # p/ prefix filter # +# TODO: add more filter test cases for the rest of the filters +# use Test; BEGIN { plan tests => 17 };