Mod countm

Byron Young January 7, 2006

An Apache 2 only DSO module serving link counting information via jpeg and png images. Direct support for Fedora Core 4 (i386) and FreeBSD 5.4-RELEASE (i386) distributions. Supports, at least, the major Multi-Processing Modules, separate virtual server databases and configurations, and per link background images. DB4 or MySQL database build options.

Contents

1 Databases 7 1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2 DB4 Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3 DB4 Database File . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4 DB4 Database - Locking . . . . . . . . . . . . . . . . . . . . . . . 9 1.5 DB4 Database - mod countm environment lockfile . . . . . . . . 9 1.6 DB4 Databases - Fine Tuning . . . . . . . . . . . . . . . . . . . . 9 1.7 DB4 Databases - Utilities . . . . . . . . . . . . . . . . . . . . . . 10 1.8 MySQL Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.9 MySQL Database - Locking . . . . . . . . . . . . . . . . . . . . . 10 1.10 MySQL Database - Setting Up . . . . . . . . . . . . . . . . . . . 11

2 Counter Usage 13

2.1 Common Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.1 No link in Counter . . . . . . . . . . . . . . . . . . . . . . 13 2.1.2 insert vs ignore . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.3 Arst Changes Colors . . . . . . . . . . . . . . . . . . . . . 13 2.1.4 Broken Image . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.2 URL Formation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.2.1 QUERY STRING . . . . . . . . . . . . . . . . . . . . . . 15 2.3 QUERY STRING application/x-www-form-urlencoded . . . . . . 16 2.4 Enter Link in Database. . . . . . . . . . . . . . . . . . . . . . . . 18 2.5 Add Image to Document . . . . . . . . . . . . . . . . . . . . . . . 18 2.6 Reset Link Count . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.7 Reset Access List . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.8 Delete Link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.9 A First Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.10 A Complete Session . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.11 Fonts/ Query Available Fonts . . . . . . . . . . . . . . . . . . . . 22 2.12 QUERY STRING parameters . . . . . . . . . . . . . . . . . . . . 23

2.12.1 font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.12.2 width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.12.3 random . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.12.4 reset=access . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.12.5 reset=delete . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.12.6 reset=counting number . . . . . . . . . . . . . . . . . . . 24 2.12.7 reset=init:counting number . . . . . . . . . . . . . . . . . 25 2.12.8 image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.12.9 point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.12.10 link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.12.11 ignore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.12.12 text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.12.13 bgcolor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.12.14 count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.12.15 insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3 Module Configuration 29 3.1 CountmFontDir . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.2 CountmDefFont . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.3 CountmEnvironmentHome . . . . . . . . . . . . . . . . . . . . . . 31 3.4 CountmDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.5 CountmMySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.6 CountmDBLockFile . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.7 CountmBgfileDir . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.8 CountmActivate . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.9 CountmAllowReset . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.10 CountmDBPriority . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.11 Undefined Directives . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.12 CountmDB, CountmEnvironmentHome, and CountmActivate . . 34

3.12.1 Assigning A Database . . . . . . . . . . . . . . . . . . . . 34 3.12.2 Activating Databases . . . . . . . . . . . . . . . . . . . . . 35

3.13 Commandline VS Database Priority . . . . . . . . . . . . . . . . 35 3.14 Apache2 HostNameLookups Directive . . . . . . . . . . . . . . . 36

4 Configuration Examples 37 4.1 Configuration Zero . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.2 Configuration One . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.3 Configuration Two . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.4 Configuration Three . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.5 Configuration Four . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5 libcountm 43 5.1 symbol versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 5.2 Interface Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.3 Interface Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.4 Libcountm Versioning Infomation . . . . . . . . . . . . . . . . . . 46 5.5 Libcountm Object File Information . . . . . . . . . . . . . . . . . 46

5.5.1 Example .0.1.1 . . . . . . . . . . . . . . . . . . . . . . . . 46 5.5.2 Example .2.0.0 . . . . . . . . . . . . . . . . . . . . . . . . 46

5.6 Runtime Library Name . . . . . . . . . . . . . . . . . . . . . . . 46

5.7 libcountm.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6 Installing 49

6.1 RedHat, Fedora . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.1.1 RedHat, Fedora(i386): Installing . . . . . . . . . . . . . . 49 6.1.2 RedHat, Fedora (i386): Removing . . . . . . . . . . . . . 49

6.2 FreeBSD 5.4 (i386): Installing . . . . . . . . . . . . . . . . . . . . 50 6.2.1 Package Dependencies . . . . . . . . . . . . . . . . . . . . 50 6.2.2 FreeBSD 5.4 (i386): Installing From Package . . . . . . . 50 6.2.3 FreeBSD 5.4 (i386): Installing From Port . . . . . . . . . 50

6.3 Installing - OpenSolaris . . . . . . . . . . . . . . . . . . . . . . . 51 6.4 mod status and mod cachem integration . . . . . . . . . . . . . . 51 6.5 libgd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.6 libcountm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.7 Building Release X Y from .tar.gz distribution . . . . . . . . . . 52

6.7.1 requirements . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.7.2 ./configure variables . . . . . . . . . . . . . . . . . . . . . 53 6.7.3 ./configure command line options . . . . . . . . . . . . . . 54 6.7.4 building . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

6.8 Building CURRENT X Y From Source . . . . . . . . . . . . . . 55 6.9 Apache2 apxs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.9.1 building libcountm . . . . . . . . . . . . . . . . . . . . . . 56 6.9.2 building mod countm . . . . . . . . . . . . . . . . . . . . 56

6.10 Created/ Installed Files . . . . . . . . . . . . . . . . . . . . . . . 56 6.11 RedHat 9 i586 Systems . . . . . . . . . . . . . . . . . . . . . . . . 57

6.11.1 Disclaimer . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.11.2 Default RH9 NPTL Packages . . . . . . . . . . . . . . . . 58 6.11.3 Default Installed RPMS . . . . . . . . . . . . . . . . . . . 58 6.11.4 Patched db4.spec Created RPMS . . . . . . . . . . . . . . 58 6.11.5 db.spec Patch . . . . . . . . . . . . . . . . . . . . . . . . 58 6.11.6 Test Program . . . . . . . . . . . . . . . . . . . . . . . . . 59

7 Project Information 63 7.1 TO DO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 7.2 Project Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 7.3 Supported Distributions . . . . . . . . . . . . . . . . . . . . . . . 63 7.4 Targeted Audience . . . . . . . . . . . . . . . . . . . . . . . . . . 64 7.5 sourceforge.net Information . . . . . . . . . . . . . . . . . . . . . 64 7.6 Release Distribution Files . . . . . . . . . . . . . . . . . . . . . . 64 7.7 Credits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

8 Debugging 65 8.1 Download debuginfo Package . . . . . . . . . . . . . . . . . . . . 65 8.2 Prelink httpd Executable . . . . . . . . . . . . . . . . . . . . . . 65 8.3 Preload mod countm.so . . . . . . . . . . . . . . . . . . . . . . 66 8.4 A gdb session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 8.5 Debugging the threaded MPMs . . . . . . . . . . . . . . . . . . . 68 8.6 Debugging FreeBSD 5.4-RELEASE . . . . . . . . . . . . . . . . . 78

9 Additional Information 79 9.1 mod ometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 9.2 Network sniffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

Chapter 1

Databases

1.1 Overview

For the purposes of this manual, a virtual server is defined to be the set of configuration directives applied via a ¡VirtualHost¿ directive, and the global server the set of all other directives.

For each counter, a database maintains per link information. Within each database, two sub databases are maintained; DB COUNTER and DB ACCESS. The DB COUNTER sub-database maintains, for each link, a current count value and the default link settings. The DB ACCESS sub-database maintains, for each link, a list of hosts that have accessed the link. Operations that alter the database may act upon one or both sub-databases.

The build time database may be one of MySQL¿3.2.58 (www.mysql.com) or Berkeley DB4 (www.sleepycat.com).

The –with-bdb and the –with-mysql configure options select the mod countm database. Setting both to ’no’ is an error. A valid option adds the library to the linking process. For best results, specifically set one of –with-bdb or –with-mysql to ’no’.

1.2 DB4 Databases

Mod countm DB4 database interfaces are designed to function within a single server machine installation. They will not function across multiple Apache servers installed and running on separate server machine installations. For a more detailed description, see Berkeley DB Reference Guide: Remote Filesystems.

The configuration option –with-bdb selects the Berkeley DB4 database.

The mod countm Apache2 configuration directives CountmEnvironmentHome and CountmDB are used to describe a database (per server). The CountmDB file is created within the CountmEnvironmentHome directory. The two DB ACCESS and DB COUNTER sub-databases are created within the CountmDB file.

The linkname, when using DB4, is case sensitive. Domain names, in general, are not case sensitive. A future modification may changes this behavior. All linknames would be changed to lower case (strlower).

If the environment and database files do not exist, then mod countm automatically creates them during the first request that uses them (not at server startup). On server shutdown (-SIGTERM), or server restart (-HUP), (assuming the environment lock count decreases to 0), the environment is deleted, but the database remains. If the environment exists and the lockfile does not exist (a condition that results from the server improperly shutdown, then the env.lock file manually deleted), recovery is run on the environment, the environment deleted, then recreated.

The countm utility may be used to create the database file.

1.3 DB4 Database File

CountmEnvironmentHome/CountmDB DB COUNTER:

abcd default values,count defg default values,count lmno default values,count

DB ACCESS:

abcd localhost

abcd www.hackedme.jerk abcd www.knowitall.god defg localhost hijk localhost

In this example, the CountmDB DB COUNTER sub database contains 3 entries/links; abcd, defg, and lmno. DB ACCESS contains 3 entries/links; abcd, defg, hijk. Note that DB COUNTER contains entry/link lmno, but DB ACCESS does not, and DB ACCESS contains hijk, which DB COUNTER does not. Links/entries abcd and defg which are in both DB COUNTER and DB ACCESS are typical of normal counter operation. They were entered into the counter database, and, have a list of associated hosts. However, links/entries hijk and lmno are not typical of normal counter operation. Link lmno probably was just entered into the database, and, either no hosts have accessed the links, or its access list was just deleted from DB ACCESS. Link hijk was probably just deleted from DB COUNTER, and the link/entry will be deleted soon from DB ACCESS. Unmatched links/entries are perfectly acceptable, and considered normal by the internal counter update mechanism.

1.4 DB4 Database - Locking

The DB4 API defines a locking subsystem. For the most part, it is automatic, and certainly the Sleepycat documentation details its operations. As part of the locking subsystem, the application may define objects, with scope the database environment, to lock. The mod countm module defines and obtains a lock object for each link (defined by the link= parameter) it is currently serving. This means that within an environment, no two threads of control (accessing a common environment) may access a links data, in any database defined within the environment, simultaneously.

1.5 DB4 Database - mod countm environment lockfile

Additionally, mod countm creates an environment lockfile within each environment (env.lck) that contains a count of the number of additional processes currently using the environment. Access to this file by mod countm is subject to strict global locks. However, access to this file by other utilities that are aware of this file, is not controlled. The countm utility, for example, is aware of this environment lockfile. Providing the two do not attempt to access the file simultaneously, it will do its job. If the server crashes (shuts down incorrectly, or other reason) the env.lck file must be removed manually.

This lockfile is accessed whenever a process using the environment terminates or when a process opens/ creates the environment via a thread of control on first usage. For mod countm, this is whenever the server shuts down, or restarts, or when a process thread of control uses the environment for the first time, or when a process using the environment terminates, either by exceeding MaxRequestsPerChild or by shutdown or by restart. If neither the Apache server is running or the countm utility is running, then this file should not exist. When a process closes an environment, and the lock count within the file is zero (0), that process attempts to remove the environment.

1.6 DB4 Databases - Fine Tuning

The database environments may be configured using a DB4 API DB CONFIG file. See the Sleepycat DB4 documentation for proper usage. If this file exists when the environment is opened, it is read for configuration information.

Two compile time options, COUNTM BDB MAX ENV and COUNTM BDB MAX DB (countm mod.h), determine the maximum number of BDB Environment Homes and BDB database files, respectively, that may be defined.

1.7 DB4 Databases - Utilities

The DB4 distribution contains numerous utilities to interact with the databases. Mod countm does not implement any shared locks with these utilities. On Fedora Core systems, they may be listed with:

rpm -ql db4
rpm -ql db4-devel
rpm -ql db4-utils

The DB4 db stat utility may be used to gather information about the environment.

The DB4 db dump utility may be used to get a quick dump of the database file.

The DB4 db recover utility may be used to recover stale locks. If DB4 locks are valid and the server crashes, they must be recovered. See the DB4 utility db recover for more information.

1.8 MySQL Database

The –with-mysql configure option selects MySQL database.

The CountmMySQL mod countm Apache2 configuration directive may be used to configure the connection parameters.

When using the MySQL database, the max allowable link parameter size is 255 bytes, and the maximum allowable hostname parameter size is 245 bytes. No check is made to enforce this. When HOSTNAMELOOKUPS ON, this has the potential to introduce inaccurate counts.

When using MySQL, all linkname searches are case insensitive. Domain names, in general, are case insensitive. A future modification may changes this behavior. All linknames would be changed to lower case (strlower).

The MySQL database implements the DB COUNTER and DB ACCESS sub-databases using tables.

Mod countm access to the MySQL database tables is basic and each SE-LECT, DELETE, INSERT statement results in no more than one row of information being transmitted.

1.9 MySQL Database - Locking

For each query, both the DB COUNTER and DB ACCESS tables are locked. Because all tables are unlocked when a connection terminates, this should be automatic.

1.10 MySQL Database - Setting Up

Mod countm will not create and/or delete the MySQL database and tables. See the countm utility for more information.

The CountmMySQL mod countm Apache2 configuration directive uses a - db=name option to determine the database within MySQL to be used. Within that database, a DB COUNTER and a DB ACCESS table contain information about a specific link. The countm utility help option outputs the exact scripts it uses to create the tables.

The MySQL database administrator must grant permission for SELECT, INSERT, UPDATE, LOCK, DELETE, and CREATE operations to the configured MySQL user.

Note: When information here conflicts with the countm utilty info, use the countm utility information.

Ex:
CountmMySQL -user=bkyoung -host=waiter -db=COUNTM
(Administrator)
GRANT ALL ON COUNTM.* TO 'bkyoung'@'waiter.localzone.'
(As MySQL user ID bkyoung)
CREATE DATABASE COUNTM;
USE COUNTM;
CREATE TABLE DB_COUNTER (
link VARCHAR(255) NOT NULL PRIMARY KEY,
font TEXT NULL,
width INTEGER NULL,
point INTEGER NULL,
bgcolor TEXT NULL,
bgfile_type ENUM('jpeg', 'png') NULL,
text VARCHAR(7) NULL,
image ENUM('jpeg', 'png') NULL,
cnt BIGINT UNSIGNED NOT NULL,
random ENUM('true', 'false') NULL,
count ENUM('norm_inc', 'inc', 'inc_nopub', 'norm_dec', 'dec','dec_nopub') NULL,
atime DATE NOT NULL
);
CREATE TABLE DB_ACCESS (
link VARCHAR(255) NOT NULL,
host VARCHAR(245) NOT NULL,
PRIMARY KEY ( link, host));

