From 203925785fa2dacbc3f55e9cbae7bd7609b2331a Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Fri, 1 Mar 2013 16:54:20 +0200 Subject: [PATCH] Improved quirks mode: Clean up spaces in end of path elements --- src/incoming.c | 86 ++++++++++++++++++++++++++++++----------- src/web/aprsc.js | 3 +- src/worker.h | 3 +- tests/t/12quirks-mode.t | 15 ++++++- 4 files changed, 81 insertions(+), 26 deletions(-) diff --git a/src/incoming.c b/src/incoming.c index 88b3a86..cc450e8 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -74,7 +74,8 @@ const char *inerr_labels[] = { "q_qau_path_call_srccall", "q_newq_buffer_small", "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]) @@ -692,35 +693,74 @@ int incoming_parse(struct worker_t *self, struct client_t *c, char *s, int len) int path_append_len; int originated_by_client = 0; 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) { + /* rewritten packet */ + char *np = quirked; + + // Easy pointer for comparing against far end.. + packet_end = s + len; + /* trim spaces and NULs from beginning */ - while ((*s == ' ' || *s == 0) && len > 0) { - len--; - s++; + p = 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 '>' */ - src_end = memchr(s, '>', len < CALLSIGNLEN_MAX+1 ? len : CALLSIGNLEN_MAX+1); - if (!src_end) - return INERR_NO_DST; // No ">" in packet start.. + /* copy rest of packet */ + while (p < packet_end) + *(np++) = *(p++); - /* trim spaces from end of srccall */ - char *old_src_end = src_end; - while (src_end > s && *(src_end-1) == ' ') - src_end--; - - 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); + *np = 0; + if (np - quirked != len) { + hlog_packet(LOG_DEBUG, s, len, "borrked packet: "); + hlog_packet(LOG_DEBUG, quirked, np - quirked, "quirked packet: "); } + + s = quirked; + len = np - quirked; } /* check for minimum length of packet */ diff --git a/src/web/aprsc.js b/src/web/aprsc.js index d9f65d7..3355bd6 100644 --- a/src/web/aprsc.js +++ b/src/web/aprsc.js @@ -214,7 +214,8 @@ var rx_err_strings = { "q_qau_path_call_srccall": 'qAU callsign in path equals srccall', "q_newq_buffer_small": 'New Q construct too big', "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 = { diff --git a/src/worker.h b/src/worker.h index 8ac4a6a..26cb851 100644 --- a/src/worker.h +++ b/src/worker.h @@ -213,8 +213,9 @@ struct client_heard_t { #define INERR_Q_NEWQ_BUFFER_SMALL -28 #define INERR_Q_NONVAL_MULTI_Q_CALLS -29 #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! */ #define INERR_BUCKETS (INERR_MIN*-1 + 1) diff --git a/tests/t/12quirks-mode.t b/tests/t/12quirks-mode.t index 25edb1f..a34e935 100644 --- a/tests/t/12quirks-mode.t +++ b/tests/t/12quirks-mode.t @@ -4,7 +4,7 @@ # use Test; -BEGIN { plan tests => 6 + 3 + 3 }; +BEGIN { plan tests => 6 + 5 + 3 }; use runproduct; use istest; use Ham::APRS::IS; @@ -51,6 +51,19 @@ $tx = "SRC $tail"; $rx = "SRC$tail"; 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 $ret = $i_tx->disconnect();