mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-05 21:07:52 +00:00
use GLib GHashTable for port monitors
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@806 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
parent
e881609a07
commit
e4713dc790
@ -1,5 +1,14 @@
|
||||
# $Id$
|
||||
|
||||
2006-12-09
|
||||
* Replaced hash module used by libtcp-portmon with GLib's GHashTable,
|
||||
due to licensing issue noted by Fedora Core packagers.
|
||||
* Eliminated config items:
|
||||
min_port_monitors,
|
||||
min_port_monitor_connections
|
||||
* Added config item:
|
||||
max_port_monitor_connections
|
||||
|
||||
2006-11-30
|
||||
* Added $entropy_avail, $entropy_poolsize and $entropy_bar
|
||||
for the crypto freaks. Idea suggested by Perttu Luukko
|
||||
|
251
README
251
README
@ -220,8 +220,13 @@ CONFIGURATION SETTINGS
|
||||
Mail spool for mail checking
|
||||
|
||||
|
||||
max_port_monitor_connections
|
||||
Allow each port monitor to track at most this many connections
|
||||
(if 0 or not set, default is 256)
|
||||
|
||||
|
||||
max_specials
|
||||
Maximum number of special things, e.g. fonts, offsets, aligns,
|
||||
Maximum number of special things, e.g. fonts, offsets, aligns,
|
||||
etc. (default is 512)
|
||||
|
||||
|
||||
@ -238,16 +243,6 @@ CONFIGURATION SETTINGS
|
||||
Minimum size of window
|
||||
|
||||
|
||||
min_port_monitors
|
||||
Allow for the creation of at least this number of port monitors
|
||||
(if 0 or not set, default is 16)
|
||||
|
||||
|
||||
min_port_monitor_connections
|
||||
Allow each port monitor to track at least this many connections
|
||||
(if 0 or not set, default is 256)
|
||||
|
||||
|
||||
mpd_host
|
||||
Host of MPD server
|
||||
|
||||
@ -281,26 +276,26 @@ CONFIGURATION SETTINGS
|
||||
|
||||
|
||||
own_window_type
|
||||
if own_window is yes, you may specify type normal, desktop or
|
||||
if own_window is yes, you may specify type normal, desktop or
|
||||
override (default: normal). Desktop windows are special windows
|
||||
that have no window decorations; are always visible on your
|
||||
desktop; do not appear in your pager or taskbar; and are sticky
|
||||
across all workspaces. Override windows are not under the con-
|
||||
that have no window decorations; are always visible on your
|
||||
desktop; do not appear in your pager or taskbar; and are sticky
|
||||
across all workspaces. Override windows are not under the con-
|
||||
trol of the window manager. Hints are ignored. This type of win-
|
||||
dow can be useful for certain situations.
|
||||
|
||||
|
||||
own_window_colour colour
|
||||
If own_window_transparent no, set a specified background colour
|
||||
(defaults to black). Takes either a hex value (#ffffff) or a
|
||||
If own_window_transparent no, set a specified background colour
|
||||
(defaults to black). Takes either a hex value (#ffffff) or a
|
||||
valid RGB name (see /usr/lib/X11/rgb.txt)
|
||||
|
||||
|
||||
own_window_hints undecorated,below,above,sticky,skip_taskbar,skip_pager
|
||||
If own_window is yes, you may use these window manager hints to
|
||||
If own_window is yes, you may use these window manager hints to
|
||||
affect the way Conky displays. Notes: Use own_window_type desk-
|
||||
top as another way to implement many of these hints implicitly.
|
||||
If you use own_window_type override, window manager hints have
|
||||
top as another way to implement many of these hints implicitly.
|
||||
If you use own_window_type override, window manager hints have
|
||||
no meaning and are ignored.
|
||||
|
||||
|
||||
@ -312,9 +307,9 @@ CONFIGURATION SETTINGS
|
||||
Pad percentages to this many decimals (0 = no padding)
|
||||
|
||||
|
||||
pop3 Default global POP3 server. Arguments are: "host user pass [-i
|
||||
interval] [-p port] [-e command]". Default port is 110, default
|
||||
interval is 5 minutes. If the password is supplied as '*', you
|
||||
pop3 Default global POP3 server. Arguments are: "host user pass [-i
|
||||
interval] [-p port] [-e command]". Default port is 110, default
|
||||
interval is 5 minutes. If the password is supplied as '*', you
|
||||
will be prompted to enter the password when Conky starts.
|
||||
|
||||
|
||||
@ -323,7 +318,7 @@ CONFIGURATION SETTINGS
|
||||
|
||||
|
||||
total_run_times
|
||||
Total number of times for Conky to update before quitting. Zero
|
||||
Total number of times for Conky to update before quitting. Zero
|
||||
makes Conky run forever
|
||||
|
||||
|
||||
@ -361,10 +356,10 @@ CONFIGURATION SETTINGS
|
||||
|
||||
|
||||
VARIABLES
|
||||
Colors are parsed using XParsecolor(), there might be a list of them:
|
||||
/usr/X11R6/lib/X11/rgb.txt. Also, <http://sedition.com/perl/rgb.html>.
|
||||
Color can be also in #rrggbb format (hex). Note that when displaying
|
||||
bytes, power is 1024 and not 1000 so 1M really means 1024*1024 bytes
|
||||
Colors are parsed using XParsecolor(), there might be a list of them:
|
||||
/usr/X11R6/lib/X11/rgb.txt. Also, <http://sedition.com/perl/rgb.html>.
|
||||
Color can be also in #rrggbb format (hex). Note that when displaying
|
||||
bytes, power is 1024 and not 1000 so 1M really means 1024*1024 bytes
|
||||
and not 1000*1000.
|
||||
|
||||
addr interface
|
||||
@ -412,7 +407,7 @@ VARIABLES
|
||||
|
||||
|
||||
apm_battery_time
|
||||
Display remaining APM battery life in hh:mm:ss or "unknown" if
|
||||
Display remaining APM battery life in hh:mm:ss or "unknown" if
|
||||
AC adapterstatus is on-line or charging (FreeBSD only)
|
||||
|
||||
|
||||
@ -469,7 +464,7 @@ VARIABLES
|
||||
|
||||
|
||||
battery (num)
|
||||
Remaining capacity in ACPI or APM battery. ACPI battery number
|
||||
Remaining capacity in ACPI or APM battery. ACPI battery number
|
||||
can be given as argument (default is BAT0).
|
||||
|
||||
|
||||
@ -509,28 +504,28 @@ VARIABLES
|
||||
|
||||
|
||||
cpu (cpuN)
|
||||
CPU usage in percents. For SMP machines, the CPU number can be
|
||||
provided as an argument. ${cpu 0} is the total usage, and ${cpu
|
||||
CPU usage in percents. For SMP machines, the CPU number can be
|
||||
provided as an argument. ${cpu 0} is the total usage, and ${cpu
|
||||
X} (X >= 1) are individual CPUs.
|
||||
|
||||
|
||||
cpubar (cpu number) (height),(width)
|
||||
Bar that shows CPU usage, height is bar's height in pixels. See
|
||||
Bar that shows CPU usage, height is bar's height in pixels. See
|
||||
$cpu for more info on SMP.
|
||||
|
||||
|
||||
cpugraph (cpu number) (height),(width) (gradient colour 1) (gradient
|
||||
cpugraph (cpu number) (height),(width) (gradient colour 1) (gradient
|
||||
colour 2)
|
||||
CPU usage graph, with optional colours in hex, minus the #. See
|
||||
CPU usage graph, with optional colours in hex, minus the #. See
|
||||
$cpu for more info on SMP.
|
||||
|
||||
|
||||
diskio Displays current disk IO.
|
||||
|
||||
|
||||
diskiograph (height),(width) (gradient colour 1) (gradient colour 2)
|
||||
diskiograph (height),(width) (gradient colour 1) (gradient colour 2)
|
||||
(scale)
|
||||
Disk IO graph, colours defined in hex, minus the #. If scale is
|
||||
Disk IO graph, colours defined in hex, minus the #. If scale is
|
||||
non-zero, it becomes the scale for the graph.
|
||||
|
||||
|
||||
@ -544,7 +539,7 @@ VARIABLES
|
||||
|
||||
downspeedgraph net (height),(width) (gradient colour 1) (gradient
|
||||
colour 2) (scale)
|
||||
Download speed graph, colours defined in hex, minus the #. If
|
||||
Download speed graph, colours defined in hex, minus the #. If
|
||||
scale is non-zero, it becomes the scale for the graph.
|
||||
|
||||
|
||||
@ -565,12 +560,12 @@ VARIABLES
|
||||
|
||||
exec command
|
||||
Executes a shell command and displays the output in conky. warn-
|
||||
ing: this takes a lot more resources than other variables. I'd
|
||||
ing: this takes a lot more resources than other variables. I'd
|
||||
recommend coding wanted behaviour in C and posting a patch.
|
||||
|
||||
|
||||
execbar command
|
||||
Same as exec, except if the first value return is a value be-
|
||||
Same as exec, except if the first value return is a value be-
|
||||
tween 0-100, it will use that number for a bar. The size for the
|
||||
bar is currently fixed, but that may change in the future.
|
||||
|
||||
@ -580,7 +575,7 @@ VARIABLES
|
||||
|
||||
|
||||
execi interval command
|
||||
Same as exec but with specific interval. Interval can't be less
|
||||
Same as exec but with specific interval. Interval can't be less
|
||||
than update_interval in configuration. See also $texeci
|
||||
|
||||
|
||||
@ -593,36 +588,36 @@ VARIABLES
|
||||
|
||||
|
||||
font (font)
|
||||
Specify a different font. This new font will apply to the cur-
|
||||
rent line and everything following. You can use a $font with no
|
||||
arguments to change back to the default font (much like with
|
||||
Specify a different font. This new font will apply to the cur-
|
||||
rent line and everything following. You can use a $font with no
|
||||
arguments to change back to the default font (much like with
|
||||
$color)
|
||||
|
||||
|
||||
freq (n)
|
||||
Returns CPU #n's frequency in MHz. CPUs are counted from 1. If
|
||||
Returns CPU #n's frequency in MHz. CPUs are counted from 1. If
|
||||
omitted, the parameter defaults to 1.
|
||||
|
||||
|
||||
freq_g (n)
|
||||
Returns CPU #n's frequency in GHz. CPUs are counted from 1. If
|
||||
Returns CPU #n's frequency in GHz. CPUs are counted from 1. If
|
||||
omitted, the parameter defaults to 1.
|
||||
|
||||
|
||||
freq_dyn
|
||||
Returns CPU frequency in MHz, but is calculated by counting to
|
||||
clock cycles to complete an instruction. Only available for
|
||||
Returns CPU frequency in MHz, but is calculated by counting to
|
||||
clock cycles to complete an instruction. Only available for
|
||||
x86/amd64.
|
||||
|
||||
|
||||
freq_dyn_g
|
||||
Returns CPU frequency in GHz, but is calculated by counting to
|
||||
clock cycles to complete an instruction. Only available for
|
||||
Returns CPU frequency in GHz, but is calculated by counting to
|
||||
clock cycles to complete an instruction. Only available for
|
||||
x86/amd64.
|
||||
|
||||
|
||||
fs_bar (height),(width) fs
|
||||
Bar that shows how much space is used on a file system. height
|
||||
Bar that shows how much space is used on a file system. height
|
||||
is the height in pixels. fs is any file on that file system.
|
||||
|
||||
|
||||
@ -646,14 +641,14 @@ VARIABLES
|
||||
|
||||
|
||||
hddtemp dev, (host,(port))
|
||||
Displays temperature of a selected hard disk drive as reported
|
||||
by the hddtemp daemon running on host:port. Default host is
|
||||
Displays temperature of a selected hard disk drive as reported
|
||||
by the hddtemp daemon running on host:port. Default host is
|
||||
127.0.0.1, default port is 7634.
|
||||
|
||||
|
||||
head logfile lines (interval)
|
||||
Displays first N lines of supplied text text file. If interval
|
||||
is not supplied, Conky assumes 2x Conky's interval. Max of 30
|
||||
Displays first N lines of supplied text text file. If interval
|
||||
is not supplied, Conky assumes 2x Conky's interval. Max of 30
|
||||
lines can be displayed, or until the text buffer is filled.
|
||||
|
||||
|
||||
@ -662,7 +657,7 @@ VARIABLES
|
||||
|
||||
|
||||
iconv_start codeset_from codeset_to
|
||||
Convert text from one codeset to another using GNU iconv. Needs
|
||||
Convert text from one codeset to another using GNU iconv. Needs
|
||||
to be stopped with iconv_stop.
|
||||
|
||||
|
||||
@ -671,75 +666,75 @@ VARIABLES
|
||||
|
||||
|
||||
i2c (dev) type n
|
||||
I2C sensor from sysfs (Linux 2.6). dev may be omitted if you
|
||||
have only one I2C device. type is either in (or vol) meaning
|
||||
I2C sensor from sysfs (Linux 2.6). dev may be omitted if you
|
||||
have only one I2C device. type is either in (or vol) meaning
|
||||
voltage, fan meaning fan or temp/tempf (first in C, second in F)
|
||||
meaning temperature. n is number of the sensor. See
|
||||
meaning temperature. n is number of the sensor. See
|
||||
/sys/bus/i2c/devices/ on your local computer.
|
||||
|
||||
|
||||
i8k_ac_status
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
whether ac power is on, as listed in /proc/i8k (translated to
|
||||
human-readable). Beware that this is by default not enabled by
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
whether ac power is on, as listed in /proc/i8k (translated to
|
||||
human-readable). Beware that this is by default not enabled by
|
||||
i8k itself.
|
||||
|
||||
|
||||
i8k_bios
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the bios version as listed in /proc/i8k.
|
||||
|
||||
|
||||
i8k_buttons_status
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the volume buttons status as listed in /proc/i8k.
|
||||
|
||||
|
||||
i8k_cpu_temp
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the cpu temperature in Celsius, as reported by /proc/i8k.
|
||||
|
||||
|
||||
i8k_cpu_tempf
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the cpu temperature in Fahrenheit, as reported by /proc/i8k.
|
||||
|
||||
|
||||
i8k_left_fan_rpm
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the left fan's rate of rotation, in revolutions per minute as
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the left fan's rate of rotation, in revolutions per minute as
|
||||
listed in /proc/i8k. Beware, some laptops i8k reports these fans
|
||||
in reverse order.
|
||||
|
||||
|
||||
i8k_left_fan_status
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the left fan status as listed in /proc/i8k (translated to human-
|
||||
readable). Beware, some laptops i8k reports these fans in re-
|
||||
readable). Beware, some laptops i8k reports these fans in re-
|
||||
verse order.
|
||||
|
||||
|
||||
i8k_right_fan_rpm
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the right fan's rate of rotation, in revolutions per minute as
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the right fan's rate of rotation, in revolutions per minute as
|
||||
listed in /proc/i8k. Beware, some laptops i8k reports these fans
|
||||
in reverse order.
|
||||
|
||||
|
||||
i8k_right_fan_status
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the right fan status as listed in /proc/i8k (translated to hu-
|
||||
man-readable). Beware, some laptops i8k reports these fans in
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the right fan status as listed in /proc/i8k (translated to hu-
|
||||
man-readable). Beware, some laptops i8k reports these fans in
|
||||
reverse order.
|
||||
|
||||
|
||||
i8k_serial
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
your laptop serial number as listed in /proc/i8k.
|
||||
|
||||
|
||||
i8k_version
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
If running the i8k kernel driver for Inspiron laptops, displays
|
||||
the version formatting of /proc/i8k.
|
||||
|
||||
|
||||
@ -748,13 +743,13 @@ VARIABLES
|
||||
|
||||
|
||||
ibm_temps N
|
||||
If running the IBM ACPI, displays the temperatures from the IBM
|
||||
If running the IBM ACPI, displays the temperatures from the IBM
|
||||
temperature sensors (N=0..7) Sensor 0 is on the CPU, 3 is on the
|
||||
GPU.
|
||||
|
||||
|
||||
ibm_volume
|
||||
If running the IBM ACPI, displays the "master" volume, con-
|
||||
If running the IBM ACPI, displays the "master" volume, con-
|
||||
trolled by the volume keys (0-14).
|
||||
|
||||
|
||||
@ -764,25 +759,25 @@ VARIABLES
|
||||
|
||||
|
||||
if_running (process)
|
||||
if PROCESS is running, display everything if_running and the
|
||||
if PROCESS is running, display everything if_running and the
|
||||
matching $endif
|
||||
|
||||
|
||||
if_existing (file)
|
||||
if FILE exists, display everything between if_existing and the
|
||||
if FILE exists, display everything between if_existing and the
|
||||
matching $endif
|
||||
|
||||
|
||||
if_mounted (mountpoint)
|
||||
if MOUNTPOINT is mounted, display everything between if_mounted
|
||||
if MOUNTPOINT is mounted, display everything between if_mounted
|
||||
and the matching $endif
|
||||
|
||||
|
||||
imap_messages (args)
|
||||
Displays the number of messages in your global IMAP inbox by de-
|
||||
fault. You can define individual IMAP inboxes seperately by
|
||||
fault. You can define individual IMAP inboxes seperately by
|
||||
passing arguments to this object. Arguments are: "host user pass
|
||||
[-i interval] [-p port] [-e command]". Default port is 143, de-
|
||||
[-i interval] [-p port] [-e command]". Default port is 143, de-
|
||||
fault interval is 5 minutes. If the password is supplied as '*',
|
||||
you will be prompted to enter the password when Conky starts.
|
||||
|
||||
@ -791,7 +786,7 @@ VARIABLES
|
||||
Displays the number of unseen messages in your global IMAP inbox
|
||||
by default. You can define individual IMAP inboxes seperately by
|
||||
passing arguments to this object. Arguments are: "host user pass
|
||||
[-i interval] [-p port] [-e command]". Default port is 143, de-
|
||||
[-i interval] [-p port] [-e command]". Default port is 143, de-
|
||||
fault interval is 5 minutes. If the password is supplied as '*',
|
||||
you will be prompted to enter the password when Conky starts.
|
||||
|
||||
@ -812,8 +807,8 @@ VARIABLES
|
||||
Machine, i686 for example
|
||||
|
||||
|
||||
mails Mail count in mail spool. You can use program like fetchmail to
|
||||
get mails from some server using your favourite protocol. See
|
||||
mails Mail count in mail spool. You can use program like fetchmail to
|
||||
get mails from some server using your favourite protocol. See
|
||||
also new_mails.
|
||||
|
||||
|
||||
@ -910,17 +905,17 @@ VARIABLES
|
||||
|
||||
pb_battery item
|
||||
If running on Apple powerbook/ibook, display information on bat-
|
||||
tery status. The item parameter specifies, what information to
|
||||
tery status. The item parameter specifies, what information to
|
||||
display. Exactly one item must be specified. Valid items are:
|
||||
|
||||
status: Display if battery is fully charged, charging, discharg-
|
||||
ing or absent (running on AC)
|
||||
percent: Display charge of battery in percent, if charging or
|
||||
discharging. Nothing will be displayed, if battery is fully
|
||||
percent: Display charge of battery in percent, if charging or
|
||||
discharging. Nothing will be displayed, if battery is fully
|
||||
charged or absent.
|
||||
time: Display the time remaining until the battery will be fully
|
||||
charged or discharged at current rate. Nothing is displayed, if
|
||||
battery is absent or if it's present but fully charged and not
|
||||
charged or discharged at current rate. Nothing is displayed, if
|
||||
battery is absent or if it's present but fully charged and not
|
||||
discharging.
|
||||
|
||||
|
||||
@ -928,17 +923,17 @@ VARIABLES
|
||||
Displays the number of unseen messages in your global POP3 inbox
|
||||
by default. You can define individual POP3 inboxes seperately by
|
||||
passing arguments to this object. Arguments are: "host user pass
|
||||
[-i interval] [-p port] [-e command]". Default port is 110, de-
|
||||
[-i interval] [-p port] [-e command]". Default port is 110, de-
|
||||
fault interval is 5 minutes. If the password is supplied as '*',
|
||||
you will be prompted to enter the password when Conky starts.
|
||||
|
||||
|
||||
pop3_used (args)
|
||||
Displays the amount of space (in MiB, 2^20) used in your global
|
||||
POP3 inbox by default. You can define individual POP3 inboxes
|
||||
seperately by passing arguments to this object. Arguments are:
|
||||
"host user pass [-i interval] [-p port] [-e command]". Default
|
||||
port is 110, default interval is 5 minutes. If the password is
|
||||
Displays the amount of space (in MiB, 2^20) used in your global
|
||||
POP3 inbox by default. You can define individual POP3 inboxes
|
||||
seperately by passing arguments to this object. Arguments are:
|
||||
"host user pass [-i interval] [-p port] [-e command]". Default
|
||||
port is 110, default interval is 5 minutes. If the password is
|
||||
supplied as '*', you will be prompted to enter the password when
|
||||
Conky starts.
|
||||
|
||||
@ -1000,36 +995,36 @@ VARIABLES
|
||||
The connection index provides you with access to each connection
|
||||
in the port monitor. The monitor will return information for in-
|
||||
dex values from 0 to n-1 connections. Values higher than n-1 are
|
||||
simply ignored. For the "count" item, the connection index must
|
||||
simply ignored. For the "count" item, the connection index must
|
||||
be omitted. It is required for all other items.
|
||||
|
||||
Examples:
|
||||
${tcp_portmon 6881 6999 count} - displays the number of connec-
|
||||
${tcp_portmon 6881 6999 count} - displays the number of connec-
|
||||
tions in the bittorrent port range
|
||||
${tcp_portmon 22 22 rip 0} - displays the remote host ip of the
|
||||
${tcp_portmon 22 22 rip 0} - displays the remote host ip of the
|
||||
first sshd connection
|
||||
${tcp_portmon 22 22 rip 9} - displays the remote host ip of the
|
||||
${tcp_portmon 22 22 rip 9} - displays the remote host ip of the
|
||||
tenth sshd connection
|
||||
${tcp_portmon 1 1024 rhost 0} - displays the remote host name of
|
||||
the first connection on a privileged port
|
||||
${tcp_portmon 1 1024 rport 4} - displays the remote host port of
|
||||
the fifth connection on a privileged port
|
||||
${tcp_portmon 1 65535 lservice 14} - displays the local service
|
||||
${tcp_portmon 1 65535 lservice 14} - displays the local service
|
||||
name of the fifteenth connection in the range of all ports
|
||||
|
||||
Note that port monitor variables which share the same port range
|
||||
actually refer to the same monitor, so many references to a sin-
|
||||
gle port range for different items and different indexes all use
|
||||
the same monitor internally. In other words, the program avoids
|
||||
the same monitor internally. In other words, the program avoids
|
||||
creating redundant monitors.
|
||||
|
||||
texeci interval command
|
||||
Runs a command at an interval inside a thread and displays the
|
||||
output. Same as $execi, except the command is run inside a
|
||||
thread. Use this if you have a slow script to keep Conky updat-
|
||||
ing. You should make the interval slightly longer then the time
|
||||
it takes your script to execute. For example, if you have a
|
||||
script that take 5 seconds to execute, you should make the in-
|
||||
Runs a command at an interval inside a thread and displays the
|
||||
output. Same as $execi, except the command is run inside a
|
||||
thread. Use this if you have a slow script to keep Conky updat-
|
||||
ing. You should make the interval slightly longer then the time
|
||||
it takes your script to execute. For example, if you have a
|
||||
script that take 5 seconds to execute, you should make the in-
|
||||
terval at least 6 seconds. See also $execi.
|
||||
|
||||
|
||||
@ -1048,7 +1043,7 @@ VARIABLES
|
||||
|
||||
|
||||
time (format)
|
||||
Local time, see man strftime to get more information about for-
|
||||
Local time, see man strftime to get more information about for-
|
||||
mat
|
||||
|
||||
|
||||
@ -1057,23 +1052,23 @@ VARIABLES
|
||||
|
||||
|
||||
tztime (timezone) (format)
|
||||
Local time for specified timezone, see man strftime to get more
|
||||
information about format. The timezone argument is specified in
|
||||
similar fashion as TZ environment variable. For hints, look in
|
||||
Local time for specified timezone, see man strftime to get more
|
||||
information about format. The timezone argument is specified in
|
||||
similar fashion as TZ environment variable. For hints, look in
|
||||
/usr/share/zoneinfo. e.g. US/Pacific, Europe/Zurich, etc.
|
||||
|
||||
|
||||
totaldown net
|
||||
Total download, overflows at 4 GB on Linux with 32-bit arch and
|
||||
Total download, overflows at 4 GB on Linux with 32-bit arch and
|
||||
there doesn't seem to be a way to know how many times it has al-
|
||||
ready done that before conky has started.
|
||||
|
||||
|
||||
top type, num
|
||||
This takes arguments in the form:top (name) (number) Basically,
|
||||
processes are ranked from highest to lowest in terms of cpu us-
|
||||
age, which is what (num) represents. The types are: "name",
|
||||
"pid", "cpu", and "mem". There can be a max of 10 processes
|
||||
This takes arguments in the form:top (name) (number) Basically,
|
||||
processes are ranked from highest to lowest in terms of cpu us-
|
||||
age, which is what (num) represents. The types are: "name",
|
||||
"pid", "cpu", and "mem". There can be a max of 10 processes
|
||||
listed.
|
||||
|
||||
|
||||
@ -1097,9 +1092,9 @@ VARIABLES
|
||||
Upload speed in kilobytes with one decimal
|
||||
|
||||
|
||||
upspeedgraph net (height),(width) (gradient colour 1) (gradient colour
|
||||
upspeedgraph net (height),(width) (gradient colour 1) (gradient colour
|
||||
2) (scale)
|
||||
Upload speed graph, colours defined in hex, minus the #. If
|
||||
Upload speed graph, colours defined in hex, minus the #. If
|
||||
scale is non-zero, it becomes the scale for the graph.
|
||||
|
||||
|
||||
@ -1111,12 +1106,12 @@ VARIABLES
|
||||
|
||||
|
||||
voffset (pixels)
|
||||
Change vertical offset by N pixels. Negative values will cause
|
||||
Change vertical offset by N pixels. Negative values will cause
|
||||
text to overlap. See also $offset.
|
||||
|
||||
|
||||
voltage_mv (n)
|
||||
Returns CPU #n's voltage in mV. CPUs are counted from 1. If
|
||||
Returns CPU #n's voltage in mV. CPUs are counted from 1. If
|
||||
omitted, the parameter defaults to 1.
|
||||
|
||||
|
||||
@ -1139,11 +1134,11 @@ FILES
|
||||
BUGS
|
||||
Drawing to root or some other desktop window directly doesn't work with
|
||||
all window managers. Especially doesn't work well with Gnome and it has
|
||||
been reported that it doesn't work with KDE either. Nautilus can be
|
||||
disabled from drawing to desktop with program gconf-editor. Uncheck
|
||||
show_desktop in /apps/nautilus/preferences/. There is -w switch in
|
||||
Conky to set some specific window id. You might find xwininfo -tree
|
||||
useful to find the window to draw to. You can also use -o argument
|
||||
been reported that it doesn't work with KDE either. Nautilus can be
|
||||
disabled from drawing to desktop with program gconf-editor. Uncheck
|
||||
show_desktop in /apps/nautilus/preferences/. There is -w switch in
|
||||
Conky to set some specific window id. You might find xwininfo -tree
|
||||
useful to find the window to draw to. You can also use -o argument
|
||||
which makes Conky to create its own window.
|
||||
|
||||
SEE ALSO
|
||||
|
@ -31,6 +31,7 @@ DEPEND_COMMON="
|
||||
bmpx? ( media-sound/bmpx
|
||||
>=sys-apps/dbus-0.35
|
||||
)
|
||||
!ipv6? (dev-libs/glib-2.0)
|
||||
)"
|
||||
|
||||
RDEPEND="${DEPEND_COMMON}
|
||||
|
@ -221,6 +221,9 @@ if test x$want_portmon = xyes; then
|
||||
if test "x$PORT_MONITORS_MISSING" = xyes; then
|
||||
AC_MSG_ERROR([missing a needed network header for port monitoring])
|
||||
fi
|
||||
PKG_CHECK_MODULES([GLIB], [glib-2.0])
|
||||
CFLAGS="$CFLAGS $GLIB_CFLAGS"
|
||||
LIBS="$LIBS $GLIB_LIBS"
|
||||
AC_DEFINE(TCP_PORT_MONITOR, 1, [Define if you want tcp port monitoring support])
|
||||
fi
|
||||
|
||||
|
@ -127,6 +127,13 @@
|
||||
<para></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command><option>max_port_monitor_connections</option></command></term>
|
||||
<listitem>
|
||||
Allow each port monitor to track at most this many connections (if 0 or not set, default is 256)
|
||||
<para></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command><option>max_specials</option></command></term>
|
||||
<listitem>
|
||||
@ -162,20 +169,6 @@
|
||||
<para></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command><option>min_port_monitors</option></command></term>
|
||||
<listitem>
|
||||
Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16)
|
||||
<para></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command><option>min_port_monitor_connections</option></command></term>
|
||||
<listitem>
|
||||
Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
|
||||
<para></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command><option>mpd_host</option></command></term>
|
||||
<listitem>
|
||||
|
12
doc/conky.1
12
doc/conky.1
@ -209,6 +209,10 @@ Default global IMAP server. Arguments are: "host user pass [-i interval] [-f fol
|
||||
\fB\*(T<\fBmail_spool\fR\*(T>\fR
|
||||
Mail spool for mail checking
|
||||
|
||||
.TP
|
||||
\fB\*(T<\fBmax_port_monitor_connections\fR\*(T>\fR
|
||||
Allow each port monitor to track at most this many connections (if 0 or not set, default is 256)
|
||||
|
||||
.TP
|
||||
\fB\*(T<\fBmax_specials\fR\*(T>\fR
|
||||
Maximum number of special things, e.g. fonts, offsets, aligns, etc. (default is 512)
|
||||
@ -226,14 +230,6 @@ Maximum width of window
|
||||
\fB\*(T<\fBminimum_size\fR\*(T>\fR \*(T<\fBwidth (height)\fR\*(T>
|
||||
Minimum size of window
|
||||
|
||||
.TP
|
||||
\fB\*(T<\fBmin_port_monitors\fR\*(T>\fR
|
||||
Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16)
|
||||
|
||||
.TP
|
||||
\fB\*(T<\fBmin_port_monitor_connections\fR\*(T>\fR
|
||||
Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
|
||||
|
||||
.TP
|
||||
\fB\*(T<\fBmpd_host\fR\*(T>\fR
|
||||
Host of MPD server
|
||||
|
@ -6,7 +6,7 @@
|
||||
syntax "conky" "\.*conkyrc.*$"
|
||||
|
||||
## Configuration items
|
||||
color green "\<(alignment|background|border_margin|border_width|cpu_avg_samples|default_color|default_shade_color|default_outline_color|double_buffer|draw_borders|draw_graph_borders|draw_shades|draw_outline|font|gap_x|gap_y|imap|mail_spool|max_specials|max_user_text|maximum_width|minimum_size|min_port_monitor_connections|min_port_monitors|mpd_host|mpd_port|mpd_password|net_avg_samples|no_buffers|out_to_console|override_utf8_locale|own_window|own_window_transparent|own_window_type|own_window_hints|own_window_colour|pad_percents|pop3|stippled_borders|total_run_times|update_interval|uppercase|use_spacer|use_xft|wm_class_name|xftalpha|xftfont)\>"
|
||||
color green "\<(alignment|background|border_margin|border_width|cpu_avg_samples|default_color|default_shade_color|default_outline_color|double_buffer|draw_borders|draw_graph_borders|draw_shades|draw_outline|font|gap_x|gap_y|imap|mail_spool|max_port_monitor_connections|max_specials|max_user_text|maximum_width|minimum_size|mpd_host|mpd_port|mpd_password|net_avg_samples|no_buffers|out_to_console|override_utf8_locale|own_window|own_window_transparent|own_window_type|own_window_hints|own_window_colour|pad_percents|pop3|stippled_borders|total_run_times|update_interval|uppercase|use_spacer|use_xft|wm_class_name|xftalpha|xftfont)\>"
|
||||
|
||||
## Variables
|
||||
color brightblue "\<(acpiacadapter|acpifan|acpitemp|acpitempf|addr|adt746xcpu|adt746xfan|align|alignr|apm_adapter|apm_battery_life|apm_battery_time|audacious_bar|audacious_bitrate|audacious_channels|audacious_filename|audacious_frequency|audacious_length|audacious_length_seconds|audacious_playlist_length|audacious_playlist_position|audacious_position|audacious_position_seconds|audacious_status|audacious_title|battery|bmpx_album|bmpx_artist|bmpx_bitrate|bmpx_title|bmpx_track|bmpx_uri|buffers|cached|color|colour|cpu|cpubar|diskio|downspeed|downspeedf|else|entropy_avail|entropy_bar|entropy_poolsize|exec|execbar|execgraph|execi|execibar|execigraph|font|freq|freq_dyn|freq_dyn_g|freq_g|fs_bar|fs_free|fs_free_perc|fs_size|fs_used|goto|hddtemp|head|hr|i2c|i8k_ac_status|i8k_bios|i8k_buttons_status|i8k_cpu_temp|i8k_cpu_tempf|i8k_left_fan_rpm|i8k_left_fan_status|i8k_right_fan_rpm|i8k_right_fan_status|i8k_serial|i8k_version|if_existing|if_running|if_mounted|kernel|linkstatus|loadavg|machine|mails|mem|membar|memmax|memperc|mpd_album|mpd_artist|mpd_bar|mpd_bitrate|mpd_elapsed|mpd_file|mpd_length|mpd_name|mpd_percent|mpd_smart|mpd_status|mpd_title|mpd_vol|new_mails|nodename|offset|outlinecolor|pre_exec|processes|running_processes|shadecolor|stippled_hr|swap|swapbar|swapmax|swapperc|sysname|tab|tail|tcp_portmon|texeci|time|top|top_mem|totaldown|totalup|tztime|updates|upspeed|upspeedf|upspeedgraph|uptime|uptime_short|voffset|voltage_mv|voltage_v)\>"
|
||||
|
@ -32,12 +32,11 @@ syn keyword ConkyrcSetting
|
||||
\ gap_y
|
||||
\ imap
|
||||
\ mail_spool
|
||||
\ max_port_monitor_connections
|
||||
\ max_specials
|
||||
\ max_user_text
|
||||
\ maximum_width
|
||||
\ minimum_size
|
||||
\ min_port_monitor_connections
|
||||
\ min_port_monitors
|
||||
\ mpd_host
|
||||
\ mpd_password
|
||||
\ mpd_port
|
||||
|
@ -35,7 +35,7 @@ endif
|
||||
#endif
|
||||
|
||||
if BUILD_PORT_MONITORS
|
||||
port_monitors = libtcp-portmon.h libtcp-portmon.c hash.h hash.c
|
||||
port_monitors = libtcp-portmon.h libtcp-portmon.c
|
||||
endif
|
||||
|
||||
if BUILD_X11
|
||||
@ -80,8 +80,6 @@ EXTRA_DIST = \
|
||||
freebsd.c \
|
||||
ftp.c \
|
||||
ftp.h \
|
||||
hash.c \
|
||||
hash.h \
|
||||
hddtemp.c \
|
||||
linux.c \
|
||||
libmpdclient.c \
|
||||
|
47
src/conky.c
47
src/conky.c
@ -374,8 +374,7 @@ int no_buffers;
|
||||
static int pad_percents = 0;
|
||||
|
||||
#ifdef TCP_PORT_MONITOR
|
||||
tcp_port_monitor_collection_args_t tcp_port_monitor_collection_args;
|
||||
tcp_port_monitor_args_t tcp_port_monitor_args;
|
||||
tcp_port_monitor_args_t tcp_port_monitor_args;
|
||||
#endif
|
||||
|
||||
/* Text that is shown */
|
||||
@ -1166,7 +1165,7 @@ struct text_object {
|
||||
struct {
|
||||
in_port_t port_range_begin; /* starting port to monitor */
|
||||
in_port_t port_range_end; /* ending port to monitor */
|
||||
int item; /* enum value from libtcp-portmon.h, e.g. COUNT, REMOTEIP, etc. */
|
||||
int item; /* enum from libtcp-portmon.h, e.g. COUNT, etc. */
|
||||
int connection_index; /* 0 to n-1 connections. */
|
||||
} tcp_port_monitor;
|
||||
#endif
|
||||
@ -2959,7 +2958,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
|
||||
if ( !info.p_tcp_port_monitor_collection )
|
||||
{
|
||||
info.p_tcp_port_monitor_collection =
|
||||
create_tcp_port_monitor_collection( &tcp_port_monitor_collection_args );
|
||||
create_tcp_port_monitor_collection ();
|
||||
if ( !info.p_tcp_port_monitor_collection )
|
||||
{
|
||||
CRIT_ERR("tcp_portmon: unable to create port monitor collection");
|
||||
@ -6188,8 +6187,7 @@ static void set_default_configurations(void)
|
||||
stuff_in_upper_case = 0;
|
||||
|
||||
#ifdef TCP_PORT_MONITOR
|
||||
tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
|
||||
tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
tcp_port_monitor_args.max_port_monitor_connections = MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -6627,41 +6625,27 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
|
||||
return;
|
||||
}
|
||||
#ifdef TCP_PORT_MONITOR
|
||||
CONF("min_port_monitors")
|
||||
CONF("max_port_monitor_connections")
|
||||
{
|
||||
if ( !value ||
|
||||
(sscanf(value, "%d", &tcp_port_monitor_collection_args.min_port_monitors) != 1) ||
|
||||
tcp_port_monitor_collection_args.min_port_monitors < 0 )
|
||||
(sscanf(value, "%d", &tcp_port_monitor_args.max_port_monitor_connections) != 1)
|
||||
|| tcp_port_monitor_args.max_port_monitor_connections < 0 )
|
||||
{
|
||||
/* an error. use default, warn and continue. */
|
||||
tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
|
||||
tcp_port_monitor_args.max_port_monitor_connections =
|
||||
MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
CONF_ERR;
|
||||
}
|
||||
else if ( tcp_port_monitor_collection_args.min_port_monitors == 0 )
|
||||
else if ( tcp_port_monitor_args.max_port_monitor_connections == 0 )
|
||||
{
|
||||
/* no error, just use default */
|
||||
tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
|
||||
tcp_port_monitor_args.max_port_monitor_connections =
|
||||
MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
}
|
||||
/* else tcp_port_monitor_collection_args.min_port_monitors > 0 as per config */
|
||||
}
|
||||
CONF("min_port_monitor_connections")
|
||||
{
|
||||
if ( !value ||
|
||||
(sscanf(value, "%d", &tcp_port_monitor_args.min_port_monitor_connections) != 1)
|
||||
|| tcp_port_monitor_args.min_port_monitor_connections < 0 )
|
||||
{
|
||||
/* an error. use default, warni and continue. */
|
||||
tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
CONF_ERR;
|
||||
}
|
||||
else if ( tcp_port_monitor_args.min_port_monitor_connections == 0 )
|
||||
{
|
||||
/* no error, just use default */
|
||||
tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
}
|
||||
/* else tcp_port_monitor_args.min_port_monitor_connections > 0 as per config */
|
||||
/* else tcp_port_monitor_args.max_port_monitor_connections > 0 as per config */
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
ERR("%s: %d: no such configuration: '%s'", f, line, name);
|
||||
|
||||
@ -6697,8 +6681,7 @@ int main(int argc, char **argv)
|
||||
memset(&info, 0, sizeof(info) );
|
||||
|
||||
#ifdef TCP_PORT_MONITOR
|
||||
tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
|
||||
tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
tcp_port_monitor_args.max_port_monitor_connections = MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
|
||||
#endif
|
||||
|
||||
/* handle command line parameters that don't change configs */
|
||||
|
@ -195,8 +195,7 @@ struct entropy_s {
|
||||
|
||||
#ifdef TCP_PORT_MONITOR
|
||||
#include "libtcp-portmon.h"
|
||||
#define MIN_PORT_MONITORS_DEFAULT 16
|
||||
#define MIN_PORT_MONITOR_CONNECTIONS_DEFAULT 256
|
||||
#define MAX_PORT_MONITOR_CONNECTIONS_DEFAULT 256
|
||||
#endif
|
||||
|
||||
enum {
|
||||
|
207
src/hash.c
207
src/hash.c
@ -1,207 +0,0 @@
|
||||
/* $Id$ */
|
||||
/* ------------------------------------------------------
|
||||
* Open-addressed hash using double hash probing
|
||||
*
|
||||
* for i in 0 to m-1:
|
||||
* h(k, i) = ( h1(k) + i*h2(k) ) mod m
|
||||
*
|
||||
* requires: 1) m must be a power of two
|
||||
* 2) h2(k) must return an odd number
|
||||
*
|
||||
* Besed on code published in _Mastering Algorithms With C_
|
||||
* by Kyle Loudon (O'Reilly & Associates, 1999), ISBN 1565924533.
|
||||
* Modified by Philip Kovacs (kovacsp3@comcast.net)
|
||||
* ------------------------------------------------------ */
|
||||
|
||||
#ifdef HASH_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "hash.h"
|
||||
|
||||
/* Create and initialize a hash table on the heap.
|
||||
Returns 0 on success, -1 otherwise. */
|
||||
int hash_create( hash_table_t *p_hash_table,
|
||||
int positions,
|
||||
int (*p_hash_fun1)(const void *p_data),
|
||||
int (*p_hash_fun2)(const void *p_data),
|
||||
int (*p_match_fun)(const void *p_data1, const void *p_data2),
|
||||
void (*p_destroy_fun)(void *p_data)
|
||||
)
|
||||
{
|
||||
if ( ( p_hash_table->pp_table = (void **)calloc(positions, sizeof(void *))) == NULL )
|
||||
return -1;
|
||||
|
||||
p_hash_table->positions = positions;
|
||||
p_hash_table->size = 0;
|
||||
p_hash_table->vacated = 0;
|
||||
|
||||
/* sentinel address indicating a vacated slot */
|
||||
p_hash_table->p_vacated = &p_hash_table->sentinel_vacated;
|
||||
|
||||
p_hash_table->p_hash_fun1 = p_hash_fun1;
|
||||
p_hash_table->p_hash_fun2 = p_hash_fun2;
|
||||
|
||||
p_hash_table->p_match_fun = p_match_fun;
|
||||
p_hash_table->p_destroy_fun = p_destroy_fun;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Destroy a hash table */
|
||||
void hash_destroy( hash_table_t *p_hash_table )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !p_hash_table )
|
||||
return;
|
||||
|
||||
/* Destroy the elements the hash points to, if a destroy function was provided */
|
||||
if (p_hash_table->p_destroy_fun != NULL) {
|
||||
|
||||
for (i = 0; i < p_hash_table->positions; i++) {
|
||||
|
||||
if ( p_hash_table->pp_table[i] != NULL && p_hash_table->pp_table[i] != p_hash_table->p_vacated )
|
||||
p_hash_table->p_destroy_fun( p_hash_table->pp_table[i] );
|
||||
}
|
||||
}
|
||||
|
||||
free( p_hash_table->pp_table );
|
||||
memset( p_hash_table, 0, sizeof(hash_table_t) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Insert an element into a hash table.
|
||||
Returns 0 on successful insert, 1 if data already in hash and -1 if unable to insert. */
|
||||
int hash_insert( hash_table_t *p_hash_table, const void *p_data )
|
||||
{
|
||||
void *temp;
|
||||
int position, i;
|
||||
int hashed_1, hashed_2;
|
||||
|
||||
if ( !p_hash_table )
|
||||
return -1;
|
||||
|
||||
if ( p_hash_table->size == p_hash_table->positions )
|
||||
return -1;
|
||||
|
||||
temp = (void *)p_data;
|
||||
|
||||
if ( hash_lookup( p_hash_table, &temp ) == 0 )
|
||||
return 1;
|
||||
|
||||
/* Loudon's original algorithm needlessly repeated running the hash algorithms with each iteration
|
||||
to find a slot. Just running the hash algorithms once is enough since they are deterministic. */
|
||||
hashed_1 = p_hash_table->p_hash_fun1( p_data );
|
||||
hashed_2 = p_hash_table->p_hash_fun2( p_data );
|
||||
|
||||
for ( i = 0; i < p_hash_table->positions; i++ ) {
|
||||
|
||||
position = ( hashed_1 + (i * hashed_2) ) % p_hash_table->positions;
|
||||
#ifdef HASH_DEBUG
|
||||
printf("--- hash_insert: probe %d, position %d\n",i,position);
|
||||
#endif
|
||||
|
||||
if ( p_hash_table->pp_table[ position ] == NULL ) /* empty slot */
|
||||
{
|
||||
p_hash_table->pp_table[ position ] = (void *)p_data;
|
||||
p_hash_table->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( p_hash_table->pp_table[ position ] == p_hash_table->p_vacated ) /* vacated slot */
|
||||
{
|
||||
p_hash_table->pp_table[ position ] = (void *)p_data;
|
||||
p_hash_table->size++;
|
||||
p_hash_table->vacated--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* hash functions not selected correctly since the above algorithm should visit all slots in the hash. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Delete an element from a hash table.
|
||||
Returns 0 on successful delete, -1 if not found. */
|
||||
int hash_remove( hash_table_t *p_hash_table, void **pp_data)
|
||||
{
|
||||
int position, i;
|
||||
int hashed_1, hashed_2;
|
||||
|
||||
if ( !p_hash_table || !pp_data )
|
||||
return -1;
|
||||
|
||||
hashed_1 = p_hash_table->p_hash_fun1( *pp_data );
|
||||
hashed_2 = p_hash_table->p_hash_fun2( *pp_data );
|
||||
|
||||
for (i = 0; i < p_hash_table->positions; i++) {
|
||||
|
||||
position= ( hashed_1 + (i * hashed_2) ) % p_hash_table->positions;
|
||||
#ifdef HASH_DEBUG
|
||||
printf("--- hash_remove: probe %d, position %d\n",i,position);
|
||||
#endif
|
||||
|
||||
if ( p_hash_table->pp_table[ position ] == NULL ) {
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
else if ( p_hash_table->pp_table[ position ] == p_hash_table->p_vacated ) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
else if ( p_hash_table->p_match_fun( p_hash_table->pp_table[ position ], *pp_data)) {
|
||||
|
||||
*pp_data = p_hash_table->pp_table[ position ];
|
||||
p_hash_table->pp_table[ position ] = p_hash_table->p_vacated;
|
||||
p_hash_table->vacated++;
|
||||
p_hash_table->size--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Lookup an element in a hash table.
|
||||
Returns 0 if found (data passed back byref), -1 if not found. */
|
||||
int hash_lookup(const hash_table_t *p_hash_table, void **pp_data)
|
||||
{
|
||||
int position, i;
|
||||
int hashed_1, hashed_2;
|
||||
|
||||
if ( !p_hash_table || !pp_data )
|
||||
return -1;
|
||||
|
||||
hashed_1 = p_hash_table->p_hash_fun1( *pp_data );
|
||||
hashed_2 = p_hash_table->p_hash_fun2( *pp_data );
|
||||
|
||||
for (i = 0; i < p_hash_table->positions; i++) {
|
||||
|
||||
position= ( hashed_1 + (i * hashed_2) ) % p_hash_table->positions;
|
||||
#ifdef HASH_DEBUG
|
||||
printf("--- hash_lookup: probe %d, position %d\n",i,position);
|
||||
#endif
|
||||
if ( p_hash_table->pp_table[ position ] == NULL ) {
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
else if ( p_hash_table->p_match_fun(p_hash_table->pp_table[ position ], *pp_data) ) {
|
||||
|
||||
*pp_data = p_hash_table->pp_table[ position ];
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
60
src/hash.h
60
src/hash.h
@ -1,60 +0,0 @@
|
||||
/* $Id$ */
|
||||
/* ------------------------------------------------------
|
||||
* Open-addressed hash using double hash probing
|
||||
*
|
||||
* for i in 0 to m-1:
|
||||
* h(k, i) = ( h1(k) + i*h2(k) ) mod m
|
||||
*
|
||||
* requires: 1) m must be a power of two
|
||||
* 2) h2(k) must return an odd number
|
||||
*
|
||||
* Besed on code published in _Mastering Algorithms With C_
|
||||
* by Kyle Loudon (O'Reilly & Associates, 1999), ISBN 1565924533.
|
||||
* Modified by Philip Kovacs (kovacsp3@comcast.net)
|
||||
* ------------------------------------------------------ */
|
||||
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
typedef struct _hash_table_t {
|
||||
int positions;
|
||||
int size;
|
||||
int vacated;
|
||||
int sentinel_vacated;
|
||||
void *p_vacated;
|
||||
int (*p_hash_fun1)(const void *p_data);
|
||||
int (*p_hash_fun2)(const void *p_data);
|
||||
int (*p_match_fun)(const void *p_data1, const void *p_data2);
|
||||
void (*p_destroy_fun)(void *p_data);
|
||||
void **pp_table;
|
||||
} hash_table_t;
|
||||
|
||||
/* Create and initialize a hash table on the heap.
|
||||
Returns 0 on success, -1 otherwise. */
|
||||
int hash_create( hash_table_t *p_hash_table,
|
||||
int positions,
|
||||
int (*p_hash_fun1)(const void *p_data),
|
||||
int (*p_hash_fun2)(const void *p_data),
|
||||
int (*p_match_fun)(const void *p_data1, const void *p_data2),
|
||||
void (*p_destroy_fun)(void *p_data)
|
||||
);
|
||||
|
||||
/* Destroy a hash table */
|
||||
void hash_destroy( hash_table_t *p_hash_table );
|
||||
|
||||
/* Insert an element into a hash table.
|
||||
Returns 0 on successful insert, 1 if data already in hash and -1 if unable to insert. */
|
||||
int hash_insert( hash_table_t *p_hash_table, const void *p_data);
|
||||
|
||||
/* Delete an element from a hash table.
|
||||
Returns 0 on successful delete, -1 if not found. */
|
||||
int hash_remove( hash_table_t *p_hash_table, void **pp_data);
|
||||
|
||||
/* Lookup an element in a hash table.
|
||||
Returns 0 if found (data passed back byref), -1 if not found. */
|
||||
int hash_lookup(const hash_table_t *p_hash_table, void **pp_data);
|
||||
|
||||
/* Return size of a hash table */
|
||||
#define hash_size(p_hash_table) ((p_hash_table)->size)
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* --------------------------------------------------------------------------- */
|
||||
|
||||
#include <glib/gprintf.h>
|
||||
#include "libtcp-portmon.h"
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
@ -43,6 +44,7 @@ int copy_tcp_connection(
|
||||
if ( !p_dest_connection || !p_source_connection )
|
||||
return (-1);
|
||||
|
||||
g_strlcpy (p_dest_connection->key, p_source_connection->key, sizeof(p_dest_connection->key));
|
||||
p_dest_connection->local_addr = p_source_connection->local_addr;
|
||||
p_dest_connection->local_port = p_source_connection->local_port;
|
||||
p_dest_connection->remote_addr = p_source_connection->remote_addr;
|
||||
@ -52,189 +54,6 @@ int copy_tcp_connection(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Open-addressed hash implementation requires that we supply two hash functions
|
||||
* and a match function to compare two hash elements for identity.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* --------------------------------------------------
|
||||
* Functions to hash the connections within a monitor
|
||||
* --------------------------------------------------*/
|
||||
|
||||
#define CONNECTION_HASH_KEY_LEN 17
|
||||
|
||||
/* ----------------------------------------------------------------------------------
|
||||
* First connection hash function: DJB with a 65521 prime modulus to govern the range.
|
||||
* ----------------------------------------------------------------------------------*/
|
||||
int connection_hash_function_1( const void *p_data )
|
||||
{
|
||||
tcp_connection_t *p_conn;
|
||||
char key[CONNECTION_HASH_KEY_LEN];
|
||||
unsigned int hash = 5381;
|
||||
unsigned int i = 0;
|
||||
|
||||
if ( !p_data )
|
||||
return -1;
|
||||
|
||||
memset(key,0,sizeof(key));
|
||||
|
||||
/* p_data is a pointer to tcp_connection_t */
|
||||
p_conn = (tcp_connection_t *)p_data;
|
||||
|
||||
/* key is a hex representation of the connection */
|
||||
snprintf(key, CONNECTION_HASH_KEY_LEN, "%08X%04X%04X",
|
||||
p_conn->remote_addr, p_conn->remote_port, p_conn->local_port);
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr,"--- key=[%s]\n",key);
|
||||
#endif
|
||||
|
||||
for(i = 0; i < CONNECTION_HASH_KEY_LEN-1; i++)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + (key[i]);
|
||||
}
|
||||
|
||||
return (hash & 0x7FFFFFFF) % 65521;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Second connection hash function: DEK, modified to return odd numbers only,
|
||||
* as required for open-address hashing using double-hash probing.
|
||||
* Also uses a 65521 prime modulus to govern the range.
|
||||
* -------------------------------------------------------------------------*/
|
||||
int connection_hash_function_2( const void *p_data )
|
||||
{
|
||||
tcp_connection_t *p_conn;
|
||||
char key[CONNECTION_HASH_KEY_LEN];
|
||||
unsigned int hash = CONNECTION_HASH_KEY_LEN-1;
|
||||
unsigned int i = 0;
|
||||
|
||||
if ( !p_data )
|
||||
return -1;
|
||||
|
||||
memset(key,0,sizeof(key));
|
||||
|
||||
/* p_data is a pointer to a tcp_connection_t */
|
||||
p_conn = (tcp_connection_t *)p_data;
|
||||
|
||||
/* key is a hex representation of the connection */
|
||||
snprintf(key, CONNECTION_HASH_KEY_LEN, "%08X%04X%04X",
|
||||
p_conn->remote_addr, p_conn->remote_port, p_conn->local_port);
|
||||
|
||||
for(i = 0; i < CONNECTION_HASH_KEY_LEN-1; i++)
|
||||
{
|
||||
hash = ((hash << 5) ^ (hash >> 27)) ^ (key[i]);
|
||||
}
|
||||
return (( hash & 0x7FFFFFFF ) % 65521 ) | 0x00000001;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Connection Match function returns non-zero if hash elements are identical.
|
||||
* -------------------------------------------------------------------------*/
|
||||
int connection_match_function( const void *p_data1, const void *p_data2 )
|
||||
{
|
||||
tcp_connection_t *p_conn1, *p_conn2;
|
||||
|
||||
if ( !p_data1 || !p_data2 )
|
||||
return 0;
|
||||
|
||||
/* p_data1, p_data2 are pointers to tcp_connection_t */
|
||||
p_conn1 = (tcp_connection_t *)p_data1;
|
||||
p_conn2 = (tcp_connection_t *)p_data2;
|
||||
|
||||
return (p_conn1->local_addr == p_conn2->local_addr &&
|
||||
p_conn1->local_port == p_conn2->local_port &&
|
||||
p_conn1->remote_addr == p_conn2->remote_addr &&
|
||||
p_conn1->remote_port == p_conn2->remote_port );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------
|
||||
* Functions to hash the monitors within a collection
|
||||
* --------------------------------------------------*/
|
||||
|
||||
#define MONITOR_HASH_KEY_LEN 9
|
||||
|
||||
/* -------------------------------------------------------------------------------
|
||||
* First monitor hash function: DJB with a 65521 prime modulus to govern the range.
|
||||
* -------------------------------------------------------------------------------*/
|
||||
int monitor_hash_function_1( const void *p_data )
|
||||
{
|
||||
tcp_port_monitor_t *p_monitor;
|
||||
char key[MONITOR_HASH_KEY_LEN];
|
||||
unsigned int hash = 5381;
|
||||
unsigned int i = 0;
|
||||
|
||||
if ( !p_data )
|
||||
return -1;
|
||||
|
||||
memset(key,0,sizeof(key));
|
||||
|
||||
/* p_data is a pointer to tcp_port_monitor_t */
|
||||
p_monitor = (tcp_port_monitor_t *)p_data;
|
||||
|
||||
/* key is a hex representation of the starting port concatenated to the ending port */
|
||||
snprintf(key, MONITOR_HASH_KEY_LEN, "%04X%04X",
|
||||
p_monitor->port_range_begin, p_monitor->port_range_end );
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr,"--- key=[%s]\n",key);
|
||||
#endif
|
||||
|
||||
for(i = 0; i < MONITOR_HASH_KEY_LEN-1; i++)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + (key[i]);
|
||||
}
|
||||
|
||||
return (hash & 0x7FFFFFFF) % 65521;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* Second monitor hash function: DEK, modified to return odd numbers only,
|
||||
* as required for open-address hashing using double-hash probing.
|
||||
* Also uses a 65521 prime modulus to govern the range.
|
||||
* -----------------------------------------------------------------------*/
|
||||
int monitor_hash_function_2( const void *p_data )
|
||||
{
|
||||
tcp_port_monitor_t *p_monitor;
|
||||
char key[MONITOR_HASH_KEY_LEN];
|
||||
unsigned int hash = MONITOR_HASH_KEY_LEN-1;
|
||||
unsigned int i = 0;
|
||||
|
||||
if ( !p_data )
|
||||
return -1;
|
||||
|
||||
memset(key,0,sizeof(key));
|
||||
|
||||
/* p_data is a pointer to a tcp_port_monitor_t */
|
||||
p_monitor = (tcp_port_monitor_t *)p_data;
|
||||
|
||||
/* key is a hex representation of the starting port concatenated to the ending port */
|
||||
snprintf(key, MONITOR_HASH_KEY_LEN, "%04X%04X",
|
||||
p_monitor->port_range_begin, p_monitor->port_range_end );
|
||||
|
||||
for(i = 0; i < MONITOR_HASH_KEY_LEN-1; i++)
|
||||
{
|
||||
hash = ((hash << 5) ^ (hash >> 27)) ^ (key[i]);
|
||||
}
|
||||
return (( hash & 0x7FFFFFFF ) % 65521 ) | 0x00000001;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Monitor match function returns non-zero if hash elements are identical.
|
||||
* ----------------------------------------------------------------------*/
|
||||
int monitor_match_function( const void *p_data1, const void *p_data2 )
|
||||
{
|
||||
tcp_port_monitor_t *p_monitor1, *p_monitor2;
|
||||
|
||||
if ( !p_data1 || !p_data2 )
|
||||
return 0;
|
||||
|
||||
/* p_data1, p_data2 are pointers to tcp_connection_t */
|
||||
p_monitor1 = (tcp_port_monitor_t *)p_data1;
|
||||
p_monitor2 = (tcp_port_monitor_t *)p_data2;
|
||||
|
||||
return (p_monitor1->port_range_begin == p_monitor2->port_range_begin &&
|
||||
p_monitor1->port_range_end == p_monitor2->port_range_end);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Port monitor utility functions implementing tcp_port_monitor_function_ptr_t
|
||||
* ---------------------------------------------------------------------------*/
|
||||
@ -248,9 +67,6 @@ void destroy_tcp_port_monitor(
|
||||
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
|
||||
return;
|
||||
|
||||
/* destroy the monitor's hash */
|
||||
hash_destroy(&p_monitor->hash);
|
||||
|
||||
/* destroy the monitor's peek array */
|
||||
free( p_monitor->p_peek );
|
||||
|
||||
@ -265,6 +81,10 @@ void destroy_tcp_port_monitor(
|
||||
p_node = p_temp;
|
||||
}
|
||||
|
||||
/* destroy the monitor's hash */
|
||||
g_hash_table_destroy (p_monitor->hash);
|
||||
p_monitor->hash=NULL;
|
||||
|
||||
/* destroy the monitor */
|
||||
free( p_monitor );
|
||||
p_monitor=NULL;
|
||||
@ -281,7 +101,6 @@ void age_tcp_port_monitor(
|
||||
|
||||
tcp_connection_node_t *p_node, *p_temp;
|
||||
tcp_connection_t *p_conn;
|
||||
void *p_cast;
|
||||
|
||||
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
|
||||
return;
|
||||
@ -289,22 +108,26 @@ void age_tcp_port_monitor(
|
||||
if ( !p_monitor->p_peek )
|
||||
return;
|
||||
|
||||
for ( p_node = p_monitor->connection_list.p_head; p_node != NULL; )
|
||||
for ( p_node = p_monitor->connection_list.p_head; p_node; )
|
||||
{
|
||||
if ( --p_node->connection.age >= 0 ) {
|
||||
p_node = p_node->p_next;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* connection on p_node is old. remove connection from the hash. */
|
||||
p_conn = &p_node->connection;
|
||||
p_cast = (void *)p_conn;
|
||||
if ( hash_remove( &p_monitor->hash, &p_cast ) != 0 ) {
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr, "--- hash_remove error\n");
|
||||
#endif
|
||||
fprintf (stderr, "monitor hash removal of connection [%s]", p_conn->key);
|
||||
if ( !g_hash_table_remove (p_monitor->hash, (gconstpointer)p_conn->key) ) {
|
||||
fprintf (stderr, " - ERROR NOT FOUND\n");
|
||||
return;
|
||||
}
|
||||
fprintf (stderr, " - OK\n");
|
||||
#else
|
||||
if ( !g_hash_table_remove (p_monitor->hash, (gconstpointer)p_conn->key) )
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* splice p_node out of the connection_list */
|
||||
if ( p_node->p_prev != NULL )
|
||||
@ -328,55 +151,6 @@ void age_tcp_port_monitor(
|
||||
}
|
||||
}
|
||||
|
||||
void maintain_tcp_port_monitor_hash(
|
||||
tcp_port_monitor_t * p_monitor,
|
||||
void * p_void
|
||||
)
|
||||
{
|
||||
/* Check the number of vacated slots in the hash. If it exceeds our maximum
|
||||
* threshold (should be about 1/4 of the hash table), then the hash table
|
||||
* performance degrades from O(1) toward O(n) as the number of vacated slots
|
||||
* climbs. This is avoided by clearing the hash and reinserting the entries.
|
||||
* The benefit of open-addressing hashing does come with this price --
|
||||
* you must rebalance it occasionally. */
|
||||
|
||||
tcp_connection_node_t *p_node;
|
||||
double vacated_load;
|
||||
|
||||
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
|
||||
return;
|
||||
|
||||
vacated_load = (double)p_monitor->hash.vacated / (double)p_monitor->hash.positions;
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr,"--- num vacated is %d, vacated factor is %.3f\n", p_monitor->hash.vacated, vacated_load );
|
||||
#endif
|
||||
if ( vacated_load <= TCP_CONNECTION_HASH_MAX_VACATED_RATIO )
|
||||
{
|
||||
/* hash is fine and needs no rebalancing */
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr,"--- rebuilding hash\n");
|
||||
#endif
|
||||
|
||||
/* rebuild the hash */
|
||||
memset( p_monitor->hash.pp_table, 0, p_monitor->hash.positions * sizeof(void **));
|
||||
p_monitor->hash.size = 0;
|
||||
p_monitor->hash.vacated = 0;
|
||||
|
||||
for ( p_node=p_monitor->connection_list.p_head; p_node!=NULL; p_node=p_node->p_next )
|
||||
{
|
||||
if ( hash_insert( &p_monitor->hash, (void *)&p_node->connection ) != 0 )
|
||||
{
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr,"--- hash_insert error\n");
|
||||
#endif
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rebuild_tcp_port_monitor_peek_table(
|
||||
tcp_port_monitor_t * p_monitor,
|
||||
void * p_void
|
||||
@ -393,12 +167,13 @@ void rebuild_tcp_port_monitor_peek_table(
|
||||
return;
|
||||
|
||||
/* zero out the peek array */
|
||||
memset( p_monitor->p_peek, 0, p_monitor->hash.positions * sizeof(tcp_connection_t *) );
|
||||
memset( p_monitor->p_peek, 0, g_hash_table_size (p_monitor->hash) * sizeof(tcp_connection_t *) );
|
||||
|
||||
for ( p_node=p_monitor->connection_list.p_head; p_node!=NULL; p_node=p_node->p_next, i++ )
|
||||
{
|
||||
p_monitor->p_peek[i] = &p_node->connection;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void show_connection_to_tcp_port_monitor(
|
||||
@ -414,14 +189,14 @@ void show_connection_to_tcp_port_monitor(
|
||||
* The function takes O(1) time. */
|
||||
|
||||
tcp_connection_node_t *p_node;
|
||||
void *p_cast;
|
||||
tcp_connection_t *p_connection, *p_conn_hash;
|
||||
|
||||
if ( !p_monitor || !p_void )
|
||||
return;
|
||||
|
||||
/* This p_connection is on caller's stack and not the heap. If we are interested,
|
||||
* we will create a copy of the connection (on the heap) and add it to our list. */
|
||||
tcp_connection_t *p_connection = (tcp_connection_t *)p_void;
|
||||
p_connection = (tcp_connection_t *)p_void;
|
||||
|
||||
/* inspect the local port number of the connection to see if we're interested. */
|
||||
if ( (p_monitor->port_range_begin <= p_connection->local_port) &&
|
||||
@ -430,31 +205,17 @@ void show_connection_to_tcp_port_monitor(
|
||||
/* the connection is in the range of the monitor. */
|
||||
|
||||
/* first check the hash to see if the connection is already there. */
|
||||
p_cast = (void *)p_connection;
|
||||
if ( hash_lookup( &p_monitor->hash, &p_cast ) == 0 )
|
||||
if ( (p_conn_hash = g_hash_table_lookup (p_monitor->hash, (gconstpointer)p_connection->key)) )
|
||||
{
|
||||
p_connection = (tcp_connection_t *)p_cast;
|
||||
/* it's already in the hash. reset the age of the connection. */
|
||||
if ( p_connection != NULL )
|
||||
{
|
||||
p_connection->age = TCP_CONNECTION_STARTING_AGE;
|
||||
}
|
||||
/* it's already in the hash. reset the age of the connection. */
|
||||
p_conn_hash->age = TCP_CONNECTION_STARTING_AGE;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connection is not yet in the hash. We will try to add it, but only if the hash is not
|
||||
* yet saturated. We assume the hash is saturated (and therefore ignore this connection)
|
||||
* if our load factor cap is now exceeded. The benefit of limiting connections in this way
|
||||
* is that the hash will continue to function at an average (1) speed by keeping the load
|
||||
* load factor down. Of course the downside is that each port monitor has a strict maximum
|
||||
* connection limit. */
|
||||
|
||||
if ( (double)p_monitor->hash.size / (double)p_monitor->hash.positions >= TCP_CONNECTION_HASH_MAX_LOAD_RATIO )
|
||||
{
|
||||
/* hash exceeds our load limit is now "full" */
|
||||
/* Connection is not yet in the hash. Add it if max_connections not exceeded. */
|
||||
if (g_hash_table_size (p_monitor->hash) >= p_monitor->max_port_monitor_connections)
|
||||
return;
|
||||
}
|
||||
|
||||
/* create a new connection node */
|
||||
if ( (p_node = (tcp_connection_node_t *) calloc(1, sizeof(tcp_connection_node_t))) == NULL )
|
||||
@ -472,15 +233,12 @@ void show_connection_to_tcp_port_monitor(
|
||||
p_node->p_next = NULL;
|
||||
|
||||
/* insert it into the monitor's hash table */
|
||||
if ( hash_insert( &p_monitor->hash, (void *)&p_node->connection ) != 0 )
|
||||
{
|
||||
/* error inserting into hash. delete the connection node we just created, so no leaks. */
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf(stderr, "--- hash_insert error\n");
|
||||
fprintf (stderr, "monitor hash insert of connection [%s]\n", p_node->connection.key);
|
||||
#endif
|
||||
free(p_node);
|
||||
return;
|
||||
}
|
||||
g_hash_table_insert( p_monitor->hash,
|
||||
(gpointer)p_node->connection.key,
|
||||
(gpointer)&p_node->connection);
|
||||
|
||||
/* append the node to the monitor's connection list */
|
||||
if ( p_monitor->connection_list.p_tail == NULL ) /* assume p_head is NULL too */
|
||||
@ -528,38 +286,6 @@ void for_each_tcp_port_monitor_in_collection(
|
||||
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Calculate an efficient hash size based on the desired number of elements and load factor.
|
||||
* ---------------------------------------------------------------------------------------- */
|
||||
int calc_efficient_hash_size(
|
||||
int min_elements,
|
||||
int max_hash_size,
|
||||
double max_load_factor
|
||||
)
|
||||
{
|
||||
double min_size, hash_size, log_base_2;
|
||||
|
||||
/* the size of the hash will the smallest power of two such that the minimum number
|
||||
of desired elements does not exceed the maximum load factor. */
|
||||
|
||||
min_size = (double)min_elements / max_load_factor; /* starting point */
|
||||
|
||||
/* now adjust size up to nearest power of two */
|
||||
log_base_2 = (double) (int) ( log(min_size) / log(2) ) ; /* lop off fractional portion of log */
|
||||
|
||||
hash_size = pow(2,log_base_2) >= min_size ? min_size : pow(2,(double)++log_base_2);
|
||||
|
||||
/* respect the maximum */
|
||||
hash_size = hash_size <= max_hash_size ? hash_size : max_hash_size;
|
||||
|
||||
/*
|
||||
fprintf(stderr,"hash size is %d, based on %d min_elements and %.02f max load, %d maximum\n",
|
||||
(int)hash_size, min_elements, max_load_factor, max_hash_size);
|
||||
*/
|
||||
|
||||
return hash_size;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* CLIENT INTERFACE
|
||||
*
|
||||
@ -585,15 +311,13 @@ tcp_port_monitor_t * create_tcp_port_monitor(
|
||||
if ( !p_monitor )
|
||||
return NULL;
|
||||
|
||||
p_monitor->max_port_monitor_connections = p_creation_args->max_port_monitor_connections;
|
||||
|
||||
/* build the monitor key for the collection hash */
|
||||
g_sprintf (p_monitor->key, ":%04X :%04X", port_range_begin, port_range_end);
|
||||
|
||||
/* create the monitor's connection hash */
|
||||
if ( hash_create( &p_monitor->hash,
|
||||
p_creation_args && p_creation_args->min_port_monitor_connections > 0 ?
|
||||
calc_efficient_hash_size( p_creation_args->min_port_monitor_connections,
|
||||
TCP_CONNECTION_HASH_SIZE_MAX,
|
||||
TCP_CONNECTION_HASH_MAX_LOAD_RATIO ) :
|
||||
TCP_CONNECTION_HASH_SIZE_DEFAULT,
|
||||
&connection_hash_function_1, &connection_hash_function_2,
|
||||
&connection_match_function, NULL ) != 0 )
|
||||
if ( (p_monitor->hash = g_hash_table_new (g_str_hash, g_str_equal)) == NULL)
|
||||
{
|
||||
/* we failed to create the hash, so destroy the monitor completely so we don't leak */
|
||||
destroy_tcp_port_monitor(p_monitor,NULL);
|
||||
@ -601,7 +325,8 @@ tcp_port_monitor_t * create_tcp_port_monitor(
|
||||
}
|
||||
|
||||
/* create the monitor's peek array */
|
||||
if ( (p_monitor->p_peek = (tcp_connection_t **) calloc( p_monitor->hash.positions, sizeof(tcp_connection_t *))) == NULL )
|
||||
if ( (p_monitor->p_peek = (tcp_connection_t **) calloc (p_monitor->max_port_monitor_connections,
|
||||
sizeof(tcp_connection_t *))) == NULL )
|
||||
{
|
||||
/* we failed to create the peek array, so destroy the monitor completely, again, so we don't leak */
|
||||
destroy_tcp_port_monitor(p_monitor,NULL);
|
||||
@ -640,14 +365,14 @@ int peek_tcp_port_monitor(
|
||||
|
||||
/* if the connection index is out of range, we simply return with no error
|
||||
* having first cleared the client-supplied buffer. */
|
||||
if ( (item!=COUNT) && (connection_index > p_monitor->hash.size - 1) )
|
||||
if ( (item!=COUNT) && ((unsigned)connection_index > g_hash_table_size (p_monitor->hash) - 1) )
|
||||
return(0);
|
||||
|
||||
switch (item) {
|
||||
|
||||
case COUNT:
|
||||
|
||||
snprintf( p_buffer, buffer_size, "%d" , p_monitor->hash.size );
|
||||
snprintf( p_buffer, buffer_size, "%d" , g_hash_table_size (p_monitor->hash) );
|
||||
break;
|
||||
|
||||
case REMOTEIP:
|
||||
@ -658,7 +383,8 @@ int peek_tcp_port_monitor(
|
||||
|
||||
case REMOTEHOST:
|
||||
|
||||
p_hostent = gethostbyaddr( &p_monitor->p_peek[ connection_index ]->remote_addr, sizeof(in_addr_t), AF_INET);
|
||||
p_hostent = gethostbyaddr( &p_monitor->p_peek[ connection_index ]->remote_addr,
|
||||
sizeof(in_addr_t), AF_INET);
|
||||
/* if no host name found, just use ip address. */
|
||||
if ( !p_hostent || !p_hostent->h_name )
|
||||
{
|
||||
@ -693,7 +419,8 @@ int peek_tcp_port_monitor(
|
||||
|
||||
case LOCALHOST:
|
||||
|
||||
p_hostent = gethostbyaddr( &p_monitor->p_peek[ connection_index ]->local_addr, sizeof(in_addr_t), AF_INET);
|
||||
p_hostent = gethostbyaddr( &p_monitor->p_peek[ connection_index ]->local_addr,
|
||||
sizeof(in_addr_t), AF_INET);
|
||||
/* if no host name found, just use ip address. */
|
||||
if ( !p_hostent || !p_hostent->h_name )
|
||||
{
|
||||
@ -733,9 +460,7 @@ int peek_tcp_port_monitor(
|
||||
* -------------------------------- */
|
||||
|
||||
/* Create a monitor collection. Do this one first. */
|
||||
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection(
|
||||
tcp_port_monitor_collection_args_t * p_creation_args
|
||||
)
|
||||
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection (void)
|
||||
{
|
||||
tcp_port_monitor_collection_t * p_collection;
|
||||
|
||||
@ -744,14 +469,7 @@ tcp_port_monitor_collection_t * create_tcp_port_monitor_collection(
|
||||
return NULL;
|
||||
|
||||
/* create the collection's monitor hash */
|
||||
if ( hash_create( &p_collection->hash,
|
||||
p_creation_args && p_creation_args->min_port_monitors > 0 ?
|
||||
calc_efficient_hash_size( p_creation_args->min_port_monitors,
|
||||
TCP_MONITOR_HASH_SIZE_MAX,
|
||||
TCP_MONITOR_HASH_MAX_LOAD_RATIO ) :
|
||||
TCP_MONITOR_HASH_SIZE_DEFAULT,
|
||||
&monitor_hash_function_1, &monitor_hash_function_2,
|
||||
&monitor_match_function, NULL ) != 0 )
|
||||
if ( (p_collection->hash = g_hash_table_new (g_str_hash, g_str_equal)) == NULL)
|
||||
{
|
||||
/* we failed to create the hash, so destroy the monitor completely so we don't leak */
|
||||
destroy_tcp_port_monitor_collection(p_collection);
|
||||
@ -774,9 +492,6 @@ void destroy_tcp_port_monitor_collection(
|
||||
if ( !p_collection )
|
||||
return;
|
||||
|
||||
/* destroy the collection's hash */
|
||||
hash_destroy( &p_collection->hash );
|
||||
|
||||
/* destroy the monitors */
|
||||
for_each_tcp_port_monitor_in_collection(
|
||||
p_collection,
|
||||
@ -793,6 +508,10 @@ void destroy_tcp_port_monitor_collection(
|
||||
p_current_node = p_next_node;
|
||||
}
|
||||
|
||||
/* destroy the collection's hash */
|
||||
g_hash_table_destroy (p_collection->hash);
|
||||
p_collection->hash = NULL;
|
||||
|
||||
free( p_collection );
|
||||
p_collection=NULL;
|
||||
}
|
||||
@ -836,6 +555,11 @@ void update_tcp_port_monitor_collection(
|
||||
|
||||
if ((inode == 0) || (state != TCP_ESTABLISHED)) continue;
|
||||
|
||||
/* build hash key */
|
||||
g_sprintf (conn.key, "%08X:%04X %08X:%04X",
|
||||
conn.local_addr, conn.local_port,
|
||||
conn.remote_addr, conn.remote_port);
|
||||
|
||||
/* show the connection to each port monitor. */
|
||||
for_each_tcp_port_monitor_in_collection(
|
||||
p_collection,
|
||||
@ -846,13 +570,6 @@ void update_tcp_port_monitor_collection(
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* check the health of the monitor hashes and rebuild them if nedded */
|
||||
for_each_tcp_port_monitor_in_collection(
|
||||
p_collection,
|
||||
&maintain_tcp_port_monitor_hash,
|
||||
NULL
|
||||
);
|
||||
|
||||
/* rebuild the connection peek tables of all monitors so clients can peek in O(1) time */
|
||||
for_each_tcp_port_monitor_in_collection(
|
||||
p_collection,
|
||||
@ -883,12 +600,10 @@ int insert_tcp_port_monitor_into_collection(
|
||||
p_node->p_next = NULL;
|
||||
|
||||
/* add a pointer to this monitor to the collection's hash */
|
||||
if ( hash_insert( &p_collection->hash, (void *)p_monitor ) != 0 )
|
||||
{
|
||||
/* error inserting into hash. destroy the monitor's container node so no leaks */
|
||||
free( p_node );
|
||||
return (-1);
|
||||
}
|
||||
#ifdef HASH_DEBUG
|
||||
fprintf (stderr, "collection hash insert of monitor [%s]\n", p_monitor->key);
|
||||
#endif
|
||||
g_hash_table_insert (p_collection->hash, (gpointer)p_monitor->key, (gpointer)p_monitor);
|
||||
|
||||
/* tail of the container gets this node */
|
||||
if ( !p_collection->monitor_list.p_tail )
|
||||
@ -918,25 +633,14 @@ tcp_port_monitor_t * find_tcp_port_monitor(
|
||||
in_port_t port_range_end
|
||||
)
|
||||
{
|
||||
tcp_port_monitor_t monitor,*p_monitor;
|
||||
void *p_cast;
|
||||
tcp_port_monitor_t *p_monitor;
|
||||
gchar key[12];
|
||||
|
||||
if ( !p_collection )
|
||||
return NULL;
|
||||
|
||||
/* need a monitor object to use for searching the hash */
|
||||
monitor.port_range_begin = port_range_begin;
|
||||
monitor.port_range_end = port_range_end;
|
||||
p_monitor = &monitor;
|
||||
p_cast = (void *)p_monitor;
|
||||
|
||||
/* simple hash table lookup */
|
||||
if ( hash_lookup( &p_collection->hash, &p_cast ) == 0 )
|
||||
{
|
||||
/* found the monitor and p_cast now points to it */
|
||||
p_monitor = (tcp_port_monitor_t *)p_cast;
|
||||
return( p_monitor );
|
||||
}
|
||||
|
||||
return NULL; /* monitor not found */
|
||||
/* is monitor in hash? */
|
||||
g_sprintf (key, ":%04X :%04X", port_range_begin, port_range_end);
|
||||
p_monitor = g_hash_table_lookup( p_collection->hash, (gconstpointer)key);
|
||||
return (p_monitor);
|
||||
}
|
||||
|
@ -35,44 +35,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hash.h"
|
||||
#include <glib.h>
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Each port monitor contains a connection hash whose contents changes dynamically as the monitor
|
||||
* is presented with connections on each update cycle. This implementation maintains the health
|
||||
* of this hash by enforcing several rules. First, the hash cannot contain more items than the
|
||||
* TCP_CONNECTION_HASH_MAX_LOAD_RATIO permits. For example, a 512 element hash with a max load of
|
||||
* 0.5 cannot contain more than 256 connections. Additional connections are ignored by the monitor.
|
||||
* The load factor of 0.5 is low enough to keep the hash running at near O(1) performanace at all
|
||||
* times. As elements are removed from the hash, the hash slots are tagged vacated, as required
|
||||
* by open address hashing. The vacated tags are essential as they enable the hash to find elements
|
||||
* for which there were collisions during insert (requiring additional probing for an open slot).
|
||||
* The problem with vacated slots (even though they are reused) is that, as they increase in number,
|
||||
* esp. past about 1/4 of all slots, the average number of probes the hash has to perform increases
|
||||
* from O(1) on average to O(n) worst case. To keep the hash healthy, we simply rebuild it when the
|
||||
* percentage of vacated slots gets too high (above TCP_CONNECTION_HASH_MAX_VACATED_RATIO).
|
||||
* Rebuilding the hash takes O(n) on the number of elements, but it well worth it as it keeps the
|
||||
* hash running at an average access time of O(1).
|
||||
* ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define TCP_CONNECTION_HASH_SIZE_DEFAULT 512 /* connection hash size default -- must be a power of two */
|
||||
#define TCP_CONNECTION_HASH_SIZE_MAX 65536 /* connection hash size maximum -- must be a power of two */
|
||||
#define TCP_CONNECTION_HASH_MAX_LOAD_RATIO 0.5 /* disallow inserts after this load ratio is exceeded */
|
||||
#define TCP_CONNECTION_HASH_MAX_VACATED_RATIO 0.25 /* rebalance hash after this ratio of vacated slots is exceeded */
|
||||
#define TCP_CONNECTION_STARTING_AGE 1 /* connection deleted if unseen again after this # of refreshes */
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* The tcp port monitor collection also contains a hash to track the monitors it contains.
|
||||
* This hash, unlike the connection hash describes above, is not very dynamic. Clients of
|
||||
* this library typically create a fixed number of monitors and let them run until program
|
||||
* termination. For this reason, I haven't included any hash rebuilding code as is done
|
||||
* above. You may store up to TCP_MONITOR_HASH_SIZE_MAX monitors in this hash, but you
|
||||
* should remember that keeping the load low (e.g. 0.5) keeps the monitor lookups at O(1).
|
||||
* ----------------------------------------------------------------------------------------*/
|
||||
|
||||
#define TCP_MONITOR_HASH_SIZE_DEFAULT 32 /* monitor hash size default -- must be a power of two */
|
||||
#define TCP_MONITOR_HASH_SIZE_MAX 512 /* monitor hash size maximum -- must be a power of two */
|
||||
#define TCP_MONITOR_HASH_MAX_LOAD_RATIO 0.5 /* disallow new monitors after this load ratio is exceeded */
|
||||
#define TCP_CONNECTION_STARTING_AGE 1 /* connection deleted if unseen again after this # of refreshes */
|
||||
#define TCP_CONNECTION_HASH_KEY_SIZE 28
|
||||
#define TCP_PORT_MONITOR_HASH_KEY_SIZE 12
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* IMPLEMENTATION INTERFACE
|
||||
@ -83,7 +50,17 @@
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
/* The inventory of peekable items within the port monitor. */
|
||||
enum tcp_port_monitor_peekables { COUNT=0, REMOTEIP, REMOTEHOST, REMOTEPORT, REMOTESERVICE, LOCALIP, LOCALHOST, LOCALPORT, LOCALSERVICE };
|
||||
enum tcp_port_monitor_peekables {
|
||||
COUNT=0,
|
||||
REMOTEIP,
|
||||
REMOTEHOST,
|
||||
REMOTEPORT,
|
||||
REMOTESERVICE,
|
||||
LOCALIP,
|
||||
LOCALHOST,
|
||||
LOCALPORT,
|
||||
LOCALSERVICE
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* A single tcp connection
|
||||
@ -92,6 +69,7 @@ enum tcp_port_monitor_peekables { COUNT=0, REMOTEIP, REMOTEHOST, REMOTEPORT, REM
|
||||
* are not seen again in subsequent update cycles.
|
||||
* ------------------------------------------------------------------------ */
|
||||
typedef struct _tcp_connection_t {
|
||||
gchar key[TCP_CONNECTION_HASH_KEY_SIZE]; /* connection's key in monitor hash */
|
||||
in_addr_t local_addr;
|
||||
in_port_t local_port;
|
||||
in_addr_t remote_addr;
|
||||
@ -129,44 +107,15 @@ typedef struct _tcp_connection_list_t {
|
||||
* A port monitor
|
||||
* -------------- */
|
||||
typedef struct _tcp_port_monitor_t {
|
||||
in_port_t port_range_begin;
|
||||
gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE]; /* monitor's key in collection hash */
|
||||
in_port_t port_range_begin; /* start of monitor port range */
|
||||
in_port_t port_range_end; /* begin = end to monitor a single port */
|
||||
tcp_connection_list_t connection_list; /* list of connections for this monitor */
|
||||
hash_table_t hash; /* hash table contains pointers into monitor's connection list */
|
||||
GHashTable *hash; /* hash table of pointers into monitor's connection list */
|
||||
tcp_connection_t **p_peek; /* array of connection pointers for O(1) peeking by index */
|
||||
unsigned int max_port_monitor_connections; /* max number of connections */
|
||||
} tcp_port_monitor_t;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Open-addressed hash implementation requires that we supply two hash functions
|
||||
* and a match function to compare two hash elements for identity.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* --------------------------------------------------
|
||||
* Functions to hash the connections within a monitor
|
||||
* --------------------------------------------------*/
|
||||
|
||||
/* First connection hash function */
|
||||
int connection_hash_function_1( const void * /* p_data */ );
|
||||
|
||||
/* Second connection hash function */
|
||||
int connection_hash_function_2( const void * /* p_data */ );
|
||||
|
||||
/* Connection match function returns non-zero if hash elements are identical. */
|
||||
int connection_match_function( const void * /* p_data1 */, const void * /* p_data2 */ );
|
||||
|
||||
/* --------------------------------------------------
|
||||
* Functions to hash the monitors within a collection
|
||||
* --------------------------------------------------*/
|
||||
|
||||
/* First monitor hash function */
|
||||
int monitor_hash_function_1( const void * /* p_data */ );
|
||||
|
||||
/* Second monitor hash function */
|
||||
int monitor_hash_function_2( const void * /* p_data */ );
|
||||
|
||||
/* Monitor match function returns non-zero if hash elements are identical. */
|
||||
int monitor_match_function( const void * /* p_data1 */, const void * /* p_data2 */ );
|
||||
|
||||
/* ------------------------
|
||||
* A port monitor node/list
|
||||
* ------------------------ */
|
||||
@ -198,11 +147,6 @@ void age_tcp_port_monitor(
|
||||
void * /* p_void (use NULL for this function) */
|
||||
);
|
||||
|
||||
void maintain_tcp_port_monitor_hash(
|
||||
tcp_port_monitor_t * /* p_monitor */,
|
||||
void * /* p_void (use NULL for this function) */
|
||||
);
|
||||
|
||||
void rebuild_tcp_port_monitor_peek_table(
|
||||
tcp_port_monitor_t * /* p_monitor */,
|
||||
void * /* p_void (use NULL for this function) */
|
||||
@ -218,7 +162,7 @@ void show_connection_to_tcp_port_monitor(
|
||||
* -----------------------------*/
|
||||
typedef struct _tcp_port_monitor_collection_t {
|
||||
tcp_port_monitor_list_t monitor_list; /* list of monitors for this collection */
|
||||
hash_table_t hash; /* hash table contains pointers into collection's monitor list */
|
||||
GHashTable *hash; /* hash table of pointers into collection's monitor list */
|
||||
} tcp_port_monitor_collection_t;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
@ -230,15 +174,6 @@ void for_each_tcp_port_monitor_in_collection(
|
||||
void * /* p_function_args (for user arguments) */
|
||||
);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Calculate an efficient hash size based on the desired number of elements and load factor.
|
||||
* ---------------------------------------------------------------------------------------- */
|
||||
int calc_efficient_hash_size(
|
||||
int /* min_elements, the minimum number of elements to store */,
|
||||
int /* max_hash_size, the maximum permissible hash size */,
|
||||
double /* max_load_factor, the fractional load we wish not to exceed, e.g. 0.5 */
|
||||
);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* CLIENT INTERFACE
|
||||
*
|
||||
@ -247,15 +182,10 @@ int calc_efficient_hash_size(
|
||||
|
||||
/* struct to hold monitor creation arguments */
|
||||
typedef struct _tcp_port_monitor_args_t {
|
||||
int min_port_monitor_connections; /* monitor must support tracking at least this many connections */
|
||||
int max_port_monitor_connections; /* monitor supports tracking at most this many connections */
|
||||
} tcp_port_monitor_args_t;
|
||||
|
||||
|
||||
/* struct to hold collection creation arguments */
|
||||
typedef struct _tcp_port_monitor_collection_args_t {
|
||||
int min_port_monitors; /* collection must support creation of at least this many monitors */
|
||||
} tcp_port_monitor_collection_args_t;
|
||||
|
||||
/* ----------------------------------
|
||||
* Client operations on port monitors
|
||||
* ---------------------------------- */
|
||||
@ -263,20 +193,20 @@ typedef struct _tcp_port_monitor_collection_args_t {
|
||||
/* Clients should first try to "find_tcp_port_monitor" before creating one
|
||||
so that there are no redundant monitors. */
|
||||
tcp_port_monitor_t * create_tcp_port_monitor(
|
||||
in_port_t /* port_range_begin */,
|
||||
in_port_t /* port_range_end */,
|
||||
tcp_port_monitor_args_t * /* p_creation_args, NULL ok for library defaults */
|
||||
in_port_t /* port_range_begin */,
|
||||
in_port_t /* port_range_end */,
|
||||
tcp_port_monitor_args_t * /* p_creation_args */
|
||||
);
|
||||
|
||||
/* Clients use this function to get connection data from the indicated port monitor.
|
||||
The requested monitor value is copied into a client-supplied char buffer.
|
||||
Returns 0 on success, -1 otherwise. */
|
||||
int peek_tcp_port_monitor(
|
||||
const tcp_port_monitor_t * /* p_monitor */,
|
||||
int /* item, ( item of interest, from tcp_port_monitor_peekables enum ) */,
|
||||
int /* connection_index, ( 0 to number of connections in monitor - 1 )*/,
|
||||
char * /* p_buffer, buffer to receive requested value */,
|
||||
size_t /* buffer_size, size of p_buffer */
|
||||
const tcp_port_monitor_t * /* p_monitor */,
|
||||
int /* item, ( item of interest, from tcp_port_monitor_peekables enum ) */,
|
||||
int /* connection_index, ( 0 to number of connections in monitor - 1 )*/,
|
||||
char * /* p_buffer, buffer to receive requested value */,
|
||||
size_t /* buffer_size, size of p_buffer */
|
||||
);
|
||||
|
||||
/* --------------------------------
|
||||
@ -284,9 +214,7 @@ int peek_tcp_port_monitor(
|
||||
* -------------------------------- */
|
||||
|
||||
/* Create a monitor collection. Do this one first. */
|
||||
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection(
|
||||
tcp_port_monitor_collection_args_t * /* p_creation_args, NULL ok for library defaults */
|
||||
);
|
||||
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection (void);
|
||||
|
||||
/* Destroy the monitor collection (and everything it contains). Do this one last. */
|
||||
void destroy_tcp_port_monitor_collection(
|
||||
|
@ -1,43 +0,0 @@
|
||||
# --------------------------------------------------------------------
|
||||
# Philip Kovacs (kovacsp3@comcast.net) 2005
|
||||
# Make programs for testing libtcp-portmon and hash stuff up in ../src
|
||||
# Sorry no autoconf/automake for this stuff as of now.
|
||||
#
|
||||
# $Id$
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
#CFLAGS = -g -Wall
|
||||
CFLAGS = -g -Wall -DHASH_DEBUG
|
||||
CC = gcc
|
||||
|
||||
all: test-hash test-portmon
|
||||
|
||||
test-hash: test-hash.o hash.o
|
||||
$(CC) $(CFLAGS) -o $@ test-hash.o hash.o
|
||||
|
||||
test-portmon: test-portmon.o libtcp-portmon.o hash.o
|
||||
$(CC) $(CFLAGS) -o $@ test-portmon.o libtcp-portmon.o hash.o -lm
|
||||
|
||||
test-hash.o: test-hash.c hash.h
|
||||
test-portmon.o: test-portmon.c libtcp-portmon.h hash.h
|
||||
|
||||
hash.h: ../src/hash.h
|
||||
cp ../src/hash.h .
|
||||
|
||||
hash.c: ../src/hash.c
|
||||
cp ../src/hash.c .
|
||||
|
||||
libtcp-portmon.h: ../src/libtcp-portmon.h
|
||||
cp ../src/libtcp-portmon.h .
|
||||
|
||||
libtcp-portmon.c: ../src/libtcp-portmon.c
|
||||
cp ../src/libtcp-portmon.c .
|
||||
|
||||
libtcp-portmon.o: libtcp-portmon.c libtcp-portmon.h
|
||||
hash.o: hash.c hash.h
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} -c $<
|
||||
|
||||
clean:
|
||||
/bin/rm -f *.o test-portmon test-hash hash.? libtcp-portmon.?
|
@ -1,137 +0,0 @@
|
||||
/* ------------------------------------------------------
|
||||
* test-hash.c: unit testing for hash functions in hash.h
|
||||
* Philip Kovacs kovacsp3@comcast.net 2005
|
||||
*
|
||||
* $Id$
|
||||
* ------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "hash.h"
|
||||
|
||||
char *data[] = {
|
||||
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
|
||||
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
|
||||
"eighteen", "nineteen", "twenty", "twenty-one", "twenty-two", "twenty-three",
|
||||
"twenty-four", "twenty-five", "twenty-six", "twenty-seven", "twenty-eight",
|
||||
"twenty-nine", "thirty", "thirty-one", "thirty-two"
|
||||
};
|
||||
|
||||
/* Primary hash function is DJB with a 65521 prime modulus to govern the range. */
|
||||
unsigned int DJBHash(const char* str, unsigned int len)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
unsigned int i = 0;
|
||||
|
||||
for(i = 0; i < len; str++, i++)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + (*str);
|
||||
}
|
||||
|
||||
return (hash & 0x7FFFFFFF) % 65521;
|
||||
}
|
||||
|
||||
/* Second hash function is DEK, modified to always return an odd number,
|
||||
as required for open-address hashing using double-hash probing and
|
||||
also with a 65521 prime modulus to govern the range. */
|
||||
unsigned int DEKHash(const char* str, unsigned int len)
|
||||
{
|
||||
unsigned int hash = len;
|
||||
unsigned int i = 0;
|
||||
|
||||
for(i = 0; i < len; str++, i++)
|
||||
{
|
||||
hash = ((hash << 5) ^ (hash >> 27)) ^ (*str);
|
||||
}
|
||||
return (( hash & 0x7FFFFFFF ) % 65521 ) | 0x00000001;
|
||||
}
|
||||
|
||||
int hash_fun1( const void *p_data )
|
||||
{
|
||||
char *p_item = (char *)p_data;
|
||||
|
||||
return DJBHash( p_item, strlen(p_item) );
|
||||
}
|
||||
|
||||
int hash_fun2( const void *p_data )
|
||||
{
|
||||
char *p_item = (char *)p_data;
|
||||
|
||||
return DEKHash( p_item, strlen(p_item) );
|
||||
}
|
||||
|
||||
/* must return non-zero if a match */
|
||||
int match_fun( const void *p_data1, const void *p_data2 )
|
||||
{
|
||||
int l1,l2;
|
||||
char *p_item1, *p_item2;
|
||||
|
||||
p_item1 = (char *)p_data1;
|
||||
p_item2 = (char *)p_data2;
|
||||
|
||||
l1=strlen( p_item1 );
|
||||
l2=strlen( p_item2 );
|
||||
|
||||
return (l1==l2) && (strncmp( p_item1, p_item2, l1 ) == 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i,size,modulus;
|
||||
size=128;
|
||||
modulus=32;
|
||||
|
||||
hash_table_t hash;
|
||||
|
||||
printf("testing hash functions 1 and 2...\n");
|
||||
for ( i=0; i<31; i++ ) {
|
||||
printf("(func 1,func 2): hash of \"%s\" mod %d is (%d,%d)\n",
|
||||
data[i], modulus, hash_fun1(data[i]) % modulus, hash_fun2(data[i]) % modulus );
|
||||
}
|
||||
|
||||
printf("creating hash table with %d positions...\n",size);
|
||||
if ( hash_create( &hash, size, &hash_fun1, &hash_fun2, &match_fun, NULL ) != 0 ) {
|
||||
fprintf(stderr,"error creating hash table!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("testing that double-hashes can visit all slots...\n");
|
||||
for ( i=0; i<31; i++ ) {
|
||||
printf("inserting \"%s\" into hash...\n", data[i]); fflush(stdout);
|
||||
if ( hash_insert( &hash, data[i] ) != 0 ) {
|
||||
fprintf(stderr, "error inserting value!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("ok\n");
|
||||
printf("looking up \"%s\"...\n", data[i]); fflush(stdout);
|
||||
if ( hash_lookup( &hash, (void **)&data[i] ) != 0 ) {
|
||||
fprintf(stderr, "error looking up value!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("found\n");
|
||||
printf("hash size now %d, vacated slots %d\n",hash_size(&hash),hash.vacated);
|
||||
}
|
||||
|
||||
printf("removing all items from hash...\n");
|
||||
for ( i=0; i<31; i++ ) {
|
||||
printf("deleting \"%s\" from hash...\n", data[i]); fflush(stdout);
|
||||
if ( hash_remove( &hash, (void **)&data[i] ) != 0 ) {
|
||||
fprintf(stderr, "error deleting value!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("ok\n");
|
||||
printf("looking up \"%s\"...\n", data[i]); fflush(stdout);
|
||||
if ( hash_lookup( &hash, (void **)&data[i] ) != -1 ) {
|
||||
fprintf(stderr, "error: deleted value still found in hash!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("not found, good\n");
|
||||
printf("hash size now %d, vacated slots %d\n",hash_size(&hash),hash.vacated);
|
||||
}
|
||||
|
||||
printf("destroying hash table...\n");
|
||||
hash_destroy(&hash);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/* -------------------------------------------------------
|
||||
* test-portmon.c: unit testing for libtcp-portmon library
|
||||
* Philip Kovacs (kovacsp3@comcast.net) 2005
|
||||
*
|
||||
* $Id$
|
||||
* ------------------------------------------------------*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include "libtcp-portmon.h"
|
||||
|
||||
volatile int g_signal;
|
||||
|
||||
tcp_port_monitor_collection_t *p_collection = NULL;
|
||||
|
||||
void set_terminate(int);
|
||||
|
||||
int main()
|
||||
{
|
||||
tcp_port_monitor_t * p_monitor;
|
||||
int i;
|
||||
char buf[256];
|
||||
|
||||
g_signal=0;
|
||||
|
||||
(void) signal(SIGINT,set_terminate);
|
||||
|
||||
if ( (p_collection = create_tcp_port_monitor_collection( NULL )) == NULL) {
|
||||
fprintf(stderr,"error: create_tcp_port_monitor_collection()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( (p_monitor = create_tcp_port_monitor( 1, 65535, NULL )) == NULL) {
|
||||
fprintf(stderr,"error: create_tcp_port_monitor()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( (insert_tcp_port_monitor_into_collection( p_collection, p_monitor )) != 0 ) {
|
||||
fprintf(stderr,"error: insert_tcp_port_monitor_into_collection()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
update_tcp_port_monitor_collection( p_collection );
|
||||
|
||||
if ( (p_monitor = find_tcp_port_monitor( p_collection, 1, 65535 )) == NULL ) {
|
||||
fprintf(stderr,"error: find_tcp_port_monitor()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
peek_tcp_port_monitor( p_monitor, COUNT, 0, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "\n(%d,%d) COUNT=%s\n",
|
||||
p_monitor->port_range_begin, p_monitor->port_range_end, buf );
|
||||
for ( i=0; i<p_monitor->hash.size; i++ )
|
||||
{
|
||||
fprintf( stdout, "(%d,%d) -- connection %d -- ",
|
||||
p_monitor->port_range_begin, p_monitor->port_range_end, i );
|
||||
peek_tcp_port_monitor( p_monitor, REMOTEIP, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "%s ", buf );
|
||||
peek_tcp_port_monitor( p_monitor, REMOTEHOST, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "(%s) ", buf );
|
||||
peek_tcp_port_monitor( p_monitor, REMOTEPORT, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, ": %s ", buf );
|
||||
peek_tcp_port_monitor( p_monitor, LOCALIP, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "on %s ", buf );
|
||||
peek_tcp_port_monitor( p_monitor, LOCALHOST, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "(%s) ", buf );
|
||||
peek_tcp_port_monitor( p_monitor, LOCALPORT, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, ": %s\n", buf );
|
||||
/*
|
||||
peek_tcp_port_monitor( p_monitor, LOCALSERVICE, i, buf, sizeof(buf)-1 );
|
||||
fprintf( stdout, "(%s)\n", buf );
|
||||
*/
|
||||
}
|
||||
|
||||
printf("\n<< PRESS CNTL-C TO EXIT >>\n");
|
||||
|
||||
sleep(3);
|
||||
|
||||
if ( g_signal && p_collection ) {
|
||||
destroy_tcp_port_monitor_collection(p_collection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("bye\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
void set_terminate(int sig)
|
||||
{
|
||||
g_signal=1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user