Direct manipulation of the database, though possible, is not recommended. All information stored in the database is placed into the database with certain assumptions. Data within the database that does not meet these assumptions will force undefined runtime errors.

12 CHAPTER 1. DATABASES

Counter Usage

2.1 Common Errors

2.1.1 No link in Counter

Attempting to increment a link that has not be inserted into the database:

<IMG src="localhost/countm?link=linkname">

The returned image displays NoLink. Solution: Insert the counter into DB COUNTER using

<IMG src="localhost/countm?link=linkname&reset=init:0">

The image will display ”Cadd”. In general, avoid duplicate ¡IMG¿ tags in a html page. Browsers tend to optimize resource retrievals, and could receive the count image out of desired order.

2.1.2 insert vs ignore

What is the difference between insert= and ignore=? Insert adds the hostname to DB ACCESS (during a reset=init:0 query), and ignore does not. Because ignore does not add hostnames to DB ACCESS, the hostnames will only be valid for that query. However, because insert adds the hostnames to DB ACCESS, subsequent queries will consider the hostnames to have already accessed the counter.

2.1.3 Arst Changes Colors

The Arst image seems to change colors sometimes. Why?

If the link information in DB COUNTER (default values) has been deleted, and the link’s access list is reset, the image will be displayed with compile time default values (usually black and white.)

2.1.4 Broken Image

A broken image is always returned!

• Check the servers CountmActivate setting. OFF will almost always return a broken image.

• An invalid configuration will force CountmActivate to OFF. Check the error log for an “Invalid server configuration error.”

2.2 URL Formation

The following contains information necessary to properly create the GET request URL for mod countm. Although some information is technical in nature, most is not required for simple, everyday use, URL formation.

RFC 1630 establishes a universal method to define a resource, called a Universal Resource Identifier (URI): scheme:path The scheme identifies a defined interpretation. Once scheme is defined, the URI becomes a URL. The exact path format depends on the definition of the scheme, but is generally defined as:

/location/of/resource#fragment?querystring

Within path, /location/of/resource identifies a query-able object. The ’/’ separating substrings establishes a hierarchical definition of the query-able object. The ’#’ delimits a fragment within the query-able object. The ’?’ delimits the query on that object. Within the URI, ’%’ is used as an escape character for an encoding process. In addition to reserving the ’/’, ’#’, and ’?’ characters, the asterik ’*’ and the exclamation mark ’!’ are reserved. Within querystring, ’+’ is reserved as shorthand for a ’ ’. Any character that may not be used directly should be encoded. This includes control characters and characters with an ascii value ¿ 127.

RFC 1738 defines the URL within the URI syntax:

<scheme>:<scheme-specific-string>

and expands its definition. Only alphanumerics, “$- .+!*’(),” and reserved characters used for their defined purposes may be used uncoded in a URL. Although the URI reserves the exclamation mark ’!’ and the asterisk ’*’, the URL permits them. Currently, mod countm does not attach any special significance to the ’!’ and ’*’ characters (as a shell would for file globing), and should never be required. A future exercise in futility would be to modify mod countm to interpret the ’*’ character in a URL as a “match all that is given.” Any database link that matched the given URL would be acted upon, presumably incremented, deleted, reset, etc., depending on the command. Requiring spaces to be encoded is common to both standards, but RFC 1630 uses a +, and RFC 1738 uses a triplet. Fortunately, all recent mainstream User Agents translate a space (’ ’) automatically. Characters other than those allowed or defined must be encoded using % octets. For http scheme, and family, the URL syntax is:

http://<host>:<port>/<path>?<searchpart>

Within path and searchpart, ’/’, ’;’, ’%’, and ’?’ are reserved, and have special meaning. The ’/’ character, within path designates a hierarchical structure, which, mod countm mainly uses as a separator of logical directories defining a hierarchical set of configuration options, with the lowest, or rightmost, settings having priority, and the highest, or leftmost, replacing missing options. The directories may also define logical query-able objects, such as a dynamic list of all fonts available to the server, or a counter. The basic format format of a mod countm URLs is:

<IMG SRC=scheme://host:port/path/PATH_INFO?QUERY_STRING>

• scheme is usually almost always http

• host is the Apache2 server, or possibly a virtual server, controlling the mod countm resource.

• port is almost always missing and assumed to be 80, but may be different (for https 8080 for example).

• path will be the MOD URI PATH STRING compile time option, which is set to countm by default.

• PATH INFO is dependent on the per-directory/ per-location server configuration, and, if given, will refer to a logical directory specification that allows or disallows some command, or represents a query-able object such as a list of fonts.

2.2.1 QUERY STRING

The QUERY STRING represents all characters after the reserved ’?’ character and is encoded in the RFC 1866 section 8.2.1 form-urlencoded Media Type. The basic format of the QUERY STRING is:

parameter1&parameter2&..&parameterN

where each parameterN is delineated by the reserved character ’&’ and formated as a key/ value pair. The key/ value pair is separated by the reserved character ’=’, and the key is noted as a command, and the value is noted as the parameter value.

command=parameter\_value

2.3 QUERY STRING application/x-www-form-urlencoded

Information presented here based on section 8.2 RFC 1866. The enctype application/x-www-form-urlencoded states:

• The parameters are separated from each other by a visible (uncoded) ampersand ’&’.

• The key portion of the key/ value pair is separated from the value portion by a visible (uncoded) ’=’.

• All spaces (’ ’) in key and value are replaced by a visible (uncoded) (’+’).

• All non-alphanumeric characters are replaced by percent %[hex code].

• Default encoding for all forms name/value pairs is application/x-www-form-urlencoded.

• All parameters are placed into the data set in order of appearance in ¡FORM¿.

A User Agent (browser) tends to apply application/x-www-form-urlencoded encoding as follows:

• For ¡FORM METHOD=POST¿, Content-type is set to application/xwww-form-urlencoded, Content-length is set to the length of the QUERY STRING, and QUERY STRING is encoded.

• For ¡FORM METHOD=GET¿, Content-type is not set, Content-length is not set, but QUERY STRING is encoded.

• For ¡IMG¿ (a GET operation), the URL is encoded differently, usually, visible (uncoded) spaces (’ ’) are encoded to %20 codes. Technically, all spaces must be encoded in a URL, so the browser is helping out here.

• A ¡FORM¿ tags ¡INPUT¿ tag using attribute TYPE file may cause extra information to be sent in the request body. If the Enctype attribute is not used, or is specifically set to x-www-form-urlencoded, then no extra data will be sent.

Mod countm decodes the QUERY STRING as follows:

2.3. QUERY STRING APPLICATION/X-WWW-FORM-URLENCODED 17 • All visible (uncoded) plus (’+’) characters are changed to spaces (’ ’).

• All & separated parameter/ value pairs are processed into a parameter string and a value string.

• All encoded triplets (%[hex num octets]) within the value string are de-

coded to their ascii characters via the Apache2 API. When creating the link commands parameter value, follow these guidelines:

• Decide on the actual parameter value, as it will be represented within, and entered into, the database.

• Within ¡FORM¿ the parameter value is entered exactly as it will be stored in the database. Placing encoded triplets may introduce invalid characters into the URL definition when they are decoded. No check is made to prevent invalid characters.

• Within ¡IMG¿ parameter value, encode all URL plus (’+’) characters as

%2B. Example: Actual parameter value, as to be entered into the database.

link=http://www.mydomain.com/b+ +stuff/index.html

Would be entered into ¡FORM¿ exactly as above. However, It would be entered into ¡IMG¿ as:

link=http://www.mydomain.com/b%2B %2Bstuff/index.html

Just as a note,

link=http://www.mydomain.com/b+ +stuff/index.html

would be encoded by ¡FORM¿ as

link=http%3A%2F%2Fwww.mydomain.com%2Fb%2B+%2Bstuff%2Findex.html

and

link=http://www.mydomain.com/b%2B %2Bstuff/index.html

would most likely be encoded by ¡IMG¿ as

link=http://www.mydomain.com/b%2B%20%2Bstuff/index.html

In either case, decoding the encoded parameter value will result in

link=http://www.mydomain.com/b+ +stuff/index.html

2.4 Enter Link in Database.

After installation, no databases exist. BDB databases are created when the first link is entered into a database using the reset=init:0 parameter. MySQL database and tables must be created via the countm utility. To insert a link into the database and set the counter to the initial value:

<IMG src="localhost/countm?link=linkname&reset=init:0">

The image will indicate success with ”Cadd”. If the link is already present in DB COUNTER, ”Elink” is displayed. In the above example, no other parameters were entered into the database, so future queries would have to state them on the query command line, or the compile time defaults will be used. Also, the directive CountmAllowReset must be ON.

2.5 Add Image to Document

Add the link count image to the HTML document to be monitored using the ¡IMG¿ tag.

<IMG src="localhost/counter?link=linkname">

The image will display the count. If the link is not present in DB COUNTER, ”NoLink” is displayed.

The browser loading the page containing the ¡IMG¿ tag will attempt to retrieve the ¡IMG¿ resource. Mod countm will handle the request and return a generated or modified image containing the current page count.

2.6 Reset Link Count

Add the link count image to a test or temporary HTML document using the ¡IMG¿ tag.

<IMG src="localhost/countm?link=linkname&reset=44">

If the link is currently present in the database, the old value is displayed, and count is set to new value. If the link is not in the database, ”NoLink” is displayed. CountmAllowReset must be ON.

2.7 Reset Access List

Add the link count image to a test or temporary HTML document using the ¡IMG¿ tag.

<IMG src="localhost/countm?link=linkname&reset=access">

The image will display Arst (Access Reset). If the link is not present in the access list, ”NoLink” is displayed. CountmAllowReset must be ON.

The database contains an access list for each link. Each host visiting the monitored link will be entered into the access link. The reset=access command deletes the access list, but does not alter the counter values.

2.8 Delete Link

Add the link count image to a test or temporary HTML document using the ¡IMG¿ tag.

<IMG src="localhost/countm?link=linkname&reset=delete">

The image will display Cdel. (Deleted) If the link is not in the counter database, ”NoLink” is displayed. CountmAllowReset must be ON.

The database maintains a counter value, along with default values, for each link. To delete all default values and any count value, use the reset=delete command.

2.9 A First Entry

<img
src="http://www.localzone/countm/admin?
     link=http://www.mydomain.com/b%2B %2Bstuff/index.html
     &reset=init:34
     &image=png
     &text=FFFFFF
     &bgcolor=9933FF
     &count=norm_inc
     &point=20
     &random=false
     &width=0
     &font=FreeMono.txt
     &insert=localhost
     &insert=localhost.localdomain
     &insert=www.hackedme.jerk"
>

For the above example, the link

http://www.mydomain.com/b+ +stuff/index.html

is inserted into the database. Note: the IMG tag SRC elements + signs are encoded. If using BDB and the database does not exist, it will be created.

If using MySQL, the database and tables must exist prior to mod countm usage. The counter value will start at 34, the returned image will be png, the text of the returned image will be FFFFFF (white), the background color of the returned image will be 9933FF (a purple), the text font will be FreeMono, and the text size will be 20 point. The counter mode will be norm inc, which means only unique hostnames will increment the counter value in DB COUNTER. The random mode will be false, which means that the returned image will display the actual count in DB COUNTER. If random mode was true, then a random value would be returned. The width will be set to 0, which means any returned value will use exactly the necessary number of digits to display the number. The three insert commands add the hostnames localhost, localhost.localdomain, and www.hackedme.jerk to DB ACCESS.

After inserting the above example, dump the database to verify proper operation

#countm -dbenv=/var/countm/dbase -dbfile=countm.db L
LINK:http://www.mydomain.com/b+ +stuff/index.html
DB_COUNTER:
countval=34
image=png
count=norm_inc
random=false
atime=May 05 2004
width=0
point=20
bgcolor=9933FF
text=FFFFFF
font=FreeMono.ttf
DB_ACCESS:
localhost
localhost.localdomain
www.hackedme.jerk

Or, use db dump:

#db_dump -p /var/countm/dbase/countm.db
VERSION=3
format=print
database=DB_ACCESS
type=hash
h_nelem=1
duplicates=1
dupsort=1
db_pagesize=4096
HEADER=END
 http://www.mydomain.com/b+ +stuff/index.html\00
 localhost\00

 http://www.mydomain.com/b+ +stuff/index.html\00
 localhost.localdomain\00
 http://www.mydomain.com/b+ +stuff/index.html\00
 www.hackedme.jerk\00
DATA=END
VERSION=3
format=print
database=DB_COUNTER
type=hash
h_nelem=1
db_pagesize=4096
HEADER=END
 http://www.mydomain.com/b+ +stuff/index.html\00
 "\00\00\00\01\00\00\00\03\00\00\00\01\00\00\00\1f\00\00\00\00\00\00\00\14\00
 \00\00\99\00\00\003\00\00\00\ff\00\00\00\ff\00\00\00\ff\00\00\00\ff\00\00\00
 May 05 2004\00FreeMono\00
DATA=END

2.10 A Complete Session

The following assumes a new installation, defining a global server only.

• Verify CountmAllowReset in

         /etc/httpd/conf.d/mod_countm.conf

for the Directory/Location is ON. Later, after the database is created and the count entered, setting CountmAllowReset to OFF will reject any requests containing a reset= command.

• Access ex enter.html, just hit submit.

– If the database file does not exist within the environment, it is created.

– The specified link is entered into the counter databases DB COUNTER sub database.

– Verify with

               db_dump -p /var/countm/dbase/countm.db

• Access ex query.html

– The counter is incremented by 1.

– The accessing localhost is entered into the counters database DB ACCESS sub database.

• Access ex reset.html

– The count in DB COUNTER is reset to the given value.

– The current value is returned.

• Access ex access.html

– The link information in DB ACCESS is deleted.

– Verify with

         db_dump -p /var/countm/dbase/countm.db

• Access ex delete.html

– The link information in DB COUNTER is deleted.

– db dump should indicate nothing in the databases.

         db_dump -p /var/countm/dbase/countm.db

The above sequence enters a link into the database, then queries the link and returns the counter value. For this sequence, ex query.html would be considered the document being monitored. After querying the counter, the value is reset, then the access list is reset, and, finally, the count is deleted from the databases.

