Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
742 lines (526 sloc) 25.8 KB
170217 Corrected typo in pen.c per suggestion by Belinda Liu.
This fixes issue #38.
Released 0.34.1.
161029 Released 0.34.0.
161028 Merged pull request from Vincent Bernat for OpenSSL 1.1.0 compatibility.
This fixes issue #28.
161024 Allow setting local address for upstream connections. This fixes issue #31.
New penctl command "source" to set this option.
160914 Fixed issue #30: UDP not working in combination with a configuration file.
160908 Released 0.33.2.
160560 In epoll.c: check for EPOLLHUP.
160503 In dsr.c: always use our real mac address, to avoid confusing switches.
Released 0.33.1.
160407 Cleaned up code residue surrounded by "#if 0".
Released 0.33.0.
160407 Added CS_HALFDEAD for UDP streams that haven't seen traffic in a while.
160321 Bug in pending_and_closing: don't modify the list we're looping over.
160318 Updated pen manpage.
Deprecated -Q option (it didn't do anything since kqueue was already the
default where it was available).
Fixed error handling in epoll support.
160217 Added transparent UDP test case to
160128 Contribution from Talik Eichinger: add X-Forwarded-Proto when doing
SSL decryption.
151123 Released 0.32.0.
151120 Added tarpit test case to
151117 Tarpit functionality to be used with the DSR mode.
151112 pen.1: removed obsolete -S option, updated defaults for -x and -L.
151105 Released 0.31.1.
151103 In failover_server: sanity checks to failover routine.
151102 In add_client: add the initial server to .client as well as .initial.
151029 In failover_server: changed abuse_server to ABUSE_SERVER and emerg_server
to EMERG_SERVER, to handle their default NO_SERVER values.
See issue #19 on Github.
151012 At the suggestion from Marcos Vinicius Rogowski, the hash algorith
will now include the client port number if the -r (roundrobin)
option is used. See
Released 0.31.0.
150915 Officially released 0.30.1.
150909 Fixed IP-based client tracking.
150828 Removed unnecessary #include <pen.h> in dlist.c
150818 Released 0.30.0.
150803 Added UDP mode for Direct Server Return.
150803 Updated for compatibility with CentOS 6.
150725 Added #ifdef around SSLv3 initialization code in ssl, as
suggested by
150608 Released 0.29.0.
150528 Transparent reverse proxy support for Linux, FreeBSD and OpenBSD.
150527 Allow the client table size to be updated on the fly. Default size still 2048.
Allow the connection table size to be updated in the fly. Default still 500.
See penctl.1, options clients_max and conn_max.
150526 Introduced the macro NO_SERVER to be used instead of -1 to signify
error conditions and such.
Removed the fixed server table size along with the -S option.
150525 Fixed cosmetic bug in startup code which required port to be specified
on backend servers even if it was the same as the listening port.
150520 Released 0.28.0.
150513 Numerous updates to support the madness that is Windows.
150501 Fix from Vincent Bernat: segfault when not using SSL.
150427 DSR support using Netmap on FreeBSD.
Unbroke DSR on Linux.
150424 Replaced all calls to perror with debug(..., strerror(errno);
Updated penlog and penlogd to use diag.[ch].
150422 More refactoring: broke out conn.[ch], client.[ch], server.[ch],
Made a hash index such that the load balancer may balance load.
150420 Broke out Windows code from pen.c into windows.c. Added windows.h.
150419 Broke out public definitions for dsr into dsr.h.
Broke out memory management into memory.[ch].
Broke out dignostic and logging functions into diag.[ch].
Broke out settings into settings.[ch].
Broke out access lists into acl.[ch].
Broke out event initialization into event.[ch].
Added pen_epoll.h, pen_kqueue.h, pen_poll.h, pen_select.h.
Broke out pen_aton et al into netconv.[ch].
150416 Added dsr.c
150408 Bug in copy_down affecting SSL connections fixed.
Released 0.27.5.
150408 Updated ocsp stapling to be compatible with server name indication.
Added script.
Released 0.27.4.
150407 SSL code broken out into ssl.[ch]. SSL context creation broken
out from ssl_init to ssl_create_context.
Server Name Indication support. New command to enable:
ssl_sni_path PATH
where PATH is the name of a directory containing domain.key,
domain.crt and files for each domain.
150406 OCSP stapling. New command ssl_ocsp_response filename
specifies the location of the ocsp response to be stapled.
The response must be pre-fetched. The idea was borrowed
from Rob Stradling.
150403 New command ssl_client_renegotiation_interval specifies the
minimum number of seconds the client must wait between
renegotiation requests. Default 3600.
150402 Enabled SSL session resumption.
In do_cmd: don't print "ignoring command" for comments starting
with '#'.
150330 Added ssl_option no_tlsv1.1 and ssl_option no_tlsv1.2 to disable
SSL 1.1 and 1.2 respectively.
150330 Released 0.27.3.
150330 Added autoconf check that the ECDHE is available and not disabled.
Bumped default max connections and listen queue to 500.
150326 Support for ECDHE cipher suites.
150325 New commands ssl_option and ssl_ciphers to individually disable
insecure protocols and ciphers.
150324 Updated penctl.1 with the new command.
150322 New knob to tweak max number of pending nonblocking connection
attempts: pending_max N (default 100).
150305 Released 0.27.2.
150228 Moved dlist prototypes to dlist.h.
150227 Added check to close idle connections after a period of inactivity.
Penctl: idle_timeout N (default 0 = never close idle connections).
150225 Moved git repository to GitHub..
150225 New feature: dummy server. Rather than acting as a proxy,
Pen will pretend to be a web server with just barely enough
functionality to work as a test target.
Penctl: dummy|no dummy.
150224 Yet Another command: abort_on_error|no abort_on_error makes
Pen call abort() (or not) when encountering a fatal error.
150224 New feature: "reliable idling". Pen will make and maintain a
number of idle connections to the backend servers. When a connection
closes, a new one is made (hence "reliable"). Penctl: idlers [N].
150223 In do_cmd: return diagnostics to penctl so the user can see them,
instead of uselessly sending them to syslog.
150223 New penctl commands:
socket N (print which connection the socket belongs to)
connection N (print info on the specified connection)
close N (forcibly close connection N)
150219 In open_listener: check that the requested port is in range.
Fixed bug in dlist_insert.
Released 0.27.1.
150215 Even load distribution when a server is unavailable.
150212 Let pen save the settings for tcp_nodelay and tcp_fastclose.
Make flush_up and flush_down return the correct value on error.
150212 Added with reasonable settings for Windows.
Released 0.27.0.
150211 Better detection and blacklisting of unavailable servers.
150209 New penctl commands:
tcp_nodelay sets TCP_NODELAY on sockets. Turn off with no tcp_nodelay.
tcp_fastclose closes both upstream and downstream sockets if one of them
closes theirs. Will take the values up, down, both or off (default).
150208 Rather than making a table of pending connections every time through
the main loop, keep them in a doubly linked list which is only updated
as needed. O(n) -> O(1).
150207 A bug in udp mode: after successful "connect", do not event_add downfd,
because it is equal to listenfd and epoll_ctl doesn't like that.
150206 Module kqueue.c updated.
Module poll.c: set unused fd:s to -1, or Solaris will say ENOSYS.
150205 Enable diagnostic messages by default in
Changed event bookkeeping from stateless to stateful.
Made keepalive optional and added "keepalive / no keepalive" penctl command.
150204 Added windows.c and pen.h to the release tarball.
Released 0.26.1.
150204 Released 0.26.0.
150203 More sensible autoconfiguration defaults: poll, kqueue, epoll, openssl and geoip
are built if found unless explicitly excluded.
New event management defaults: kqueue, epoll, poll, select in that order.
New penctl commands: kqueue, epoll, poll, select.
New command line option: -O cmd where cmd is any penctl command.
E.g. -O select to use select instead of the compiled-in default.
150127 New penctl option "listen [address:]port" to allow listening address
to be changed on the fly or via a configuration file.
New pen options -i and -u to install and uninstall Pen as a Windows service.
See pen manpage.
Reduced default timeout to 3 seconds.
150126 New autoconf option --enable-debugging to enable debugging code.
Lots of fixes for compatibility with Windows.
Released 0.26.0beta2.
150123 Fixed bug in mainloop which kept trying to write 0 bytes.
MinGW port. Use to compile.
150121 Event management code broken out into select.c, poll.c, kqueue.c and epoll.c.
150113 New command-line option -m to accept multiple incoming connections in a batch.
New command-line option -q to set incoming pending connection queue length.
150112 Close upfd when failing over.
150109 Released 0.26.0beta1.
Adjusted debug logging levels.
150108 Started on epoll support for Linux.
150107 Rewrote output_net and output_file to take a variable number of arguments.
Handle timed out connection attempts in mainloop_kqueue.
150105 Fixed mainloop_kqueue.
150103 A lot of code broken out from mainloop_select into separate functions.
Fixed mainloop_poll.
150102 Bugfixes related to the new backend connection logic.
141229 Cleaned up and simplified add_client() and associated circuitry.
Connections to back end servers are now nonblocking and parallel.
141217 Removed the -n option and all code explicitly using blocking sockets.
Removed the -D option and the "delayed forward" feature.
141213 Renamed server and client fields in the conn, client and server structures
to better reflect what they are.
Restructured the add_client, store_client, store_conn and try_server
140814 Allow write_cfg to save IPv6 and GeoIP access lists.
Released 0.25.1.
140804 Fixed a bug in write_cfg, where Pen would try to write to an unwritable
file. Reported by Steven Myint
140804 Released 0.25.0.
140701 Return UDP replies from the server to the client.
140621 UDP load balancing code restructured and bugfixed. Released 0.24.0.
140616 Released 0.23.0.
140417 In mainloop_select: When there is a pending connection, keep accepting
up to multi_accept times *or* until EAGAIN *or* connection table is full.
This improves performance under load.
140414 Updated GeoIP support for IPv6.
140410 Servers can have ipv6 addresses. It is possible to use a mix of ipv4
and ipv6 servers:
./pen -df -S 2 -r :::2222 [::1]:22 []:22
140409 In order to allow server addresses with : in them (i.e. ipv6), it is now
possible to use square brackets around the address part of the server
specification: [address]:port (e.g. [::1]:8080).
140408 Pen can now listen on ipv6 sockets in addition to ipv4 and unix ones.
I.e. things like "pen ::1:2222" are now possible.
140402 snprintf format errors reported by Christopher Meng fixed in
pen.c and penctl.c.
Released 0.22.1.
140331 Updated pen manpage to clarify what the control socket does.
Resist opening control socket running as root.
Remove the default file name for web log.
New feature: unix domain listening sockets.
Released 0.22.0.
140221 Redesigned server and client structs to allow ipv6 addresses and require
less casting (yuck) in the code.
140205 Updated penctl man page with syntax for IPv6 and GeoIP access lists.
Fixed cosmetic signedness compiler warnings.
140204 Moved defines for ACE_IPV4 et al outside #ifdef HAVE_SSL clause.
Otherwise pen won't compile without ssl.
Released 0.21.1.
140204 GeoIP access lists.
Released 0.21.0.
140120 Added "special exception" clause for linking with OpenSSL.
Released 0.20.2.
131127 Penlog ipv6 compatible.
131126 Modernized automake configuration.
Penctl ipv6 compatible.
131123 Updated autoconf to 2.69.
Released 0.20.1.
131122 Updated SSL code. Protocol ssl2 removed. Default changed to tls1.
Released 0.20.0.
131120 Added UDP patch from Zen.
Released 0.19.0.
080517 Added patch from Debian that fixes some issues with penctl.cgi.
Released 0.18.0.
080503 Priority based server selection algorithm.
080501 Patch from Stephen P. Schaefer fixes several issues in
In the server_by_weight function, multiply current connections
by WEIGHT_FACTOR to make the selection mo fine grained when the
number of connections is small.
Released 0.17.3.
080326 Patch from Dana Contreras: send stdio to /dev/null after
Fixed a bunch of cosmetic signedness compiler warnings.
070912 Added sanity check to init() to make sure that servers_max
is large enough for the number of servers specified on the
command line.
Released 0.17.2.
070829 Faster string duplication courtesy of Nigel Horne.
070502 Updated automake links.
070212 Updated INSTALL with instructions for increasing the number
of connections on Windows.
061204 Include server weight in response to "penctl servers" command.
Set server weight on command line. Server is specified as
060627 Bugfix by Chris Elsworth: server_by_weight would never
consider blacklisted servers, which kept them blacklisted
Released 0.17.1.
051230 Added code by Chris Elsworth for kqueue support. Configure
with --with-kqueue to enable.
Released 0.17.0.
051215 Changed the configure option for ssl to
Released 0.16.0.
040709 Added an "abuse server" for naughty clients that have been
denied access by an acl. Works similar to the emergency server,
use command-line option "-B host:port" to enable.
040706 Servers can be assigned different weights to account for
differing capacity. New -W command-line option. New penctl
server S weight W (assign weight to server)
weight (use weight for server selection)
no weight (do not use weight for server selection)
Cleaned up the logic in add_client so the weighted server
selection can be used without client tracking.
Released 0.15.0.
040624 Some performance enhancing changes:
New variable connections_used remembers the number of used
slots in conns[]. It is incremented by store_conn and
decremented by close_conn. This allows the main loop to
only accept new connections if there are empty slots in
conns[], which is much better than accepting the connection
only to immediately close it because we can't handle it.
New variable connections_last remembers the last used slot
in conns[]. This allows us to scan for empty slots much faster
in store_conn when there are many simultaneous connections.
Released 0.14.0.
040622 Documented the procedure to change FD_SETSIZE on Linux
040604 Documented the include command in the penctl manpage.
040527 Fixed SSL so it works in nonblocking mode, except that
it doesn't work anyway.
Moved listenfd and ctrlfd out of main.
040428 Highly experimental SSL code in pen.c. Updated manpage
with the new options. Added https example to HOWTO.
Released 0.13.0.
040403 Replaced signal with sigaction so connect() to nonexisting
servers can be interrupted and not restarted.
Released 0.12.3.
040318 Bugfix by Andreas Wrede: Running pen with -H to generate
X-Forwarded-For headers causes POST request data sections
to be dropped, if they are in the same packet as the POST
header (rather than a continuation packet) and the if the
POST data contains binary zeros. This is almost always the
case with Internet Explorer 6. Mozilla and friends send
the data of a POST request in a separate packet, so the
problem does not show up there.
040310 Changed setlinebuf to setvbuf in penlogd.c
Released 0.12.2.
040201 Bugfix: rewrite_request would only add the X-Forwarded-For
header for the first request.
Released 0.12.1.
040104 Removed the reference to mergelogs from the README and
added one to penlogd instead.
031023 Released 0.12.0.
031022 Penlogd: sscanf would read 100 bytes + terminating nul into
a buffer of size 100. Now reads 99+nul. Spotted by Oezguer Kesim.
031021 Let tracking time be set through penctl.cgi.
In do_cmd, "no log": only close the logfile if it is open.
New penctl command, "write [FILE]" writes current configuration
to a file. If FILE is omitted, overwrite the original
configuration file (-F option).
031017 Pen: Time based expiration of tracked clients. Default is
0 seconds = never expire. Added -T option to control expiry
time. Also added penctl command "tracking N".
Penlogd: zero-terminate results from recvfrom.
031013 In penlogd.c: don't complain if recvfrom is interrupted by signal.
031013 Released 0.11.1.
031011 Use sigaction rather than signal in penlogd.
Check for inet_aton in libresolv (needed for Solaris).
Install documentation into ${prefix}/doc/pen (can be
changed using the --with-doc= configuration option).
Added tgz target to for Slackware packaging.
030922 Added an "include" keyword to the command interface, so the
configuration can be split into several files.
Added access control lists, numbered 0 to 9. The command
syntax to define them are:
acl N permit|deny ipaddress mask create acl
no acl N delete acl
client_acl N bind clients to acl
control_acl N bind control interface to acl
server S acl N who can use server S
All access lists start out empty, defaulting to permit anything.
030910 In rewrite_request: don't add an X-Forwarded-For: if there
already is one.
030906 Added a configuration file (-F option) with commands in
penctl format. It is read after processing all command line
arguments and also when a HUP signal is received.
030905 Updated pen manpage to reflect the new -X and -S options.
In rewrite_request: look for \n\n if we can't find
\r\n\r\n. Some clients do that, according to
Steve Hall <>.
Moved everything from CONTROL into penctl.1.
Also added the exit command to penctl.1.
030905 Released 0.10.3.
030904 Preallocate slots for servers that can be dynamically added
and removed using the control interface, up to a maximum
number determined by the -S option (default 16).
030821 A patch from Anders Nordby <> sets the group
as well as user id when running pen with the -u option.
030821 Released 0.10.2.
030820 A patch from Mikko Ruuska (mikko.ruuskaxi at adds
an exit command to pen's control port interface.
030820 Patch for pen.c by Andreas Wrede <>, fixing
the following bugs:
The message indicating a failed server is re-issued on every attempt,
due to a inverted if-test.
The attached patch issues the messages only the first time a server
fails and it shows when we will retry the connection. It also
suppresses multiple "Using emergency server" messages.
030820 #include <string.h> in penlog.c.
030820 Patch for penlogd.c by Branson Matheson <>:
- pen sends two lines for every log.. penlogd only needs one
to function.
- added a -b ... unbuffer to the opts for penlogd so that you
can actually see the lines as they come out.
- changed one of the dubugs to so post processing of the input
030407 Bugs uncovered by Charlie Reitsma <>:
HOWTO incorrectly specified penctl in place of penlog
in Apache configuration example, and using penctl to
redirect log to penlogd didn't work.
Avoid bogus header rewriting in rewrite_request.
Released 0.10.1.
030210 New penctl commands "http" and "no http" to toggle -H.
030208 New option -H adds X-Forwarded-For header to http requests.
020717 Patches from Patroklos G. Argyroudis <>:
- check getopt() calls against -1 and not EOF
- fix for a possible format string in pen.c
020711 Ported to Darwin/MacOS X.
Released 0.9.4.
020705 New penctl command: recent [seconds] displays clients that have
connected recently (default five minutes), along with number of
connects, transmitted and received data.
020702 Buffer overflow in netlog. See comment in pen.c.
Added options -j (for chroot) and -u (for setuid) to pen and
penlogd. See manpages.
020627 Fixed an error which could throw penlogd into an endless loop
if a udp packet was lost at the crucial moment.
020626 Pedantic checking of memory allocations and buffer sizes.
020618 Penlogd: added option -n to adjust the number of cached log
entries from Pen.
020614 Added options -d, -f, -l and -p to penlogd. They do the same
as in pen. Also added signal handlers for TERM and HUP; these
too do the same as in pen. Updated penlogd manpage.
Updated www section in HOWTO to use penlog rather than mergelogs.
020613 Added penlog.c to log over a network using Apaches reliable
piped logs. A companion log server, penlogd.c, consolidates
logs from Pen and from all web servers into a single file.
Added the necessary code to Pen log over the network.
020610 Wrote penctl.cgi, a web wrapper for penctl.
020609 Wrote a new version of the main loop, using poll() instead of
select(). Added configuration option --with-poll to enable.
Also turned redefinition of FD_SETSIZE into a configuration
option --with-fd_setsize=N.
Updated installation instructions in INSTALL.
020605 Added optional hard limit to the number of connections to each
Timestamps in debug log entries.
Released 0.8.0.
020604 Added "server of last resort" (-e option) which is only used
when all other servers are unavailable. (Andreas Wrede)
020528 Several enhancements and bugfixes by Andreas Wrede:
In webstats: changed CLIENTS_MAX to clients_max and
CONNECTIONS_MAX to connections_max.
Show time in human-readable format rather than seconds since 1970.
Changed byte counters from unsigned long to unsigned long long.
Fixed file descriptor leak: The connection wasn't closed when
the connection table was full.
Moved stats generation and log restart out of the signal handlers
and into the main loop.
If a client went away before receiving all its data (large files),
the remaining portion would be sent to the next client occupying
the same slot.
Added pointers in connection structure to avoid having to memcpy
the buffers in flush_up/flush_down.
Released 0.7.0.
020507 Updated the penctl manpage to reflect reality.
Released 0.6.3.
020417 Added -D switch to make copy_up and copy_down *always* store data
in a temporary buffer and wait for the next round through the
main loop before passing it on to the receiving end.
The penctl command for this is "delayed_forward".
When making sockets nonblocking (through fcntl(..., O_NONBLOCK)),
make sure that any existing flags are not reset in the process.
Important bugfix: each failed connection attempt in try_server
would result in one socket leaked because we returned without
closing it.
020413 Figured out why nonblocking mode was slower than blocking. Fixed.
020411 Added penctl, a simple user interface to the control protocol.
020324 Cancel timeout if it isn't needed.
020115 Added LDAP info in the HOWTO.
Added the flush_up/flush_down bugfix from 0.5.0 again.
Released 0.6.1.
020111 Moved #include <sys/types.h> before #include <netinet/in.h>
Replaced the call to setpgrp with setsid.
Transformed mergelogs into ultimately portable ANSI C (almost).
Thanks to Mike Dugas <> for help with porting
to FreeBSD 4.4-RELEASE.
020110 Rewrote mergelogs completely. It will now never discard a web
server log entry, and it tries much harder to locate a good
match in the pen log. It deals with log entries that are out
of order and servers with unsynchronized clocks and/or
different time zones. The -l (lag) option is no more.
Removed the -r (rejects) option, since we no longer reject anything.
Released 0.6.0
010915 Made the use of daemon() optional.
Added the cgi script penstats to update and display statistics.
Set current in store_conn.
Released 0.5.0.
010914 Statistics in HTML format (Riccard Åkerman).
Tested pen on HP-UX 10.20.
010913 Released 0.4.0.
010912 When storing part of the buffer for a renewed attempt,
store the *end*, not the beginning. Affects copy_up and copy_down.
Autoconf. Use daemon() if available. Make sure that we don't try
to close uninitialized file handles in add_client.
New option -n to not make sockets nonblocking (mainly useful
for debugging).
010911 Make sure that remaining data is stored away when we get EAGAIN
in copy_up.
Released 0.3.3.
010909 Added -p argument to store process id in a file (Andreas Wrede).
Made the sockets nonblocking. Handle EAGAIN in copy_up/down.
Released 0.3.2.
010908 Ignore SIGPIPE. Released 0.3.1.
010827 Option -h uses a hash on the client IP address for the initial
server selection. Option -s ("stubborn") prevents failover to
another server if the initial choice is unavailable.
010824 Use getport for the local port as well.
010820 Append to the logfile rather than overwriting it.
Released 0.2.0.
010817 Server selection algorithm rewritten in a cleaner, simpler way.
Blacklist nonresponding servers for a selectable period of time.
Optional "plain" roundrobin without client tracking.
(options -b and -r, see manpage).
Log to syslog if we are running in the background.
010814 Installed pen on, which now load-balances itself. Apache
runs on port 8080, pen on 80. Seems to work (tm).
010813 Added description of options to pen.1 and mergelogs.1.
Script to guess libraries.
010812 Fixed typo (webmerge -> mergelogs) in pen.1.
010809 Added mergelogs, a program to match pen logs against web server
logs and merge the results into one log file with the correct
client addresses.
Released 0.1.0.
010808 Print statistics on stderr when sent USR1 signal.
Ported to Solaris, i.e. verified that it works ;-).
Logging. Reopen log file when sent HUP signal.
Exit cleanly when sent TERM signal.
010807 Wrote a manpage.
010803 Completed the conversion to non-forking, selecting mode. Works
really well now, with very low CPU utilization even with many
simultaneous connections.
010729 Rewrote the program to not fork.
010722 Prettied up the source.
001218 Updated the README.
001022 Rewrote the load balancing algorithm.