I've completely rewritten the 'host' sorting routines, based on the
acrimonious discussion and research over the last 4-5 days.
It works for me.
Your challenge is to test it. Now.
This routine still isn't perfect and guess what - it still isn't...
always... quite sorting what you see. It is, however, now sorting things
with some plan and intelligence.
Read the page "about sorting this column" for more details than you ever
want. Read the comment in utils.c for the skinny (quoted at the bottom of
this message).
The epiphany was that I realized that the 1st piece I was doing (and talked
about on Friday) would only go so far, because the makeHostLink() routine -
probably the 2nd most troublesome piece of code in ntop (after the now gone
hash resize) - was taking the fixed-up names and mucking with them further
AFTER THEY HAD BEEN SORTED. So what you saw was sometimes nowhere near what
was being sorted.
When I realized this, it woke me out of a sound sleep at 2:45 am on Saturday
Morning and I worked on it until 5 a.m. I've spent the better part of the
last two days polishing it and working out the edge cases.
This represents a lot of internal cleanup.
hostSymIpAddress has been renamed to the more correct hostResolvedName and a
hostResolvedNameType flag added so we know what type it represents. Flag
values are in globals-defines.h - look for FLAG_HOST_SYM_ADDR_TYPE_
There is a routine, setResolvedName() to use when you change this. DO NOT
JUST ARBITRARILY RESET IT. The routine lets you change only from a less
preferred name to a more preferred one (e.g. MAC address -> DNS name).
If you turn on the debug, you can actually SEE ntop resolve the host as it
learns more about it:
DEBUG_CMPFCTN: setResolvedName(0x08a31ff0) 0 -> 5 3COM
CORPORATION:XX:XX:XX - hash.c(1150)
DEBUG_CMPFCTN: setResolvedName(0x08a31ff0) 5 3COM CORPORATION:XX:XX:XX -> 6
192.168.xxx.xxx - hash.c(948)
DEBUG_CMPFCTN: setResolvedName(0x08a31ff0) 6 192.168.xxx.xxx -> -7
pooh.yyy.yyy - address.c(68)
(Neat, eh?)
The compare function to use is cmpFctnResolvedName - this not only knows how
to sort based on hostResolvedNameType, it knows how to sort on the
underlying fields if the resolved version is unavailable!
All of the routines that sorted hostSymIpAddress have been adjusted and a
few additional ones too - it can't HURT to use the smarter sort, even if the
table has been preselected to have only one type of entries.
It works for me - but I've only been able to test in a limited, mostly
TCP/IP and MAC environment.
ToDos:
1) Somebody with NetBIOS and AppleTalk needs to test it.
2) The FibreChanel stuff was touched, albeit with some care, but there's
still one TODO tag in util.c where I think we need to add the proper
FibreChanel test - it may be the one in CMP_FC_PORT, I'm not sure. In fact,
it may be possible to remove CMP_FC_PORT totally and just use
cmpFctnResolvedName. But I don't have enough data to test this - the test
file Dinesh sent me only has one HA.
3) Everybody with edge cases (oddball things) should probably test this.
My plan is to wait a few days, collecting and fixing minor problems, then
package and put out a 3.0pre2.
-----Burton
>From util.c:
/* ********************************************* */
/* ********************************************* */
/* hostResolvedName compare function */
/* ********************************************* */
int cmpFctnResolvedName(const void *_a, const void *_b) {
/* This function is ugly, but critical, so bare with...
It takes two HostTraffic entries and performs a standardized compare
of the hostResolvedName fields, reaching into OTHER fields as necessary.
The SOLE goal is to provide a stable comparison.
Hopefully the results are PREDICTABLE and EXPLAINABLE, but that's
totally
secondary.
Why? Because sorts don't handle non-transitive compares very well.
If A>B but B !< A, the sort will probably CHOKE.
Since the hostResolvedName field contains something like six or nine
possible types of 'names' for a host, a simple alphabetic compare
won't cut it. Especially as hostResolvedName may not be valued
at the time of the compare...
We also can't simply just use the next valued field in the
sets, because we run the risk of intransitive compares,
where
primary(a) > primary(b)
but
secondary(a) < secondary(b)
and if we have say primary for a and c, but not b, risk that
just because a<b and b<c a !< c... this completely hoses the
sort.
So instead in this routine, we practice a gracefull, explicit fallback:
1. If the HostTraffic pointers are NULL, we return equality.
1A. If one of the HostTraffic pointers is NULL, we return THAT entry
as <
2. If both of the hostResolvedName fields are NOT NULL,
and both of the hostResolvedNameType fields are NONE, we:
2A. Check the hostResolvedNameType fields for both A and B.
2A1. If they are identical, we perform the approprate
apples to apples compare.
For example using hostNumIpAddress for a meaningful
IP address sort (where 9.0.0.0 < 10.0.0.0).
2A2. If the hostResolvedNameType fields are NOT identical, we
do the sort on the hostResolvedNameType field itself.
2A1+2A2 means that we sort all of the NAMES alphabetically,
followed by all of the IP addresses sorted NUMERICALLY,
followed by...
3A. If precisely ONE of the hostResolvedName fields is NULL or precisely
ONE
of the hostResolvedNameType fields is NONE, we return the
valued field < the unvalued one (so unresolved things fall to the
end of the sort).
3B. If both of the hostResolvedName fields are NULL, we fall back
gracefully, seeking - in the order of the _TYPE flags, a field which
is valued in BOTH a and b.
4. Finally if nothing matches, we return a=b.
*/
_______________________________________________
Ntop-dev mailing list
[EMAIL PROTECTED]
http://listgateway.unipi.it/mailman/listinfo/ntop-dev