2.11 Fonts/ Query Available Fonts

Any directory containing fonts to be used by mod countm must be accessible by runtime Apache. Also, the fonts within the directory must be readable by runtime Apache.

Mod countm uses libgd to create and/or manipulate the returned image. libgd DBFONTPATH environmental variable or the gd.h compile time option DEFAULT FONTPATH is used by libgd to locate TrueType fonts if the font name does not contain any directory separator characters. Also, libgd will automatically check valid TrueType font name extensions, so font names may not have extensions. However, if the font name contains a directory separator character, then libgd uses the font name directly, bypassing the font path scheme. To force libgd to use the font name directly, define the mod countm CountmFontDir directive. Mod countm will appended the font name to CountmFontDir, and will be used directly by libgd, bypassing the automatic font location scheme. When CountmFontDir is defined, all font names must include the extension.

Decide on a font location strategy. Sites comfortable allowing server access to system font directories and/or setting environment variables should use DBFONTPATH, avoid defining CountmFontDir, and specify all font names as base font names, without any directory separators or extensions. Sites wanting to restrict all server font access to a specific directory hierarchy should define CountmFontDir, and use font name extensions.

When changing the font location strategy, the databases, and all information within them, must be deleted. Otherwise, any font name within the database will be incorrect.

The list fonts query will return the list of ”known” fonts based on Countm-FontDir. If CountmFontDir is not defined, the fonts listed are font names that match the extensions from GDFONTPATH or DEFAULT FONTPATH (without extensions). Otherwise, they are the names of files, (with extensions) from within CountmFontDir listed recursively.

Avoid the critical error: Always adjust CountmDefFont extension after defining/ removing CountmFontDir directive.

The COUNTM EXTENSIONS TTF compile time option defines a PCRE that mod countm thinks is what libgd uses for TrueType font filename extension. It is set for gd-2.0.21.

Setting the per directory config directive AllowFontsQuery option to ON activates the font query capability.

A mod countm request with PATH INFO /fonts will return a listing of all known TrueType fonts. Symbolic links are not followed. No check is made to see if the file actually is a valid font. If CountmFontDir is defined, all files within CountmFontDir are assumed to be valid TrueType fonts. If countmFontDir is not defined, all files with COUNTM EXTENSIONS TTF extensions within GDFONTPATH or DEFAULT FONTDIR are assumed to be valid TrueType fonts.

The returned listing is printed exactly as each font should be entered into the font= command.

Correct operation is also dependent on non mod countm per server and per directory access configuration directives.

Example:

http://localhost/countm/fonts

The gd.h DEFAULT FONTPATH may not be correct for all installations of gd. In most cases, it is probably correct. Irregardless, if GDFONTPATH is not defined, it is used.

¡

2.12 QUERY STRING parameters

2.12.1 font

font=font name Default: font=FreeMono The TrueType font for the counter image text/digits. A font error is indicated by ”Efont”.

2.12.2 width

width=counting number Default width=0 The number of digits displayed. If the returned count requires more digits, then ”Eovr” is returned. If the background image may not display all the digits, then Eovr is returned. A width=0 will use exactly the number of digits required (default). Normally only used with random command. Returned error/information strings always use width=0. The max value is 9 (MAX WIDTH CHAR DISPLAY). If the width is greater than the number of digits, then leading zeros are added to fill width.

2.12.3 random

random=[true,false] Default random=false

If true, then instead of displaying the count value, display a random value. The access list and counter information is adjusted according to current settings.

2.12.4 reset=access

reset=access The links’ access list is removed from the database. Success is indicated by the returned image ”Arst”. If link is not currently in the database, ”NoLink” is returned. If the CountmAllowReset httpd configuration directive does not allow reset= query command line options, ”Eparm” will be returned for all queries that have a reset= parameter on the query command line.

2.12.5 reset=delete

reset=delete The links’ counter value is removed from the database. Success is indicated by the returned image ”Cdel”. If the link has an access list, it remains in the database. If the link is not currently in the database, ”NoLink” is returned. If the CountmAllowReset httpd configuration directive does not allow reset= query command line options, ”Eparm” will be returned for all queries that have a reset= parameter on the query command line.

2.12.6 reset=counting number

reset=counting number If the link exists in DB COUNT, then the counter value is changed to counting number, and the current counter value is returned. If the link does not exist in the database, ”NoLink” is returned. If the CountmAllowReset httpd configuration directive does not allow reset= query command line options, ”Eparm” will be returned for all queries that have a reset= parameter on the query command line.

2.12.7 reset=init:counting number

reset=init:counting number Insert the link into the counter database (DB COUNTER), set the the values on the command line as defaults, initialize the counter start value to counting number, and return ”Cadd”. Any parameters given during the counter reset/ initialization phase will become the link defaults, and not be required on subsequent calls. On subsequent queries, compile time option COUNTM INFORMATION PRIORITY specifies if the command line values take priority, or if the database options take priority. Default is COUNTM INFORMATION PRIORITY DATABASE. If the link is already present in the counter database (DB COUNTER), ”Elink” is returned, and the current database values for the link are not changed. If the CountmAllowReset httpd configuration directive does not allow reset= query command line options, ”Eparm” will be returned for all queries that have a reset= parameter on the query command line.

2.12.8 image

image=[jpeg, png] The return image format. If the module has been compiled with USE PNG IF ACCEPTABLE, and the requesting client accepts png images, then a png image will be returned.

2.12.9 point

point=number The point size of the font.

2.12.10 link

link=linkname The linkname to be associated with this counter.

2.12.11 ignore

ignore=[IPADDR, DOMAINNAME] For this query only, these cannot adjust the counter. The ignore=value value may be of the form IPADDR@mask or numbits (192.168.1.0@24 or 192.168.1.0@255.255.255.0) to indicate that a request with ip address in the subnet is not allowed to adjust the counter. The @ notation instead of the usual / is a implementation issue.

2.12.12 text

text=000000 The font color using ”web color” rgb triplet notation (HEX, do not use a leading 0x).

2.12.13 bgcolor

bgcolor[000000, filename jpeg, filename png] bgcolor=000000 The image background color, specified with ”web color” rgb triplet notation (HEX, do not use a leading 0x).

bgcolor=filename jpeg bgcolor=filename png A image to use as the returned images background. The size of the background image determines exactly the size of the returned image. The count string is centered within the image. If the count string will not fit within the image, a error is returned. If the image may not be accessed, or is not a valid jpeg or png image, the default background is used. If the bgcolor value matches the COUNTM EXTENSIONS JPEG or COUNTM EXTENSIONS PNG extension, it is assumed to be a valid background image file within CountmBgfileDir. Otherwise, it is assumed to be a RGB hex value.

2.12.14 count

count=[inc, inc nopub, dec, dec nopub, norm inc, norm dec]

count=inc Specifies that the count should be incremented without checking DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS.

count=inc nopub Specifies that the count should be incremented without checking DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS. If the request remote ip address is from an RFC 1918 public network, do not adjust the counter.

count=dec Specifies that the count should be decremented without checking DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS.

count=dec nopub Specifies that the count should be decremented without checking DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS. If the request remote ip address is from an RFC 1918 public network, do not adjust the counter. count=norm inc Specifies that the count should be incremented if host is not in DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS.

count=norm dec Specifies that the count should be decremented if host is not in DB ACCESS. If host is not in DB ACCESS, host is entered into DB ACCESS.

2.12.15 insert

insert=hostname This hostname is added to DB ACCESS. Only valid during reset=counting number query if and only if the link is not in DB COUNT. Multiple insert commands may be used.

28 CHAPTER 2. COUNTER USAGE

Module Configuration

Configuring mod countm for use within the Apache2 server environment requires setting mod countm configuration directives and, optionally, Apache2 configuration directives. The mod countm.conf file contains the default apache2 mod countm configuration directives. Ordering of the ¡Location¿ directives are important. The first ¡Location¿ directive must be (at least):

<Location /countm>
SetHandler mod-countm
</Location>

Apache 2 Location directive documentation states that Location sections are processed in order of appearance in the configuration files. If this section is not first, the first parameter to the module per dir merge function will be incorrect. The best solution would probably be to add it to the main config file (httpd.conf) prior to any Include *.conf statements, or other countm location sections. Additional ¡Location /countm/whatever¿ sections must follow the ¡Location /countm¿ section. Mod countm does not support nested virtualhost sections, but neither does Apache2. For best results, always activate the global CountmActivate directive and alway define a global database. Virtual servers then have the option of using the global database, using a unique database, or setting CountmActivate to OFF, and not serving any countm queries.

3.1 CountmFontDir

Description: Directory containing true type fonts. Syntax: CountmFontDir /Absolute/path/to/dir/string Context: Server Config Status: Extension Module: mod countm.so See Also: CountmDefFont

CountmFontDir is an absolute path (no ending directory separator ’/’) of a directory containing TrueType fonts. The directory must be readable. The directory must have the correct ownership and permissions for runtime server access. See the Apache configuration User and Group directives. If defined, the complete path must exist at startup. A missing CountmFontDir directive is considered not defined. Any file within CountmFontDir will be considered a valid true type font. If it is not, a runtime error will result when mod countm attempts to use it. If CountmFontDir is defined, all font names are considered relative to Countm-FontDir and must include the necessary extensions. GDFONTPATH and DE-FAULT FONTPATH are ignored. If CountmFontDir is not defined, then standard GD font location procedures using GDFONTPATH and DEFAULT FONTPATH apply. Relative and absolute font names are invalid. Font base names are required, which implies no extension.

If the global server defines CountmDefFont: A virtual server without a CountmDefFont will inherit the global server value. Virtual servers must use base font names. If the global server does not define CountmDefFont: Virtual servers that do not define CountmDefFont must use base font names. Virtual servers that define CountmDefFont must use relative font names with extensions, or font names with extensions. Font names stored in DB COUNTER create runtime problems if the CountmFontDir setting is altered from defined to not defined. When changing mod countm configuration from (or to) a defined CountmFontDir to (or from) a non defined CountmFontDir, always delete and reset the database. Changing the CountmFontDir value (as opposed to defined/not defined) does not alter any DB COUNTER font names.

3.2 CountmDefFont

Description: The default true type font. Syntax: CountmDefFont fontname Context: Server Config Status: Extension Module: mod countm.so See Also: CountmFontDir

CountmDefFont is the name of the default mod countm TrueType font. The default font is used to return error values, replace missing font= parameter values, or replace incorrect font= parameter values. The fonts must be readable and have correct ownership for runtime server access. A missing CountmDefFont is considered not defined and is an error.

When defining CountFontDir, alway use an extension with CountmDefFont. See CountmFontDir for more information.

3.3 CountmEnvironmentHome

Description: Berkeley DB4 database environment home directory. Syntax: CountmEnvironmentHome /Absolute/path/to/dir/string/ Context: Server Config Status: Extension Module: mod countm.so See Also: CountmDB

CountmEnvironmentHome is the absolute pathname (with a trailing directory separator) of the counter database environment/home. All per server database files are relative to this directory. The directory must be writable, and have correct ownership for runtime server access. If defined, the entire directory path must exist at startup. A missing CountmEnvironmentHome directive is considered not defined.

3.4 CountmDB

Description: Berkeley DB4 database filename. Syntax: CountmDB valid file name string Context: Server Config Status: Extension Module: mod countm.so See Also: CountmEnvironmentHome

CountmDB is the name of the database file, (no directory separators allowed), and is relative to CountmEnvironmentHome. A DB COUNTER and a DB ACCESS sub database are created within this file. A missing CountmDB directive is considered not defined.

3.5 CountmMySQL

Description: MySQL Database configuration information. Syntax: CountmMySQL ”option1” ”option2” ... ”optionN” Context: Server Config Status: Extension Module: mod countm.so

CountmMySQL sets the per server MySQL database configuration. Required for MySQL database support. Each optionN value sets a configuration value. Very little checking, if any, is performed on the values. If they are not correct, then runtime errors will result in a deactivated server counter. Each optionN is in the form -parameter=value. The leading parameter dash ’-’ is required. All characters following the equals ’=’ and up to but not including the separating spaces ’ ’, are considered the value.

-host=The host name or IP address.
-user=The user ID. (Required.)
-passwd=The password for user.
-db=The database. (Required)
-port=The port.
-unix_socket=The socket or Named pipe.
-opt_group=The MYSQL_READ_DEFAULT_GROUP value.
-opt_file=The MYSQL_READ_DEFAULT_FILE value.
Must have runtime permissions to access opt_file.
Ex: (unix)
CountmMySQL -host=waiter -user=joe -passwd=yippee -opt_group=joe_counter -opt_file=/home/joe/joe.mysql

The -passwd=value value is stored by mod countm in plaintext. The MySQL client API automatically encrypts it prior to usage.

All of the above values are subject to per server merging. Global server values will become default values for any virtual servers undefined values. This is an especially important consideration for the -passwd value.

An optionN parameter using a ’ ’ (space) character should be enclosed within quotes (“). An optionN parameter using a quote (“) should use a backslash quote.

3.6 CountmDBLockFile

Description: Global DB4 lockfile. Syntax: CountmDBLockFile /Absolute/path/and/file name string Context: Server Config Status: Extension Module: mod countm.so

CountmDBLockFile is the absolute path and filename of a file to be used, by mod countm, as a possible locking mechanism. If AcceptMutex is set to Lock-File, the CountmDBLockFile will be used at runtime. The directory containing the lockfile must be writable and have correct ownership to allow for runtime server access. This directive must be defined for the global server and is ignored if defined for virtual servers. A missing CountmDBLockFile is considered not defined, and is an error.

3.7 CountmBgfileDir

Description: Background images directory. Syntax: CountmBgfileDir /Absolute/path/name/string Context: Server Config Status: Extension Module: mod countm.so

A runtime readable directory string (no trailing /) containing png or jpeg background images. If defined, the complete directory path must exist at startup. A missing CountmBgfileDir is considered not defined. All files within the directory, if any, are assumed to be jpeg or png images. Any file with a .jpeg (exactly) extension is assumed to be a valid jpeg image. Any file with a .png (exactly) extension is assumed to ba a valid png image.

3.8 CountmActivate

Description: Controls the servers response to requests. Syntax: CountmActivate [ON, OFF] Context: Server Config Status: Extension Module: mod countm.so

CountmActivate ON Activates the counter for the server.

CountmActivate OFF Ignores all countm requests to this server. Also, does not internally process the server directives, or open/access the database that may be defined. A missing CountmActivate directive is considered not defined. When ignoring requests, returns a HTTP NOT FOUND message, which usually means a broken image.

3.9 CountmAllowReset

Description: Controls servers reset= command handling. Syntax: CountmAllowReset [ON,OFF] Context: directory/location Status: Extension Module: mod countm.so

CountmAllowReset ON Activates the reset= query command. CountmAllowReset OFF Deactivates the reset= query command. Any queries using the reset= query command will return Eparm. Because no link is associated with the returned image, the compiled in defaults and default font will be used. A missing CountmAllowReset directive is considered not defined.

3.10 CountmDBPriority

Description: Determines the priority of the database. Syntax: CountmDBPriority [ON,OFF] Context: directory/location Status: Extension Module: mod countm.so

CountmDBPriority ON All defined parameters (have a valid value) in the database are used to construct the returned image, even if new parameters (have a valid value) are given on the query command line. These values are entered using the reset=init:# command, or, after the database is created, the countm utility. CountmDBPriority OFF Any defined parameters (have a valid value) on the query command line will be used to construct the returned image, even if the same parameters are already defined (have a valid value) in the database. A missing CountmDBPriority directive is considered not defined.

3.11 Undefined Directives

Undefined virtual server directives inherit the global server directives values. Undefined per directory directives inherit the values of the per directory settings above it.

3.12 CountmDB, CountmEnvironmentHome, and CountmActivate

3.12.1 Assigning A Database

The database assigned to a server depends on the CountmEnvironmentHome and CountmDB directives. Defined directives will be used directly. Undefined directives may inherit values from the global server. At runtime, an undefined database directive is only allowed for an inactive (CountmActivate OFF) server, or a server using the global database. Otherwise, CountmActivate is forced OFF.

• If CountmEnvironmentHome matches (exactly) a previous servers CountmEnvironmentHome and if CountmDB match’s (exactly) a previous servers CountmDB directive, the server will be assigned that existing database, and no new database is created.

• If CountmEnvironmentHome match’s (exactly) the global servers CountmEnvironmentHome and if CountmDB matches (exactly) the global servers CountmDB directive, the server will be assigned the global servers database.

• If a virtual server does not define a CountmEnvironmentHome or a CountmDB, the server will be assigned the global servers database, if active, or the virtual server will force deactivate.

• If a combined CountmEnvironmentHome and CountmDB create a unique database definition, then a new database is created and assigned to the server.

• If a combined CountmEnvironmentHome and CountmDB match (exactly) a previous servers combined CountmEnvironmentHome and CountmDB, but each CountmEnvironmentHome and CountmDB do not match, then an error is noted to the log, CountmActivate is forced OFF, and no new database is created. This condition is not supported.

These rules may be used to assign a group of servers to a specific database, allow some, none, or all virtual servers to default to the global database, or define a unique database for each server.

3.12.2 Activating Databases

Mod countm officially requires the global server to define a database and set CountmActivate ON. For this configuration, each virtual server choosing to to redefine the database parameters will use the globals servers database. However, attempts have been made to accommodate a variety of situations where this is not true.

Defining the global CountmActivate to OFF implies that the global server does not define a database, and all virtual servers CountmActivate will be OFF. Virtual servers that set CountmActivate ON must define a database. Here, although the global server is OFF, if the database directives are defined, they can be inherited to effect a global database.

3.13 Commandline VS Database Priority

Information (parameters) given in QUERY STRING during a reset=init command are inserted into the database and may be used to replace missing parameters/values on subsequent requests. Those subsequent requests may specify different values for certain parameters. If the priority is database, the defined parameters’ parameter values in the database will always be used, even if new parameter values are specified on subsequent queries command lines. If the priority is commandline, then the parameter values on subsequent queries command line will be used, even if a value for the parameter is already in the database.

The usage of priority database decreases security holes. Assuming all administration reset= commands are restricted to localhost, and all parameters are defined and entered into the database during reset=init, all future QUERY STRING parameters except link= are ignored, and the values in the database are used.

3.14 Apache2 HostNameLookups Directive

HostNameLookups [ON,OFF,DOUBLE] If HostNameLookups is OFF inside the location directive, the Apache 2 api will return the remote IP address as the hostname, and mod countm will use the remote client IP address as a hostname.

If HostNameLookups is ON inside the location directive, the Apache 2 api will use single lookup to get the hostname. If there is a hostname, mod countm will use the remote client hostname, otherwise, mod countm will use the IP address as the hostname. This reduces performance, as a remote hostname single lookup is required for each query. If HostNameLookups is DOU-BLE inside the location directive, the Apache 2 api will use double reverse lookup to get the hostname. Double reverse lookup in this context means that a list of IP addresses is obtained for the hostname returned from single reverse lookup. If the stated IP address matches one in the returned list, then the hostname is returned. Otherwise, an error is returned. When double reverse lookup succeeds, mod countm uses the returned hostname as the hostname. Otherwise, mod countm will log the failure, and return ”Econn”. If HostNameLookups are OFF and the remote host is still being identified as a hostname, and not an IP address, the compile time parameter COUNTM FORCE HOSTNAMELOOKUPS must be set to 1, and the module recompiled. Setting compile time option COUNTM FORCE HOSTNAMELOOKUPS to 1, and using HostNameLookups [ON, DOUBLE] is acceptable, but performance is reduced due to required additional reverse or double reverse lookups. If HostNameLookups is DOUBLE, and you would like to force a failed double reverse lookup to return an error, then COUNTM FORCE HOSTNAMELOOKUPS must be set to 1.

Configuration Examples

4.1 Configuration Zero

4.2 Configuration One

The simplest setup is to use on global database for all servers. Each server, when answering mod countm queries would use the same database.

<Location /countm>
    SetHandler               mod-countm
    HostNameLookups          ON
    CountmAllowFontsQuery    ON
    CountmAllowReset         ON
    CountmDBPriority         ON
</Location>
LoadModule countm_module @libexecdir@/mod_countm.so
CountmFontDir                "/var/countm/fonts"
CountmDefFont                "FreeMono"
CountmEnvironmentHome        "/var/countm/dbase"
CountmDB                     "countm.db"
CountmDBLockFile             "/var/countm/countm.lock"
CountmBgfileDir              "/var/countm/bgfiles"
CountmActivate               ON

This basic configuration defines one database, which all servers will use, and defines one logical queryable object which will allow a font listing query, use of the reset= command, and use database priority. All information in the database will refer to the accessing host as a hostname, if one exists. All servers will use the same default font, and share the fonts in the fonts directories.

An HTML 4.0 ¡FORM¿ Element Attribute ACTION URL PATH INFO to enter the counter into the database would be /countm.

Example: ¡form action=http://my.domain.com/countm method=GET enctype=”xwww-form-urlencoded”¿ Somewhere in the form, an HTML 4.0 INPUT Element with an attribute NAME link attribute VALUE linkname would set the ?link=linkname portion. In some rare cases, a / trailing countm may be necessary.

Once the counter is entered into the database, it may be accessed by the page being counted using a HTML 4.0 IMG element ”Query URL”. For this example,

¡img src=”http://my.domain.com/countm?link=linkname”¿ Generally, only one countm IMG element per page works.

If the link linkname is not in the database (has not been entered), then an image ”ELink” should be returned, not a broken image.

An IMG element attribute SRC value using the localhost (or 127.0.0.1) as the domain name will always return a broken image when the accessing client is not on the local machine.

Using the IPV4 address of the server in place of any hostnames (ie 127.0.0.1 instead of localhost) would rule out any problematic resolver issues.

4.3 Configuration Two

Defining additional logical query-able objects increases access control and defining additional databases adds per server statistics.

<Location /countm>
    SetHandler               mod-countm
    HostNameLookups          ON
    CountmAllowFontsQuery    OFF
    CountmAllowReset         OFF
    CountmDBPriority         ON
</Location>
<Location /countm/admin>
    CountmAllowReset        ON
    Order                   deny,allow
    Deny                    from all
    Allow                   from 127.0.0.1
    Allow                   from localhost
    Allow                   from 192.168.1
</Location>
<Location /countm/fonts>
   CountmAllowFontsQuery   ON
</Location>
LoadModule countm_module @libexecdir@/mod_countm.so

CountmFontDir                "/var/countm/fonts"
CountmDefFont                "FreeMono"
CountmEnvironmentHome        "/var/countm/dbase"
CountmDB                     "countm.db"
CountmDBLockFile             "/var/countm/countm.lock"
CountmBgfileDir              "/var/countm/bgfiles"
CountmActivate               ON
<VirtualHost www.localzone:80>
    ServerName               www.localzone:80
    CountmDB                 "countm_virt.db"
</VirtualHost>

This example adds an admin and fonts object. A request to just /countm will be restricted to non reset= commands, but all requests are accepted. A request to /countm/admin will allow reset= command, but only from localhost, 127.0.0.1, and public network 192.168.1, presumably behind a firewall. Also, www.localzone will use a separate database file countm virt.db, but share a database environment with the global server. Locks will be shared across both global and virtual servers database files. Both servers will use the same default font, and share the fonts in the fonts directories.

4.4 Configuration Three

Defining additional logical query-able objects increases access control and defining additional databases adds per server statistics.

<Location /countm>
    SetHandler               mod-countm
    HostNameLookups          ON
    CountmAllowFontsQuery    OFF
    CountmAllowReset         OFF
    CountmDBPriority         ON
</Location>
<Location /countm/admin>
    CountmAllowReset        ON
    Order                   deny,allow
    Deny                    from all
    Allow                   from 127.0.0.1
    Allow                   from localhost
    Allow                   from 192.168.1
</Location>
<Location /countm/fonts>
   CountmAllowFontsQuery   ON

</Location>
LoadModule countm_module @libexecdir@/mod_countm.so
CountmFontDir                "/var/countm/fonts"
CountmDefFont                "FreeMono"
CountmEnvironmentHome        "/var/countm/dbase"
CountmDB                     "countm.db"
CountmDBLockFile             "/var/countm/countm.lock"
CountmBgfileDir              "/var/countm/bgfiles"
CountmActivate               ON
<VirtualHost www.localzone:80>
    ServerName               www.localzone:80
    CountmEnvironmentHome    "/var/countm/virt_dbase"
    CountmDB                 "countm_virt.db"
</VirtualHost>

This example is the same as example two, but uses a separate environment for each database file. Locks will not be shared.

4.5 Configuration Four

Here is a crazy, powerful, and realistic example:

# Example 4
<Location /countm>
    SetHandler               mod-countm
    HostNameLookups          ON
    CountmAllowFontsQuery    OFF
    CountmAllowReset         OFF
    CountmDBPriority         ON
</Location>
<Location /countm/admin>
    CountmAllowReset        ON
    Order                   deny,allow
    Deny                    from all
    Allow                   from 127.0.0.1
    Allow                   from localhost
    Allow                   from 192.168.1
</Location>
<Location /countm/fonts>
   CountmAllowFontsQuery   ON
</Location>

LoadModule countm_module modules/mod_countm.so
# Global sever configuration
# The Global Server counter is not active
# The Global Server CountmEnvironmentHome directive is not defined.
CountmFontDir                "/var/countm/fonts"
CountmDefFont                "FreeMono"
CountmDB                     "countm.db"
CountmDBLockFile             "/var/countm/countm.lock"
CountmBgfileDir              "/var/countm/bgfiles"
CountmActivate               OFF
# 192.168.1.241
# Results in an active counter /var/countm/dbase1/countm.db
<VirtualHost www1.localzone:80>
    ServerName               www1.localzone:80
    CountmEnvironmentHome    "/var/countm/dbase1"
    CountmActivate           ON
</VirtualHost>
# 192.168.1.242
# Results in an active counter /var/countm/dbase2/countm.db
<VirtualHost www2.localzone:80>
    ServerName               www2.localzone:80
    CountmEnvironmentHome    "/var/countm/dbase2"
    CountmActivate           ON
</VirtualHost>
# 192.168.1.243
# Results in an active counter /var/countm/dbase3/countm.db
<VirtualHost www3.localzone:80>
    ServerName               www3.localzone:80
    CountmEnvironmentHome    "/var/countm/dbase3"
    CountmActivate           ON
</VirtualHost>
# 192.168.1.244
# Results in an inactive counter
# Add CountmActivate ON to activate
<VirtualHost www4.localzone:80>
    ServerName               www4.localzone:80
    CountmEnvironmentHome    "/var/countm/dbase4"
</VirtualHost>
# 192.168.1.245
# Results in an inactive counter and a warning message.

# CountmEnvironmentHome is not defined.
<VirtualHost www5.localzone:80>
    ServerName               www5.localzone:80
    CountmActivate           ON
</VirtualHost>
# 192.168.1.246
# Results in an active counter, shared with www3
<VirtualHost www6.localzone:80>
    ServerName               www6.localzone:80
    CountmEnvironmentHome    "/var/countm/dbase3"
    CountmActivate           ON
</VirtualHost>

Notice that the global server defines CountmDB, but not CountmEnvironmentHome, and that it is not active (CountmActivate OFF). This means that all virtual servers will be inactive (like www4.localzone) unless specifically set to ON, and all virtual servers that do not redefine CountmDB will inherit the global configuration “countm.db” value. Servers www1, www2, www3, and www6 are active, and define unique environment home directories, so they will not share locks with other database files sharing a common environment, increasing performance. Virtual server www5 does not define CountmEnvironmentHome and cannot inherit a valid value from the global server. Although CountmActivate is ON, virtual server www4 will be forced inactive, and a warning message issued. Virtual servers www3 and www6 will share database dbase3/countm.db. All virtual servers will use the same default font, and access the fonts from the same font directory. Mod countm will ignore requests for global server www and virtual server www4 and www5 due to their inactive counters, normally returning a Not Found page. Requests to www1-3, an www6 will be accepted, because they are active.

libcountm

The mod countm build process creates and install libcountm. The configure option –enable-versioning will enable building a versioned libcountm if the compiler supports the .symver directive and the linker supports the –versionscript option.

Almost all of the following is specific to ELF 32bit, default for FC3/i386.

5.1 symbol versioning

Associated with libcountm are numerous pieces of version and location information. The most recent interface number exported, IFACE N. The interfaces the library exports. The library versioning information, C:R:A. The library object version info, .x.y.z. The link/compile time library name, usually libcountm.so. The link/compile time library location. The runtime linker library name, usually libcountm.so.x. The library object file name, usually libcountm.so.x.y.z. The runtime location of the library.

The two i386 32bit ELF sections of interest are .dynstr and .dynamic. These are only created if dynamic linking is requested (default.) In the execution view of the ELF object file, the .dynamic segment is available if an element in the program header has p type PT DYNAMIC. The .dynamic section is an array of elements, some of which are DT STRTAB, DT SONAME, DT RPATH, and DT NEEDED. DT STRTAB points to the .dynstr section, DT NEEDED (may be duplicates) points to a NEEDED name entry in .dynstr, DT SONAME points to the SONAME of the file, DT RPATH (may be duplicates) points to a RPATH name in .dynstr.

During the libcountm build link time, SONAME is set inside the libcountm.so.x.y.z library object. Objdump -p libbky.so.x.y.z will list the internal SONAME setting. Normally, this is libcountm.so.x.

An object linked to libcountm must identify the library at build link time using the -lcountm and -L/path/to/installation options. The build time linker finds libcountm.so in the -L path and uses the libcountm.so SONAME value to set the NEEDED value in the created object (either a binary or a library). If a -rpath was stated, then the RPATH is set also. Use objdump -p name of object to view the NEEDED and, if any, RPATH values of the created object. Normally, RPATH is only set if the library is in a location unknown to the application opening the library (either the runtime linker or an application using a dlopen function.)

During libcountm installation, 3 files are typically created, libcountm.so, libcountm.so.x, and libcountm.so.x.y.z. Normally libcountm.so is a symlink pointing to libcountm.so.x and libcountm.so.x is a symlink pointing to libcountm.so.x.y.z. libcountm.so.x.y.z is the actual libcountm library object. libcountm.so is used by the build time (compile/link) linker to locate libcountm. libcountm.so.x is used by the runtime linker to locate the libcountm exporting the correct interface for the application being run.

At load/runtime, the loader (either the runtime dynamic linker or an application opening the library using a dlopen function) uses the objects’ (either a binary or a library) NAME value as the name of the library to load. The loader looks for the library in one of the locations it knows about or, if one is in the load object, in the RPATHs. Environmental variables also may be used to determine the runtime location of a library.

When the libcountm library is updated, the new libcountm.so.x.y.z file is installed. However, depending on the exported interface compatibility, the libcountm.so.x value will either be changed, or a new one added. The interfaces exported by the new libcountm determines the manner in which it is installed.

If existing interfaces do not change (the newly installed library is just a revision change of the existing exported interfaces), then the existing libcountm.so.x will be changed to point to the newly installed libcountm.x.y.z+1 library.

If a new interface is added, but does not break any old interfaces, then y will increase, but the existing libcountm.so.x will be changed to point to the newly installed libcountm.so.z.y+1.0 library.

If a new interface was added, which breaks old interfaces, then an new libcountm.so.x+1 will be created, pointing to the new libcountm.so.x+1.y.0. The y value may change to zero, remain the same, or increase depending on the type of interface changes. Also, x may change by two, but usually changes by one. Assuming no interfaces are dropped from the library, the old libcountm.so.x, libcountm.so.x-1 ti libcountm.so.0 values (if any) are altered to point to the newly installed libcountm library.

By versioning all symbols in the libcountm library, and maintaining each interface, the new libcountm library may be used for all objects that have been linked against any version of libcountm without having to recompile the application binaries and/or libraries.

This is all accomplished by strictly following the versioning sequence in the libtool manual, and diligently and judiciously updating the versioning script map file each release.

When a new interface is added, create a new IFACE number. Any interface that is compatible with it is added as a dependency. If a function in a previous interface changes then the ifaceN fname remains as local to that interface, and the versioned symbol fname@IFACE N remains. However, a new function ifaceY fname is created, assigned local to IFACE Y, and a new versioned symbol fname@IFACE Y is created. Using objdump -T lib name will list all the versioned symbols in the library.

Applications will know what version of symbols are required from libcountm at runtime. Each symbol the application requires is versioned, using version symbolfrom libcountm.h, to the most recently exported interface. The programmer needs only to use the function, in the current interface form, to link with the versioned symbol. As long as the current libcountm library maintains the interface, the binary may runtime link with the new libcountm, and the binary does not require recompiling.

5.2 Interface Numbers

Symbols in libcountm are associated with an interface, identified by IFACE N. N is the interface number. Interfaces, once defined, must alway export the same functions using the same parameters. If the function parameters in an interface must change, or a function is added to an interface, a new interface must be created. In the case of a function being added, the new interface will be compatible with the old interface. If a function parameter must change, then a new, incompatible interface is created with the new function.

5.3 Interface Functions

The functions in an interface are exported as versioned symbols. The actual function is identified by the local symbol ifaceN fname. Then, the libcountm.h header file versions fname to fname@IFACE N. The programmer simply refers to function fname in the normal manner. Example. Consider function fone with prototype as follows: int fone(int i); The actual function definition for IFACE 0 is: int iface0 fone(int i) return 0; IFACE 0 exports it as fone@IFACE 0. Later, a parameter is added to fone, changing the prototype to: int fone(int i, int k); This breaks interface compatibility and a new interface IFACE 2 is created. The new fone is exported by IFACE 2 as fone@IFACE 2, but the old fone remains as fone@IFACE 0. New executable binaries (at compile/link time) linked with the new version of libcountm will link with fone@IFACE 2, and, at runtime will link with fone@IFACE 2. Old executable binaries will know they require fone@IFACE 0, and, at runtime link time will link with fone@IFACE 0.

5.4 Libcountm Versioning Infomation

The library versioning information, C:R:A is passed to libtool via the -version-info option. As described in the libtool manual, C is the current, most recent interface exported by the library. R is the revision number indicating the number of changes in the implementation of the interfaces since a new interface was added. A, Age, is the number of previous additional compatible interfaces supported and exported by the library.

5.5 Libcountm Object File Information

The library object file uses an extension of the form .x.y.z. x+y+1 is the number of interfaces the library exports. x+y is the interface number of the most recent, current interface. Interface numbers start at 0. z is R. x is the interface number of the first compatible interface. y is the number of compatible interfaces above x.

5.5.1 Example .0.1.1

x=0 y=1 z=1 This library exports 2 interfaces, IFACE 0, IFACE 1. IFACE 1 is the most recent, current interface. IFACE 0 is the first compatible interface. There is one interface compatible with IFACE 0, IFACE 1. This is the first revision since adding IFACE 1.

5.5.2 Example .2.0.0

x=2 y=0 z=0 This library exports 3 interfaces, IFACE 0, IFACE 1, IFACE 2. IFACE 2 is the most recent, current interface. IFACE 2 is the first compatible interface. There are no interfaces compatible with IFACE 2. There have been no revisions since adding IFACE 2.

5.6 Runtime Library Name

The runtime library name (SONAME), usually libcountm.so.x, must change to point to the new library. Consider the installation for libcountm.so.0.1.1.

libcountm.so -¿ libcountm.so.0 libcountm.so.0 -¿ libcountm.so.0.1.1 libcountm.so.0.1.1 When the libcountm.so.2.0.0 library is added, the new interface IFACE 2

breaks compatibility with all previous interfaces, but, because of versioning, it may still be used by binaries without recompiling. However, the SONAME of libcountm.so.2.0.0 is libcountm.so.2, to indicate that a previous interface has been broken. When installed, it looks like this: libcountm.so -¿ libcountm.so.2 libcountm.so.2 -¿ libcountm.so.2.0.0 libcountm.so.2.0.0 libcountm.so.0 -¿ libcountm.so.0.1.1 libcountm.so.0.1.1

However, when libcountm.so.0.1.1 is uninstalled (removed), a broken symlink libcountm.so.0 remains. It must be adjusted to point to libcountm.so.2.0.0. Otherwise, binaries with runtime NAME libcountm.so.0 will not load. Once the symlink points to libcountm.so.2.0.0, all binaries with runtime NAME libcountm.so.0 will use libcountm.so.2.0.0 versioned symbols, and run properly without any modification or relinking.

5.7 libcountm.h

The libcountm.h file contains the necessary code to version the symbols for building libcountm, and for compiling/linking with libcountm. During libcountm build, define LIBCOUNTM BUILD. Otherwise, libcountm.h assumes the header file is being used to compile/link with another shared object or executable. Also, define DOVERSIONING during both building and compiling/link to use the symbol versioning. During the mod countm build process, DOVERSIONING is defined inside of config.h, otherwise, a -DDOVERSIONING would have been added to CFALGS.

48 CHAPTER 5. LIBCOUNTM

Installing

6.1 RedHat, Fedora

6.1.1 RedHat, Fedora(i386): Installing

Verify the required rpms are installed and install any missing requirements.

rpm -i --test apache2-mod countm-5.4-54 fc2.i386.rpm

Verify the server is not running.

/etc/rc.d/init.d/httpd status

If it is, then stop the server.

/etc/rc.d/init.d/httpd stop

Install the rpm.

rpm -i apache2-mod countm-5.4-54 fc2.i386.rpm.i386.rpm

Adjusting /etc/httpd/conf.d/mod countm.conf should not be necessary. Restart the server.

/etc/rc.d/init.d/httpd restart

Automate httpd startup with:

chkconfig httpd on

See man mod countm for more information. See man countm for more information.

6.1.2 RedHat, Fedora (i386): Removing

rpm -e apache2-mod_countm

Due to the default nature of rpm -e, the database will not be deleted. An rm -rf /var/countm should be performed AFTER rpm -e to complete the removal.

6.2 FreeBSD 5.4 (i386): Installing

6.2.1 Package Dependencies

apache-2.0.50_3
autoconf-2.59_2
gmake-3.80_1
gd-2.0.25_1,1
png-1.2.6
db42-4.2.52_3
freetype2-2.1.7_3
jpeg-6b_3

6.2.2 FreeBSD 5.4 (i386): Installing From Package

The package is specific to 5.4-RELEASE/i686. It may (or may not) install properly for other releases. Root developer access required for other releases if testing required.

pkg add mod countm-5.4 1.tbz

Installs the prebuilt binary package into a FreeBSD 5.4-RELEASE i386 system.

pkg delete mod countm-5.4 1

Will delete the package. When the package is deleted, all information is erased, including the test/countm directory, the dbase directory, the bgimage directory, and the .conf file. Be certain to backup any important information prior to package removal.

6.2.3 FreeBSD 5.4 (i386): Installing From Port

The port is specific to 5.4-RELEASE/i686. It may (or may not) install properly for other releases. Root developer access required for other releases if testing required.

#cp mod countm-5.4.tar.gz /usr/ports/distfiles
#cd /usr/ports/distfiles
#tar -xzpf mod countm-5.4.tar.gz
#cd mod countm-5.4
#cd dist/freebsd/port
#mkdir /usr/ports/www/mod countm-5.4
#cp * /usr/ports/www/mod countm-5.4
#cd /usr/ports/www/mod countm-5.4
#make makesum
#make
#make install
#make deinstall
#make clean

Due to Apache apxs issues, the FreeBSD make step builds AND installs the module. The make install step installs the configuration files, the example/test html files, and the runtime font.

The automatic package scripts assume the apache2 httpd server default install location which implies that the httpd.conf file has an Include etc/apache2/Includes/*.conf statement. The mod countm.conf file that is installed into etc/apache2/Includes will automatically be included.

6.3 Installing - OpenSolaris

The OpenSolaris package is built on a i386/Pentium II machine using Studio 11 (cc), SFWgcc34 (gcc, libgcc s.so) and SFW/SUNW components. See the dist/solaris/depend file for more information.

Unpack the binary package into a temporary directory. A SFWcountm package directory will be created. Add the package to your system (as root) using: #pkgadd -d ‘pwd‘ SFWcountm

Once added, restart the Apache2 server #svcadm -v enable svc:/network/http:apache2 #svcadm -v restart svc:/network/http:apache2

See http://localhost/server-info/ for default mod countm.conf settings.

6.4 mod status and mod cachem integration

The total number of requests mod countm has handled and the total number of request mod countm has handled since the last status request is the information displayed.

Mod countm, if COUNTM BDB is NOT defined, uses less than 32 bytes of mod cachem shared memory cache.

If COUNTM BDB is defined at compile time, mod countm uses additional mod cachem bytes, with the maximum being calculated as follows; For each process (normally StartServers + 1): two times the string length of each environment name, plus, the string length of each database name, plus, sizeof(cachem bptr t) times ( number environments plus number of database names), plus, about 11.

Assuming normal environment file path specifications averaging about 32 characters, and normal database names averaging about 16 characters: ( 2 * COUNTM BDB MAX ENV * 32 + COUNTM BDB MAX DB * 16) * ( Start-Servers + 1 ) + ( COUNTM BDB MAX ENV + COUNTM BDB MAX DB ) * sizeof(cachem bptr t) + 11 * ( StartServers + 1 ). 16384 for the default setting should be about right.

If COUNTM BDB is defined at compile time, a listing of all BDB environments and all BDB environment/ databases opened by each process is displayed. For the environments, the flags bits are displayed in hex, and interpreted as follows:

bit 0 (LSB) = The environment was joined. bit 1 = The environment was closed. bit 2 = The environment was recovered. bit 3 = The environment was deleted. bit 4 = The environment was created.

Question: Some status requests do not display any opened environments and databases for a thread/process, even when the previous status request displayed both for a specific pid.

Answer: The process probably terminated, either due to MaxRequestsPerChild being exceeded, or due to a restart. All environments and databases opened by an process are closed on process termination.

6.5 libgd

See section ”What’s new in version 2.0.16” from the gd manual for more information. Any Apache 2 Multi-Processing Module using threads (worker, etc) requires libgd ¿= 2.0.16 and the compile time option COUNTM FORCE LIBGD THREADSAFE set to 1. If an ”Unable to find gdFontCacheSetup” error at httpd startup is presented, then COUNTM FORCE LIBGD THREADSAFE is 1, and libgd ¡ 2.0.16.

For Redhat 9.0 and Fedora Core 1, which uses gd 1.8.4 and gd 2.0.15 respectively, COUNTM FORCE LIBGD THREADSAFE should be 0. The default prefork MPM will work properly. The worker MPM will function properly, but subject to the restrictions stated in the gd manual.

6.6 libcountm

The build process creates libcountm. Functions common to both mod countm and countm are placed into libcountm. This library is intended only for use by the package and does not export any specific programming API interface. See the libcountm chapter for more info.

6.7 Building Release X Y from .tar.gz distribution

6.7.1 requirements

mod cachem (sourceforge.net/projects/cachem) gd libjpeg libfreetype libpng

One of: DB4 (www.sleepycat.com) MySQL (www.mysql.com)

optional: doxygen latex tth

6.7.2 ./configure variables

The following is a list of recognized environmental variables (Case is significant):

DIRNAME The name and location of ’dirname’ program. Defaults to ’dirname’.

BASENAME The name and location of ’basename’ program. Defaults to ’basename’.

ID The name and location of the ’id’ program. Defaults to ’id’.

APXS CFLAGS These flags are added to the APXS command line AND CFLAGS. Only valid APXS AND C compiler options are allowed. See man apxs for more info. To determine the flags being added to the apxs portion of the build, use /path/to/apxs -q CFLAGS. These are usually the -I -l -L options used to locate libraries and include files in non system standard locations. These options are added to the APXS command line and to CFLAGS.

CFLAGS Usually preset by the build tools, and does not need to be modified.

LDFLAGS Used by configure to locate libraries, then passed to apxs. See man apxs for valid flags (usually only -L and -Wl are valid).

LIBS Added to by configure, then passed to apxs. Usually only -l allowed.

LIBCOUNTM LIBS libcountm only requires a subset of the mod countm and countm libraries. If LIBS is empty, the initial contents of LIB-COUNTM LIBS is empty. If LIBS is not empty, the initial contents of LIBCOUNTM LIBS is LIBS. Added to by configure, then passed to countm build process. Currently, it requires no libraries.

COUNTM LIBS The countm utility only requires a subset of the mod countm libraries. If LIBS is empty, the initial contents of COUNTM LIBS is empty. If LIBS is not empty, the initial contents of COUNTM LIBS is LIBS. Added to by configure, then passed to countm build process.

MOD COUNTM RELEASE FreeBSD packages:” $PORTREVISION”. RPM packages:”-%release”. Default:”.tar.gz”.

NEEDWL A hack for including the libcountm library into the mod countm build. Some version require NEEDWL=”-Wl,”. Some version require NEEDWL=”” .

54 CHAPTER 6. INSTALLING

docdir The install location for the documentation (if built). Defaults to $(prefix)/doc/$MOD COUNTM PACKAGE-$MOD COUNTM VERSION. Any value given will be relative to $(prefix). If a trailing / is added, then $MOD COUNTM PACKAGE-$MOD COUNTM VERSION is appended to docdir. If a leading / is not given, then assumed to be relative to prefix.

htmldir The install location for supporting html files. APACHE UID Apache runtime user id. See the Apache configuration direc-

tive user. APACHE GID Apache runtime group id. See the Apache configuration di-

rective group. NOTE If APACHE GID and APACHE UID are not given on the command

line, and id is available, then use id to get APACHE GID and APACHE UID. Otherwise, configure fails.

6.7.3 ./configure command line options

The following is a list of recognized ./configure command options: –libdir The install location for libcountm. –mandir The install location for mod countm.1 and countm.1 man pages. –sbindir The install location for the countm utility binary. –libexecdir The install location for the Apache2 DSO module. Normally au-

tomatically set via apxs during configure. –localstatedir The install location for the DSO module support files. Nor-

mally automatically set via apxs during configure. –sysconfdir The install location of mod countm.conf DSO config file. Nor-

mally automatically set via apxs during configure. –with-apxs The executable name and location of the apxs utility. –with-db The name of the db4 library. –with-gd The name of the gd library. –with-jpeg The name of the jpeg library. –with-freetype The name of the freetype library. –with-png The name of the png library. –with-latex The path and name of the latex program. The tex docs are built

only if latex program found.

–with-doxygen The path and name of the doxygen program. The doxygen docs are built only if doxygen program found.

–with-texi2pdf The path and name of the texi2pdf program. The texi2pdf docs are built only if texi2pdf program found.

–with-tth The path and name of the [tth] program. The tth docs are built only if [tth] program found.

–enable-versioning Set to yes to build a versioned libcountm. Use –disableversioning to force a nonversioned build.

6.7.4 building

Building in a separate directory using the configure script from the .tar.gz distribution is recommended and fully supported.

For mod countm, use APXS CFLAGS to inform configure of libraries, include files, and library locations. Because of the build process, APXS CFLAGS is added to CFLAGS. For many system builds, adjusting CFLAGS should not be necessary.

Using ./path/to/configure –help will list some additional information. Comments in configure.ac are a good source of information. After configure, the usual

make
make install

will build and install the module.

Mod countm supports DESTDIR as part of the install process if, and only if, the platform instdso.sh script supports DESTDIR.

6.8 Building CURRENT X Y From Source

The cvs repository is arranged in Current/Release pattern, with the most recent release as the highest revisions on the main trunk. A cvs checkout using the default tag will always checkout the most recent release. The next release is developed along a Current branch, then merged into main as a release. Branch tags are alway Current X Y, and release tags are always on the main trunk, and are Release X Y.

The mod countm CVS repository files and the latest release distribution file should allow Current X Y to be built from source. First, download Release X Y from the project site and unpack the distribution. Then, rename the top directory from mod countm-X.Y to mod countm-A.B, where A.B is the Current A B version. Checkout the Current A B from the repository directly into the mod countm-A.B directory.

The following example assumes the latest release is mod countm-5.0 (Release 5 0), and the current version is Current 5 1, using a BASH shell.

tar -xzpf mod_countm-5.0.tar.gz
mv mod_countm-5.0 mod_countm-5.1
CVSROOT=:pserver:anonymous@cvs.sourceforge.net:/cvsroot/countm
export CVSROOT
cvs login
password:<just hit enter>
cvs co -r CURRENT_5_1 -d mod_countm-5.1 countm

6.9 Apache2 apxs

6.9.1 building libcountm

The libcountm.so library must be built, and installed, prior to building the module. In the following example, if /lib/install/directory is a system library path, then -rpath may be omitted.

libtool gcc -I./ -c libcountm.c
libtool gcc -rpath /lib/install/directory -o libcountm.la libcountm.lo
libtool cp libcountm.la /lib/install/directory

6.9.2 building mod countm

To build the module directly using apxs, specify the libraries (including libcountm), the library locations, and the other parameters. After building, see mod countm.conf.in for configuration directives and handler information.

apxs -c -i -Wc,-g -DVERSION=5.4-custom -Wl,-lpng -Wl,-lgd, -Wl,-lm
-Wl,-ljpeg -Wl,-ldb -Wl,-lcountm -DCOUNTM FORCE LIBGD THREADSAFE=1 mod countm.c
version.c

Create any database environment directories, the fonts directories, the lockfile directories, and the background images directories. The access permissions must be set so httpd can access them and create files within them at runtime. Install true-type fonts into the CountmFontDir directory or set GDFONTPATH, and install the background images into the background image directories. Add a configuration to the httpd config file (usually httpd.conf).

6.10 Created/ Installed Files

Assuming a default FC2 installation defining only a global server:

/usr/lib/libcountm.so
/usr/include/libcountm.h
/usr/sbin/countm

/usr/lib/httpd/modules/mod_countm.so
/etc/httpd/conf.d/mod_countm.conf
/var/countm/fonts/FreeMono.ttf
/var/countm/dbase
/var/countm/bgfiles/ss.jpeg
/usr/share/man/man1/mod_countm.1
/usr/share/man/man1/countm.1
/var/www/html/test/countm/ex*.html

Files created at runtime depend on server configuration, but defaults are:

/var/countm/dbase/* (various db4 database files)
/var/countm/countm.lock (intermittent, if AcceptMutex=Lockfile)

6.11 RedHat 9 i586 Systems

See bugzilla.redhat.com #86381, #88456 for a clear concise explanation of what follows.

RH9 ships with a Berkeley DB4 library that relies on the kernel or glibc support for NPTL. The i586 version of glibc does not have NPTL support. The ”function not implemented error” is not a problem with countm, but affects countm.

Try compiling and running the create.c program on your system. It compiled and ran without error on my old RH9 single processor i686 development system, compiled and ran on my old RH9 SMP PII system, and compiles and runs without error on the same hardware now running Fedora Yarrow. However, it runs with errors on all RH9 non i686 single processor hardware.

As a recommendation, install the latest kernel, the latest glibc and associated packages, and the most recent httpd. The semaphore lock method may be used with versions above 2.0.40-21.9, but there may be some semaphore cleanup problems. They may be downloaded from ftp.redhat.com/pub/redhat/linux/updates/9/en/os. The best method is to download up2date-3.1.23.2-1.i386.rpm, and up2dategnome-3.1.23.2-1.i386.rpm, then install them with: rpm -Fvh up2date-3.1.23.2-1.i386.rpm up2date-gnome-3.1.23.2-1.i386.rpm Run up2date, be sure to set the preferences to update the kernel also, and update your system. See rhn.redhat.com/errata/RHSA-2003-267.html for more info.

To solve the error, a nonptl version of db4 must be installed. Applying the following patch to db4.spec from db-4.0.14-20.src.rpm, and rebuilding with rpmbuild -ba db4.spec will create the nonptl rpms. Replace the default db4 nptl packages with the new db4 nonptl packages.

rpm -Fvh <Build RPMS>

Install the apache2-mod countm-5.4-54 rh9i586.i586.rpm package. mod countm will now run without the function not implemented error.

6.11.1 Disclaimer

Unknown is the impact of installing the nonptl version of DB4 onto the i586 system. If you decide not to keep the newly installed nonptl db4 package, then you will need to use –oldpackage when reFreshing the default distribution rpms.

6.11.2 Default RH9 NPTL Packages

db4-java-4.0.14-20
db4-4.0.14-20
db4-utils-4.0.14-20
db4-devel-4.0.14-20

6.11.3 Default Installed RPMS

SRPMS/db4-4.0.14-20.src.rpm
RPMS/i386/db4-4.0.14-20.i386.rpm
RPMS/i386/db4-utils-4.0.14-20.i386.rpm
RPMS/i386/db4-devel-4.0.14-20.i386.rpm
RPMS/i386/db4-java-4.0.14-20.i386.rpm
RPMS/i386/db4-debuginfo-4.0.14-20.i386.rpm

6.11.4 Patched db4.spec Created RPMS

SRPMS/db4-4.0.14-21.src.rpm RPMS/i586/db4-4.0.14-21.i586.rpm RPMS/i586/db4utils-4.0.14-21.i586.rpm RPMS/i586/db4-devel-4.0.14-21.i586.rpm RPMS/i586/db4java-4.0.14-21.i586.rpm RPMS/i586/db4-debuginfo-4.0.14-21.i586.rpm

6.11.5 db.spec Patch

To install the patch, use:

cp db4.spec.patch /usr/src/redhat/SPECS
patch -p0 < db4.spec.patch
BEGIN db4.spec.patch
*** db4.spec.orig 2003-02-05 13:01:35.000000000 -0800
--- db4.spec 2003-12-15 08:24:26.000000000 -0800
***************
*** 1,5 ****
  %define java_arches %{ix86} alpha ia64 ppc s390 s390x
! %define nptl_arches %{ix86}
  # compatibility with legacy versions of rpm
  %{!?_lib:%define _lib lib}
--- 1,5 ----
  %define java_arches %{ix86} alpha ia64 ppc s390 s390x

! %define nptl_arches %nil
# compatibility with legacy versions of rpm
%{!?_lib:%define _lib lib}
***************
*** 11,17 ****
Summary: The Berkeley DB database library (version 4) for C.
Name: db4
Version: 4.0.14
! Release: 20
Source: http://www.sleepycat.com/update/%{version}/db-%{version}.tar.gz
Source1: http://www.sleepycat.com/update/1.85/db.1.85.tar.gz
Patch10: http://www.sleepycat.com/update/1.85/patch.1.1
--- 11,17 ----
Summary: The Berkeley DB database library (version 4) for C.
Name: db4
Version: 4.0.14
! Release: 21
Source: http://www.sleepycat.com/update/%{version}/db-%{version}.tar.gz
Source1: http://www.sleepycat.com/update/1.85/db.1.85.tar.gz
Patch10: http://www.sleepycat.com/update/1.85/patch.1.1
***************
*** 31,36 ****
--- 31,37 ----
BuildPreReq: jdkgcj >= 0.1.0
%endif
BuildRoot: %{_tmppath}/%{name}-root
+ BuildArchitectures: i586
%description
The Berkeley Database (Berkeley DB) is a programmatic toolkit that
***************
*** 141,146 ****
--- 142,148 ----
set -x # XXX painful to watch
%build
+ export RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's/i686/i586/'`
CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS
# Static link with old db-185 libraries.
END db4.spec.patch

6.11.6 Test Program

BEGIN create.c

/* simple test program to test for error */
/* just about verbatim from the tutorial */
/* gcc -DCWD=\"`pwd`\" -o db4test -ldb create.c */
#include <stdio.h>
#include <db.h>
#ifndef CWD
#define CWD "/home/bkyoung/proj/test/dbase"
#endif
DB_ENV *
db_setup(home, data_dir, errfp, progname)
   char *home, *data_dir, *progname;
   FILE *errfp;
{
DB_ENV *dbenv;
int ret;
/*
 * Create an environment and initialize it for additional error
 * reporting.
 */
if ((ret = db_env_create(&dbenv, 0)) != 0) {
  fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
  return (NULL);
}
dbenv->set_errfile(dbenv, errfp);
dbenv->set_errpfx(dbenv, progname);
      /*
       * Specify the shared memory buffer pool cachesize: 5MB.
       * Databases are in a subdirectory of the environment home.
       */
if ((ret = dbenv->set_cachesize(dbenv, 0, 5 * 1024 * 1024, 0)) != 0) {
  dbenv->err(dbenv, ret, "set_cachesize");
  goto err;
}
if ((ret = dbenv->set_data_dir(dbenv, data_dir)) != 0) {
  dbenv->err(dbenv, ret, "set_data_dir: %s", data_dir);
  goto err;
}
/* Open the environment with full transactional support. */
if ((ret = dbenv->open(dbenv, home, DB_CREATE |
           DB_INIT_LOG | DB_INIT_LOCK | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0)

    {
      dbenv->err(dbenv, ret, "environment open: %s", home);
      goto err;
    }
  return (dbenv);
 err:    (void)dbenv->close(dbenv, 0);
  return (NULL);
}
int
main(int argc, char * argv[], char * envp[])
{
  DB_ENV * dbenv;
  dbenv = db_setup(CWD,CWD, NULL, argv[0]);
  if (dbenv !=NULL)
     (void)dbenv->close(dbenv, 0);
  return 0;
}
END create.c

62 CHAPTER 6. INSTALLING

Project Information

7.1 TO DO

• Proceed to release phase.

• Continue testing on different Multi-Processing Module systems.

• Test on different architectures and operating systems.

• Create a sourceforge web site to support the project.

• Continue to debug the module and the support utility.

• Adjust file extension recognition.

7.2 Project Status

The project is transitioning to stable. The format of DB ACCESS is stable. The format of DB COUNTER is stable. FC2 RPMS are available for download from sourceforge project site. A FreeBSD 5.4-RELEASE port is available.

7.3 Supported Distributions

Fedora Core 4 () i386 Linux/Apache 2.0.48 FreeBSD i386 5.4-RELEASE

7.4 Targeted Audience

As a simple page counter, the project is intended for small office/ home office system administrators anticipating low volume web traffic and interested in adding page counter capabilities to their Apache 2 server.

7.5 sourceforge.net Information

Development Status: 5-Stable/production Operating System: POSIX: Linux Topic: Internet: WWW/HTTP: Dynamic Content: Page Counters Intended Audience: Other Audience License: OSI Approved: BSD License Programming Language: C Environment: Web Environment Natural Language: English Project Unix Name: countm

7.6 Release Distribution Files

Release 5.4 (Release_5_4)
apache2-mod_countm-5.4-54.fc2.src.rpm
apache2-mod_countm-5.4-54.fc2.i386.rpm
apache2-mod_countm-debuginfo-5.4-54.fc2.i386.rpm
apache2-mod_countm-5.4-54.9.src.rpm
apache2-mod_countm-5.4-54.9.i686.rpm
apache2-mod_countm-debuginfo-5.4-54.9.i686.rpm
apache2-mod_countm-5.4-54.9.i586.rpm
apache2-mod_countm-debuginfo-5.4-54.9.i586.rpm
mod_countm-5.4_1.tbz
mod_countm-5.4.tar.gz

7.7 Credits

Adapted to Apache 2 by ¡Byron Young¿ spamiccling@yahoo.com, bkyoung@users.sourceforge.net Adapted from mod ometer by J Craig. See modules.apache.org for more information. Image source http://www.superform-aluminium.com/news/Photo%20Gallery/Gallery%20- %20applications/Resources/spacestation.jpeg FreeMono.ttf is from the freefont project.

Debugging

The following are specific to Fedora Core 2, gcc-3.3.2, gdb-6.0post. The rpmbuild process creates apache2-mod countm-debuginfo-5.4-54 fc2.i386.rpm. This package contains the debug information for the apaceh2-mod countm-5.4-54 fc2.i386.rpm package. The apaceh2-mod countm-5.4-54 fc2.i386.rpm package object files are stripped. After installing the deguginfo package, the mod countm.so may be debugged using gdb. The following is not the best method for debugging, but gets the job done.

8.1 Download debuginfo Package

Either figure out which deguginfo files you will need (at least httpd-debuginfo), or download all debuginfo files from download.fedora.redhat.com/pub/fedora/linux/core/2/i386/debug and install them. To debug the module, download apache2-mod countmdebuginfo-5.4-54 fc2.i386.rpm.

8.2 Prelink httpd Executable

The default build from httpd.spec creates pie httpd. In order to use gdb to debug it, it must be prelinked with prelink.

/usr/sbin/prelink /usr/sbin/httpd

Also, the directory /lib/tls was added to /etc/prelink.conf These should be run as root, so the cache file may be updated properly.

[root]objdump -f /usr/sbin/httpd
/usr/sbin/httpd:     file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000eda0
              {---------} => NOT PRELINKED!!

[root]/usr/sbin/prelink /usr/sbin/httpd
[root]objdump -f /usr/sbin/httpd
/usr/sbin/httpd:     file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0200eda0
              {---------} => PRELINKED!!

The start address in this example is 0x0200eda0

8.3 Preload mod countm.so

(BASH/fc2)
LD_PRELOAD=/usr/lib/httpd/modules/mod_countm.so:libaprutil-0.so.0:libapr-0.so.0
export LD_PRELOAD
(CSH/FreeBSD)
setenv LD_PRELOAD /usr/local/libexec/apache2/mod_countm.so:/usr/local/lib/apache2/libapr-0.so.9:/usr/local/lib/apache2/libaprutil-0.so.9

8.4 A gdb session

[root]# gdb /usr/sbin/httpd
GNU gdb Red Hat Linux (6.0post-0.20031117.7rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) add-symbol-file /usr/sbin/httpd 0x200eda0 -readnow
add symbol table from file "/usr/sbin/httpd" at
.text_addr = 0x200eda0
(y or n) y
Reading symbols from /usr/sbin/httpd...expanding to full symbols...Reading symbols from /usr/lib/debug//usr/sbin/httpd.debug...expanding to full symbols...done.
done.
(gdb) b main
Breakpoint 1 at 0x201d155: file /usr/src/debug/httpd-2.0.48/server/main.c, line 443.
(gdb) r -X
Starting program: /usr/sbin/httpd -X
setpgrp failed in child: No such process
[Thread debugging using libthread_db enabled]
[New Thread -1207136128 (LWP 7939)]
[Switching to Thread -1207136128 (LWP 7939)]

Breakpoint 1, main (argc=2, argv=0xbff8ccc4)
    at /usr/src/debug/httpd-2.0.48/server/main.c:443
443     ap_server_pre_read_config  = apr_array_make(pcommands, 1, sizeof(char *));
(gdb) info shared
From        To          Syms Read   Shared Object Library
0x007f41c0  0x007f7078  Yes         /usr/lib/httpd/modules/mod_countm.so
0x00511820  0x00534740  Yes         /lib/libssl.so.4
0x00380aa0  0x0041ac3c  Yes         /lib/libcrypto.so.4
0x00345e00  0x00351eb0  Yes         /usr/lib/libgssapi_krb5.so.2
0x002ce850  0x0031e89c  Yes         /usr/lib/libkrb5.so.3
0x00296a90  0x002971dc  Yes         /lib/libcom_err.so.2
0x0029e4e0  0x002b3e40  Yes         /usr/lib/libk5crypto.so.3
0x00d2d740  0x00d37f30  Yes         /lib/libresolv.so.2
0x00cf65d0  0x00d001f8  Yes         /usr/lib/libz.so.1
0x0053fcb0  0x0054bb34  Yes         /lib/libpcre.so.0
0x00a88a90  0x00a88f58  Yes         /usr/lib/libpcreposix.so.0
0x00c61e10  0x00c6ffb4  Yes         /usr/lib/libaprutil-0.so.0
0x0082d890  0x00850930  Yes         /usr/lib/libldap.so.2
0x00de45e0  0x00debbac  Yes         /usr/lib/liblber.so.2
0x00c16430  0x00c19edc  Yes         /usr/lib/libgdbm.so.2
0x00935ca0  0x009e0280  Yes         /lib/tls/libdb-4.2.so
0x00dc2110  0x00dd7de0  Yes         /usr/lib/libexpat.so.0
0x0044da70  0x00459a08  Yes         /lib/libnsl.so.1
0x00c7c630  0x00c90d4c  Yes         /usr/lib/libapr-0.so.0
0x004cacb0  0x004d0954  Yes         /lib/tls/librt.so.1
0x00bed300  0x00c04c4c  Yes         /lib/tls/libm.so.6
0x004907e0  0x004930a4  Yes         /lib/libcrypt.so.1
0x00d1c160  0x00d23a9c  Yes         /lib/tls/libpthread.so.0
0x00c0fcd0  0x00c10b60  Yes         /lib/libdl.so.2
0x00ac41c0  0x00bc3570  Yes         /lib/tls/libc.so.6
0x004709e0  0x00489cd4  Yes         /usr/lib/libpng12.so.0
0x001151b0  0x00124818  Yes         /usr/lib/libgd.so.2
0x002264d0  0x0023ec5c  Yes         /usr/lib/libjpeg.so.62
0x00d9e070  0x00dabc40  Yes         /usr/lib/libsasl2.so.2
0x00a92a50  0x00aa4207  Yes         /lib/ld-linux.so.2
0x00811210  0x0081bf74  Yes         /usr/X11R6/lib/libXpm.so.4
0x00560290  0x005d0bb0  Yes         /usr/X11R6/lib/libX11.so.6
0x00157280  0x00195754  Yes         /usr/lib/libfreetype.so.6
0x00d0a6d0  0x00d14178  Yes         /usr/X11R6/lib/libXext.so.6
(gdb) b countm_method_handler
Breakpoint 2 at 0x7f5266: file src/mod_countm.c, line 1129.
(gdb) c
Continuing.
Breakpoint 2, countm_method_handler (r=0x99311dc) at src/mod_countm.c:1129
1129   struct sembuf op_lock[2] =

(gdb) quit
The program is running.  Exit anyway? (y or n) y
[root]# exit

8.5 Debugging the threaded MPMs

Use the gdb attach process to debug the Worker MPM (threads). Set the Apache2 configuraion directives StartServers to 1, MaxClients and ThreadsPer-Child set to 4. All requests will be handled by the one child process. Setting MaxRequestsPerChild to 4 will restart the child server often, allowing debugging of process cleanup and process creation code.

[root@waiter mod_countm-5.3]# /etc/rc.d/init.d/httpd start
Starting httpd:                                 [OK]
[root@waiter mod_countm-5.3]# ps aux | grep httpd
root     22796  0.0  5.9 32772 15140 ?       S    12:58   0:01 /usr/sbin/httpd
apache   22799  0.0  5.9 94368 15280 ?       S    12:58   0:00 /usr/sbin/httpd
root     22807  0.0  0.2  4572  596 pts/4    S    12:58   0:00 grep httpd
[root@waiter mod_countm-5.3]# gdb /usr/sbin/httpd 22799
GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
Attaching to program: /usr/sbin/httpd, process 22799
Error while mapping shared library sections:
: Success.
Error while reading shared library symbols:
: No such file or directory.
Reading symbols from /lib/libpcre.so.0...Reading symbols from /usr/lib/debug//lib/libpcre.so.0.0.1.debug...done.
done.
Loaded symbols for /lib/libpcre.so.0
Reading symbols from /usr/lib/libpcreposix.so.0...Reading symbols from /usr/lib/debug//usr/lib/libpcreposix.so.0.0.0.debug...done.
done.
Loaded symbols for /usr/lib/libpcreposix.so.0
Reading symbols from /usr/lib/libaprutil-0.so.0...done.
Loaded symbols for /usr/lib/libaprutil-0.so.0
Reading symbols from /usr/lib/libldap.so.2...done.
Loaded symbols for /usr/lib/libldap.so.2
Reading symbols from /usr/lib/liblber.so.2...done.
Loaded symbols for /usr/lib/liblber.so.2
Reading symbols from /lib/tls/libdb-4.2.so...done.

Loaded symbols for /lib/tls/libdb-4.2.so
Reading symbols from /usr/lib/libexpat.so.0...done.
Loaded symbols for /usr/lib/libexpat.so.0
Reading symbols from /usr/lib/libapr-0.so.0...done.
Loaded symbols for /usr/lib/libapr-0.so.0
Reading symbols from /lib/tls/librt.so.1...Reading symbols from /usr/lib/debug//lib/tls/librt-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/tls/librt.so.1
Reading symbols from /lib/tls/libm.so.6...Reading symbols from /usr/lib/debug//lib/tls/libm-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/tls/libm.so.6
Reading symbols from /lib/libcrypt.so.1...Reading symbols from /usr/lib/debug//lib/libcrypt-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/tls/libpthread.so.0...Reading symbols from /usr/lib/debug//lib/tls/libpthread-0.61.so.debug...done.
[Thread debugging using libthread_db enabled]
[New Thread -150441856 (LWP 22799)]
[New Thread -211182672 (LWP 22805)]
[New Thread -200692816 (LWP 22804)]
[New Thread -190202960 (LWP 22803)]
[New Thread -179713104 (LWP 22802)]
[New Thread -169223248 (LWP 22801)]
done.
Loaded symbols for /lib/tls/libpthread.so.0
Reading symbols from /lib/libdl.so.2...Reading symbols from /usr/lib/debug//lib/libdl-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/tls/libc.so.6...Reading symbols from /usr/lib/debug//lib/tls/libc-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/libresolv.so.2...Reading symbols from /usr/lib/debug//lib/libresolv-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libresolv.so.2
Reading symbols from /usr/lib/libsasl2.so.2...done.
Loaded symbols for /usr/lib/libsasl2.so.2
Reading symbols from /lib/libssl.so.4...done.
Loaded symbols for /lib/libssl.so.4
Reading symbols from /lib/libcrypto.so.4...done.
Loaded symbols for /lib/libcrypto.so.4
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug//lib/ld-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/lib/libgssapi_krb5.so.2...done.
Loaded symbols for /usr/lib/libgssapi_krb5.so.2
Reading symbols from /usr/lib/libkrb5.so.3...done.
Loaded symbols for /usr/lib/libkrb5.so.3

Reading symbols from /lib/libcom_err.so.2...done.
Loaded symbols for /lib/libcom_err.so.2
Reading symbols from /usr/lib/libk5crypto.so.3...done.
Loaded symbols for /usr/lib/libk5crypto.so.3
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/libnss_files.so.2...Reading symbols from /usr/lib/debug//lib/libnss_files-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /etc/httpd/modules/mod_access.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_access.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_access.so
Reading symbols from /etc/httpd/modules/mod_auth.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_auth.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_auth.so
Reading symbols from /etc/httpd/modules/mod_auth_anon.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_auth_anon.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_auth_anon.so
Reading symbols from /etc/httpd/modules/mod_auth_dbm.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_auth_dbm.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_auth_dbm.so
Reading symbols from /etc/httpd/modules/mod_auth_digest.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_auth_digest.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_auth_digest.so
Reading symbols from /etc/httpd/modules/mod_ldap.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_ldap.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_ldap.so
Reading symbols from /etc/httpd/modules/mod_auth_ldap.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_auth_ldap.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_auth_ldap.so
Reading symbols from /etc/httpd/modules/mod_include.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_include.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_include.so
Reading symbols from /etc/httpd/modules/mod_log_config.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_log_config.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_log_config.so
Reading symbols from /etc/httpd/modules/mod_env.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_env.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_env.so
Reading symbols from /etc/httpd/modules/mod_mime_magic.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_mime_magic.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_mime_magic.so
Reading symbols from /etc/httpd/modules/mod_cern_meta.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_cern_meta.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_cern_meta.so
Reading symbols from /etc/httpd/modules/mod_expires.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_expires.so.debug...done.

done.
Loaded symbols for /etc/httpd/modules/mod_expires.so
Reading symbols from /etc/httpd/modules/mod_deflate.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_deflate.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_deflate.so
Reading symbols from /etc/httpd/modules/mod_headers.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_headers.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_headers.so
Reading symbols from /etc/httpd/modules/mod_usertrack.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_usertrack.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_usertrack.so
Reading symbols from /etc/httpd/modules/mod_setenvif.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_setenvif.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_setenvif.so
Reading symbols from /etc/httpd/modules/mod_mime.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_mime.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_mime.so
Reading symbols from /etc/httpd/modules/mod_dav.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_dav.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_dav.so
Reading symbols from /etc/httpd/modules/mod_status.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_status.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_status.so
Reading symbols from /etc/httpd/modules/mod_autoindex.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_autoindex.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_autoindex.so
Reading symbols from /etc/httpd/modules/mod_asis.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_asis.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_asis.so
Reading symbols from /etc/httpd/modules/mod_info.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_info.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_info.so
Reading symbols from /etc/httpd/modules/mod_dav_fs.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_dav_fs.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_dav_fs.so
Reading symbols from /etc/httpd/modules/mod_vhost_alias.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_vhost_alias.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_vhost_alias.so
Reading symbols from /etc/httpd/modules/mod_negotiation.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_negotiation.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_negotiation.so
Reading symbols from /etc/httpd/modules/mod_dir.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_dir.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_dir.so
Reading symbols from /etc/httpd/modules/mod_imap.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_imap.so.debug...done.
done.

Loaded symbols for /etc/httpd/modules/mod_imap.so
Reading symbols from /etc/httpd/modules/mod_actions.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_actions.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_actions.so
Reading symbols from /etc/httpd/modules/mod_speling.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_speling.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_speling.so
Reading symbols from /etc/httpd/modules/mod_userdir.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_userdir.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_userdir.so
Reading symbols from /etc/httpd/modules/mod_alias.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_alias.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_alias.so
Reading symbols from /etc/httpd/modules/mod_rewrite.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_rewrite.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_rewrite.so
Reading symbols from /etc/httpd/modules/mod_proxy.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_proxy.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_proxy.so
Reading symbols from /etc/httpd/modules/mod_proxy_ftp.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_proxy_ftp.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_proxy_ftp.so
Reading symbols from /etc/httpd/modules/mod_proxy_http.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_proxy_http.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_proxy_http.so
Reading symbols from /etc/httpd/modules/mod_proxy_connect.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_proxy_connect.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_proxy_connect.so
Reading symbols from /etc/httpd/modules/mod_cache.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_cache.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_cache.so
Reading symbols from /etc/httpd/modules/mod_suexec.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_suexec.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_suexec.so
Reading symbols from /etc/httpd/modules/mod_disk_cache.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_disk_cache.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_disk_cache.so
Reading symbols from /etc/httpd/modules/mod_file_cache.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_file_cache.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_file_cache.so
Reading symbols from /etc/httpd/modules/mod_mem_cache.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_mem_cache.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_mem_cache.so
Reading symbols from /etc/httpd/modules/mod_cgi.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_cgi.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_cgi.so

Reading symbols from /etc/httpd/modules/mod_auth_kerb.so...done.
Loaded symbols for /etc/httpd/modules/mod_auth_kerb.so
Reading symbols from /etc/httpd/modules/mod_auth_mysql.so...done.
Loaded symbols for /etc/httpd/modules/mod_auth_mysql.so
Reading symbols from /usr/lib/mysql/libmysqlclient.so.10...done.
Loaded symbols for /usr/lib/mysql/libmysqlclient.so.10
Reading symbols from /lib/libnsl.so.1...Reading symbols from /usr/lib/debug//lib/libnsl-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /etc/httpd/modules/mod_auth_pgsql.so...done.
Loaded symbols for /etc/httpd/modules/mod_auth_pgsql.so
Reading symbols from /usr/lib/libpq.so.3...done.
Loaded symbols for /usr/lib/libpq.so.3
Reading symbols from /etc/httpd/modules/mod_jk2.so...done.
Loaded symbols for /etc/httpd/modules/mod_jk2.so
Reading symbols from /usr/lib/httpd/modules/mod_countm.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_countm.so.debug...done.
done.
Loaded symbols for /usr/lib/httpd/modules/mod_countm.so
Reading symbols from /usr/lib/libpng12.so.0...done.
Loaded symbols for /usr/lib/libpng12.so.0
Reading symbols from /usr/lib/libfreetype.so.6...done.
Loaded symbols for /usr/lib/libfreetype.so.6
Reading symbols from /usr/lib/libjpeg.so.62...done.
Loaded symbols for /usr/lib/libjpeg.so.62
Reading symbols from /usr/lib/libgd.so.2...done.
Loaded symbols for /usr/lib/libgd.so.2
Reading symbols from /usr/lib/libcountm.so.0...Reading symbols from /usr/lib/debug//usr/lib/libcountm.so.0.0.1.debug...done.
done.
Loaded symbols for /usr/lib/libcountm.so.0
Reading symbols from /usr/X11R6/lib/libXpm.so.4...done.
Loaded symbols for /usr/X11R6/lib/libXpm.so.4
Reading symbols from /usr/X11R6/lib/libX11.so.6...done.
Loaded symbols for /usr/X11R6/lib/libX11.so.6
Reading symbols from /usr/X11R6/lib/libXext.so.6...done.
Loaded symbols for /usr/X11R6/lib/libXext.so.6
Reading symbols from /etc/httpd/modules/mod_fltr.so...done.
Loaded symbols for /etc/httpd/modules/mod_fltr.so
Reading symbols from /etc/httpd/modules/mod_hilitem.so...done.
Loaded symbols for /etc/httpd/modules/mod_hilitem.so
Reading symbols from /usr/lib/libxml2.so.2...Reading symbols from /usr/lib/debug//usr/lib/libxml2.so.2.6.8.debug...done.
done.
Loaded symbols for /usr/lib/libxml2.so.2
Reading symbols from /etc/httpd/modules/mod_iterate.so...done.
Loaded symbols for /etc/httpd/modules/mod_iterate.so
Reading symbols from /etc/httpd/modules/mod_searchm.so...done.
Loaded symbols for /etc/httpd/modules/mod_searchm.so

Reading symbols from /usr/lib/libswish-e.so.2...Reading symbols from /usr/lib/debug//usr/lib/libswish-e.so.2.0.0.debug...done.
done.
Loaded symbols for /usr/lib/libswish-e.so.2
Reading symbols from /etc/httpd/modules/mod_test.so...done.
Loaded symbols for /etc/httpd/modules/mod_test.so
Reading symbols from /etc/httpd/modules/mod_testing.so...done.
Loaded symbols for /etc/httpd/modules/mod_testing.so
Reading symbols from /etc/httpd/modules/mod_time.so...done.
Loaded symbols for /etc/httpd/modules/mod_time.so
Reading symbols from /etc/httpd/modules/mod_perl.so...done.
Loaded symbols for /etc/httpd/modules/mod_perl.so
Reading symbols from /usr/lib/perl5/5.8.3/i386-linux-thread-multi/CORE/libperl.so...done.
Loaded symbols for /usr/lib/perl5/5.8.3/i386-linux-thread-multi/CORE/libperl.so
Reading symbols from /lib/libutil.so.1...Reading symbols from /usr/lib/debug//lib/libutil-2.3.3.so.debug...done.
done.
Loaded symbols for /lib/libutil.so.1
Reading symbols from /etc/httpd/modules/libphp5.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/libphp5.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/libphp5.so
Reading symbols from /usr/lib/libpspell.so.15...done.
Loaded symbols for /usr/lib/libpspell.so.15
Reading symbols from /usr/lib/libgmp.so.3...done.
Loaded symbols for /usr/lib/libgmp.so.3
Reading symbols from /usr/lib/libcurl.so.2...done.
Loaded symbols for /usr/lib/libcurl.so.2
Reading symbols from /usr/lib/libbz2.so.1...done.
Loaded symbols for /usr/lib/libbz2.so.1
Reading symbols from /usr/lib/libaspell.so.15...done.
Loaded symbols for /usr/lib/libaspell.so.15
Reading symbols from /usr/lib/libstdc++.so.5...done.
Loaded symbols for /usr/lib/libstdc++.so.5
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /etc/httpd/modules/mod_python.so...done.
Loaded symbols for /etc/httpd/modules/mod_python.so
Reading symbols from /etc/httpd/modules/mod_ssl.so...Reading symbols from /usr/lib/debug//usr/lib/httpd/modules/mod_ssl.so.debug...done.
done.
Loaded symbols for /etc/httpd/modules/mod_ssl.so
Reading symbols from /usr/lib/libdistcache.so.1...done.
Loaded symbols for /usr/lib/libdistcache.so.1
Reading symbols from /usr/lib/libnal.so.1...done.
Loaded symbols for /usr/lib/libnal.so.1
Reading symbols from /etc/httpd/modules/mod_dav_svn.so...done.
Loaded symbols for /etc/httpd/modules/mod_dav_svn.so
Reading symbols from /usr/lib/libsvn_repos-1.so.0...done.
Loaded symbols for /usr/lib/libsvn_repos-1.so.0

Reading symbols from /usr/lib/libsvn_fs-1.so.0...done.
Loaded symbols for /usr/lib/libsvn_fs-1.so.0
Reading symbols from /usr/lib/libsvn_delta-1.so.0...done.
Loaded symbols for /usr/lib/libsvn_delta-1.so.0
Reading symbols from /usr/lib/libsvn_subr-1.so.0...done.
Loaded symbols for /usr/lib/libsvn_subr-1.so.0
Reading symbols from /etc/httpd/modules/mod_authz_svn.so...done.
Loaded symbols for /etc/httpd/modules/mod_authz_svn.so
Reading symbols from /usr/lib/php/modules/dom.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/dom.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/dom.so
Reading symbols from /usr/lib/php/modules/gd.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/gd.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/gd.so
Reading symbols from /usr/lib/php/modules/imap.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/imap.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/imap.so
Reading symbols from /usr/lib/libc-client.so.0...done.
Loaded symbols for /usr/lib/libc-client.so.0
Reading symbols from /lib/libpam.so.0...done.
Loaded symbols for /lib/libpam.so.0
Reading symbols from /usr/lib/php/modules/ldap.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/ldap.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/ldap.so
Reading symbols from /usr/lib/php/modules/mbstring.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/mbstring.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/mbstring.so
Reading symbols from /usr/lib/php/modules/mysql.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/mysql.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/mysql.so
Reading symbols from /usr/lib/php/modules/ncurses.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/ncurses.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/ncurses.so
Reading symbols from /usr/lib/libpanel.so.5...done.
Loaded symbols for /usr/lib/libpanel.so.5
Reading symbols from /usr/lib/libncurses.so.5...done.
Loaded symbols for /usr/lib/libncurses.so.5
Reading symbols from /usr/lib/php/modules/odbc.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/odbc.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/odbc.so
Reading symbols from /usr/lib/libodbc.so.1...done.
Loaded symbols for /usr/lib/libodbc.so.1
Reading symbols from /usr/lib/libodbcpsql.so.2...done.
Loaded symbols for /usr/lib/libodbcpsql.so.2
Reading symbols from /usr/lib/libltdl.so.3...done.
Loaded symbols for /usr/lib/libltdl.so.3

Reading symbols from /usr/lib/php/modules/pgsql.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/pgsql.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/pgsql.so
Reading symbols from /usr/lib/php/modules/snmp.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/snmp.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/snmp.so
Reading symbols from /usr/lib/libnetsnmp.so.5...done.
Loaded symbols for /usr/lib/libnetsnmp.so.5
Reading symbols from /usr/lib/libelf.so.1...done.
Loaded symbols for /usr/lib/libelf.so.1
Reading symbols from /usr/lib/php/modules/xmlrpc.so...Reading symbols from /usr/lib/debug//usr/lib/php/modules/xmlrpc.so.debug...done.
done.
Loaded symbols for /usr/lib/php/modules/xmlrpc.so
0x00433402 in ?? ()
(gdb) b countm_method_handler
Breakpoint 1 at 0x656f90: file mod_countm.c, line 778.
(gdb) b countm_process_cleanup
Breakpoint 2 at 0x656da1: file mod_countm.c, line 694.
(gdb) c
Continuing.
===================================
At this point, access ex_enter.html
===================================
[Switching to Thread -200692816 (LWP 22804)]
Breakpoint 1, countm_method_handler (r=0x8f453d8) at mod_countm.c:778
778   countent_t ce=INITIALIZE_COUNTENT;
(gdb) c
Continuing.
[Switching to Thread -169223248 (LWP 22801)]
Breakpoint 1, countm_method_handler (r=0x8fd9e28) at mod_countm.c:778
778   countent_t ce=INITIALIZE_COUNTENT;
(gdb) c
Continuing.
========================================================
At this point, hit "Submit" button on form ex_enter.html
========================================================
[Switching to Thread -179713104 (LWP 22802)]
Breakpoint 1, countm_method_handler (r=0x8f473e0) at mod_countm.c:778
778   countent_t ce=INITIALIZE_COUNTENT;

(gdb) c
Continuing.
===================================
At this point, access ex_query.html
===================================
[Switching to Thread -169223248 (LWP 22801)]
Breakpoint 1, countm_method_handler (r=0x8fdfe40) at mod_countm.c:778
778   countent_t ce=INITIALIZE_COUNTENT;
(gdb) c
Continuing.
===============================================================
At this point, access any webpage, like http://localhost/manual
===============================================================
Program received signal SIGHUP, Hangup.
[Switching to Thread -211182672 (LWP 22805)]
0x00433402 in ?? ()
(gdb) c
Continuing.
Program received signal SIGTERM, Terminated.
[Switching to Thread -150441856 (LWP 22799)]
0x00433402 in ?? ()
(gdb) c
Continuing.
[Thread -200692816 (zombie) exited]
[Thread -211182672 (zombie) exited]
[Thread -179713104 (zombie) exited]
[Thread -169223248 (zombie) exited]
[Thread -190202960 (zombie) exited]
Breakpoint 2, countm_process_cleanup (p=0x8ed6900, bSS=0) at mod_countm.c:694
694   int i=0;
(gdb) b 733
Breakpoint 3 at 0x656e94: file mod_countm.c, line 733.
(gdb) c
Continuing.
Breakpoint 3, countm_process_cleanup (p=0x8ed6900, bSS=0) at mod_countm.c:733
733   for (i=0; i<COUNTM_BDB_MAX_DB; ++i) {
(gdb) c
Continuing.

Program exited normally.
(gdb) q
[root@waiter mod_countm-5.3]# /etc/rc.d/init.d/httpd stop
Stopping httpd:                     [OK]
[root@waiter mod_countm-5.3]#

8.6 Debugging FreeBSD 5.4-RELEASE

The apache-2.0.50 3 package must be rebuilt using make -DWITH DEBUG for the debugging scripts to work properly.

First, install apache-2.0.53 3 package, then delete it. Rebuild the port, then make a new package, and install that. As an extra precaution, you may want to adjust PORTVERSIONS.

Additional Information

9.1 mod ometer

If the directive CountmDBPriority is set OFF, then some compatibility with mod ometer is maintained. Once the counter is entered into the database, the idea is to be URL compatible with ometer. The compile time option MOD-ULE URI PATH STRING should be changed and the config file ¡Location¿ directive must set to the same value.

9.2 Network sniffers

Network traffic sniffers may seek to identify sites running mod countm. Although the module was written within the Apache API, vulnerabilities probably exist. A easy method to disguise your counter installation is to alter MOD-ULE URI PATH STRING to a new value, and adjust ¡Location¿ to that new value. Rebuild mod countm, and restart the server. The new URIs will now use:

http://localhost/newvalue&link=

to access the counter, and

http://localhost/newvalue/fonts

to list available fonts.

Althouth link is common, network sniffers will still be able to identify the link= portion. The compile time option COUNTM PARAMETER LINK may be used to change the link= value. Then, a typical counter query (CountmDBPriority ON) would be written as:

http://localhost/newvalue?newlink=