Improved quirks mode: Clean up spaces in end of path elements

This commit is contained in:
Heikki Hannikainen 2013-03-01 16:54:20 +02:00
parent 2bae92daae
commit 203925785f
4 changed files with 81 additions and 26 deletions

View File

@ -74,7 +74,8 @@ const char *inerr_labels[] = {
"q_qau_path_call_srccall", "q_qau_path_call_srccall",
"q_newq_buffer_small", "q_newq_buffer_small",
"q_nonval_multi_q_calls", "q_nonval_multi_q_calls",
"q_i_no_viacall" "q_i_no_viacall",
"inerr_empty"
}; };
#define incoming_strerror(i) ((i <= 0 && i >= INERR_MIN) ? inerr_labels[i * -1] : inerr_labels[0]) #define incoming_strerror(i) ((i <= 0 && i >= INERR_MIN) ? inerr_labels[i * -1] : inerr_labels[0])
@ -692,35 +693,74 @@ int incoming_parse(struct worker_t *self, struct client_t *c, char *s, int len)
int path_append_len; int path_append_len;
int originated_by_client = 0; int originated_by_client = 0;
char *p; char *p;
char quirked[PACKETLEN_MAX+2]; /* rewritten packet */
/* for quirky clients, do some special treatment */ /* for quirky clients, do some special treatment: build a new copy of
* the packet with extra spaces removed from packets
*/
if (c->quirks_mode) { if (c->quirks_mode) {
/* rewritten packet */
char *np = quirked;
// Easy pointer for comparing against far end..
packet_end = s + len;
/* trim spaces and NULs from beginning */ /* trim spaces and NULs from beginning */
while ((*s == ' ' || *s == 0) && len > 0) { p = s;
len--;
s++; while (p < packet_end && (*p == ' ' || *p == 0))
p++;
if (p == packet_end)
return INERR_EMPTY;
/* copy srccall, look for the '>' */
while (p < packet_end && *p != '>' && *p != ' ')
*np++ = *p++;
/* skip spaces in end of srccall */
while (*p == ' ' && p < packet_end)
p++;
if (*p != '>')
return INERR_NO_DST;
/* copy path, removing trailing spaces from callsigns */
while (p < packet_end && *p != ':') {
/* copy path element */
while (p < packet_end && *p != ',' && *p != ':' && *p != ' ')
*np++ = *p++;
/* if we found spaces, scan over them */
while (p < packet_end && *p == ' ')
p++;
/* if the element ends with a comma, fine */
if (p < packet_end && *p == ',') {
*np++ = *p++;
continue;
}
/* end of path? fine */
if (*p == ':')
continue;
/* not fine. */
return INERR_INV_PATH_CALL;
} }
/* look for the '>' */ /* copy rest of packet */
src_end = memchr(s, '>', len < CALLSIGNLEN_MAX+1 ? len : CALLSIGNLEN_MAX+1); while (p < packet_end)
if (!src_end) *(np++) = *(p++);
return INERR_NO_DST; // No ">" in packet start..
/* trim spaces from end of srccall */ *np = 0;
char *old_src_end = src_end; if (np - quirked != len) {
while (src_end > s && *(src_end-1) == ' ') hlog_packet(LOG_DEBUG, s, len, "borrked packet: ");
src_end--; hlog_packet(LOG_DEBUG, quirked, np - quirked, "quirked packet: ");
if (src_end == s)
return INERR_NO_DST; /* srccall was all spaces */
if (src_end != old_src_end) {
int dist = old_src_end - src_end;
memmove(s + dist, s, src_end - s);
len -= dist;
s += dist;
hlog_packet(LOG_DEBUG, s, len, "quirks_mode trimmed %d spaces from srccall: ", dist);
} }
s = quirked;
len = np - quirked;
} }
/* check for minimum length of packet */ /* check for minimum length of packet */

View File

@ -214,7 +214,8 @@ var rx_err_strings = {
"q_qau_path_call_srccall": 'qAU callsign in path equals srccall', "q_qau_path_call_srccall": 'qAU callsign in path equals srccall',
"q_newq_buffer_small": 'New Q construct too big', "q_newq_buffer_small": 'New Q construct too big',
"q_nonval_multi_q_calls": 'Multiple callsigns in Q path from unverified client', "q_nonval_multi_q_calls": 'Multiple callsigns in Q path from unverified client',
"q_i_no_viacall": 'I path has no viacall' "q_i_no_viacall": 'I path has no viacall',
"inerr_empty": 'Empty packet'
}; };
var key_translate = { var key_translate = {

View File

@ -213,8 +213,9 @@ struct client_heard_t {
#define INERR_Q_NEWQ_BUFFER_SMALL -28 #define INERR_Q_NEWQ_BUFFER_SMALL -28
#define INERR_Q_NONVAL_MULTI_Q_CALLS -29 #define INERR_Q_NONVAL_MULTI_Q_CALLS -29
#define INERR_Q_I_NO_VIACALL -30 #define INERR_Q_I_NO_VIACALL -30
#define INERR_EMPTY -31
#define INERR_MIN -30 /* MINIMUM VALUE FOR INERR, GROW WHEN NEEDED! */ #define INERR_MIN -31 /* MINIMUM VALUE FOR INERR, GROW WHEN NEEDED! */
/* WHEN ADDING STUFF HERE, REMEMBER TO UPDATE inerr_labels IN incoming.c. Thanks! */ /* WHEN ADDING STUFF HERE, REMEMBER TO UPDATE inerr_labels IN incoming.c. Thanks! */
#define INERR_BUCKETS (INERR_MIN*-1 + 1) #define INERR_BUCKETS (INERR_MIN*-1 + 1)

View File

@ -4,7 +4,7 @@
# #
use Test; use Test;
BEGIN { plan tests => 6 + 3 + 3 }; BEGIN { plan tests => 6 + 5 + 3 };
use runproduct; use runproduct;
use istest; use istest;
use Ham::APRS::IS; use Ham::APRS::IS;
@ -51,6 +51,19 @@ $tx = "SRC $tail";
$rx = "SRC$tail"; $rx = "SRC$tail";
istest::txrx(\&ok, $i_tx, $i_rx, $tx, $rx); istest::txrx(\&ok, $i_tx, $i_rx, $tx, $rx);
# spaces in path callsign
$tail = ":>spaces in end of path element";
$tx = "SRC>DST,qAR,$login $tail";
$rx = "SRC>DST,qAR,$login$tail";
istest::txrx(\&ok, $i_tx, $i_rx, $tx, $rx);
# should drop with bad srccall
$tx = 'default setting is>DST,qAR,FOO:bad srccall';
istest::should_drop(\&ok, $i_tx, $i_rx,
$tx,
"SRC>LONG:dummy", 1); # will pass (helper packet)
# disconnect # disconnect
$ret = $i_tx->disconnect(); $ret = $i_tx->disconnect();