[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-hams
Subject: Re: [PATCH] ax25tools mheard : don't display empty records
From: Thomas Osterried <thomas () x-berg ! in-berlin ! de>
Date: 2013-08-09 8:10:36
Message-ID: 20130809081036.GF18314 () x-berg ! in-berlin ! de
[Download RAW message or body]
On 2013-08-06 19:57:51 +0200, f6bvp@free <f6bvp@free.fr>
wrote in <5201391F.40607@free.fr>:
> I noticed that in some cases, mheard would read data base and list a
> number of empty lines with zero packet received.
> Empty lines displayed roll up the list and sometime makes
> uncomfortable the reading of captured callsigns.
>
> With this patch mheard client will display only usefull information
> and skip empty records.
The data file is a block list of struct mheard_struct. This data
is stored along with "in_use" and "position" (SEEK) in mheard_list_struct
for operation in memory. This data is synced to file after each heard
AX.25 frame.
findentry() operates on the memory list mheard_list_struct. It
- looks for an exact match (from call + portname)
- If not found, it searches for the first "not in_use" in the memory list \
mheard_list_struct. It marks it in_use and returns a fictive SEEK (for SEEK_END usage \
during the later file sync)
- If the list is "full", it searches for the oldest entry, and nulls the data.
This looks fine.
If you look in the mheard program for "count != 0" only for displaying the data, then \
calls with exactly heard 65536 (sizeof(unsigned int) packets are not display. Ok, \
this is not large issue. But more reliably is, that a callsign never starts with \0 \
(calls are stored left aligned, and have only chars like A..Z, 0..9 and ' ').
Let's look at the potential race-conditions that causes the "bad" entries you try to \
filter out.
I assume, that condition 2 of findentry() is responsible. It looks for the first \
"hole" (i. E. if you just have heard 1 call, the first hole in the list of 1000 nodes \
is the second position) and marks it "in_use".
findendry() is called in the large mainloop after each packet receiption.
First race-condition:
if (!ax25_validate(data + 0) || !ax25_validate(data + AXLEN)) {
if (logging)
syslog(LOG_WARNING, "invalid callsign on port %s\n", \
port); continue;
}
=> After the receiption of a corrupted callsign in the from or to address field, \
the packet will be ignored.
The field is marked as in_use. The count is 0 (because the complete struct is \
nulled).
Next race-condition:
From and To call, port name and ndigis is filled.
Afterwards, the size of the packet is looked up. If 0, then it's thrown away:
if (size == 0) {
if (logging)
syslog(LOG_WARNING, "packet too short\n");
continue;
}
=> The field is marked in use. The data filled in is incomplete (other info would \
have stored later, like packet type, heard time, ..). count is still 0.
After this: mheard->entry.count++;
After the next new call has been heard after this race-condx, fseek() makes a gap \
between the last entry and this new entry, that contains zero data.
==> mheardd may cause empty blocks. and mheard does not care.
Further theoretical impacts:
if ((fp = fopen(DATA_MHEARD_FILE, "r+")) == NULL) {
if (logging)
syslog(LOG_ERR, "cannot open mheard data file\n");
continue;
}
=> If the filesystem is temporarily full, the entry will be ommited.
If i.E. 3 new calls are heard, then the filesystem is filled, and then the next new \
call is heard, then fseek(fp, mheard->position, SEEK_SET);
will make 3 gaps (nulled) and stores the new mheard struct entry.
The info of the 3 calls is lost. The file has gap entries. But since we always \
operate with seek, it doesn't matter at all.
Next potential problem:
fwrite(&mheard->entry, sizeof(struct mheard_struct), 1, fp);
If fwrrite() cannot write the whole data (i.E. filesystem gets full during write, or \
if the hd has an error and the write times out during operation, then the appended \
length of data is shorter than sizeof(struct mheard_struct). Because we operate on \
blocks, all other data that is appended later is completely garbage (i.E. you expcect \
a callsignt but get statistic data at that position).
This could be corrected by changing
if (mheard->position == 0xFFFFFF) {
fseek(fp, 0L, SEEK_END);
mheard->position = ftell(fp);
}
to:
if (mheard->position == 0xFFFFFF) {
fseek(fp, 0L, SEEK_END);
mheard->position = ftell(fp);
/* check for block offset error and align to */
if ((mheard->position % sizeof(struct mheard_struct)) != 0)
mheard->position -= (mheard->position % sizeof(struct \
mheard_struct); }
Bernard, what do you think was the real cause for your corruptd data?
I think it was a fail of ax25_validate() of the from/to call.
Thus I'd suggest to set
memset(&mheard->entry, 0x00, sizeof(struct mheard_struct));
mheard->in_use = FALSE;
before the "continue" statement in the validity checks for a received frame.
This should avoid gaps.
Perhaps, we've not been successful to avoid all gaps. And the gaps really
do not harm.
=> For mheard:
zero records have *from_call == \0.
incomplete records may have some other data not filled in.
Because the mheardd does after filling all data sets the time
(time(&mheard->entry.last_heard);)
I argue, that this information is well enough to say, that it contains
valid information.
That said, we're able to skip empty blocks during the file read in the mheard \
program: currently:
while (fread(&mheard, sizeof(struct mheard_struct), 1, fp) == 1) {
pr = malloc(sizeof(struct PortRecord));
pr->entry = mheard;
pr->Next = PortList;
PortList = pr;
}
solution:
while (fread(&mheard, sizeof(struct mheard_struct), 1, fp) == 1) {
/* skip empty blocks */
if (mheard->entry.last_heard == 0L)
continue;
/* or, if you really like better this one: if (*mheard->from_call == \
'\0) continue; */ pr = malloc(sizeof(struct PortRecord));
pr->entry = mheard;
pr->Next = PortList;
PortList = pr;
}
vy 73,
- Thomas dl9sau
--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic