-DOC = prog-guide
-all: $(DOC).html $(DOC).ps $(DOC).txt
+all:
+ dyn-docs
+ html-docs
-$(DOC).ps: $(DOC).dvi
- dvips -o $(DOC).ps $(DOC).dvi
+dyn-docs:
+ rm -f -r tmp
+ cd ../../ && doxygen squid3.dox 2>doxygen.log
+ mv tmp dyn
-$(DOC).tex: $(DOC).sgml
- linuxdoc --backend=latex --papersize=letter $(DOC)
-
-$(DOC).dvi: $(DOC).tex
- latex $(DOC).tex
- latex $(DOC).tex
- latex $(DOC).tex
-
-$(DOC).txt: $(DOC).sgml
- linuxdoc --backend=txt $(DOC)
-
-$(DOC).html: $(DOC).sgml
- sgml2html $(DOC)
+html-docs:
+ rm -f -r tmp
+ cd ../../ && (cat squid3.dox | sed s/dyn/html/g | sed s/CALL_GRAPH/#/ | sed s/CALLER_GRAPH/#/ | doxygen -) 2>doxygen.log
+ mv tmp html
clean:
- rm -f *.html
- rm -f $(DOC).tex $(DOC).ps $(DOC).dvi $(DOC).aux $(DOC).log $(DOC).toc
+ rm -f -r tmp html dyn
-/**
- \page 03_Makefile Altering Squid Makefiles
- *
- \section MakefileWhich1 Which file to edit.
- \par
- * Each directory in the squid sources is largely self-sufficient
- * \b Makefile.in is auto-generated by autotools based on the
- * \b configure.in and \b Makefile.am files.
- *
- \par
- * In general your additions should go in \b Makefile.am
- *
- *
- \section MakefileUnitTests Adding new Unit Tests
- *
- \par
- * To alter or add new tests for a class where a set of tests
- * already exist, you should simply edit the \b tests/testX.(h|cc) files
- * for that class.
- *
- \par
- * When a new class needs testing you will need to add some variables
- * to Makefile.am telling autotools what to build. These variables are:
- *
- \subsection _SOURCES tests_testX_SOURCES= ...
- \par
- * The list of .(h|cc) files that need linking to the class.
- * Most tests \b should use the actual Squid code. Though there are \b stub_X.cc
- * files available that simplify some of the more complex optional components.
- *
- \subsection _LDFLAGS tests_testX_LDFLAGS= ...
- \par
- * Most cases it should be just \b \$(LIBADD_DL).
- *
- \subsection _DEPENDENCIES tests_testX_DEPENDENCIES= ...
- \par
- * this is a list of the additional module *.a files that need linking.
- * All unit tests require: \b \@SQUID_CPPUNIT_LA\@
- *
- \subsection _LDADD tests_testX_LDADD= ...
- \par
- * this is a list of the additional module libraries that need linking.
- * All unit tests require: \b \@SQUID_CPPUNIT_LIBS\@
- \par
- *
- \subsection LIBS Modules available for *_DEPENDENCIES and *_LDADD
- *
- \par Linking ~/lib/* code:
- \li *_LDADD= \b -L../lib \b -lmiscutil ...
- \li *_DEPENDENCIES= \b \$(top_builddir)/lib/libmiscutil.a ...
- *
- \par Linking ~/src/auth/* code:
- \li *_LDADD= \b libauth.la ...
- *
- */
-<!doctype linuxdoc system>
-<article>
-<title>Squid Programmers Guide</title>
-<author>Squid Developers</author>
-<date>$Id: prog-guide.sgml,v 1.60 2006/05/20 13:15:14 hno Exp $</date>
-
-<abstract>
-Squid is a WWW Cache application developed by the National Laboratory
-for Applied Network Research and members of the Web Caching community.
-Squid is implemented as a single, non-blocking process based around
-a BSD select() loop. This document describes the operation of the Squid
-source code and is intended to be used by others who wish to customize
-or improve it.
-</abstract>
-
-<toc>
-
-
-<!-- %%%% Chapter : INTRODUCTION %%%% -->
-<sect>Introduction
-
- <P>
- The Squid source code has evolved more from empirical
- observation and tinkering, rather than a solid design
- process. It carries a legacy of being ``touched'' by
- numerous individuals, each with somewhat different techniques
- and terminology.
-
- <P>
- Squid is a single-process proxy server. Every request is
- handled by the main process, with the exception of FTP.
- However, Squid does not use a ``threads package'' such has
- Pthreads. While this might be easier to code, it suffers
- from portability and performance problems. Instead Squid
- maintains data structures and state information for each
- active request.
-
- <P>
- The code is often difficult to follow because there are no
- explicit state variables for the active requests. Instead,
- thread execution progresses as a sequence of ``callback
- functions'' which get executed when I/O is ready to occur,
- or some other event has happened. As a callback function
- completes, it is responsible for registering the next
- callback function for subsequent I/O.
-
- <P>
- Note there is only a pseudo-consistent naming scheme. In
- most cases functions are named like <tt/moduleFooBar()/.
- However, there are also some functions named like
- <tt/module_foo_bar()/.
-
- <P>
- Note that the Squid source changes rapidly, and some parts
- of this document may become out-of-date. If you find any
- inconsistencies, please feel free to notify <url
- url="mailto:squid-dev@squid-cache.org" name="the Squid Developers">.
-
-<sect1>Conventions
-
- <P>
- Function names and file names will be written in a courier
- font, such as <tt/store.c/ and <tt/storeRegister()/. Data
- structures and their members will be written in an italicized
- font, such as <em/StoreEntry/.
-
-<sect>Coding Conventions
-
-<sect1>Infrastructure
-
- <P>
- Most custom types and tools are documented in the code or the relevant
- portions of this manual. Some key points apply globally however.
-
-<sect2>Fixed width types
- <P>
- If you need to use specific width types - such as
- a 16 bit unsigned integer, use one of the following types. To access
- them simply include "config.h".
- <enum>
- <item>int16_t - 16 bit signed.
- <item>u_int16_t - 16 bit unsigned.
- <item>int32t - 32 bit signed.
- <item>u_int32_t - 32 bit unsigned.
- <item>int64_t - 64 bit signed.
- <item>u_int64_t - 64 bit unsigned.
- </enum>
-
-<sect2>Unit tests
- <P>
- It is preferrable to automated tests for units of functionality. There
- is a boilerplate for tests in "src/tests/testBoilerplate.[cc|h]". New
- tests need to be added to src/Makefile.am to build and run them during
- "make check". To add a new test script, just copy the references to
- testBoilerplate in Makefile.am adjusting the name, and likewise copy the
- source files. If you are testing an already tested area you may be able
- to just add new test cases to an existing script. I.e. to test the store
- some more just edit tests/testStore.h and add a new unit test method
- name,
-
-<sect>Overview of Squid Components
-
- <P>
-Squid consists of the following major components
-
-<sect1>Client Side Socket
-
- <P>
- Here new client connections are accepted, parsed, and
- reply data sent. Per-connection state information is held
- in a data structure called <em/ConnStateData/. Per-request
- state information is stored in the <em/clientSocketContext/
- structure. With HTTP/1.1 we may have multiple requests from
- a single TCP connection.
-
-<sect1>Client Side Request
- <P>
- This is where requests are processed. We determine if the
- request is to be redirected, if it passes access lists,
- and setup the initial client stream for internal requests.
- Temporary state for this processing is held in a
- <em/clientRequestContext/ struct.
-
-<sect1>Client Side Reply
- <P>
- This is where we determine if the request is cache HIT,
- REFRESH, MISS, etc. This involves querying the store
- (possibly multiple times) to work through Vary lists and
- the list. Per-request state information is stored
- in the <em/clientReplyContext/ structure.
-
-<sect1>Client Streams
- <P>
- These routines implement a unidirectional, non-blocking,
- pull pipeline. They allow code to be inserted into the
- reply logic on an as-needed basis. For instance,
- transfer-encoding logic is only needed when sending a
- HTTP/1.1 reply.
-
-<sect1>Server Side
- <P>
- These routines are responsible for forwarding cache misses
- to other servers, depending on the protocol. Cache misses
- may be forwarded to either origin servers, or other proxy
- caches. Note that all requests (FTP, Gopher) to other
- proxies are sent as HTTP requests. <tt/gopher.c/ is somewhat
- complex and gross because it must convert from the Gopher
- protocol to HTTP. Wais and Gopher don't receive much
- attention because they comprise a relatively insignificant
- portion of Internet traffic.
-
-<sect1>Storage Manager
-
- <P>
- The Storage Manager is the glue between client and server
- sides. Every object saved in the cache is allocated a
- <em/StoreEntry/ structure. While the object is being
- accessed, it also has a <em/MemObject/ structure.
-
- <P>
- Squid can quickly locate cached objects because it keeps
- (in memory) a hash table of all <em/StoreEntry/'s. The
- keys for the hash table are MD5 checksums of the objects
- URI. In addition there is also a storage policy such
- as LRU that keeps track of the objects and determines
- the removal order when space needs to be reclaimed.
- For the LRU policy this is implemented as a doubly linked
- list.
-
- <P>
- For each object the <em/StoreEntry/ maps to a cache_dir
- and location via sdirn and sfilen. For the "ufs" store
- this file number (sfilen) is converted to a disk pathname
- by a simple modulo of L2 and L1, but other storage drivers may
- map sfilen in other ways. A cache swap file consists
- of two parts: the cache metadata, and the object data.
- Note the object data includes the full HTTP reply---headers
- and body. The HTTP reply headers are not the same as the
- cache metadata.
-
- <P>
- Client-side requests register themselves with a <em/StoreEntry/
- to be notified when new data arrives. Multiple clients
- may receive data via a single <em/StoreEntry/. For POST
- and PUT request, this process works in reverse. Server-side
- functions are notified when additional data is read from
- the client.
-
-<sect1>Request Forwarding
-
-<sect1>Peer Selection
-
- <P>
- These functions are responsible for selecting one (or none)
- of the neighbor caches as the appropriate forwarding
- location.
-
-<sect1>Access Control
-
- <P>
- These functions are responsible for allowing or denying a
- request, based on a number of different parameters. These
- parameters include the client's IP address, the hostname
- of the requested resource, the request method, etc. Some
- of the necessary information may not be immediately available,
- for example the origin server's IP address. In these cases,
- the ACL routines initiate lookups for the necessary
- information and continues the access control checks when
- the information is available.
-
-<sect1>Authentication Framework
-
- <P>
- These functions are responsible for handling HTTP
- authentication. They follow a modular framework allow
- different authentication schemes to be added at will. For
- information on working with the authentication schemes See
- the chapter Authentication Framework.
-
-<sect1>Network Communication
-
- <P>
- These are the routines for communicating over TCP and UDP
- network sockets. Here is where sockets are opened, closed,
- read, and written. In addition, note that the heart of
- Squid (<tt/comm_select()/ or <tt/comm_poll()/) exists here,
- even though it handles all file descriptors, not just
- network sockets. These routines do not support queuing
- multiple blocks of data for writing. Consequently, a
- callback occurs for every write request.
-
-<sect1>File/Disk I/O
-
- <P>
- Routines for reading and writing disk files (and FIFOs).
- Reasons for separating network and disk I/O functions are
- partly historical, and partly because of different behaviors.
- For example, we don't worry about getting a ``No space left
- on device'' error for network sockets. The disk I/O routines
- support queuing of multiple blocks for writing. In some
- cases, it is possible to merge multiple blocks into a single
- write request. The write callback does not necessarily
- occur for every write request.
-
-<sect1>Neighbors
-
- <P>
- Maintains the list of neighbor caches. Sends and receives
- ICP messages to neighbors. Decides which neighbors to
- query for a given request. File: <tt/neighbors.c/.
-
-<sect1>IP/FQDN Cache
-
- <P>
- A cache of name-to-address and address-to-name lookups.
- These are hash tables keyed on the names and addresses.
- <tt/ipcache_nbgethostbyname()/ and <tt/fqdncache_nbgethostbyaddr()/
- implement the non-blocking lookups. Files: <tt/ipcache.c/,
- <tt/fqdncache.c/.
-
-<sect1>Cache Manager
-
- <P>
- This provides access to certain information needed by the
- cache administrator. A companion program, <em/cachemgr.cgi/
- can be used to make this information available via a Web
- browser. Cache manager requests to Squid are made with a
- special URL of the form
-<verb>
- cache_object://hostname/operation
-</verb>
- The cache manager provides essentially ``read-only'' access
- to information. It does not provide a method for configuring
- Squid while it is running.
-
-<sect1>Network Measurement Database
-
- <P>
- In a number of situation, Squid finds it useful to know the
- estimated network round-trip time (RTT) between itself and
- origin servers. A particularly useful is example is
- the peer selection algorithm. By making RTT measurements, a
- Squid cache will know if it, or one if its neighbors, is closest
- to a given origin server. The actual measurements are made
- with the <em/pinger/ program, described below. The measured
- values are stored in a database indexed under two keys. The
- primary index field is the /24 prefix of the origin server's
- IP address. Secondly, a hash table of fully-qualified host
- names have have data structures with links to the appropriate
- network entry. This allows Squid to quickly look up measurements
- when given either an IP address, or a host name. The /24 prefix
- aggregation is used to reduce the overall database size. File:
- <tt/net_db.c/.
-
-<sect1>Redirectors
-
- <P>
- Squid has the ability to rewrite requests from clients. After
- checking the access controls, but before checking for cache hits,
- requested URLs may optionally be written to an external
- <em/redirector/ process. This program, which can be highly
- customized, may return a new URL to replace the original request.
- Common applications for this feature are extended access controls
- and local mirroring. File: <tt/redirect.c/.
-
-<sect1>Autonomous System Numbers
-
- <P>
- Squid supports Autonomous System (AS) numbers as another
- access control element. The routines in <tt/asn.c/
- query databases which map AS numbers into lists of CIDR
- prefixes. These results are stored in a radix tree which
- allows fast searching of the AS number for a given IP address.
-
-<sect1>Configuration File Parsing
-
- <P>
- The primary configuration file specification is in the file
- <tt/cf.data.pre/. A simple utility program, <tt/cf_gen/,
- reads the <tt/cf.data.pre/ file and generates <tt/cf_parser.c/
- and <tt/squid.conf/. <tt/cf_parser.c/ is included directly
- into <tt/cache_cf.c/ at compile time.
-
-<sect1>Callback Data Allocator
-
- <P>
- Squid's extensive use of callback functions makes it very
- susceptible to memory access errors. Care must be taken
- so that the <tt/callback_data/ memory is still valid when
- the callback function is executed. The routines in <tt/cbdata.c/
- provide a uniform method for managing callback data memory,
- canceling callbacks, and preventing erroneous memory accesses.
-
-<sect1>Refcount Data Allocator (C++ Only)
-
- <P>
- Manual reference counting such as cbdata uses is error prone,
- and time consuming for the programmer. C++'s operator overloading
- allows us to create automatic reference counting pointers, that will
- free objects when they are no longer needed. With some care these
- objects can be passed to functions needed Callback Data pointers.
-
-<sect1>Debugging
-
- <P>
- Squid includes extensive debugging statements to assist in
- tracking down bugs and strange behavior. Every debug statement
- is assigned a section and level. Usually, every debug statement
- in the same source file has the same section. Levels are chosen
- depending on how much output will be generated, or how useful the
- provided information will be. The <em/debug_options/ line
- in the configuration file determines which debug statements will
- be shown and which will not. The <em/debug_options/ line
- assigns a maximum level for every section. If a given debug
- statement has a level less than or equal to the configured
- level for that section, it will be shown. This description
- probably sounds more complicated than it really is.
- File: <em/debug.c/. Note that <tt/debug()/ itself is a macro.
-
-<sect1>Error Generation
-
- <P>
- The routines in <tt/errorpage.c/ generate error messages from
- a template file and specific request parameters. This allows
- for customized error messages and multilingual support.
-
-<sect1>Event Queue
-
- <P>
- The routines in <tt/event.c/ maintain a linked-list event
- queue for functions to be executed at a future time. The
- event queue is used for periodic functions such as performing
- cache replacement, cleaning swap directories, as well as one-time
- functions such as ICP query timeouts.
-
-<sect1>Filedescriptor Management
-
- <P>
- Here we track the number of filedescriptors in use, and the
- number of bytes which has been read from or written to each
- file descriptor.
-
-
-<sect1>Hashtable Support
-
- <P>
- These routines implement generic hash tables. A hash table
- is created with a function for hashing the key values, and a
- function for comparing the key values.
-
-<sect1>HTTP Anonymization
-
- <P>
- These routines support anonymizing of HTTP requests leaving
- the cache. Either specific request headers will be removed
- (the ``standard'' mode), or only specific request headers
- will be allowed (the ``paranoid'' mode).
-
-<sect1>Delay Pools
-
- <P>
- Delay pools provide bandwidth regulation by restricting the rate
- at which squid reads from a server before sending to a client. They
- do not prevent cache hits from being sent at maximal capacity. Delay
- pools can aggregate the bandwidth from multiple machines and users
- to provide more or less general restrictions.
-
-<sect1>Internet Cache Protocol
-
- <P>
- Here we implement the Internet Cache Protocol. This
- protocol is documented in the RFC 2186 and RFC 2187.
- The bulk of code is in the <tt/icp_v2.c/ file. The
- other, <tt/icp_v3.c/ is a single function for handling
- ICP queries from Netcache/Netapp caches; they use
- a different version number and a slightly different message
- format.
-
-<sect1>Ident Lookups
-
- <P>
- These routines support RFC 931 ``Ident'' lookups. An ident
- server running on a host will report the user name associated
- with a connected TCP socket. Some sites use this facility for
- access control and logging purposes.
-
-<sect1>Memory Management
-
- <P>
- These routines allocate and manage pools of memory for
- frequently-used data structures. When the <em/memory_pools/
- configuration option is enabled, unused memory is not actually
- freed. Instead it is kept for future use. This may result
- in more efficient use of memory at the expense of a larger
- process size.
-
-<sect1>Multicast Support
-
- <P>
- Currently, multicast is only used for ICP queries. The
- routines in this file implement joining a UDP
- socket to a multicast group (or groups), and setting
- the multicast TTL value on outgoing packets.
-
-<sect1>Persistent Server Connections
-
- <P>
- These routines manage idle, persistent HTTP connections
- to origin servers and neighbor caches. Idle sockets
- are indexed in a hash table by their socket address
- (IP address and port number). Up to 10 idle sockets
- will be kept for each socket address, but only for
- 15 seconds. After 15 seconds, idle socket connections
- are closed.
-
-<sect1>Refresh Rules
-
- <P>
- These routines decide whether a cached object is stale or fresh,
- based on the <em/refresh_pattern/ configuration options.
- If an object is fresh, it can be returned as a cache hit.
- If it is stale, then it must be revalidated with an
- If-Modified-Since request.
-
-<sect1>SNMP Support
-
- <P>
- These routines implement SNMP for Squid. At the present time,
- we have made almost all of the cachemgr information available
- via SNMP.
-
-<sect1>URN Support
-
- <P>
- We are experimenting with URN support in Squid version 1.2.
- Note, we're not talking full-blown generic URN's here. This
- is primarily targeted toward using URN's as an smart way
- of handling lists of mirror sites. For more details, please
- see <url url="http://squid.nlanr.net/Squid/urn-support.html"
- name="URN support in Squid">.
-
-<sect1>ESI
- <P>
- ESI is an implementation of Edge Side Includes (<url url="http://www.esi.org">.)
- ESI is implemented as a client side stream and a small
- modification to client_side_reply.c to check whether
- ESI should be inserted into the reply stream or not.
-
-<sect>External Programs
-
-<sect1>dnsserver
-
- <P>
- Because the standard <tt/gethostbyname(3)/ library call
- blocks, Squid must use external processes to actually make
- these calls. Typically there will be ten <tt/dnsserver/
- processes spawned from Squid. Communication occurs via
- TCP sockets bound to the loopback interface. The functions
- in <tt/dns.c/ are primarily concerned with starting and
- stopping the dnsservers. Reading and writing to and from
- the dnsservers occurs in the IP and FQDN cache modules.
-
-<sect1>pinger
-
- <P>
- Although it would be possible for Squid to send and receive
- ICMP messages directly, we use an external process for
- two important reasons:
- <enum>
- <item>Because squid handles many filedescriptors simultaneously,
- we get much more accurate RTT measurements when ICMP is
- handled by a separate process.
- <item>Superuser privileges are required to send and receive
- ICMP. Rather than require Squid to be started as root,
- we prefer to have the smaller and simpler <em/pinger/
- program installed with setuid permissions.
- </enum>
-
-<sect1>unlinkd
-
- <P>
- The <tt/unlink(2)/ system call can cause a process to block
- for a significant amount of time. Therefore we do not want
- to make unlink() calls from Squid. Instead we pass them
- to this external process.
-
-<sect1>redirector
-
- <P>
- A redirector process reads URLs on stdin and writes (possibly
- changed) URLs on stdout. It is implemented as an external
- process to maximize flexibility.
-
-<sect>Flow of a Typical Request
-
- <P>
- <enum>
- <item>
- A client connection is accepted by the <em/client-side socket
- support/ and parsed, or is directly created via
- <em/clientBeginRequest/.
-
- <item>
- The access controls are checked. The client-side-request builds
- an ACL state data structure and registers a callback function
- for notification when access control checking is completed.
-
- <item>
- After the access controls have been verified, the request
- may be redirected.
-
- <item>The client-side-request is forwarded up the client stream
- to <em/GetMoreData/ which looks for the requested object in the
- cache, and or Vary: versions of the same. If is a cache hit,
- then the client-side registers its interest in the
- <em/StoreEntry/. Otherwise, Squid needs to forward the request,
- perhaps with an If-Modified-Since header.
-
- <item>
- The request-forwarding process begins with <tt/protoDispatch/.
- This function begins the peer selection procedure, which
- may involve sending ICP queries and receiving ICP replies.
- The peer selection procedure also involves checking
- configuration options such as <em/never_direct/ and
- <em/always_direct/.
-
- <item>
- When the ICP replies (if any) have been processed, we end
- up at <em/protoStart/. This function calls an appropriate
- protocol-specific function for forwarding the request.
- Here we will assume it is an HTTP request.
-
- <item>
- The HTTP module first opens a connection to the origin
- server or cache peer. If there is no idle persistent socket
- available, a new connection request is given to the Network
- Communication module with a callback function. The
- <tt/comm.c/ routines may try establishing a connection
- multiple times before giving up.
-
- <item>
- When a TCP connection has been established, HTTP builds a
- request buffer and submits it for writing on the socket.
- It then registers a read handler to receive and process
- the HTTP reply.
-
- <item>
- As the reply is initially received, the HTTP reply headers
- are parsed and placed into a reply data structure. As
- reply data is read, it is appended to the <em/StoreEntry/.
- Every time data is appended to the <em/StoreEntry/, the
- client-side is notified of the new data via a callback
- function. The rate at which reading occurs is regulated by
- the delay pools routines, via the deferred read mechanism.
-
- <item>
- As the client-side is notified of new data, it copies the
- data from the StoreEntry and submits it for writing on the
- client socket.
-
- <item>
- As data is appended to the <em/StoreEntry/, and the client(s)
- read it, the data may be submitted for writing to disk.
-
- <item>
- When the HTTP module finishes reading the reply from the
- upstream server, it marks the <em/StoreEntry/ as ``complete.''
- The server socket is either closed or given to the persistent
- connection pool for future use.
-
- <item>
- When the client-side has written all of the object data,
- it unregisters itself from the <em/StoreEntry/. At the
- same time it either waits for another request from the
- client, or closes the client connection.
-
- </enum>
-
-<sect>Callback Functions
-
-<sect>The Main Loop: <tt/comm_select()/
-
- <P>
- At the core of Squid is the <tt/select(2)/ system call.
- Squid uses <tt/select()/ or <tt/poll(2)/ to process I/O on
- all open file descriptors. Hereafter we'll only use
- ``select'' to refer generically to either system call.
-
- <P>
- The <tt/select()/ and <tt/poll()/ system calls work by
- waiting for I/O events on a set of file descriptors. Squid
- only checks for <em/read/ and <em/write/ events. Squid
- knows that it should check for reading or writing when
- there is a read or write handler registered for a given
- file descriptor. Handler functions are registered with
- the <tt/commSetSelect/ function. For example:
-<verb>
- commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0);
-</verb>
- In this example, <em/fd/ is a TCP socket to a client
- connection. When there is data to be read from the socket,
- then the select loop will execute
-<verb>
- clientReadRequest(fd, conn);
-</verb>
-
- <P>
- The I/O handlers are reset every time they are called. In
- other words, a handler function must re-register itself
- with <tt/commSetSelect/ if it wants to continue reading or
- writing on a file descriptor. The I/O handler may be
- canceled before being called by providing NULL arguments,
- e.g.:
-<verb>
- commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
-</verb>
-
- <P>
- These I/O handlers (and others) and their associated callback
- data pointers are saved in the <em/fde/ data structure:
-<verb>
- struct _fde {
- ...
- PF *read_handler;
- void *read_data;
- PF *write_handler;
- void *write_data;
- close_handler *close_handler;
- DEFER *defer_check;
- void *defer_data;
- };
-</verb>
- <em/read_handler/ and <em/write_handler/ are called when
- the file descriptor is ready for reading or writing,
- respectively. The <em/close_handler/ is called when the
- filedescriptor is closed. The <em/close_handler/ is
- actually a linked list of callback functions to be called.
-
- <P>
- In some situations we want to defer reading from a
- filedescriptor, even though it has data for us to read.
- This may be the case when data arrives from the server-side
- faster than it can be written to the client-side. Before
- adding a filedescriptor to the ``read set'' for select, we
- call <em/defer_check/ (if it is non-NULL). If <em/defer_check/
- returns 1, then we skip the filedescriptor for that time
- through the select loop.
-
-
-
- <P>
- These handlers are stored in the <em/FD_ENTRY/ structure
- as defined in <tt/comm.h/. <tt/fd_table[]/ is the global
- array of <em/FD_ENTRY/ structures. The handler functions
- are of type <em/PF/, which is a typedef:
-<verb>
- typedef void (*PF) (int, void *);
-</verb>
- The close handler is really a linked list of handler
- functions. Each handler also has an associated pointer
- <tt/(void *data)/ to some kind of data structure.
-
- <P>
- <tt/comm_select()/ is the function which issues the select()
- system call. It scans the entire <tt/fd_table[]/ array
- looking for handler functions. Each file descriptor with
- a read handler will be set in the <tt/fd_set/ read bitmask.
- Similarly, write handlers are scanned and bits set for the
- write bitmask. <tt/select()/ is then called, and the return
- read and write bitmasks are scanned for descriptors with
- pending I/O. For each ready descriptor, the handler is
- called. Note that the handler is cleared from the
- <em/FD_ENTRY/ before it is called.
-
- <P>
- After each handler is called, <tt/comm_select_incoming()/
- is called to process new HTTP and ICP requests.
-
- <P>
- Typical read handlers are
- <tt/httpReadReply()/,
- <tt/diskHandleRead()/,
- <tt/icpHandleUdp()/,
- and <tt/ipcache_dnsHandleRead()/.
- Typical write handlers are
- <tt/commHandleWrite()/,
- <tt/diskHandleWrite()/,
- and <tt/icpUdpReply()/.
- The handler function is set with <tt/commSetSelect()/, with the
- exception of the close handlers, which are set with
- <tt/comm_add_close_handler()/.
-
- <P>
- The close handlers are normally called from <tt/comm_close()/.
- The job of the close handlers is to deallocate data structures
- associated with the file descriptor. For this reason
- <tt/comm_close()/ must normally be the last function in a
- sequence to prevent accessing just-freed memory.
-
- <P>
- The timeout and lifetime handlers are called for file
- descriptors which have been idle for too long. They are
- further discussed in a following chapter.
-
-<!-- %%%% Chapter : CLIENT STREAMS %%%% -->
-<sect>Client Streams
-<sect1>Introduction
- <P>A clientStream is a uni-directional loosely coupled pipe. Each node
-consists of four methods - read, callback, detach, and status, along with the
-stream housekeeping variables (a dlink node and pointer to the head of
-the list), context data for the node, and read request parameters -
-readbuf, readlen and readoff (in the body).
-<P>clientStream is the basic unit for scheduling, and the clientStreamRead
-and clientStreamCallback calls allow for deferred scheduled activity if desired.
-<P>Theory on stream operation:
-<enum>
-<item>Something creates a pipeline. At a minimum it needs a head with a
-status method and a read method, and a tail with a callback method and a
-valid initial read request.
-<item>Other nodes may be added into the pipeline.
-<item>The tail-1th node's read method is called.
-<item>for each node going up the pipeline, the node either:
-<enum>
-<item>satisfies the read request, or
-<item>inserts a new node above it and calls clientStreamRead, or
-<item>calls clientStreamRead
-</enum>
-<P>There is no requirement for the Read parameters from different
-nodes to have any correspondence, as long as the callbacks provided are
-correct.
-<item>The first node that satisfies the read request MUST generate an
-httpReply to be passed down the pipeline. Body data MAY be provided.
-<item>On the first callback a node MAY insert further downstream nodes in
-the pipeline, but MAY NOT do so thereafter.
-<item>the callbacks progress down the pipeline until a node makes further
-reads instead of satisfying the callback (go to 4) or the end of the
-pipe line is reached, where a new read sequence may be scheduled.
-</enum>
-<sect1>Implementation notes
-<P>ClientStreams have been implemented for the client side reply logic,
-starting with either a client socket (tail of the list is
-clientSocketRecipient) or a custom handler for in-squid requests, and
-with the pipeline HEAD being clientGetMoreData, which uses
-clientSendMoreData to send data down the pipeline.
-<P>client POST bodies do not use a pipeline currently, they use the
-previous code to send the data. This is a TODO when time permits.
-
-<sect1>Whats in a node
-<P>Each node must have:
-<itemize>
-<item>read method - to allow loose coupling in the pipeline. (The reader may
-therefore change if the pipeline is altered, even mid-flow).
-<item>callback method - likewise.
-<item>status method - likewise.
-<item>detach method - used to ensure all resources are cleaned up properly.
-<item>dlink head pointer - to allow list inserts and deletes from within a
-node.
-<item>context data - to allow the called back nodes to maintain their
-private information.
-<item>read request parameters - For two reasons:
-<enum>
-<item>To allow a node to determine the requested data offset, length and
-target buffer dynamically. Again, this is to promote loose coupling.
-<item>Because of the callback nature of squid, every node would have to
-keep these parameters in their context anyway, so this reduces
-programmer overhead.
-</enum>
-</itemize>
-
-<sect1>Method details
-<P>The first parameter is always the 'this' reference for the client
-stream - a clientStreamNode *.
-<sect2>Read
-<P>Parameters:
-<itemize>
-<item>clientHttpRequest * - superset of request data, being winnowed down
-over time. MUST NOT be NULL.
-<item>offset, length, buffer - what, how much and where.
-</itemize>
-<P>Side effects:
-<P>Triggers a read of data that satisfies the httpClientRequest
-metainformation and (if appropriate) the offset,length and buffer
-parameters.
-<sect2>Callback
-<P>Parameters:
-<itemize>
-<item>clientHttpRequest * - superset of request data, being winnowed down
-over time. MUST NOT be NULL.
-<item>httpReply * - not NULL on the first call back only. Ownership is
-passed down the pipeline. Each node may alter the reply if appropriate.
-<item>buffer, length - where and how much.
-</itemize>
-<P>Side effects:
-<P>Return data to the next node in the stream. The data may be returned immediately,
-or may be delayed for a later scheduling cycle.
-<sect2>Detach
-<P>Parameters:
-<itemize>
-<item>clienthttpRequest * - MUST NOT be NULL.
-</itemize>
-<P>Side effects:
-<itemize>
-<item>Removes this node from a clientStream. The stream infrastructure handles
-the removal. This node MUST have cleaned up all context data, UNLESS scheduled
-callbacks will take care of that.
-<item>Informs the prev node in the list of this nodes detachment.
-</itemize>
-<sect2>Status
-<P>Parameters:
-<itemize>
-<item>clienthttpRequest * - MUST NOT be NULL.
-</itemize>
-<P>Side effects:
-<P>Allows nodes to query the upstream nodes for :
-<itemize>
-<item>stream ABORTS - request cancelled for some reason. upstream will not
-accept further reads().
-<item>stream COMPLETION - upstream has completed and will not accept further
-reads().
-<item>stream UNPLANNED COMPLETION - upstream has completed, but not at a
-pre-planned location (used for keepalive checking), and will not accept
-further reads().
-<item>stream NONE - no special status, further reads permitted.
-</itemize>
-
-<sect2>Abort
-<P>Parameters:
-<itemize>
-<item>clienthttpRequest * - MUST NOT be NULL.
-</itemize>
-<P>Side effects:
-<P>Detachs the tail of the stream. CURRENTLY DOES NOT clean up the tail node data -
-this must be done separately. Thus Abort may ONLY be called by the tail node.
-
-<!-- %%%% Chapter : CLIENT REQUEST PROCESSING %%%% -->
-<sect>Processing Client Requests
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : DELAY POOLS %%%% -->
-<sect>Delay Pools
-<sect1>Introduction
- <P>A DelayPool is a Composite used to manage bandwidth for any request
- assigned to the pool by an access expression. DelayId's are a used
- to manage the bandwith on a given request, whereas a DelayPool
- manages the bandwidth availability and assigned DelayId's.
-<sect1>Extending Delay Pools
-
- <P>A CompositePoolNode is the base type for all members of a DelayPool.
- Any child must implement the RefCounting primitives, as well as five
- delay pool functions:
- <enum>
- <item>stats() - provide cachemanager statistics for itself.
- <item>dump() - generate squid.conf syntax for the current configuration
- of the item.
- <item>update() - allocate more bandwith to all buckets in the item.
- <item>parse() - accept squid.conf syntax for the item, and configure
- for use appropriately.
- <item>id() - return a DelayId entry for the current item.
- </enum>
- <P>A DelayIdComposite is the base type for all delay Id's. Concrete
- Delay Id's must implement the refcounting primitives, as well as two
- delay id functions:
- <enum>
- <item>bytesWanted() - return the largest amount of bytes that this
- delay id allows by policy.
- <item>bytesIn() - record the use of bandwidth by the request(s) that
- this delayId is monitoring.
- </enum>
- <P> Composite creation is currently under design review, so see the
- DelayPool class and follow the parse() code path for details.
-
-<sect1>Neat things that could be done.
-
- <P>With the composite structure, some neat things have become possible.
- For instance:
- <enum>
- <item>Dynamically defined pool arrangements - for instance an
- aggregate (class 1) combined with the per-class-C-net tracking of a
- class 3 pool, without the individual host tracking. This differs
- from a class 3 pool with -1/-1 in the host bucket, because no memory
- or cpu would be used on hosts, whereas with a class 3 pool, they are
- allocated and used.
- <item>Per request bandwidth limits - a delayId that contains it's own
- bucket could limit each request independently to a given policy, with
- no aggregate restrictions.
- </enum>
-
-<!-- %%%% Chapter : STORAGE MANAGER %%%% -->
-<sect>Storage Manager
-
-<sect1>Introduction
-
- <P>
- The Storage Manager is the glue between client and server
- sides. Every object saved in the cache is allocated a
- <em/StoreEntry/ structure. While the object is being
- accessed, it also has a <em/MemObject/ structure.
-
- <P>
- Squid can quickly locate cached objects because it keeps
- (in memory) a hash table of all <em/StoreEntry/'s. The
- keys for the hash table are MD5 checksums of the objects
- URI. In addition there is also a storage policy such
- as LRU that keeps track of the objects and determines
- the removal order when space needs to be reclaimed.
- For the LRU policy this is implemented as a doubly linked
- list.
-
- <P>
- For each object the <em/StoreEntry/ maps to a cache_dir
- and location via sdirn and sfilen. For the "ufs" store
- this file number (sfilen) is converted to a disk pathname
- by a simple modulo of L2 and L1, but other storage drivers may
- map sfilen in other ways. A cache swap file consists
- of two parts: the cache metadata, and the object data.
- Note the object data includes the full HTTP reply---headers
- and body. The HTTP reply headers are not the same as the
- cache metadata.
-
- <P>
- Client-side requests register themselves with a <em/StoreEntry/
- to be notified when new data arrives. Multiple clients
- may receive data via a single <em/StoreEntry/. For POST
- and PUT request, this process works in reverse. Server-side
- functions are notified when additional data is read from
- the client.
-
-<sect1>Object storage
-
- <P>
- To be written...
-
-<sect1>Object retrieval
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : STORAGE INTERFACE %%%% -->
-<sect>Storage Interface
-
-<sect1>Introduction
-
- <P>
- Traditionally, Squid has always used the Unix filesystem (UFS)
- to store cache objects on disk. Over the years, the
- poor performance of UFS has become very obvious. In most
- cases, UFS limits Squid to about 30-50 requests per second.
- Our work indicates that the poor performance is mostly
- due to the synchronous nature of <tt/open()/ and <tt/unlink()/
- system calls, and perhaps thrashing of inode/buffer caches.
-
- <P>
- We want to try out our own, customized filesystems with Squid.
- In order to do that, we need a well-defined interface
- for the bits of Squid that access the permanent storage
- devices. We also require tighter control of the replacement
- policy by each storage module, rather than a single global
- replacement policy.
-
-<sect1>Build structure
-
- <P>
- The storage types live in squid/src/fs/ . Each subdirectory corresponds
- to the name of the storage type. When a new storage type is implemented
- configure.in must be updated to autogenerate a Makefile in
- squid/src/fs/$type/ from a Makefile.in file.
-
- <P>
- configure will take a list of storage types through the
- <em/--enable-store-io/ parameter. This parameter takes a list of
- space seperated storage types. For example,
- --enable-store-io="ufs coss" .
-
- <P>
- Each storage type must create an archive file
- <tt/in squid/src/fs/$type/.a . This file is automatically linked into
- squid at compile time.
-
- <P>
- Each storefs must export a function named <tt/storeFsSetup_$type()/.
- This function is called at runtime to initialise each storage type.
- The list of storage types is passed through <tt/store_modules.sh/
- to generate the initialisation function <tt/storeFsSetup()/. This
- function lives in <tt/store_modules.c/.
-
- <P>
- An example of the automatically generated file:
-
-<verb>
- /* automatically generated by ./store_modules.sh ufs coss
- * do not edit
- */
- #include "squid.h"
-
- extern STSETUP storeFsSetup_ufs;
- extern STSETUP storeFsSetup_coss;
- void storeFsSetup(void)
- {
- storeFsAdd("ufs", storeFsSetup_ufs);
- storeFsAdd("coss", storeFsSetup_coss);
- }
-</verb>
-
-
-<sect1>Initialization of a storage type
-
- <P>
- Each storage type initializes through the <tt/storeFsSetup_$type()/
- function. The <tt/storeFsSetup_$type()/ function takes a single
- argument - a <tt/storefs_entry_t/ pointer. This pointer references
- the storefs_entry to initialise. A typical setup function is as
- follows:
-
-<verb>
- void
- storeFsSetup_ufs(storefs_entry_t *storefs)
- {
- assert(!ufs_initialised);
- storefs->parsefunc = storeUfsDirParse;
- storefs->reconfigurefunc = storeUfsDirReconfigure;
- storefs->donefunc = storeUfsDirDone;
- ufs_state_pool = memPoolCreate("UFS IO State data", sizeof(ufsstate_t));
- ufs_initialised = 1;
- }
-</verb>
-
- <P>
- There are five function pointers in the storefs_entry which require
- initializing. In this example, some protection is made against the
- setup function being called twice, and a memory pool is initialised
- for use inside the storage module.
-
- <P>
- Each function will be covered below.
-
-
-<sect2>done
-
- <P>
-<verb>
- typedef void
- STFSSHUTDOWN(void);
-</verb>
-
- <P>
- This function is called whenever the storage system is to be shut down.
- It should take care of deallocating any resources currently allocated.
-
-
-<verb>
- typedef void STFSPARSE(SwapDir *SD, int index, char *path);
- typedef void STFSRECONFIGURE(SwapDir *SD, int index, char *path);
-</verb>
-
- <P>
- These functions handle configuring and reconfiguring a storage
- directory. Additional arguments from the cache_dir configuration
- line can be retrieved through calls to strtok() and GetInteger().
-
- <P>
- <em/STFSPARSE/ has the task of initialising a new swapdir. It should
- parse the remaining arguments on the cache_dir line, initialise the
- relevant function pointers and data structures, and choose the
- replacement policy. <em/STFSRECONFIGURE/ deals with reconfiguring an
- active swapdir. It should parse the remaining arguments on the
- cache_dir line and change any active configuration parameters. The
- actual storage initialisation is done through the <em/STINIT/ function
- pointer in the SwapDir.
-
- <P>
-<verb>
- struct _SwapDir {
- char *type; /* Pointer to the store dir type string */
- int cur_size; /* Current swapsize in kb */
- int low_size; /* ?? */
- int max_size; /* Maximum swapsize in kb */
- char *path; /* Path to store */
- int index; /* This entry's index into the swapDir array */
- int suggest; /* Suggestion for UFS style stores (??) */
- size_t max_objsize; /* Maximum object size for this store */
- union { /* Replacement policy-specific fields */
- #ifdef HEAP_REPLACEMENT
- struct {
- heap *heap;
- } heap;
- #endif
- struct {
- dlink_list list;
- dlink_node *walker;
- } lru;
- } repl;
- int removals;
- int scanned;
- struct {
- unsigned int selected:1; /* Currently selected for write */
- unsigned int read_only:1; /* This store is read only */
- } flags;
- STINIT *init; /* Initialise the fs */
- STNEWFS *newfs; /* Create a new fs */
- STDUMP *dump; /* Dump fs config snippet */
- STFREE *freefs; /* Free the fs data */
- STDBLCHECK *dblcheck; /* Double check the obj integrity */
- STSTATFS *statfs; /* Dump fs statistics */
- STMAINTAINFS *maintainfs; /* Replacement maintainence */
- STCHECKOBJ *checkob; /* Check if the fs will store an object, and get the FS load */
- /* These two are notifications */
- STREFOBJ *refobj; /* Reference this object */
- STUNREFOBJ *unrefobj; /* Unreference this object */
- STCALLBACK *callback; /* Handle pending callbacks */
- STSYNC *sync; /* Sync the directory */
- struct {
- STOBJCREATE *create; /* Create a new object */
- STOBJOPEN *open; /* Open an existing object */
- STOBJCLOSE *close; /* Close an open object */
- STOBJREAD *read; /* Read from an open object */
- STOBJWRITE *write; /* Write to a created object */
- STOBJUNLINK *unlink; /* Remove the given object */
- } obj;
- struct {
- STLOGOPEN *open; /* Open the log */
- STLOGCLOSE *close; /* Close the log */
- STLOGWRITE *write; /* Write to the log */
- struct {
- STLOGCLEANOPEN *open; /* Open a clean log */
- STLOGCLEANWRITE *write; /* Write to the log */
- void *state; /* Current state */
- } clean;
- } log;
- void *fsdata; /* FS-specific data */
- };
-</verb>
-
-
-
-<sect1>Operation of a storage module
-
- <P>
- Squid understands the concept of multiple diverse storage directories.
- Each storage directory provides a caching object store, with object
- storage, retrieval, indexing and replacement.
-
- <P>
- Each open object has associated with it a <em/storeIOState/ object. The
- <em/storeIOState/ object is used to record the state of the current
- object. Each <em/storeIOState/ can have a storage module specific data
- structure containing information private to the storage module.
-
- <P>
-<verb>
- struct _storeIOState {
- sdirno swap_dirn; /* SwapDir index */
- sfileno swap_filen; /* Unique file index number */
- StoreEntry *e; /* Pointer to parent StoreEntry */
- mode_t mode; /* Mode - O_RDONLY or O_WRONLY */
- size_t st_size; /* Size of the object if known */
- off_t offset; /* current _on-disk_ offset pointer */
- STFNCB *file_callback; /* called on delayed sfileno assignments */
- STIOCB *callback; /* IO Error handler callback */
- void *callback_data; /* IO Error handler callback data */
- struct {
- STRCB *callback; /* Read completion callback */
- void *callback_data; /* Read complation callback data */
- } read;
- struct {
- unsigned int closing:1; /* debugging aid */
- } flags;
- void *fsstate; /* pointer to private fs state */
- };
-</verb>
-
- <P>
- Each <em/SwapDir/ has the concept of a maximum object size. This is used
- as a basic hint to the storage layer in first choosing a suitable
- <em/SwapDir/. The checkobj function is then called for suitable
- candidate <em/SwapDirs/ to find out whether it wants to store a
- given <em/StoreEntry/. A <em/maxobjsize/ of -1 means 'any size'.
-
- <P>
- The specific filesystem operations listed in the SwapDir object are
- covered below.
-
-<sect2>initfs
-
- <P>
-<verb>
- typedef void
- STINIT(SwapDir *SD);
-</verb>
-
- <P>
- Initialise the given <em/SwapDir/. Operations such as verifying and
- rebuilding the storage and creating any needed bitmaps are done
- here.
-
-
-<sect2>newfs
-
- <P>
-<verb>
- typedef void
- STNEWFS(SwapDir *SD);
-</verb>
-
- <P>
- Called for each configured <em/SwapDir/ to perform filesystem
- initialisation. This happens when '-z' is given to squid on the
- command line.
-
-
-<sect2>dumpfs
-
- <P>
-<verb>
- typedef void
- STDUMP(StoreEntry *e, SwapDir *SD);
-</verb>
-
- <P>
- Dump the FS specific configuration data of the current <em/SwapDir/
- to the given <em/StoreEntry/. Used to grab a configuration file dump
- from th <em/cachemgr/ interface.
-
- Note: The printed options should start with a space character to
- separate them from the cache_dir path.
-
-<sect2>freefs
-
- <P>
-<verb>
- typedef void
- STFREE(SwapDir *SD);
-</verb>
-
- <P>
- Free the <em/SwapDir/ filesystem information. This routine should
- deallocate <em/SD->fsdata/.
-
-
-<sect2>doublecheckfs
-
- <P>
-<verb>
- typedef int
- STDBLCHECK(SwapDir *SD, StoreEntry *e);
-</verb>
-
- <P>
- Double-check the given object for validity. Called during rebuild if
- the '-S' flag is given to squid on the command line. Returns 1 if the
- object is indeed valid, and 0 if the object is found invalid.
-
-
-<sect2>statfs
-
- <P>
-<verb>
- typedef void
- STSTATFS(SwapDir *SD, StoreEntry *e);
-</verb>
-
- <P>
- Called to retrieve filesystem statistics, such as usage, load and
- errors. The information should be appended to the passed
- <em/StoreEntry/ e.
-
-
-<sect2>maintainfs
-
- <P>
-<verb>
- typedef void
- STMAINTAINFS(SwapDir *SD);
-</verb>
-
- <P>
- Called periodically to replace objects. The active replacement policy
- should be used to timeout unused objects in order to make room for
- new objects.
-
-<sect2>callback
-
- <P>
-<verb>
- typedef void
- STCALLBACK(SwapDir *SD);
-</verb>
-
- <P>
- This function is called inside the comm_select/comm_poll loop to handle
- any callbacks pending.
-
-
-<sect2>sync
-
- <P>
-<verb>
- typedef void
- STSYNC(SwapDir *SD);
-</verb>
-
- <P>
- This function is called whenever a sync to disk is required. This
- function should not return until all pending data has been flushed to
- disk.
-
-
-<sect2>parse/reconfigure
-
- <P>
-
-<sect2>checkobj
-
- <P>
-<verb>
- typedef int
- STCHECKOBJ(SwapDir *SD, const StoreEntry *e);
-</verb>
-
- <P>
- Called by <tt/storeDirSelectSwapDir()/ to determine whether the
- <em/SwapDir/ will store the given <em/StoreEntry/ object. If the
- <em/SwapDir/ is not willing to store the given <em/StoreEntry/
- -1 should be returned. Otherwise, a value between 0 and 1000 should
- be returned indicating the current IO load. A value of 1000 indicates
- the <em/SwapDir/ has an IO load of 100%. This is used by
- <tt/storeDirSelectSwapDir()/ to choose the <em/SwapDir/ with the
- lowest IO load.
-
-
-<sect2>referenceobj
-
- <P>
-<verb>
- typedef void
- STREFOBJ(SwapDir *SD, StoreEntry *e);
-</verb>
-
- <P>
- Called whenever an object is locked by <tt/storeLockObject()/.
- It is typically used to update the objects position in the replacement
- policy.
-
-
-<sect2>unreferenceobj
-
- <P>
-<verb>
- typedef void
- STUNREFOBJ(SwapDir *SD, StoreEntry *e);
-</verb>
-
- <P>
- Called whenever the object is unlocked by <tt/storeUnlockObject()/
- and the lock count reaches 0. It is also typically used to update the
- objects position in the replacement policy.
-
-
-<sect2>createobj
-
- <P>
-<verb>
- typedef storeIOState *
- STOBJCREATE(SwapDir *SD, StoreEntry *e, STFNCB *file_callback, STIOCB *io_callback, void *io_callback_data);
-</verb>
-
- <P>
- Create an object in the <em/SwapDir/ *SD. <em/file_callback/ is called
- whenever the filesystem allocates or reallocates the <em/swap_filen/.
- Note - <em/STFNCB/ is called with a generic cbdata pointer, which
- points to the <em/StoreEntry/ e. The <em/StoreEntry/ should not be
- modified EXCEPT for the replacement policy fields.
-
- <P>
- The IO callback should be called when an error occurs and when the
- object is closed. Once the IO callback is called, the <em/storeIOState/
- becomes invalid.
-
- <P>
- <em/STOBJCREATE/ returns a <em/storeIOState/ suitable for writing on
- sucess, or NULL if an error occurs.
-
-
-<sect2>openobj
-
- <P>
-<verb>
- typedef storeIOState *
- STOBJOPEN(SwapDir *SD, StoreEntry *e, STFNCB *file_callback, STIOCB *io_callback, void *io_callback_data);
-</verb>
-
- <P>
- Open the <em/StoreEntry/ in <em/SwapDir/ *SD for reading. Much the
- same is applicable from <em/STOBJCREATE/, the major difference being
- that the data passed to <em/file_callback/ is the relevant
- <em/store_client/ .
-
-
-<sect2>closeobj
-
- <P>
-<verb>
- typedef void
- STOBJCLOSE(SwapDir *SD, storeIOState *sio);
-</verb>
-
- <P>
- Close an opened object. The <em/STIOCB/ callback should be called at
- the end of this routine.
-
-
-<sect2>readobj
-
- <P>
-<verb>
- typedef void
- STOBJREAD(SwapDir *SD, storeIOState *sio, char *buf, size_t size, off_t offset, STRCB *read_callback, void *read_callback_data);
-</verb>
-
- <P>
- Read part of the object of into <em/buf/. It is safe to request a read
- when there are other pending reads or writes. <em/STRCB/ is called at
- completion.
-
- <P>
- If a read operation fails, the filesystem layer notifies the
- calling module by calling the <em/STIOCB/ callback with an
- error status code.
-
-
-<sect2>writeobj
-
- <P>
-<verb>
- typedef void
- STOBJWRITE(SwapDir *SD, storeIOState *sio, char *buf, size_t size, off_t offset, FREE *freefunc);
-</verb>
-
- <P>
- Write the given block of data to the given store object. <em/buf/ is
- allocated by the caller. When the write is complete, the data is freed
- through <em/free_func/.
-
- <P>
- If a write operation fails, the filesystem layer notifies the
- calling module by calling the <em/STIOCB/ callback with an
- error status code.
-
-
-<sect2>unlinkobj
-
- <P>
-<verb>
- typedef void STOBJUNLINK(SwapDir *, StoreEntry *);
-</verb>
-
- <P>
- Remove the <em/StoreEntry/ e from the <em/SwapDir/ SD and the
- replacement policy.
-
-
-
-<sect1>Store IO calls
-
- <P>
- These routines are used inside the storage manager to create and
- retrieve objects from a storage directory.
-
-<sect2>storeCreate()
-
- <P>
-<verb>
- storeIOState *
- storeCreate(StoreEntry *e, STIOCB *file_callback, STIOCB *close_callback, void * callback_data)
-</verb>
-
- <P>
- <tt/storeCreate/ is called to store the given <em/StoreEntry/ in
- a storage directory.
-
- <P>
- <tt/callback/ is a function that will be called either when
- an error is encountered, or when the object is closed (by
- calling <tt/storeClose()/). If the open request is
- successful, there is no callback. The calling module must
- assume the open request will succeed, and may begin reading
- or writing immediately.
-
- <P>
- <tt/storeCreate()/ may return NULL if the requested object
- can not be created. In this case the <tt/callback/ function
- will not be called.
-
-
-<sect2>storeOpen()
-
- <P>
-<verb>
- storeIOState *
- storeOpen(StoreEntry *e, STFNCB * file_callback, STIOCB * callback, void *callback_data)
-</verb>
-
- <P>
- <tt/storeOpen/ is called to open the given <em/StoreEntry/ from
- the storage directory it resides on.
-
- <P>
- <tt/callback/ is a function that will be called either when
- an error is encountered, or when the object is closed (by
- calling <tt/storeClose()/). If the open request is
- successful, there is no callback. The calling module must
- assume the open request will succeed, and may begin reading
- or writing immediately.
-
- <P>
- <tt/storeOpen()/ may return NULL if the requested object
- can not be openeed. In this case the <tt/callback/ function
- will not be called.
-
-
-<sect2>storeRead()
-
- <P>
-<verb>
- void
- storeRead(storeIOState *sio, char *buf, size_t size, off_t offset, STRCB *callback, void *callback_data)
-</verb>
-
- <P>
- <tt/storeRead()/ is more complicated than the other functions
- because it requires its own callback function to notify the
- caller when the requested data has actually been read.
- <em/buf/ must be a valid memory buffer of at least <em/size/
- bytes. <em/offset/ specifies the byte offset where the
- read should begin. Note that with the Swap Meta Headers
- prepended to each cache object, this offset does not equal
- the offset into the actual object data.
-
- <P>
- The caller is responsible for allocating and freeing <em/buf/ .
-
-
-<sect2>storeWrite()
-
- <P>
-<verb>
- void
- storeWrite(storeIOState *sio, char *buf, size_t size, off_t offset, FREE *free_func)
-</verb>
-
- <P>
- <tt/storeWrite()/ submits a request to write a block
- of data to the disk store.
- The caller is responsible for allocating <em/buf/, but since
- there is no per-write callback, this memory must be freed by
- the lower filesystem implementation. Therefore, the caller
- must specify the <em/free_func/ to be used to deallocate
- the memory.
-
- <P>
- If a write operation fails, the filesystem layer notifies the
- calling module by calling the <em/STIOCB/ callback with an
- error status code.
-
-
-<sect2>storeUnlink()
-
- <P>
-<verb>
- void
- storeUnlink(StoreEntry *e)
-</verb>
-
- <P>
- <tt/storeUnlink()/ removes the cached object from the disk
- store. There is no callback function, and the object
- does not need to be opened first. The filesystem
- layer will remove the object if it exists on the disk.
-
-
-<sect2>storeOffset()
-
- <P>
-<verb>
- off_t storeOffset(storeIOState *sio)
-</verb>
-
-
-
- <P>
- <tt/storeOffset()/ returns the current _ondisk_ offset. This is used to
- determine how much of an objects memory can be freed to make way for
- other in-transit and cached objects. You must make sure that the
- <em/storeIOState->offset/ refers to the ondisk offset, or undefined
- results will occur. For reads, this returns the current offset of
- successfully read data, not including queued reads.
-
-
-<sect1>Callbacks
-
-<sect2><em/STIOCB/ callback
-
- <P>
-<verb>
- void
- stiocb(void *data, int errorflag, storeIOState *sio)
-</verb>
-
- <P>
- The <em/stiocb/ function is passed as a parameter to
- <tt/storeOpen()/. The filesystem layer calls <em/stiocb/
- either when an I/O error occurs, or when the disk
- object is closed.
-
- <P>
- <em/errorflag/ is one of the following:
-<verb>
- #define DISK_OK (0)
- #define DISK_ERROR (-1)
- #define DISK_EOF (-2)
- #define DISK_NO_SPACE_LEFT (-6)
-</verb>
-
- <P>
- Once the The <em/stiocb/ function has been called,
- the <em/sio/ structure should not be accessed further.
-
-<sect2><em/STRCB/ callback
-
- <P>
-<verb>
- void
- strcb(void *data, const char *buf, size_t len)
-</verb>
-
- <P>
- The <em/strcb/ function is passed as a parameter to
- <tt/storeRead()/. The filesystem layer calls <em/strcb/
- after a block of data has been read from the disk and placed
- into <em/buf/. <em/len/ indicates how many bytes were
- placed into <em/buf/. The <em/strcb/ function is only
- called if the read operation is successful. If it fails,
- then the <em/STIOCB/ callback will be called instead.
-
-<sect1>State Logging
-
- <P>
- These functions deal with state
- logging and related tasks for a squid storage system.
- These functions are used (called) in <tt/store_dir.c/.
-
- <P>
- Each storage system must provide the functions described
- in this section, although it may be a no-op (null) function
- that does nothing. Each function is accessed through a
- function pointer stored in the <em/SwapDir/ structure:
-
-<verb>
- struct _SwapDir {
- ...
- STINIT *init;
- STNEWFS *newfs;
- struct {
- STLOGOPEN *open;
- STLOGCLOSE *close;
- STLOGWRITE *write;
- struct {
- STLOGCLEANOPEN *open;
- STLOGCLEANWRITE *write;
- void *state;
- } clean;
- } log;
- ....
- };
-</verb>
-
-<sect2><tt/log.open()/
-
- <P>
-<verb>
- void
- STLOGOPEN(SwapDir *);
-</verb>
-
- <P>
- The <tt/log.open/ function, of type <em/STLOGOPEN/,
- is used to open or initialize the state-holding log
- files (if any) for the storage system. For UFS this
- opens the <em/swap.state/ files.
-
- <P>
- The <tt/log.open/ function may be called any number of
- times during Squid's execution. For example, the
- process of rotating, or writing clean logfiles closes
- the state log and then re-opens them. A <em/squid -k reconfigure/
- does the same.
-
-<sect2><tt/log.close()/
-
- <P>
-<verb>
- void
- STLOGCLOSE(SwapDir *);
-</verb>
-
- <P>
- The <tt/log.close/ function, of type <em/STLOGCLOSE/, is
- obviously the counterpart to <tt/log.open/. It must close
- the open state-holding log files (if any) for the storage
- system.
-
-<sect2><tt/log.write()/
-
- <P>
-<verb>
- void
- STLOGWRITE(const SwapDir *, const StoreEntry *, int op);
-</verb>
-
- <P>
- The <tt/log.write/ function, of type <em/STLOGWRITE/, is
- used to write an entry to the state-holding log file. The
- <em/op/ argument is either <em/SWAP_LOG_ADD/ or <em/SWAP_LOG_DEL/.
- This feature may not be required by some storage systems
- and can be implemented as a null-function (no-op).
-
-<sect2><tt/log.clean.start()/
-
- <P>
-<verb>
- int
- STLOGCLEANSTART(SwapDir *);
-</verb>
-
- <P>
- The <tt/log.clean.start/ function, of type <em/STLOGCLEANSTART/,
- is used for the process of writing "clean" state-holding
- log files. The clean-writing procedure is initiated by
- the <em/squid -k rotate/ command. This is a special case
- because we want to optimize the process as much as possible.
- This might be a no-op for some storage systems that don't
- have the same logging issues as UFS.
-
- <P>
- The <em/log.clean.state/ pointer may be used to
- keep state information for the clean-writing process, but
- should not be accessed by upper layers.
-
-<sect2><tt/log.clean.nextentry()/
-
- <P>
-<verb>
- StoreEntry *
- STLOGCLEANNEXTENTRY(SwapDir *);
-</verb>
-
- <P>
- Gets the next entry that is a candidate for the clean log.
-
- <P>
- Returns NULL when there is no more objects to log
-
-<sect2><tt/log.clean.write()/
-
- <P>
-<verb>
- void
- STLOGCLEANWRITE(SwapDir *, const StoreEntry *);
-</verb>
-
- <P>
- The <tt/log.clean.write/ function, of type <em/STLOGCLEANWRITE/,
- writes an entry to the clean log file (if any).
-
-<sect2><tt/log.clean.done()/
-
- <P>
-<verb>
- void
- STLOGCLEANDONE(SwapDir *);
-</verb>
-
- <P>
- Indicates the end of the clean-writing process and signals
- the storage system to close the clean log, and rename or
- move them to become the official state-holding log ready
- to be opened.
-
-<sect1>Replacement policy implementation
-
-<P>
-The replacement policy can be updated during STOBJREAD/STOBJWRITE/STOBJOPEN/
-STOBJCLOSE as well as STREFOBJ and STUNREFOBJ. Care should be taken to
-only modify the relevant replacement policy entries in the StoreEntry.
-The responsibility of replacement policy maintainence has been moved into
-each SwapDir so that the storage code can have tight control of the
-replacement policy. Cyclic filesystems such as COSS require this tight
-coupling between the storage layer and the replacement policy.
-
-
-<sect1>Removal policy API
-
- <P>
- The removal policy is responsible for determining in which order
- objects are deleted when Squid needs to reclaim space for new objects.
- Such a policy is used by a object storage for maintaining the stored
- objects and determining what to remove to reclaim space for new objects.
- (together they implements a replacement policy)
-
-<sect2>API
- <P>
- It is implemented as a modular API where a storage directory or
- memory creates a policy of choice for maintaining it's objects,
- and modules registering to be used by this API.
-
-<sect3>createRemovalPolicy()
-
-<P>
-<verb>
- RemovalPolicy policy = createRemovalPolicy(cons char *type, cons char *args)
-</verb>
-
- <P>
- Creates a removal policy instance where object priority can be
- maintained
-
- <P>
- The returned RemovalPolicy instance is cbdata registered
-
-<sect3>policy.Free()
-
- <P>
-<verb>
- policy->Free(RemovalPolicy *policy)
-</verb>
-
-<P>
- Destroys the policy instance and frees all related memory.
-
-<sect3>policy.Add()
-
-<P>
-<verb>
- policy->Add(RemovalPolicy *policy, StoreEntry *, RemovalPolicyNode *node)
-</verb>
-
- <P>
- Adds a StoreEntry to the policy instance.
-
- <P>
- datap is a pointer to where policy specific data can be stored
- for the store entry, currently the size of one (void *) pointer.
-
-<sect3>policy.Remove()
-
-<P>
-<verb>
- policy->Remove(RemovalPolicy *policy, StoreEntry *, RemovalPolicyNode *node)
-</verb>
-
- <P>
- Removes a StoreEntry from the policy instance out of
- policy order. For example when an object is replaced
- by a newer one or is manually purged from the store.
-
- <P>
- datap is a pointer to where policy specific data is stored
- for the store entry, currently the size of one (void *) pointer.
-
-<sect3>policy.Referenced()
-
-<P>
-<verb>
- policy->Referenced(RemovalPolicy *policy, const StoreEntry *, RemovalPolicyNode *node)
-</verb>
-
- <P>
- Tells the policy that a StoreEntry is going to be referenced. Called
- whenever a entry gets locked.
-
- <P>
- node is a pointer to where policy specific data is stored
- for the store entry, currently the size of one (void *) pointer.
-
-<sect3>policy.Dereferenced()
-
-<P>
-<verb>
- policy->Dereferenced(RemovalPolicy *policy, const StoreEntry *, RemovalPolicyNode *node)
-</verb>
-
- <P>
- Tells the policy that a StoreEntry has been referenced. Called when
- an access to the entry has finished.
-
- <P>
- node is a pointer to where policy specific data is stored
- for the store entry, currently the size of one (void *) pointer.
-
-<sect3>policy.WalkInit()
-
-<P>
-<verb>
- RemovalPolicyWalker walker = policy->WalkInit(RemovalPolicy *policy)
-</verb>
-
- <P>
- Initiates a walk of all objects in the policy instance.
- The objects is returned in an order suitable for using
- as reinsertion order when rebuilding the policy.
-
- <P>
- The returned RemovalPolicyWalker instance is cbdata registered
-
- <P>
- Note: The walk must be performed as an atomic operation
- with no other policy actions intervening, or the outcome
- will be undefined.
-
-<sect3>walker.Next()
-
- <P>
-<verb>
- const StoreEntry *entry = walker->Next(RemovalPolicyWalker *walker)
-</verb>
-
-<P>
- Gets the next object in the walk chain
-
- <P>
- Return NULL when there is no further objects
-
-<sect3>walker.Done()
-
-<P>
-<verb>
- walker->Done(RemovalPolicyWalker *walker)
-</verb>
-
- <P>
- Finishes a walk of the maintained objects, destroys
- walker.
-
-<sect3>policy.PurgeInit()
-
-<P>
-<verb>
- RemovalPurgeWalker purgewalker = policy->PurgeInit(RemovalPolicy *policy, int max_scan)
-</verb>
-
- <P>
- Initiates a search for removal candidates. Search depth is indicated
- by max_scan.
-
- <P>
- The returned RemovalPurgeWalker instance is cbdata registered
-
- <P>
- Note: The walk must be performed as an atomic operation
- with no other policy actions intervening, or the outcome
- will be undefined.
-
-<sect3>purgewalker.Next()
-
-<P>
-<verb>
- StoreEntry *entry = purgewalker->Next(RemovalPurgeWalker *purgewalker)
-</verb>
-
- <P>
- Gets the next object to purge. The purgewalker will remove each
- returned object from the policy.
-
- <P>It is the polices responsibility to verify that the object
- isn't locked or otherwise prevented from being removed. What this
- means is that the policy must not return objects where
- storeEntryLocked() is true.
-
- <P>
- Return NULL when there is no further purgeable objects in the policy.
-
-<sect3>purgewalker.Done()
-
-<P>
-<verb>
- purgewalker->Done(RemovalPurgeWalker *purgewalker)
-</verb>
-
- <P>
- Finishes a walk of the maintained objects, destroys
- walker and restores the policy to it's normal state.
-
-<sect3>policy.Stats()
-
-<P>
-<verb>
- purgewalker->Stats(RemovalPurgeWalker *purgewalker, StoreEntry *entry)
-</verb>
-
- <P>
- Appends statistics about the policy to the given entry.
-
-<sect2>Source layout
-
-<P>
- Policy implementations resides in src/repl/<name>/, and a make in
- such a directory must result in a object archive src/repl/<name>.a
- containing all the objects implementing the policy.
-
-<sect2>Internal structures
-
-<sect3>RemovalPolicy
-
-<P>
-<verb>
- typedef struct _RemovalPolicy RemovalPolicy;
- struct _RemovalPolicy {
- char *_type;
- void *_data;
- void (*add)(RemovalPolicy *policy, StoreEntry *);
- ... /* see the API definition above */
- };
-</verb>
-
-<P>
- The _type member is mainly for debugging and diagnostics purposes, and
- should be a pointer to the name of the policy (same name as used for
- creation)
-
-<P>
- The _data member is for storing policy specific information.
-
-<sect3>RemovalPolicyWalker
-
-<P>
-<verb>
- typedef struct _RemovalPolicyWalker RemovalPolicyWalker;
- struct _RemovalPolicyWalker {
- RemovalPolicy *_policy;
- void *_data;
- StoreEntry *(*next)(RemovalPolicyWalker *);
- ... /* see the API definition above */
- };
-</verb>
-
-<sect3>RemovalPolicyNode
-
-<P>
-<verb>
- typedef struct _RemovalPolicyNode RemovalPolicyNode;
- struct _RemovalPolicyNode {
- void *data;
- };
-</verb>
-
- Stores policy specific information about a entry. Currently
- there is only space for a single pointer, but plans are to
- maybe later provide more space here to allow simple policies
- to store all their data "inline" to preserve some memory.
-
-<sect2>Policy registration
-
-<P>
- Policies are automatically registered in the Squid binary from the
- policy selection made by the user building Squid. In the future this
- might get extended to support loadable modules. All registered
- policies are available to object stores which wishes to use them.
-
-<sect2>Policy instance creation
-
-<P>
- Each policy must implement a "create/new" function "<tt/RemovalPolicy *
- createRemovalPolicy_<name>(char *arguments)/". This function
- creates the policy instance and populates it with at least the API
- methods supported. Currently all API calls are mandatory, but the
- policy implementation must make sure to NULL fill the structure prior
- to populating it in order to assure future API compability.
-
-<P>
- It should also populate the _data member with a pointer to policy
- specific data.
-
-<sect2>Walker
-
-<P>
- When a walker is created the policy populates it with at least the API
- methods supported. Currently all API calls are mandatory, but the
- policy implementation must make sure to NULL fill the structure prior
- to populating it in order to assure future API compatibility.
-
-<sect2>Design notes/bugs
-
-<P>
- The RemovalPolicyNode design is incomplete/insufficient. The intention
- was to abstract the location of the index pointers from the policy
- implementation to allow the policy to work on both on-disk and memory
- caches, but unfortunately the purge method for HEAP based policies
- needs to update this, and it is also preferable if the purge method
- in general knows how to clear the information. I think the agreement
- was that the current design of tightly coupling the two together
- on one StoreEntry is not the best design possible.
-
-<P>
- It is debated if the design in having the policy index control the
- clean index writes is the correct approach. Perhaps not. Perhaps a
- more appropriate design is probably to do the store indexing
- completely outside the policy implementation (i.e. using the hash
- index), and only ask the policy to dump it's state somehow.
-
-<P>
- The Referenced/Dereferenced() calls is today mapped to lock/unlock
- which is an approximation of when they are intended to be called.
- However, the real intention is to have Referenced() called whenever
- an object is referenced, and Dereferenced() only called when the
- object has actually been used for anything good.
-
-<!-- %%%% Chapter : FORWARDING SELECTION %%%% -->
-<sect>Forwarding Selection
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : IP/FQDN CACHE %%%% -->
-<sect>IP Cache and FQDN Cache
-
-<sect1> Introduction
-
- <P>
- The IP cache is a built-in component of squid providing
- Hostname to IP-Number translation functionality and managing
- the involved data-structures. Efficiency concerns require
- mechanisms that allow non-blocking access to these mappings.
- The IP cache usually doesn't block on a request except for
- special cases where this is desired (see below).
-
-<sect1> Data Structures
-
- <P>
- The data structure used for storing name-address mappings
- is a small hashtable (<em>static hash_table *ip_table</em>),
- where structures of type <em>ipcache_entry</em> whose most
- interesting members are:
-
-<verb>
- struct _ipcache_entry {
- char *name;
- time_t lastref;
- ipcache_addrs addrs;
- struct _ip_pending *pending_head;
- char *error_message;
- unsigned char locks;
- ipcache_status_t status:3;
- }
-</verb>
-
-
-<sect1> External overview
-
- <P>
- Main functionality
- is provided through calls to:
- <descrip>
-
- <tag>ipcache_nbgethostbyname(const char *name, IPH *handler,
- void *handlerdata)</tag>
- where <em/name/ is the name of the host to resolve,
- <em/handler/ is a pointer to the function to be called when
- the reply from the IP cache (or the DNS if the IP cache
- misses) and <em/handlerdata/ is information that is passed
- to the handler and does not affect the IP cache.
-
- <tag>ipcache_gethostbyname(const char *name,int flags)</tag>
- is different in that it only checks if an entry exists in
- it's data-structures and does not by default contact the
- DNS, unless this is requested, by setting the <em/flags/
- to <em/IP_BLOCKING_LOOKUP/ or <em/IP_LOOKUP_IF_MISS/.
-
- <tag>ipcache_init()</tag> is called from <em/mainInitialize()/
- after disk initialization and prior to the reverse fqdn
- cache initialization
-
- <tag>ipcache_restart()</tag> is called to clear the IP
- cache's data structures, cancel all pending requests.
- Currently, it is only called from <em/mainReconfigure/.
-
- </descrip>
-
-<sect1> Internal Operation
-
- <P>
- Internally, the execution flow is as follows: On a miss,
- <em/ipcache_getnbhostbyname/ checks whether a request for
- this name is already pending, and if positive, it creates
- a new entry using <em/ipcacheAddNew/ with the <em/IP_PENDING/
- flag set . Then it calls <em/ipcacheAddPending/ to add a
- request to the queue together with data and handler. Else,
- <em/ipcache_dnsDispatch()/ is called to directly create a
- DNS query or to <em/ipcacheEnqueue()/ if all no DNS port
- is free. <em/ipcache_call_pending()/ is called regularly
- to walk down the pending list and call handlers. LRU clean-up
- is performed through <em/ipcache_purgelru()/ according to
- the <em/ipcache_high/ threshold.
-
-<!-- %%%% Chapter : SERVER PROTOCOLS %%%% -->
-<sect>Server Protocols
-<sect1>HTTP
-
- <P>
- To be written...
-
-<sect1>FTP
-
- <P>
- To be written...
-
-<sect1>Gopher
-
- <P>
- To be written...
-
-<sect1>Wais
-
- <P>
- To be written...
-
-<sect1>SSL
-
- <P>
- To be written...
-
-<sect1>Passthrough
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : TIMEOUTS %%%% -->
-<sect>Timeouts
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : EVENTS %%%% -->
-<sect>Events
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : ACCESS CONTROLS %%%% -->
-<sect>Access Controls
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : Authentication Framework %%%% -->
-<sect>Authentication Framework
-
- <p>
- Squid's authentication system is responsible for reading
- authentication credentials from HTTP requests and deciding
- whether or not those credentials are valid. This functionality
- resides in two separate components: Authentication Schemes
- and Authentication Modules.
-
- <p>
- An Authentication Scheme describes how Squid gets the
- credentials (i.e. username, password) from user requests.
- Squid currently supports two authentication schemes: Basic
- and NTLM. Basic authentication uses the <em/WWW-Authenticate/
- HTTP header. The Authentication Scheme code is implemented
- inside Squid itself.
-
- <p>
- An Authentication Module takes the credentials received
- from a client's request and tells Squid if they are
- are valid. Authentication Modules are implemented
- externally from Squid, as child helper processes.
- Authentication Modules interface with various types
- authentication databases, such as LDAP, PAM, NCSA-style
- password files, and more.
-
-<sect1>Authentication Scheme API
-
-<sect2>Definition of an Authentication Scheme
-
- <P>An auth scheme in squid is the collection of functions required to
- manage the authentication process for a given HTTP authentication
- scheme. Existing auth schemes in squid are Basic and NTLM. Other HTTP
- schemes (see for example RFC 2617) have been published and could be
- implemented in squid. The term auth scheme and auth module are
- interchangeable. An auth module is not to be confused with an
- authentication helper, which is a scheme specific external program used
- by a specific scheme to perform data manipulation external to squid.
- Typically this involves comparing the browser submitted credentials with
- those in the organization's user directory.
-
- <P>Auth modules SHOULD NOT perform access control functions. Squid has
- advanced caching access control functionality already. Future work in
- squid will allow a auth scheme helper to return group information for a
- user, to allow Squid to more seamlessly implement access control.
-
- <sect2>Function typedefs
-
- <P>Each function related to the general case of HTTP authentication has
- a matching typedef. There are some additional function types used to
- register/initialize, deregister/shutdown and provide stats on auth
- modules:
-
- <descrip>
-
- <tag/typedef int AUTHSACTIVE();/
-
- <P>The Active function is used by squid to determine whether
- the auth module has successfully initialised itself with
- the current configuration.
-
- <tag/typedef int AUTHSCONFIGURED();/
-
- <P>The configured function is used to see if the auth module
- has been given valid parameters and is able to handle
- authentication requests if initialised. If configured
- returns 0 no other module functions except
- Shutdown/Dump/Parse/FreeConfig will be called by Squid.
-
- <tag/typedef void AUTHSSETUP(authscheme_entry_t *);/
-
- <P>functions of type AUTHSSETUP are used to register an
- auth module with squid. The registration function MUST be
- named "authSchemeSetup_SCHEME" where SCHEME is the auth_scheme
- as defined by RFC 2617. Only one auth scheme registered in
- squid can provide functionality for a given auth_scheme.
- (I.e. only one auth module can handle Basic, only one can
- handle Digest and so forth). The Setup function is responsible
- for registering the functions in the auth module into the
- passed authscheme_entry_t. The authscheme_entry_t will
- never be NULL. If it is NULL the auth module should log an
- error and do nothing. The other functions can have any
- desired name that does not collide with any statically
- linked function name within Squid. It is recommended to
- use names of the form "authe_SCHEME_FUNCTIONNAME" (for
- example authenticate_NTLM_Active is the Active() function
- for the NTLM auth module.
-
- <tag/typedef void AUTHSSHUTDOWN(void);/
-
- <P>Functions of type AUTHSSHUTDOWN are responsible for
- freeing any resources used by the auth modules. The shutdown
- function will be called before squid reconfigures, and
- before squid shuts down.
-
- <tag/typedef void AUTHSINIT(authScheme *);/
-
- <P>Functions of type AUTHSINIT are responsible for allocating
- any needed resources for the authentication module. AUTHSINIT
- functions are called after each configuration takes place
- before any new requests are made.
-
- <tag/typedef void AUTHSPARSE(authScheme *, int, char *);/
-
- <P>Functions of type AUTHSPARSE are responsible for parsing
- authentication parameters. The function currently needs a
- scheme scope data structure to store the configuration in.
- The passed scheme's scheme_data pointer should point to
- the local data structure. Future development will allow
- all authentication schemes direct access to their configuration
- data without a locally scope structure. The parse function
- is called by Squid's config file parser when a auth_param
- scheme_name entry is encountered.
-
- <tag/typedef void AUTHSFREECONFIG(authScheme *);/
-
- <P>Functions of type AUTHSFREECONFIG are called by squid
- when freeing configuration data. The auth scheme should
- free any memory allocated that is related to parse data
- structures. The scheme MAY take advantage of this call to
- remove scheme local configuration dependent data. (Ie cached
- user details that are only relevant to a config setting).
-
- <tag/typedef void AUTHSDUMP(StoreEntry *, const char *, authScheme *);/
-
- <P>Functions of type AUTHSDUMP are responsible for writing
- to the StoreEntry the configuration parameters that a user
- would put in a config file to recreate the running
- configuration.
-
- <tag/typedef void AUTHSSTATS(StoreEntry *);/
-
- <P>Functions of type AUTHSSTATS are called by the cachemgr
- to provide statistics on the authmodule. Current modules
- simply provide the statistics from the back end helpers
- (number of requests, state of the helpers), but more detailed
- statistics are possible - for example unique users seen or
- failed authentication requests. <P>The next set of functions
- work on the data structures used by the authentication
- schemes.
-
- <tag/typedef void AUTHSREQFREE(auth_user_request_t *);/
-
- <P>The AUTHSREQFREE function is called when a auth_user_request is being
- freed by the authentication framework, and scheme specific data was
- present. The function should free any scheme related data and MUST set
- the scheme_data pointer to NULL. Failure to unlink the scheme data will
- result in squid dying.
-
- <tag/typedef char *AUTHSUSERNAME(auth_user_t *);/
-
- <P>Squid does not make assumptions about where the username
- is stored. This function must return a pointer to a NULL
- terminated string to be used in logging the request. Return
- NULL if no username/usercode is known. The string should
- NOT be allocated each time this function is called.
-
- <tag/typedef int AUTHSAUTHED(auth_user_request_t *);/
-
- <P>The AUTHED function is used by squid to determine whether
- the auth scheme has successfully authenticated the user
- request. If timeouts on cached credentials have occurred
- or for any reason the credentials are not valid, return
- false.<P>The next set of functions perform the actual
- authentication. The functions are used by squid for both
- WWW- and Proxy- authentication. Therefore they MUST NOT
- assume the authentication will be based on the Proxy-*
- Headers.
-
- <tag/typedef void AUTHSAUTHUSER(auth_user_request_t *, request_t *, ConnStateData *, http_hdr_type);/
-
- <P>Functions of type AUTHSAUTHUSER are called when Squid
- has a request that needs authentication. If needed the auth
- scheme can alter the auth_user pointer (usually to point
- to a previous instance of the user whose name is discovered
- late in the auth process. For an example of this see the
- NTLM scheme). These functions are responsible for performing
- any in-squid routines for the authentication of the user.
- The auth_user_request struct that is passed around is only
- persistent for the current request. If the auth module
- requires access to the structure in the future it MUST lock
- it, and implement some method for identifying it in the
- future. For example the NTLM module implements a connection
- based authentication scheme, so the auth_user_request struct
- gets referenced from the ConnStateData.
-
- <tag/typedef void AUTHSDECODE(auth_user_request_t *, const char *);/
-
- <P>Functions of type AUTHSDECODE are responsible for decoding the passed
- authentication header, creating or linking to a auth_user struct and for
- storing any needed details to complete authentication in AUTHSAUTHUSER.
-
- <tag/typedef int AUTHSDIRECTION(auth_user_request_t *);/
-
- <P>Functions of type AUTHSDIRECTION are used by squid to determine what
- the next step in performing authentication for a given scheme is. The
- following are the return codes:
-
- <itemize>
- <item>-2 = error in the auth module. Cannot determine request direction.
- <item>-1 = the auth module needs to send data to an external helper.
- Squid will prepare for a callback on the request and call the
- AUTHSSTART function.
- <item>0 = the auth module has all the information it needs to
- perform the authentication and provide a succeed/fail result.
- <item>1 = the auth module needs to send a new challenge to the
- request originator. Squid will return the appropriate status code
- (401 or 407) and call the registered FixError function to allow the
- auth module to insert it's challenge.
- </itemize>
-
- <tag/typedef void AUTHSFIXERR(auth_user_request_t *, HttpReply *, http_hdr_type, request_t *);/
-
- <P>Functions of type AUTHSFIXERR are used by squid to add scheme
- specific challenges when returning a 401 or 407 error code. On requests
- where no authentication information was provided, all registered auth
- modules will have their AUTHSFIXERR function called. When the client
- makes a request with an authentication header, on subsequent calls only the matching
- AUTHSFIXERR function is called (and then only if the auth module
- indicated it had a new challenge to send the client). If no auth schemes
- match the request, the authentication credentials in the request are
- ignored - and all auth modules are called.
-
- <tag/typedef void AUTHSFREE(auth_user_t *);/
-
- <P>These functions are responsible for freeing scheme specific data from
- the passed auth_user_t structure. This should only be called by squid
- when there are no outstanding requests linked to the auth user. This includes
- removing the user from any scheme specific memory caches.
-
- <tag/typedef void AUTHSADDHEADER(auth_user_request_t *, HttpReply *, int);/
- <p>
-
- <tag/typedef void AUTHSADDTRAILER(auth_user_request_t *, HttpReply *, int);/
-
- <P>These functions are responsible for adding any authentication
- specific header(s) or trailer(s) OTHER THAN the WWW-Authenticate and
- Proxy-Authenticate headers to the passed HttpReply. The int indicates
- whether the request was an accelerated request or a proxied request. For
- example operation see the digest auth scheme. (Digest uses a
- Authentication-Info header.) This function is called whenever a
- auth_user_request exists in a request when the reply is constructed
- after the body is sent on chunked replies respectively.
-
- <tag/typedef void AUTHSONCLOSEC(ConnStateData *);/
-
- <P>This function type is called when a auth_user_request is
- linked into a ConnStateData struct, and the connection is closed. If any
- scheme specific activities related to the request or connection are in
- progress, this function MUST clear them.
-
- <tag/typedef void AUTHSSTART(auth_user_request_t * , RH * , void *);/
-
- <P>This function type is called when squid is ready to put the request
- on hold and wait for a callback from the auth module when the auth
- module has performed it's external activities.
-
- </descrip>
-
- <sect2>Data Structures
-
- <P>This is used to link auth_users into the username cache.
- Because some schemes may link in aliases to a user, the
- link is not part of the auth_user structure itself.
-
- <verb>
-struct _auth_user_hash_pointer {
- /* first two items must be same as hash_link */
- char *key;
- auth_user_hash_pointer *next;
- auth_user_t *auth_user;
- dlink_node link; /* other hash entries that point to the same auth_user */
-};
- </verb>
-
- <P>This is the main user related structure. It stores user-related data,
- and is persistent across requests. It can even persistent across
- multiple external authentications. One major benefit of preserving this
- structure is the cached ACL match results. This structure, is private to
- the authentication framework.
-
-<verb>
-struct _auth_user_t {
- /* extra fields for proxy_auth */
- /* this determines what scheme owns the user data. */
- auth_type_t auth_type;
- /* the index +1 in the authscheme_list to the authscheme entry */
- int auth_module;
- /* we only have one username associated with a given auth_user struct */
- auth_user_hash_pointer *usernamehash;
- /* we may have many proxy-authenticate strings that decode to the same user*/
- dlink_list proxy_auth_list;
- dlink_list proxy_match_cache;
- struct {
- unsigned int credentials_ok:2; /*0=unchecked,1=ok,2=failed*/
- } flags;
- long expiretime;
- /* IP addr this user authenticated from */
- struct IN_ADDR ipaddr;
- time_t ip_expiretime;
- /* how many references are outstanding to this instance*/
- size_t references;
- /* the auth scheme has it's own private data area */
- void *scheme_data;
- /* the auth_user_request structures that link to this. Yes it could be a splaytree
- * but how many requests will a single username have in parallel? */
- dlink_list requests;
-};
-</verb>
-
- <P>This is a short lived structure is the visible aspect of the
- authentication framework.
-
-<verb>
-struct _auth_user_request_t {
- /* this is the object passed around by client_side and acl functions */
- /* it has request specific data, and links to user specific data */
- /* the user */
- auth_user_t *auth_user;
- /* return a message on the 401/407 error pages */
- char *message;
- /* any scheme specific request related data */
- void *scheme_data;
- /* how many 'processes' are working on this data */
- size_t references;
-};
-</verb>
-
- <p>
- The authscheme_entry struct is used to store the runtime
- registered functions that make up an auth scheme. An auth
- scheme module MUST implement ALL functions except the
- following functions: oncloseconnection, AddHeader, AddTrailer..
- In the future more optional functions may be added to this
- data type.
-
-<verb>
-struct _authscheme_entry {
- char *typestr;
- AUTHSACTIVE *Active;
- AUTHSADDHEADER *AddHeader;
- AUTHSADDTRAILER *AddTrailer;
- AUTHSAUTHED *authenticated;
- AUTHSAUTHUSER *authAuthenticate;
- AUTHSDUMP *dump;
- AUTHSFIXERR *authFixHeader;
- AUTHSFREE *FreeUser;
- AUTHSFREECONFIG *freeconfig;
- AUTHSUSERNAME *authUserUsername;
- AUTHSONCLOSEC *oncloseconnection; /*optional*/
- AUTHSDECODE *decodeauth;
- AUTHSDIRECTION *getdirection;
- AUTHSPARSE *parse;
- AUTHSINIT *init;
- AUTHSREQFREE *requestFree;
- AUTHSSHUTDOWN *donefunc;
- AUTHSSTART *authStart;
- AUTHSSTATS *authStats;
-};
-</verb>
-
- <P>For information on the requirements for each of the
- functions, see the details under the typedefs above. For
- reference implementations, see the squid source code,
- /src/auth/basic for a request based stateless auth module,
- and /src/auth/ntlm for a connection based stateful auth
- module.
-
-<sect2>How to add a new Authentication Scheme
-
- <P>Copy the nearest existing auth scheme and modify to receive the
- appropriate scheme headers. Now step through the acl.c MatchAclProxyUser
- function's code path and see how the functions call down through
- authenticate.c to your scheme. Write a helper to provide you scheme with
- any backend existence it needs. Remember any blocking code must go in
- AUTHSSTART function(s) and _MUST_ use callbacks.
-
-<sect2>How to ``hook in'' new functions to the API
-
- <P>Start of by figuring the code path that will result in
- the function being called, and what data it will need. Then
- create a typedef for the function, add and entry to the
- authscheme_entry struct. Add a wrapper function to
- authenticate.c (or if appropriate cf_cache.c) that called
- the scheme specific function if it exists. Test it. Test
- it again. Now port to all the existing auth schemes, or at
- least add a setting of NULL for the function for each
- scheme.
-
-<sect1>Authentication Module Interface
-
-<sect2>Basic Authentication Modules
-
-<p>
-Basic authentication provides a username and password. These
-are written to the authentication module processes on a single
-line, separated by a space:
-<verb>
-<USERNAME> <PASSWORD>
-</verb>
-<p>
-The authentication module process reads username, password pairs
-on stdin and returns either ``OK'' or ``ERR'' on stdout for
-each input line.
-
-<p>
-The following simple perl script demonstrates how the
-authentication module works. This script allows any
-user named ``Dirk'' (without checking the password)
-and allows any user that uses the password ``Sekrit'':
-
-<verb>
-#!/usr/bin/perl -w
-$|=1; # no buffering, important!
-while (<>) {
- chop;
- ($u,$p) = split;
- $ans = &check($u,$p);
- print "$ans\n";
-}
-
-sub check {
- local($u,$p) = @_;
- return 'ERR' unless (defined $p && defined $u);
- return 'OK' if ('Dirk' eq $u);
- return 'OK' if ('Sekrit' eq $p);
- return 'ERR';
-}
-</verb>
-
-<!-- %%%% Chapter : ICP %%%% -->
-<sect>ICP
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : NETDB %%%% -->
-<sect>Network Measurement Database
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : Error Pages %%%% -->
-<sect>Error Pages
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : Callback Data Allocator %%%% -->
-<sect>Callback Data Allocator
-
- <P>
- Squid's extensive use of callback functions makes it very
- susceptible to memory access errors. To address this all callback
- functions make use of a construct called "cbdata". This allows
- functions doing callbacks to verify that the caller is still
- valid before making the callback.
-
- <P>
- Note: cbdata is intended for callback data and is tailored specifically
- to make callbacks less dangerous leaving as few windows of errors as
- possible. It is not suitable or intended as a generic referencecounted
- memory allocator.
-
-<sect1>API
-
-<sect2>CBDATA_TYPE
-
- <P>
-<verb>
- CBDATA_TYPE(datatype);
-</verb>
-
- <P>
- Macro that defines a new cbdata datatype. Similar to a variable
- or struct definition. Scope is always local to the file/block
- where it is defined and all calls to cbdataAlloc for this type
- must be within the same scope as the CBDATA_TYPE declaration.
- Allocated entries may be referenced or freed anywhere with no
- restrictions on scope.
-
-<sect2>CBDATA_GLOBAL_TYPE
-
- <P>
-<verb>
- /* Module header file */
- external CBDATA_GLOBAL_TYPE(datatype);
-
- /* Module main C file */
- CBDATA_GLOBAL_TYPE(datatype);
-</verb>
-
- <P>
- Defines a global cbdata type that can be referenced anywhere in
- the code.
-
-<sect2>CBDATA_INIT_TYPE
-
- <P>
-<verb>
- CBDATA_INIT_TYPE(datatype);
- /* or */
- CBDATA_INIT_TYPE_FREECB(datatype, FREE *freehandler);
-</verb>
-
- <P>
- Initializes the cbdatatype. Must be called prior to the first use of
- cbdataAlloc() for the type.
-
- <P>
- The freehandler is called when the last known reference to a
- allocated entry goes away.
-
-<sect2>cbdataAlloc
-
- <P>
-<verb>
- pointer = cbdataAlloc(datatype);
-</verb>
-
- <P>
- Allocates a new entry of a registered cbdata type.
-
-<sect2>cbdataFree
-
- <P>
-<verb>
- cbdataFree(pointer);
-</verb>
-
- <P>
- Frees a entry allocated by cbdataAlloc().
-
- <P>
- Note: If there are active references to the entry then the entry
- will be freed with the last reference is removed. However,
- cbdataReferenceValid() will return false for those references.
-
-<sect2>cbdataReference
-
- <P>
-<verb>
- reference = cbdataReference(pointer);
-</verb>
-
- <P>
- Creates a new reference to a cbdata entry. Used when you need to
- store a reference in another structure. The reference can later
- be verified for validity by cbdataReferenceValid().
-
- <P>
- Note: The reference variable is a pointer to the entry, in all
- aspects identical to the original pointer. But semantically it
- is quite different. It is best if the reference is thought of
- and handled as a "void *".
-
-<sect2>cbdataReferenceDone
-
- <P>
-<verb>
- cbdataReferenceDone(reference);
-</verb>
-
- <P>
- Removes a reference created by cbdataReference().
-
- <P>
- Note: The reference variable will be automatically cleared to NULL.
-
-<sect2>cbdataReferenceValid
-
- <P>
-<verb>
- if (cbdataReferenceValid(reference)) {
- ...
- }
-</verb>
-
- <P>
- cbdataReferenceValid() returns false if a reference is stale (refers to a
- entry freed by cbdataFree).
-
-<sect2>cbdataReferenceValidDone
-
- <P>
-<verb>
- void *pointer;
- bool cbdataReferenceValidDone(reference, &pointer);
-</verb>
-
- <P>
- Removes a reference created by cbdataReference() and checks
- it for validity. A temporary pointer to the referenced data
- (if valid) is returned in the &pointer argument.
-
- <P>
- Meant to be used on the last dereference, usually to make
- a callback.
-
-<verb>
- void *cbdata;
- ...
- if (cbdataReferenceValidDone(reference, &cbdata)) != NULL)
- callback(..., cbdata);
-</verb>
-
- <P>
- Note: The reference variable will be automatically cleared to NULL.
-
-<sect1>Examples
-
- <P>
- Here you can find some examples on how to use cbdata, and why
-
-<sect2>Asynchronous operation without cbdata, showing why cbdata is needed
-
- <P>
- For a asyncronous operation with callback functions, the normal
- sequence of events in programs NOT using cbdata is as follows:
-<verb>
- /* initialization */
- type_of_data our_data;
- ...
- our_data = malloc(...);
- ...
- /* Initiate a asyncronous operation, with our_data as callback_data */
- fooOperationStart(bar, callback_func, our_data);
- ...
- /* The asyncronous operation completes and makes the callback */
- callback_func(callback_data, ....);
- /* Some time later we clean up our data */
- free(our_data);
-</verb>
- However, things become more interesting if we want or need
- to free the callback_data, or otherwise cancel the callback,
- before the operation completes. In constructs like this you
- can quite easily end up with having the memory referenced
- pointed to by callback_data freed before the callback is invoked
- causing a program failure or memory corruption:
-<verb>
- /* initialization */
- type_of_data our_data;
- ...
- our_data = malloc(...);
- ...
- /* Initiate a asyncronous operation, with our_data as callback_data */
- fooOperationStart(bar, callback_func, our_data);
- ...
- /* ouch, something bad happened elsewhere.. try to cleanup
- * but the programmer forgot there is a callback pending from
- * fooOperationsStart() (an easy thing to forget when writing code
- * to deal with errors, especially if there may be many different
- * pending operation)
- */
- free(our_data);
- ...
- /* The asyncronous operation completes and makes the callback */
- callback_func(callback_data, ....);
- /* CRASH, the memory pointer to by callback_data is no longer valid
- * at the time of the callback
- */
-</verb>
-<sect2>Asyncronous operation with cbdata
-
- <P>
- The callback data allocator lets us do this in a uniform and
- safe manner. The callback data allocator is used to allocate,
- track and free memory pool objects used during callback
- operations. Allocated memory is locked while the asyncronous
- operation executes elsewhere, and is freed when the operation
- completes. The normal sequence of events is:
-<verb>
- /* initialization */
- type_of_data our_data;
- ...
- our_data = cbdataAlloc(type_of_data);
- ...
- /* Initiate a asyncronous operation, with our_data as callback_data */
- fooOperationStart(..., callback_func, our_data);
- ...
- /* foo */
- void *local_pointer = cbdataReference(callback_data);
- ....
- /* The asyncronous operation completes and makes the callback */
- void *cbdata;
- if (cbdataReferenceValidDone(local_pointer, &cbdata))
- callback_func(...., cbdata);
- ...
- cbdataFree(our_data);
-
-</verb>
-
-<sect2>Asynchronous operation cancelled by cbdata
-
- <P>
- With this scheme, nothing bad happens if <tt/cbdataFree/ gets called
- before fooOperantionComplete(...).
-<verb>
- /* initialization */
- type_of_data our_data;
- ...
- our_data = cbdataAlloc(type_of_data);
- ...
- /* Initiate a asyncronous operation, with our_data as callback_data */
- fooOperationStart(..., callback_func, our_data);
- ...
- /* foo */
- void *local_pointer = cbdataReference(callback_data);
- ....
- /* something bad happened elsewhere.. cleanup */
- cbdataFree(our_data);
- ...
- /* The asyncronous operation completes and tries to make the callback */
- void *cbdata;
- if (cbdataReferenceValidDone(local_pointer, &cbdata))
- /* won't be called, as the data is no longer valid */
- callback_func(...., cbdata);
-
-</verb>
- In this case, when <tt/cbdataFree/ is called before
- <tt/cbdataReferenceValidDone/, the callback_data gets marked as invalid.
- When the callback_data is invalid before executing the callback
- function, <tt/cbdataReferenceValidDone/ will return 0 and
- callback_func is never executed.
-
-<sect2>Adding a new cbdata registered type
-
- <P>
- To add new module specific data types to the allocator one uses the
- macros CBDATA_TYPE and CBDATA_INIT_TYPE. These creates a local cbdata
- definition (file or block scope). Any cbdataAlloc calls must be made
- within this scope. However, cbdataFree might be called from anywhere.
-
-<verb>
- /* First the cbdata type needs to be defined in the module. This
- * is usually done at file scope, but it can also be local to a
- * function or block..
- */
- CBDATA_TYPE(type_of_data);
-
- /* Then in the code somewhere before the first allocation
- * (can be called multiple times with only a minimal overhead)
- */
- CBDATA_INIT_TYPE(type_of_data);
- /* Or if a free function is associated with the data type. This
- * function is responsible for cleaning up any dependencies etc
- * referenced by the structure and is called on cbdataFree or
- * when the last reference is deleted by cbdataReferenceDone /
- * cbdataReferenceValidDone
- */
- CBDATA_INIT_TYPE_FREECB(type_of_data, free_function);
-</verb>
-
-<sect2>Adding a new cbdata registered data type globally
-
- <P>
- To add new global data types that can be allocated from anywhere
- within the code one have to add them to the cbdata_type enum in
- enums.h, and a corresponding CREATE_CBDATA call in
- cbdata.c:cbdataInit(). Or alternatively add a CBDATA_GLOBAL_TYPE
- definition to globals.h as shown below and use CBDATA_INIT_TYPE at
- the appropriate location(s) as described above.
-
-<verb>
- extern CBDATA_GLOBAL_TYPE(type_of_data); /* CBDATA_UNDEF */
-</verb>
-
-<!-- %%%% Chapter : Reference Counting Data Allocator %%%% -->
-<sect>Refcount Data Allocator (C++ Only)
-
- <P>
- Manual reference counting such as cbdata uses is error prone,
- and time consuming for the programmer. C++'s operator overloading
- allows us to create automatic reference counting pointers, that will
- free objects when they are no longer needed. With some care these
- objects can be passed to functions needed Callback Data pointers.
-
-<sect1> API
-
- <P>
- There are two classes involved in the automatic refcouting - a
- <em/RefCountable/ class that provides the mechanics for reference
- counting a given derived class. And a 'RefCount' class that is the
- smart pointer, and handles const correctness, and tells the RefCountable
- class of references and dereferences.
-
-<sect2> RefCountable
-
- <P>
- The RefCountable base class defines one abstract function -
- <tt/deleteSelf()/. You must implement deleteSelf for each concrete
- class and. deleteSelf() is a workaround for 'operator delete' not
- being virtual. delete Self typically looks like:
-<verb>
- void deleteSelf() const {delete this;}
-</verb>
-
-<sect2> RefCount
-
- <P>
- The RefCount template class replaces pointers as parameters and
- variables of the class being reference counted. Typically one creates
- a typedef to aid users.
-<verb>
- class MyConcrete : public RefCountable {
- public:
- typedef RefCount<MyConcrete> Pointer;
- void deleteSelf() const {delete this;}
- };
-</verb>
- Now, one can pass objects of MyConcrete::Pointer around.
-
-<sect2> CBDATA
-
- <P>
- To make a refcounting CBDATA class, you need to overload new and delete,
- include a macro in your class definition, and ensure that some everyone
- who would call you directly (not as a cbdata callback, but as a normal
- use), holds a RefCount<> smart pointer to you.
-<verb>
- class MyConcrete : public RefCountable {
- public:
- typedef RefCount<MyConcrete> Pointer;
- void * operator new(size_t);
- void operator delete (void *);
- void deleteSelf() const {delete this;}
- private:
- CBDATA_CLASS(MyConcrete);
- };
-
- ...
- /* In your .cc file */
- CBDATA_CLASS_INIT(MyConcrete);
-
- void *
- MyConcrete::operator new (size_t)
- {
- CBDATA_INIT_TYPE(MyConcrete);
- MyConcrete *result = cbdataAlloc(MyConcrete);
- /* Mark result as being owned - we want the refcounter to do the
- * delete call
- */
- cbdataReference(result);
- return result;
- }
-
- void
- MyConcrete::operator delete (void *address)
- {
- MyConcrete *t = static_cast<MyConcrete *>(address);
- cbdataFree(address);
- /* And allow the memory to be freed */
- cbdataReferenceDone (t);
- }
-</verb>
-
- When no RefCount<MyConcrete> smart pointers exist, the objects
- delete method will be called. This will run the object destructor,
- freeing any foreign resources it hold. Then cbdataFree
- will be called, marking the object as invalid for all the cbdata
- functions that it may have queued. When they all return, the actual
- memory will be returned to the pool.
-
-<sect2> Using the Refcounter
-
- <P>
- Allocation and deallocation of refcounted objects (including those of
- the RefCount template class) must be done via new() and delete(). If a
- class that will hold an instance of a RefCount <foo> variable
- does not use delete(), you must assign NULL to the variable before
- it is freed. Failure to do this will result in memory leaks. You HAVE
- been warned.
-
- <P>
- Never call delete or deleteSelf on a RefCountable object. You will
- create a large number of dangling references and squid will segfault
- eventually.
-
- <P>
- Always create at least one RefCount smart pointer, so that the
- reference counting mechanism will delete the object when it's not
- needed.
-
- <P>
- Do not pass RefCount smart pointers outside the squid memory space.
- They will invariably segfault when copied.
-
- <P>
- If, in a method, all other smart pointer holding objects may be deleted
- or may set their smart pointers to NULL, then you will be deleted
- partway through the method (and thus crash). To prevent this, assign
- a smart pointer to yourself:
-<verb>
- void
- MyConcrete::aMethod(){
- /* This holds a reference to us */
- Pointer aPointer(this);
- /* This is a method that may mean we don't need to exist anymore */
- someObject->someMethod();
- /* This prevents aPointer being optimised away before this point,
- * and must be the last line in our method
- */
- aPointer = NULL;
- }
-</verb>
-
- <P>
- Calling methods via smart pointers is easy just dereference via ->
-<verb>
- void
- SomeObject::someFunction() {
- myConcretePointer->someOtherMethod();
- }
-</verb>
-
- <P>
- When passing RefCount smart pointers, always pass them as their
- native type, never as '*' or as '&'.
-
-<!-- %%%% Chapter : CACHE MANAGER %%%% -->
-<sect>Cache Manager
-
- <P>
- To be written...
-
-<!-- %%%% Chapter : HTTP Headers %%%% -->
-<sect>HTTP Headers
-
- <P>
- <em/Files:/
- <tt/HttpHeader.c/,
- <tt/HttpHeaderTools.c/,
- <tt/HttpHdrCc.c/,
- <tt/HttpHdrContRange.c/,
- <tt/HttpHdrExtField.c/,
- <tt/HttpHdrRange.c/
-
-
- <P>
- <tt/HttpHeader/ class encapsulates methods and data for HTTP header
- manipulation. <tt/HttpHeader/ can be viewed as a collection of HTTP
- header-fields with such common operations as add, delete, and find.
- Compared to an ascii "string" representation, <tt/HttpHeader/ performs
- those operations without rebuilding the underlying structures from
- scratch or searching through the entire "string".
-
-<sect1>General remarks
-
- <P>
- <tt/HttpHeader/ is a collection (or array) of HTTP header-fields. A header
- field is represented by an <tt/HttpHeaderEntry/ object. <tt/HttpHeaderEntry/ is
- an (id, name, value) triplet. Meaningful "Id"s are defined for
- "well-known" header-fields like "Connection" or "Content-Length".
- When Squid fails to recognize a field, it uses special "id",
- <em/HDR_OTHER/. Ids are formed by capitalizing the corresponding HTTP
- header-field name and replacing dashes ('-') with underscores ('_').
-
- <P>
- Most operations on <tt/HttpHeader/ require a "known" id as a parameter. The
- rationale behind the later restriction is that Squid programmer should
- operate on "known" fields only. If a new field is being added to
- header processing, it must be given an id.
-
-<sect1>Life cycle
-
- <P>
- <tt/HttpHeader/ follows a common pattern for object initialization and
- cleaning:
-
-<verb>
- /* declare */
- HttpHeader hdr;
-
- /* initialize (as an HTTP Request header) */
- httpHeaderInit(&hdr, hoRequest);
-
- /* do something */
- ...
-
- /* cleanup */
- httpHeaderClean(&hdr);
-</verb>
-
- <P>
- Prior to use, an <tt/HttpHeader/ must be initialized. A
- programmer must specify if a header belongs to a request
- or reply message. The "ownership" information is used mostly
- for statistical purposes.
-
- <P>
- Once initialized, the <tt/HttpHeader/ object <em/must/ be,
- eventually, cleaned. Failure to do so will result in a
- memory leak.
-
- <P>
- Note that there are no methods for "creating" or "destroying"
- a "dynamic" <tt/HttpHeader/ object. Looks like headers are
- always stored as a part of another object or as a temporary
- variable. Thus, dynamic allocation of headers is not needed.
-
-
-<sect1>Header Manipulation
-
- <P>
- The mostly common operations on HTTP headers are testing
- for a particular header-field (<tt/httpHeaderHas()/),
- extracting field-values (<tt/httpHeaderGet*()/), and adding
- new fields (<tt/httpHeaderPut*()/).
-
- <P>
- <tt/httpHeaderHas(hdr, id)/ returns true if at least one
- header-field specified by "id" is present in the header.
- Note that using <em/HDR_OTHER/ as an id is prohibited.
- There is usually no reason to know if there are "other"
- header-fields in a header.
-
- <P>
- <tt/httpHeaderGet<Type>(hdr, id)/ returns the value
- of the specified header-field. The "Type" must match
- header-field type. If a header is not present a "null"
- value is returned. "Null" values depend on field-type, of
- course.
-
- <P>
- Special care must be taken when several header-fields with
- the same id are preset in the header. If HTTP protocol
- allows only one copy of the specified field per header
- (e.g. "Content-Length"), <tt/httpHeaderGet<Type>()/
- will return one of the field-values (chosen semi-randomly).
- If HTTP protocol allows for several values (e.g. "Accept"),
- a "String List" will be returned.
-
- <P>
- It is prohibited to ask for a List of values when only one
- value is permitted, and visa-versa. This restriction prevents
- a programmer from processing one value of an header-field
- while ignoring other valid values.
-
- <P>
- <tt/httpHeaderPut<Type>(hdr, id, value)/ will add an
- header-field with a specified field-name (based on "id")
- and field_value. The location of the newly added field in
- the header array is undefined, but it is guaranteed to be
- after all fields with the same "id" if any. Note that old
- header-fields with the same id (if any) are not altered in
- any way.
-
- <P>
- The value being put using one of the <tt/httpHeaderPut()/
- methods is converted to and stored as a String object.
-
- <P>
- Example:
-
-<verb>
- /* add our own Age field if none was added before */
- int age = ...
- if (!httpHeaderHas(hdr, HDR_AGE))
- httpHeaderPutInt(hdr, HDR_AGE, age);
-</verb>
-
- <P>
- There are two ways to delete a field from a header. To
- delete a "known" field (a field with "id" other than
- <em/HDR_OTHER/), use <tt/httpHeaderDelById()/ function.
- Sometimes, it is convenient to delete all fields with a
- given name ("known" or not) using <tt/httpHeaderDelByName()/
- method. Both methods will delete <em/all/ fields specified.
-
- <P>
- The <em/httpHeaderGetEntry(hdr, pos)/ function can be used
- for iterating through all fields in a given header. Iteration
- is controlled by the <em/pos/ parameter. Thus, several
- concurrent iterations over one <em/hdr/ are possible. It
- is also safe to delete/add fields from/to <em/hdr/ while
- iteration is in progress.
-
-<verb>
- /* delete all fields with a given name */
- HttpHeaderPos pos = HttpHeaderInitPos;
- HttpHeaderEntry *e;
- while ((e = httpHeaderGetEntry(hdr, &pos))) {
- if (!strCaseCmp(e->name, name))
- ... /* delete entry */
- }
-</verb>
-
- Note that <em/httpHeaderGetEntry()/ is a low level function
- and must not be used if high level alternatives are available.
- For example, to delete an entry with a given name, use the
- <em/httpHeaderDelByName()/ function rather than the loop
- above.
-
-<sect1>I/O and Headers
-
- <P>
- To store a header in a file or socket, pack it using
- <tt/httpHeaderPackInto()/ method and a corresponding
- "Packer". Note that <tt/httpHeaderPackInto/ will pack only
- header-fields; request-lines and status-lines are not
- prepended, and CRLF is not appended. Remember that neither
- of them is a part of HTTP message header as defined by the
- HTTP protocol.
-
-
-<sect1>Adding new header-field ids
-
- <P>
- Adding new ids is simple. First add new HDR_ entry to the
- http_hdr_type enumeration in enums.h. Then describe a new
- header-field attributes in the HeadersAttrs array located
- in <tt/HttpHeader.c/. The last attribute specifies field
- type. Five types are supported: integer (<em/ftInt/), string
- (<em/ftStr/), date in RFC 1123 format (<em/ftDate_1123/),
- cache control field (<em/ftPCc/), range field (<em/ftPRange/),
- and content range field (<em/ftPContRange/). Squid uses
- type information to convert internal binary representation
- of fields to their string representation (<tt/httpHeaderPut/
- functions) and visa-versa (<tt/httpHeaderGet/ functions).
-
- <P>
- Finally, add new id to one of the following arrays:
- <em/GeneralHeadersArr/, <em/EntityHeadersArr/,
- <em/ReplyHeadersArr/, <em/RequestHeadersArr/. Use HTTP
- specs to determine the applicable array. If your header-field
- is an "extension-header", its place is in <em/ReplyHeadersArr/
- and/or in <em/RequestHeadersArr/. You can also use
- <em/EntityHeadersArr/ for "extension-header"s that can be
- used both in replies and requests. Header fields other
- than "extension-header"s must go to one and only one of
- the arrays mentioned above.
-
- <P>
- Also, if the new field is a "list" header, add it to the
- <em/ListHeadersArr/ array. A "list" field-header is the
- one that is defined (or can be defined) using "#" BNF
- construct described in the HTTP specs. Essentially, a field
- that may have more than one valid field-value in a single
- header is a "list" field.
-
- <P>
- In most cases, if you forget to include a new field id in
- one of the required arrays, you will get a run-time assertion.
- For rarely used fields, however, it may take a long time
- for an assertion to be triggered.
-
- <P>
- There is virtually no limit on the number of fields supported
- by Squid. If current mask sizes cannot fit all the ids (you
- will get an assertion if that happens), simply enlarge
- HttpHeaderMask type in <tt/typedefs.h/.
-
-
-<sect1>A Word on Efficiency
-
- <P>
- <tt/httpHeaderHas()/ is a very cheap (fast) operation
- implemented using a bit mask lookup.
-
- <P>
- Adding new fields is somewhat expensive if they require
- complex conversions to a string.
-
- <P>
- Deleting existing fields requires scan of all the entries
- and comparing their "id"s (faster) or "names" (slower) with
- the one specified for deletion.
-
- <P>
- Most of the operations are faster than their "ascii string"
- equivalents.
-
-<sect>File Formats
-
-<sect1><em/swap.state/
-
-<P>
-NOTE: this information is current as of version 2.2.STABLE4.
-
-<P>
-A <em/swap.state/ entry is defined by the <em/storeSwapLogData/
-structure, and has the following elements:
-<verb>
-struct _storeSwapLogData {
- char op;
- int swap_file_number;
- time_t timestamp;
- time_t lastref;
- time_t expires;
- time_t lastmod;
- size_t swap_file_sz;
- u_short refcount;
- u_short flags;
- unsigned char key[MD5_DIGEST_CHARS];
-};
-</verb>
-
-<descrip>
-<tag/op/
- Either SWAP_LOG_ADD (1) when an object is added to
- the disk storage, or SWAP_LOG_DEL (2) when an object is
- deleted.
-
-<tag/swap_file_number/
- The 32-bit file number which maps to a pathname. Only
- the low 24-bits are relevant. The high 8-bits are
- used as an index to an array of storage directories, and
- are set at run time because the order of storage directories
- may change over time.
-
-<tag/timestamp/
- A 32-bit Unix time value that represents the time when
- the origin server generated this response. If the response
- has a valid <em/Date:/ header, this timestamp corresponds
- to that time. Otherwise, it is set to the Squid process time
- when the response is read (as soon as the end of headers are
- found).
-
-<tag/lastref/
- The last time that a client requested this object.
- Strictly speaking, this time is set whenver the StoreEntry
- is locked (via <em/storeLockObject()/).
-
-<tag/expires/
- The value of the response's <em/Expires:/ header, if any.
- If the response does not have an <em/Expires:/ header, this
- is set to -1. If the response has an invalid (unparseable)
- <em/Expires:/ header, it is also set to -1. There are some cases
- where Squid sets <em/expires/ to -2. This happens for the
- internal ``netdb'' object and for FTP URL responses.
-
-<tag/lastmod/
- The value of the response's <em/Last-modified:/ header, if any.
- This is set to -1 if there is no <em/Last-modified:/ header,
- or if it is unparseable.
-
-<tag/swap_file_sz/
- This is the number of bytes that the object occupies on
- disk. It includes the Squid ``swap file header''.
-
-<tag/refcount/
- The number of times that this object has been accessed (referenced).
- Since its a 16-bit quantity, it is susceptible to overflow
- if a single object is accessed 65,536 times before being replaced.
-
-<tag/flags/
- A copy of the <em/StoreEntry/ flags field. Used as a sanity
- check when rebuilding the cache at startup. Objects that
- have the KEY_PRIVATE flag set are not added back to the cache.
-
-<tag/key/
- The 128-bit MD5 hash for this object.
-
-</descrip>
-
-Note that <em/storeSwapLogData/ entries are written in native machine
-byte order. They are not necessarily portable across architectures.
-
-<sect>Store ``swap meta'' Description
-<p>
-``swap meta'' refers to a section of meta data stored at the beginning
-of an object that is stored on disk. This meta data includes information
-such as the object's cache key (MD5), URL, and part of the StoreEntry
-structure.
-
-<p>
-The meta data is stored using a TYPE-LENGTH-VALUE format. That is,
-each chunk of meta information consists of a TYPE identifier, a
-LENGTH field, and then the VALUE (which is LENGTH octets long).
-
-<sect1>Types
-
-<p>
-As of Squid-2.3, the following TYPES are defined (from <em/enums.h/):
-<descrip>
-<tag/STORE_META_VOID/
- Just a placeholder for the zeroth value. It is never used
- on disk.
-
-<tag/STORE_META_KEY_URL/
- This represents the case when we use the URL as the cache
- key, as Squid-1.1 does. Currently we don't support using
- a URL as a cache key, so this is not used.
-
-<tag/STORE_META_KEY_SHA/
- For a brief time we considered supporting SHA (secure
- hash algorithm) as a cache key. Nobody liked it, and
- this type is not currently used.
-
-<tag/STORE_META_KEY_MD5/
- This represents the MD5 cache key that Squid currently uses.
- When Squid opens a disk file for reading, it can check that
- this MD5 matches the MD5 of the user's request. If not, then
- something went wrong and this is probably the wrong object.
-
-<tag/STORE_META_URL/
- The object's URL. This also may be matched against a user's
- request for cache hits to make sure we got the right object.
-
-<tag/STORE_META_STD/
- This is the ``standard metadata'' for an object. Really
- its just this middle chunk of the StoreEntry structure:
-<verb>
- time_t timestamp;
- time_t lastref;
- time_t expires;
- time_t lastmod;
- size_t swap_file_sz;
- u_short refcount;
- u_short flags;
-</verb>
-
-<tag/STORE_META_STD_LFS/
- Updated version of STORE_META_STD, with support for
- >2GB objects. As STORE_META_STD except that the swap_file_sz
- is a squid_file_sz (64-bit integer) instead of size_t.
-
-<tag/STORE_META_HITMETERING/
- Reserved for future hit-metering (RFC 2227) stuff.
-
-<tag/STORE_META_VALID/
- ?
-
-<tag/STORE_META_VARY_HEADERS/
- Information about the Vary header relation on this object
-
-<tag/STORE_META_OBJSIZE/
- object size, if its known
-
-</descrip>
-
-
-<sect1>Implementation Notes
-
-<p>
-When writing an object to disk, we must first write the meta data.
-This is done with a couple of functions. First, <tt/storeSwapMetaPack()/
-takes a <em/StoreEntry/ as a parameter and returns a <em/tlv/ linked
-list. Second, <tt/storeSwapMetaPack()/ converts the <em/tlv/ list
-into a character buffer that we can write.
-
-<p>
-Note that the <em/MemObject/ has a member called <em/swap_hdr_sz/.
-This value is the size of that character buffer; the size of the
-swap file meta data. The <em/StoreEntry/ has a member named
-<em/swap_file_sz/ that represents the size of the disk file.
-Thus, the size of the object ``content'' is
-<verb>
- StoreEntry->swap_file_sz - MemObject->swap_hdr_sz;
-</verb>
-Note that the swap file content includes the HTTP reply headers
-and the HTTP reply body (if any).
-
-<p>
-When reading a swap file, there is a similar process to extract
-the swap meta data. First, <tt/storeSwapMetaUnpack()/ converts a
-character buffer into a <em/tlv/ linked list. It also tells us
-the value for <em/MemObject->swap_hdr_sz/.
-
-<sect>leakFinder
-
-<p>
-<em>src/leakfinder.c</em> contains some routines useful for debugging
-and finding memory leaks. It is not enabled by default. To enable
-it, use
-<verb>
-configure --enable-leakfinder ...
-</verb>
-
-<p>
-The module has three public functions: <em>leakAdd</em>,
-<em>leakFree</em>, and <em>leakTouch</em> Note, these are actually
-macros that insert __FILE__ and __LINE__ arguments to the real
-functions.
-<p>
-<em>leakAdd</em> should be called when a pointer is first created.
-Usually this follows immediately after a call to malloc or some
-other memory allocation function. For example:
-<verb>
- ...
- void *p;
- p = malloc(100);
- leakAdd(p);
- ...
-</verb>
-
-<p>
-<em>leakFree</em> is the opposite. Call it just before releasing
-the pointer memory, such as a call to free. For example:
-<verb>
- ...
- leakFree(foo);
- free(foo);
- return;
-</verb>
-NOTE: <em>leakFree</em> aborts with an assertion if you give it a
-pointer that was never added with <em>leakAdd</em>.
-
-
-<p>
-The definition of a leak is memory that was allocated but never
-freed. Thus, to find a leak we need to track the pointer between
-the time it got allocated and the time when it should have been
-freed. Use <em>leakTouch</em> to accomplish this. You can sprinkle
-<em>leakTouch</em> calls throughout the code where the pointer is
-used. For example:
-<verb>
-void
-myfunc(void *ptr)
-{
- ...
- leakTouch(ptr);
- ...
-}
-</verb>
-NOTE: <em>leakTouch</em> aborts with an assertion if you give it
-a pointer that was never added with <em>leakAdd</em>, or if the
-pointer was already freed.
-
-<p>
-For each pointer tracked, the module remembers the filename, line
-number, and time of last access. You can view this data with the
-cache manager by selecting the <em>leaks</em> option. You can also
-do it from the command line:
-<verb>
-% client mgr:leaks | less
-</verb>
-
-<p>
-The way to identify possible leaks is to look at the time of last
-access. Pointers that haven't been accessed for a long time are
-candidates for leaks. The filename and line numbers tell you where
-that pointer was last accessed. If there is a leak, then the bug
-occurs somewhere after that point of the code.
-
-<sect>MemPools
-
-<p>
-MemPools are a pooled memory allocator running on top of malloc(). It's
-purpose is to reduce memory fragmentation and provide detailed statistics
-on memory consumption.
-
-<p>
-Preferably all memory allocations in Squid should be done using MemPools
-or one of the types built on top of it (i.e. cbdata).
-
-<p>
-Note: Usually it is better to use cbdata types as these gives you additional
-safeguards in references and typechecking. However, for high usage pools where
-the cbdata functionality of cbdata is not required directly using a MemPool
-might be the way to go.
-
-<sect1>Public API
-
-<p>
-This defines the public API definitions
-
-<sect2>createMemPool
-
-<p>
-<verb>
- MemPool * pool = memPoolCreate(char *name, size_t element_size);
-</verb>
-
- <p>
- Creates a MemPool of elements with the given size.
-
-<sect2>memPoolAlloc
-
-<p>
-<verb>
- type * data = memPoolAlloc(pool);
-</verb>
-
- <p>
- Allocate one element from the pool
-
-<sect2>memPoolFree
-
-<p>
-<verb>
- memPoolFree(pool, data);
-</verb>
-
- <p>
- Free a element allocated by memPoolAlloc();
-
-<sect2>memPoolDestroy
-
-<p>
-<verb>
- memPoolDestroy(&pool);
-</verb>
-
- <p>
- Destroys a memory pool created by memPoolCreate() and reset pool to NULL.
-
- <p>
- Typical usage could be:
-<verb>
- ...
- myStructType *myStruct;
- MemPool * myType_pool = memPoolCreate("This is cute pool", sizeof(myStructType));
- myStruct = memPoolAlloc(myType_pool);
- myStruct->item = xxx;
- ...
- memPoolFree(myStruct, myType_pool);
- memPoolDestroy(&myType_pool)
-</verb>
-
-<sect2>memPoolIterate
-
-<p>
-<verb>
- MemPoolIterator * iter = memPoolIterate(void);
-</verb>
-
- <p>
- Initialise iteration through all of the pools.
-
-<sect2>memPoolIterateNext
-
-<p>
-<verb>
- MemPool * pool = memPoolIterateNext(MemPoolIterator * iter);
-</verb>
-
- <p>
- Get next pool pointer, until getting NULL pointer.
-
- <P>
-<verb>
- MemPoolIterator *iter;
- iter = memPoolIterate();
- while ( (pool = memPoolIterateNext(iter)) ) {
- ... handle(pool);
- }
- memPoolIterateDone(&iter);
-</verb>
-
-<sect2>memPoolIterateDone
-
-<p>
-<verb>
- memPoolIterateDone(MemPoolIterator ** iter);
-</verb>
-
- <p>
- Should be called after finished with iterating through all pools.
-
-<sect2>memPoolSetChunkSize
-
-<p>
-<verb>
- memPoolSetChunkSize(MemPool * pool, size_t chunksize);
-</verb>
-
- <p>
- Allows you tune chunk size of pooling. Objects are allocated in chunks
- instead of individually. This conserves memory, reduces fragmentation.
- Because of that memory can be freed also only in chunks. Therefore
- there is tradeoff between memory conservation due to chunking and free
- memory fragmentation.
- As a general guideline, increase chunk size only for pools that keep very
- many items for relatively long time.
-
-<sect2>memPoolSetIdleLimit
-
-<p>
-<verb>
- memPoolSetIdleLimit(size_t new_idle_limit);
-</verb>
-
- <p>
- Sets upper limit in bytes to amount of free ram kept in pools. This is
- not strict upper limit, but a hint. When MemPools are over this limit,
- totally free chunks are immediately considered for release. Otherwise
- only chunks that have not been referenced for a long time are checked.
-
-<sect2>memPoolGetStats
-
-<p>
-<verb>
- int inuse = memPoolGetStats(MemPoolStats * stats, MemPool * pool);
-</verb>
-
- <p>
- Fills MemPoolStats struct with statistical data about pool. As a
- return value returns number of objects in use, ie. allocated.
- <p>
-<verb>
- struct _MemPoolStats {
- MemPool *pool;
- const char *label;
- MemPoolMeter *meter;
- int obj_size;
- int chunk_capacity;
- int chunk_size;
-
- int chunks_alloc;
- int chunks_inuse;
- int chunks_partial;
- int chunks_free;
-
- int items_alloc;
- int items_inuse;
- int items_idle;
-
- int overhead;
- };
-
- /* object to track per-pool cumulative counters */
- typedef struct {
- double count;
- double bytes;
- } mgb_t;
-
- /* object to track per-pool memory usage (alloc = inuse+idle) */
- struct _MemPoolMeter {
- MemMeter alloc;
- MemMeter inuse;
- MemMeter idle;
- mgb_t gb_saved; /* account Allocations */
- mgb_t gb_osaved; /* history Allocations */
- mgb_t gb_freed; /* account Free calls */
- };
-</verb>
-
-<sect2>memPoolGetGlobalStats
-
-<p>
-<verb>
- int pools_inuse = memPoolGetGlobalStats(MemPoolGlobalStats * stats);
-</verb>
-
- <p>
- Fills MemPoolGlobalStats struct with statistical data about overall
- usage for all pools. As a return value returns number of pools that
- have at least one object in use. Ie. number of dirty pools.
- <p>
-<verb>
- struct _MemPoolGlobalStats {
- MemPoolMeter *TheMeter;
-
- int tot_pools_alloc;
- int tot_pools_inuse;
- int tot_pools_mempid;
-
- int tot_chunks_alloc;
- int tot_chunks_inuse;
- int tot_chunks_partial;
- int tot_chunks_free;
-
- int tot_items_alloc;
- int tot_items_inuse;
- int tot_items_idle;
-
- int tot_overhead;
- int mem_idle_limit;
- };
-</verb>
-
-<sect2>memPoolClean
-
-<p>
-<verb>
- memPoolClean(time_t maxage);
-</verb>
-
-<p>
- Main cleanup handler. For MemPools to stay within upper idle limits,
- this function needs to be called periodically, preferrably at some
- constant rate, eg. from Squid event. It looks through all pools and
- chunks, cleans up internal states and checks for releasable chunks.
-<p>
- Between the calls to this function objects are placed onto internal
- cache instead of returning to their home chunks, mainly for speedup
- purpose. During that time state of chunk is not known, it is not
- known whether chunk is free or in use. This call returns all objects
- to their chunks and restores consistency.
-<p>
- Should be called relatively often, as it sorts chunks in suitable
- order as to reduce free memory fragmentation and increase chunk
- utilisation.
-<p>
- Parameter maxage instructs to release all totally idle chunks that
- have not been referenced for maxage seconds.
-<p>
- Suitable frequency for cleanup is in range of few tens of seconds to
- few minutes, depending of memory activity.
- Several functions above call memPoolClean internally to operate on
- consistent states.
-
-</article>
/*
- * $Id: List.h,v 1.7 2006/08/21 00:50:40 robertc Exp $
+ * $Id: List.h,v 1.8 2008/02/26 21:49:33 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "cbdata.h"
+/// \ingroup POD
template <class C>
-
class List
{
CBDATA_CLASS(List);
};
+/// \ingroup POD
template<class C>
-
class ListContainer
{
List<C> *head;
};
+/// \ingroup POD
template<class C>
class ListIterator
{
};
/* implementation follows */
-#if 0
-template <class C>
-MemPool *List<C>::Pool(NULL);
-#endif
+/** \cond AUTODOCS-IGNORE */
template <class C>
cbdata_type List<C>::CBDATA_List = CBDATA_UNKNOWN;
+/** \endcond */
template <class C>
void *
#ifndef _MEM_POOLS_H_
#define _MEM_POOLS_H_
+/**
+ \defgroup MemPoolsAPI Memory Management (Memory Pool Allocator)
+ \ingroup Components
+ *
+ *\par
+ * MemPools are a pooled memory allocator running on top of malloc(). It's
+ * purpose is to reduce memory fragmentation and provide detailed statistics
+ * on memory consumption.
+ *
+ \par
+ * Preferably all memory allocations in Squid should be done using MemPools
+ * or one of the types built on top of it (i.e. cbdata).
+ *
+ \note Usually it is better to use cbdata types as these gives you additional
+ * safeguards in references and typechecking. However, for high usage pools where
+ * the cbdata functionality of cbdata is not required directly using a MemPool
+ * might be the way to go.
+ */
+
#include "config.h"
#include "assert.h"
#include "util.h"
#endif
#endif
+/// \ingroup MemPoolsAPI
#define MB ((size_t)1024*1024)
+/// \ingroup MemPoolsAPI
#define mem_unlimited_size 2 * 1024 * MB
+/// \ingroup MemPoolsAPI
#define toMB(size) ( ((double) size) / MB )
+/// \ingroup MemPoolsAPI
#define toKB(size) ( (size + 1024 - 1) / 1024 )
+/// \ingroup MemPoolsAPI
#define MEM_PAGE_SIZE 4096
+/// \ingroup MemPoolsAPI
#define MEM_CHUNK_SIZE 4096 * 4
+/// \ingroup MemPoolsAPI
#define MEM_CHUNK_MAX_SIZE 256 * 1024 /* 2MB */
+/// \ingroup MemPoolsAPI
#define MEM_MIN_FREE 32
+/// \ingroup MemPoolsAPI
#define MEM_MAX_FREE 65535 /* ushort is max number of items per chunk */
class MemImplementingAllocator;
class MemChunk;
class MemPoolStats;
+/// \ingroup MemPoolsAPI
+/// \todo Kill this typedef for C++
typedef struct _MemPoolGlobalStats MemPoolGlobalStats;
+/// \ingroup MemPoolsAPI
class MemPoolIterator
{
public:
MemPoolIterator * next;
};
-/* object to track per-pool cumulative counters */
-
+/**
+ \ingroup MemPoolsAPI
+ * Object to track per-pool cumulative counters
+ */
class mgb_t
{
public:
double bytes;
};
-/* object to track per-pool memory usage (alloc = inuse+idle) */
-
+/**
+ \ingroup MemPoolsAPI
+ * Object to track per-pool memory usage (alloc = inuse+idle)
+ */
class MemPoolMeter
{
public:
MemMeter alloc;
MemMeter inuse;
MemMeter idle;
- mgb_t gb_saved; /* account Allocations */
- mgb_t gb_osaved; /* history Allocations */
- mgb_t gb_freed; /* account Free calls */
+
+ /** account Allocations */
+ mgb_t gb_saved;
+
+ /** history Allocations */
+ mgb_t gb_osaved;
+
+ /** account Free calls */
+ mgb_t gb_freed;
};
class MemImplementingAllocator;
+/// \ingroup MemPoolsAPI
class MemPools
{
public:
MemPools();
void init();
void flushMeters();
+
+ /**
+ \param label Name for the pool. Displayed in stats.
+ \param obj_size Size of elements in MemPool.
+ */
MemImplementingAllocator * create(const char *label, size_t obj_size);
+
+ /**
+ \param label Name for the pool. Displayed in stats.
+ \param obj_size Size of elements in MemPool.
+ \param chunked ??
+ */
MemImplementingAllocator * create(const char *label, size_t obj_size, bool const chunked);
+
+ /**
+ * Sets upper limit in bytes to amount of free ram kept in pools. This is
+ * not strict upper limit, but a hint. When MemPools are over this limit,
+ * totally free chunks are immediately considered for release. Otherwise
+ * only chunks that have not been referenced for a long time are checked.
+ */
void setIdleLimit(size_t new_idle_limit);
+
size_t idleLimit() const;
+
+ /**
+ \par
+ * Main cleanup handler. For MemPools to stay within upper idle limits,
+ * this function needs to be called periodically, preferrably at some
+ * constant rate, eg. from Squid event. It looks through all pools and
+ * chunks, cleans up internal states and checks for releasable chunks.
+ *
+ \par
+ * Between the calls to this function objects are placed onto internal
+ * cache instead of returning to their home chunks, mainly for speedup
+ * purpose. During that time state of chunk is not known, it is not
+ * known whether chunk is free or in use. This call returns all objects
+ * to their chunks and restores consistency.
+ *
+ \par
+ * Should be called relatively often, as it sorts chunks in suitable
+ * order as to reduce free memory fragmentation and increase chunk
+ * utilisation.
+ * Suitable frequency for cleanup is in range of few tens of seconds to
+ * few minutes, depending of memory activity.
+ *
+ \todo DOCS: Re-write this shorter!
+ *
+ \param maxage Release all totally idle chunks that
+ * have not been referenced for maxage seconds.
+ */
void clean(time_t maxage);
+
void setDefaultPoolChunking(bool const &);
MemImplementingAllocator *pools;
int mem_idle_limit;
static MemPools *Instance;
};
-/* a pool is a [growing] space for objects of the same size */
-
+/**
+ \ingroup MemPoolsAPI
+ * a pool is a [growing] space for objects of the same size
+ */
class MemAllocator
{
public:
MemAllocator (char const *aLabel);
virtual ~MemAllocator() {}
+
+ /**
+ \param stats Object to be filled with statistical data about pool.
+ \retval Number of objects in use, ie. allocated.
+ */
virtual int getStats(MemPoolStats * stats) = 0;
+
virtual MemPoolMeter const &getMeter() const = 0;
+
+ /**
+ * Allocate one element from the pool
+ */
virtual void *alloc() = 0;
+
+ /**
+ * Free a element allocated by MemAllocator::alloc()
+ */
virtual void free(void *) = 0;
+
virtual char const *objectType() const;
virtual size_t objectSize() const = 0;
virtual int getInUseCount() = 0;
void zeroOnPush(bool doIt);
int inUseCount();
+
+ /**
+ * Allows you tune chunk size of pooling. Objects are allocated in chunks
+ * instead of individually. This conserves memory, reduces fragmentation.
+ * Because of that memory can be freed also only in chunks. Therefore
+ * there is tradeoff between memory conservation due to chunking and free
+ * memory fragmentation.
+ *
+ \note As a general guideline, increase chunk size only for pools that keep
+ * very many items for relatively long time.
+ */
virtual void setChunkSize(size_t chunksize) {}
- // smallest size divisible by sizeof(void*) and at least minSize
+ /**
+ \param minSize Minimum size needed to be allocated.
+ \retval n Smallest size divisible by sizeof(void*)
+ */
static size_t RoundedSize(size_t minSize);
+
protected:
bool doZeroOnPush;
+
private:
const char *label;
};
-/* Support late binding of pool type for allocator agnostic classes */
+/**
+ \ingroup MemPoolsAPI
+ * Support late binding of pool type for allocator agnostic classes
+ */
class MemAllocatorProxy
{
public:
inline MemAllocatorProxy(char const *aLabel, size_t const &);
+
+ /**
+ * Allocate one element from the pool
+ */
void *alloc();
+
+ /**
+ * Free a element allocated by MemAllocatorProxy::alloc()
+ */
void free(void *);
+
int inUseCount() const;
size_t objectSize() const;
MemPoolMeter const &getMeter() const;
+
+ /**
+ \param stats Object to be filled with statistical data about pool.
+ \retval Number of objects in use, ie. allocated.
+ */
int getStats(MemPoolStats * stats);
+
char const * objectType() const;
private:
MemAllocator *getAllocator() const;
size_t size;
mutable MemAllocator *theAllocator;
};
+
/* help for classes */
-/* Put this in the class */
+
+/**
+ \ingroup MemPoolsAPI
+ \hideinitializer
+ *
+ * This macro is intended for use within the declaration of a class.
+ */
#define MEMPROXY_CLASS(CLASS) \
-/* TODO change syntax to allow moving into .cci files */ \
inline void *operator new(size_t); \
inline void operator delete(void *); \
static inline MemAllocatorProxy &Pool()
-/* put this in the class .h, or .cci as appropriate */
+/**
+ \ingroup MemPoolsAPI
+ \hideinitializer
+ *
+ * This macro is intended for use within the .h or .cci of a class as appropriate.
+ */
#define MEMPROXY_CLASS_INLINE(CLASS) \
MemAllocatorProxy& CLASS::Pool() \
{ \
Pool().free(address); \
}
+/// \ingroup MemPoolsAPI
class MemImplementingAllocator : public MemAllocator
{
public:
virtual MemPoolMeter &getMeter();
virtual void flushMetersFull();
virtual void flushMeters();
+
+ /**
+ * Allocate one element from the pool
+ */
virtual void *alloc();
+
+ /**
+ * Free a element allocated by MemImplementingAllocator::alloc()
+ */
virtual void free(void *);
+
virtual bool idleTrigger(int shift) const = 0;
virtual void clean(time_t maxage) = 0;
- /* Hint to the allocator - may be ignored */
+ /** Hint to the allocator - may be ignored */
virtual void setChunkSize(size_t chunksize) {}
virtual size_t objectSize() const;
virtual int getInUseCount() = 0;
size_t obj_size;
};
+/// \ingroup MemPoolsAPI
class MemPool : public MemImplementingAllocator
{
public:
~MemPool();
void convertFreeCacheToChunkFreeCache();
virtual void clean(time_t maxage);
+
+ /**
+ \param stats Object to be filled with statistical data about pool.
+ \retval Number of objects in use, ie. allocated.
+ */
virtual int getStats(MemPoolStats * stats);
+
void createChunk();
void *get();
void push(void *obj);
virtual void *allocate();
virtual void deallocate(void *);
public:
+ /**
+ * Allows you tune chunk size of pooling. Objects are allocated in chunks
+ * instead of individually. This conserves memory, reduces fragmentation.
+ * Because of that memory can be freed also only in chunks. Therefore
+ * there is tradeoff between memory conservation due to chunking and free
+ * memory fragmentation.
+ *
+ \note As a general guideline, increase chunk size only for pools that keep
+ * very many items for relatively long time.
+ */
virtual void setChunkSize(size_t chunksize);
+
virtual bool idleTrigger(int shift) const;
size_t chunk_size;
Splay<MemChunk *> allChunks;
};
+/// \ingroup MemPoolsAPI
class MemMalloc : public MemImplementingAllocator
{
public:
MemMalloc(char const *label, size_t aSize);
virtual bool idleTrigger(int shift) const;
virtual void clean(time_t maxage);
+
+ /**
+ \param stats Object to be filled with statistical data about pool.
+ \retval Number of objects in use, ie. allocated.
+ */
virtual int getStats(MemPoolStats * stats);
+
virtual int getInUseCount();
protected:
virtual void *allocate();
int inuse;
};
+/// \ingroup MemPoolsAPI
class MemChunk
{
public:
MemPool *pool;
};
+/// \ingroup MemPoolsAPI
class MemPoolStats
{
public:
int overhead;
};
+/// \ingroup MemPoolsAPI
+/// \todo Classify and add constructor/destructor to initialize properly.
struct _MemPoolGlobalStats
{
MemPoolMeter *TheMeter;
int mem_idle_limit;
};
+/// \ingroup MemPoolsAPI
#define memPoolCreate MemPools::GetInstance().create
/* Allocator API */
+/**
+ \ingroup MemPoolsAPI
+ * Initialise iteration through all of the pools.
+ \retval Iterator for use by memPoolIterateNext() and memPoolIterateDone()
+ */
extern MemPoolIterator * memPoolIterate(void);
+
+/**
+ \ingroup MemPoolsAPI
+ * Get next pool pointer, until getting NULL pointer.
+ */
extern MemImplementingAllocator * memPoolIterateNext(MemPoolIterator * iter);
+
+/**
+ \ingroup MemPoolsAPI
+ * Should be called after finished with iterating through all pools.
+ */
extern void memPoolIterateDone(MemPoolIterator ** iter);
-/* Stats API - not sured how to refactor yet */
+/**
+ \ingroup MemPoolsAPI
+ \todo Stats API - not sured how to refactor yet
+ *
+ * Fills MemPoolGlobalStats with statistical data about overall
+ * usage for all pools.
+ *
+ \retval Number of pools that have at least one object in use.
+ * Ie. number of dirty pools.
+ */
extern int memPoolGetGlobalStats(MemPoolGlobalStats * stats);
+/// \ingroup MemPoolsAPI
extern int memPoolInUseCount(MemAllocator *);
+/// \ingroup MemPoolsAPI
extern int memPoolsTotalAllocated(void);
MemAllocatorProxy::MemAllocatorProxy(char const *aLabel, size_t const &aSize) : label (aLabel), size(aSize), theAllocator (NULL)
/*
- * $Id: squid_mswin.h,v 1.9 2008/01/22 20:12:57 serassio Exp $
+ * $Id: squid_mswin.h,v 1.10 2008/02/26 21:49:33 amosjeffries Exp $
*
* AUTHOR: Andrey Shorin <tolsty@tushino.com>
* AUTHOR: Guido Serassio <serassio@squid-cache.org>
return (char *)strchr(s,c);
}
+/** \cond AUTODOCS-IGNORE */
namespace Squid {
+/** \endcond */
inline
int accept(int s, struct sockaddr * a, size_t * l)
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
-EXCLUDE_PATTERNS = */CVS/* */lib/libTrie/* */Programming-Guide/html/*
+EXCLUDE_PATTERNS = */CVS/* */lib/libTrie/* */Programming-Guide/html/* */Programming-guide/dyn/*
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT = html
+HTML_OUTPUT = tmp
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
-HTML_HEADER = ./doc/Programming-Guide/doxygen.header.html
+HTML_HEADER = ./doc/Programming-Guide/doxygen.header.dyn
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
-HTML_FOOTER = ./doc/Programming-Guide/doxygen.footer.html
+HTML_FOOTER = ./doc/Programming-Guide/doxygen.footer.dyn
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command.
-CALLER_GRAPH = YES
+CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
-DOT_MULTI_TARGETS = NO
+DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
-
/*
- * $Id: ACL.h,v 1.19 2007/09/01 05:56:37 amosjeffries Exp $
+ * $Id: ACL.h,v 1.20 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACL_H
#define SQUID_ACL_H
+
#include "Array.h"
#include "cbdata.h"
#include "dlink.h"
-/* FIXME: finish splitting out the dependencies here
- * - typedefs should not be needed to parse this.
+/**
+ \todo FIXME: finish splitting out the dependencies here
+ * - typedefs should not be needed to parse this.
*/
#include "typedefs.h"
class ConfigParser;
/* acl.c */
+
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclDestroyAccessList(acl_access **list);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclDestroyAcls(ACL **);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclDestroyAclList(ACLList **);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclParseAccessLine(ConfigParser &parser, acl_access **);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclParseAclList(ConfigParser &parser, ACLList **);
+/// \ingroup ACLAPI
SQUIDCEXTERN int aclIsProxyAuth(const char *name);
+/// \ingroup ACLAPI
SQUIDCEXTERN err_type aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclParseDenyInfoLine(struct _acl_deny_info_list **);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclDestroyDenyInfoList(struct _acl_deny_info_list **);
+/// \ingroup ACLAPI
SQUIDCEXTERN wordlist *aclDumpGeneric(const ACL *);
+/// \ingroup ACLAPI
SQUIDCEXTERN void aclCacheMatchFlush(dlink_list * cache);
+/// \ingroup ACLAPI
extern void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head);
+/// \ingroup ACLAPI
int aclPurgeMethodInUse(acl_access * a);
+/// \ingroup ACLAPI
extern const char *AclMatchedName; /* NULL */
+/// \ingroup ACLAPI
class ACL
{
};
};
+/// \ingroup ACLAPI
class acl_access
{
CBDATA_CLASS(acl_access);
};
+/// \ingroup ACLAPI
class ACLList
{
ACLList *next;
};
-MEMPROXY_CLASS_INLINE(ACLList)
+MEMPROXY_CLASS_INLINE(ACLList);
+/// \ingroup ACLAPI
class acl_proxy_auth_match_cache
{
-
/*
- * $Id: ACLARP.h,v 1.4 2005/05/06 01:57:55 hno Exp $
+ * $Id: ACLARP.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLARP_H
#define SQUID_ACLARP_H
+
#include "ACL.h"
#include "ACLChecklist.h"
#include "splay.h"
+/// \ingroup ACLAPI
struct acl_arp_data
{
char eth[6];
};
+/// \ingroup ACLAPI
class ACLARP : public ACL
{
char const *class_;
};
-MEMPROXY_CLASS_INLINE(ACLARP)
+MEMPROXY_CLASS_INLINE(ACLARP) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLARP_H */
-
/*
- * $Id: ACLASN.h,v 1.9 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: ACLASN.h,v 1.10 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLASN_H
#define SQUID_ACLASN_H
+
#include "ACLData.h"
#include "List.h"
#include "ACLStrategised.h"
class CacheManager;
SQUIDCEXTERN int asnMatchIp(List<int> *, IPAddress &);
+
+/// \ingroup ACLAPI
SQUIDCEXTERN void asnInit(void);
+
+/// \ingroup ACLAPI
extern void asnRegisterWithCacheManager(CacheManager & manager);
+
+/// \ingroup ACLAPI
SQUIDCEXTERN void asnFreeMemory(void);
+/// \ingroup ACLAPI
class ACLASN : public ACLData<IPAddress>
{
List<int> *data;
};
-MEMPROXY_CLASS_INLINE(ACLASN)
+MEMPROXY_CLASS_INLINE(ACLASN) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLASN_H */
-
/*
- * $Id: ACLBrowser.h,v 1.2 2003/02/21 22:50:04 robertc Exp $
+ * $Id: ACLBrowser.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLBROWSER_H
#define SQUID_ACLBROWSER_H
+
#include "ACL.h"
#include "ACLData.h"
#include "ACLRequestHeaderStrategy.h"
#include "ACLStrategised.h"
+/// \ingroup ACLAPI
class ACLBrowser
{
-
/*
- * $Id: ACLCertificate.h,v 1.3 2003/02/25 12:22:33 robertc Exp $
+ * $Id: ACLCertificate.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLCERTIFICATE_H
#define SQUID_ACLCERTIFICATE_H
+
#include "ACL.h"
#include "ACLData.h"
#include "ACLChecklist.h"
#include "ssl_support.h"
#include "ACLStrategised.h"
+/// \ingroup ACLAPI
class ACLCertificateStrategy : public ACLStrategy<SSL *>
{
ACLCertificateStrategy&operator=(ACLCertificateStrategy const &);
};
+/// \ingroup ACLAPI
class ACLCertificate
{
-
/*
- * $Id: ACLCertificateData.h,v 1.7 2005/05/08 06:36:45 hno Exp $
+ * $Id: ACLCertificateData.h,v 1.8 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLCERTIFICATEDATA_H
#define SQUID_ACLCERTIFICATEDATA_H
+
#include "splay.h"
#include "ACL.h"
#include "ACLData.h"
#include "ssl_support.h"
#include "ACLStringData.h"
+/// \ingroup ACLAPI
class ACLCertificateData : public ACLData<SSL *>
{
SSLGETATTRIBUTE *sslAttributeCall;
};
-MEMPROXY_CLASS_INLINE(ACLCertificateData)
+MEMPROXY_CLASS_INLINE(ACLCertificateData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLCERTIFICATEDATA_H */
-
/*
- * $Id: ACLChecklist.h,v 1.31 2008/02/12 23:29:25 rousskov Exp $
+ * $Id: ACLChecklist.h,v 1.32 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class ConnStateData;
+/// \ingroup ACLAPI
class ACLChecklist
{
public:
- /* State class.
+ /**
+ * State class.
* This abstract class defines the behaviour of
* async lookups - which can vary for different ACL types.
* Today, every state object must be a singleton.
* See NULLState for an example.
- * Note that *no* state should be stored in the state object,
+ *
+ \note *no* state should be stored in the state object,
* they are used to change the behaviour of the checklist, not
* to hold information. If you need to store information in the
* state object, consider subclassing ACLChecklist, converting it
bool lastACLResult() const { return lastACLResult_; }
};
+/// \ingroup ACLAPI
SQUIDCEXTERN ACLChecklist *aclChecklistCreate(const acl_access *,
HttpRequest *,
const char *ident);
-
/*
- * $Id: ACLData.h,v 1.6 2005/05/08 06:36:45 hno Exp $
+ * $Id: ACLData.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLDATA_H
#define SQUID_ACLDATA_H
+/// \ingroup ACLAPI
template <class M>
-
class ACLData
{
-
/*
- * $Id: ACLDestinationASN.h,v 1.3 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: ACLDestinationASN.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLDESTINATIONASN_H
#define SQUID_ACLDESTINATIONASN_H
+
#include "ACLASN.h"
#include "ACLStrategy.h"
#include "IPAddress.h"
+/// \ingroup ACLAPI
class ACLDestinationASNStrategy : public ACLStrategy<IPAddress>
{
virtual bool requiresRequest() const {return true;}
static ACLDestinationASNStrategy *Instance();
- /* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
- * private constructors with no friends */
+
+ /**
+ * Not implemented to prevent copies of the instance.
+ \par
+ * Not private to prevent brain dead g++ warnings about
+ * private constructors with no friends
+ */
ACLDestinationASNStrategy(ACLDestinationASNStrategy const &);
private:
-
/*
- * $Id: ACLDestinationDomain.h,v 1.8 2005/05/09 01:41:25 hno Exp $
+ * $Id: ACLDestinationDomain.h,v 1.9 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLSOURCEDOMAIN_H
#define SQUID_ACLSOURCEDOMAIN_H
+
#include "ACL.h"
#include "ACLData.h"
#include "ACLChecklist.h"
#include "ACLStrategised.h"
+/// \ingroup ACLAPI
class ACLDestinationDomainStrategy : public ACLStrategy<char const *>
{
public:
virtual int match (ACLData<MatchType> * &, ACLChecklist *);
static ACLDestinationDomainStrategy *Instance();
- /* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
- * private constructors with no friends */
+
+ /**
+ * Not implemented to prevent copies of the instance.
+ \par
+ * Not private to prevent brain dead g+++ warnings about
+ * private constructors with no friends
+ */
ACLDestinationDomainStrategy(ACLDestinationDomainStrategy const &);
private:
ACLDestinationDomainStrategy&operator=(ACLDestinationDomainStrategy const &);
};
+/// \ingroup ACLAPI
class DestinationDomainLookup : public ACLChecklist::AsyncState
{
static void LookupDone(const char *, void *);
};
+/// \ingroup ACLAPI
class ACLDestinationDomain
{
static ACLDestinationIP RegistryEntry_;
};
-MEMPROXY_CLASS_INLINE(ACLDestinationIP)
+MEMPROXY_CLASS_INLINE(ACLDestinationIP) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLDESTINATIONIP_H */
-
/*
- * $Id: ACLDomainData.h,v 1.6 2005/05/08 06:36:45 hno Exp $
+ * $Id: ACLDomainData.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLDOMAINDATA_H
#define SQUID_ACLDOMAINDATA_H
+
#include "splay.h"
#include "ACL.h"
#include "ACLData.h"
+/// \ingroup ACLAPI
class ACLDomainData : public ACLData<char const *>
{
SplayNode<char *> *domains;
};
-MEMPROXY_CLASS_INLINE(ACLDomainData)
+MEMPROXY_CLASS_INLINE(ACLDomainData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLDOMAINDATA_H */
-
/*
- * $Id: ACLExtUser.h,v 1.5 2005/05/06 01:57:55 hno Exp $
+ * $Id: ACLExtUser.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLIDENT_H
#define SQUID_ACLIDENT_H
+
#include "ACL.h"
#include "ACLChecklist.h"
#include "ACLData.h"
+/// \ingroup ACLAPI
class ACLExtUser : public ACL
{
char const *type_;
};
-MEMPROXY_CLASS_INLINE(ACLExtUser)
+MEMPROXY_CLASS_INLINE(ACLExtUser) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLIDENT_H */
-
/*
- * $Id: ACLHTTPHeaderData.h,v 1.4 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: ACLHTTPHeaderData.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLHTTPHEADERDATA_H
#define SQUID_ACLHTTPHEADERDATA_H
+
#include "ACLData.h"
+/// \ingroup ACLAPI
class ACLHTTPHeaderData : public ACLData<HttpHeader*>
{
ACLData<char const *> * regex_rule;
};
-MEMPROXY_CLASS_INLINE(ACLHTTPHeaderData)
+MEMPROXY_CLASS_INLINE(ACLHTTPHeaderData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLHTTPHEADERDATA_H */
-
/*
- * $Id: ACLHTTPRepHeader.h,v 1.2 2006/08/05 12:05:35 robertc Exp $
+ * $Id: ACLHTTPRepHeader.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLHTTPREPHEADER_H
#define SQUID_ACLHTTPREPHEADER_H
+
#include "ACLStrategy.h"
#include "ACLStrategised.h"
#include "HttpHeader.h"
+/// \ingroup ACLAPI
class ACLHTTPRepHeaderStrategy : public ACLStrategy<HttpHeader*>
{
virtual bool requiresReply() const { return true; }
static ACLHTTPRepHeaderStrategy *Instance();
- /* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
- * private constructors with no friends */
+ /**
+ * Not implemented to prevent copies of the instance.
+ \par
+ * Not private to prevent brain dead g+++ warnings about
+ * private constructors with no friends
+ */
ACLHTTPRepHeaderStrategy(ACLHTTPRepHeaderStrategy const &);
private:
ACLHTTPRepHeaderStrategy&operator = (ACLHTTPRepHeaderStrategy const &);
};
+/// \ingroup ACLAPI
class ACLHTTPRepHeader
{
-
/*
- * $Id: ACLHTTPReqHeader.h,v 1.2 2006/08/05 12:05:35 robertc Exp $
+ * $Id: ACLHTTPReqHeader.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLHTTPREQHEADER_H
#define SQUID_ACLHTTPREQHEADER_H
+
#include "ACLStrategy.h"
#include "ACLStrategised.h"
#include "HttpHeader.h"
+/// \ingroup ACLAPI
class ACLHTTPReqHeaderStrategy : public ACLStrategy<HttpHeader*>
{
ACLHTTPReqHeaderStrategy&operator = (ACLHTTPReqHeaderStrategy const &);
};
+/// \ingroup ACLAPI
class ACLHTTPReqHeader
{
-
/*
- * $Id: ACLHTTPStatus.h,v 1.2 2006/04/02 15:00:54 serassio Exp $
+ * $Id: ACLHTTPStatus.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLHTTPSTATUS_H
#define SQUID_ACLHTTPSTATUS_H
+
#include "ACL.h"
#include "ACLChecklist.h"
#include "splay.h"
+/// \ingroup ACLAPI
struct acl_httpstatus_data
{
int status1, status2;
static int compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b);
};
+/// \ingroup ACLAPI
class ACLHTTPStatus : public ACL
{
char const *class_;
};
-MEMPROXY_CLASS_INLINE(ACLHTTPStatus)
+MEMPROXY_CLASS_INLINE(ACLHTTPStatus) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLHTTPSTATUS_H */
-
/*
* $Id$
*
#ifndef SQUID_ACLIP_H
#define SQUID_ACLIP_H
+
#include "ACL.h"
#include "splay.h"
#include "IPAddress.h"
+/// \ingroup ACLAPI
class acl_ip_data
{
static bool DecodeMask(const char *asc, IPAddress &mask, int string_format_type);
};
-MEMPROXY_CLASS_INLINE(acl_ip_data)
+MEMPROXY_CLASS_INLINE(acl_ip_data) /**DOCS_NOSEMI*/
+/// \ingroup ACLAPI
class ACLIP : public ACL
{
-
/*
* $Id$
*
#ifndef SQUID_ACLIDENT_H
#define SQUID_ACLIDENT_H
+
#include "ACL.h"
#include "ACLChecklist.h"
#include "ACLData.h"
+/// \ingroup ACLAPI
class IdentLookup : public ACLChecklist::AsyncState
{
static void LookupDone(const char *ident, void *data);
};
+/// \ingroup ACLAPI
class ACLIdent : public ACL
{
char const *type_;
};
-MEMPROXY_CLASS_INLINE(ACLIdent)
+MEMPROXY_CLASS_INLINE(ACLIdent) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLIDENT_H */
/*
- * $Id: ACLIntRange.cc,v 1.10 2007/04/28 22:26:37 hno Exp $
+ * $Id: ACLIntRange.cc,v 1.11 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Robert Collins
#include "Parsing.h"
/* explicit instantiation required for some systems */
-
-template cbdata_type List<Range<int> >
-::CBDATA_List;
+template cbdata_type List< Range<int> >::CBDATA_List;
void
ACLIntRange::parse()
-
/*
- * $Id: ACLIntRange.h,v 1.4 2005/05/08 23:31:06 hno Exp $
+ * $Id: ACLIntRange.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLINTRANGE_H
#define SQUID_ACLINTRANGE_H
+
#include "ACLData.h"
#include "List.h"
#include "Range.h"
+/// \ingroup ACLAPI
class ACLIntRange : public ACLData<int>
{
-
/*
- * $Id: ACLMaxConnection.h,v 1.4 2005/05/06 01:57:55 hno Exp $
+ * $Id: ACLMaxConnection.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLMAXCONNECTION_H
#define SQUID_ACLMAXCONNECTION_H
+
#include "ACL.h"
#include "ACLChecklist.h"
+/// \ingroup ACLAPI
class ACLMaxConnection : public ACL
{
int limit;
};
-MEMPROXY_CLASS_INLINE(ACLMaxConnection)
+MEMPROXY_CLASS_INLINE(ACLMaxConnection) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLMAXCONNECTION_H */
-
/*
- * $Id: ACLMaxUserIP.h,v 1.10 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: ACLMaxUserIP.h,v 1.11 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLMAXUSERIP_H
#define SQUID_ACLMAXUSERIP_H
+
#include "ACL.h"
#include "ACLChecklist.h"
+/// \ingroup ACLAPI
class ACLMaxUserIP : public ACL
{
flags;
};
-MEMPROXY_CLASS_INLINE(ACLMaxUserIP)
+MEMPROXY_CLASS_INLINE(ACLMaxUserIP) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLMAXUSERIP_H */
-
/*
- * $Id: ACLMethod.h,v 1.2 2008/01/20 08:54:28 amosjeffries Exp $
+ * $Id: ACLMethod.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLMETHOD_H
#define SQUID_ACLMETHOD_H
+
#include "ACLStrategy.h"
#include "ACLStrategised.h"
+/// \ingroup ACLAPI
class ACLMethodStrategy : public ACLStrategy<HttpRequestMethod>
{
virtual bool requiresRequest() const {return true;}
static ACLMethodStrategy *Instance();
- /* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
- * private constructors with no friends */
+
+ /**
+ * Not implemented to prevent copies of the instance.
+ \par
+ * Not private to prevent brain dead g+++ warnings about
+ * private constructors with no friends
+ */
ACLMethodStrategy(ACLMethodStrategy const &);
private:
ACLMethodStrategy&operator=(ACLMethodStrategy const &);
};
+/// \ingroup ACLAPI
class ACLMethod
{
/*
- * $Id: ACLMethodData.cc,v 1.11 2008/02/03 10:00:29 amosjeffries Exp $
+ * $Id: ACLMethodData.cc,v 1.12 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
/* explicit instantiation required for some systems */
+/// \cond AUTODOCS-IGNORE
template cbdata_type List<HttpRequestMethod>
::CBDATA_List;
+/// \endcond
wordlist *
ACLMethodData::dump()
-
/*
- * $Id: ACLMethodData.h,v 1.5 2008/01/20 08:54:28 amosjeffries Exp $
+ * $Id: ACLMethodData.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLMETHODDATA_H
#define SQUID_ACLMETHODDATA_H
+
#include "ACL.h"
#include "ACLData.h"
#include "List.h"
+/// \ingroup ACLAPI
class ACLMethodData : public ACLData<HttpRequestMethod>
{
List<HttpRequestMethod> *values;
};
-MEMPROXY_CLASS_INLINE(ACLMethodData)
+MEMPROXY_CLASS_INLINE(ACLMethodData);
#endif /* SQUID_ACLMETHODDATA_H */
-
/*
* $Id$
*
#ifndef SQUID_ACLMYIP_H
#define SQUID_ACLMYIP_H
+
#include "ACLIP.h"
+/// \ingroup ACLAPI
class ACLMyIP : public ACLIP
{
static ACLMyIP RegistryEntry_;
};
-MEMPROXY_CLASS_INLINE(ACLMyIP)
+MEMPROXY_CLASS_INLINE(ACLMyIP) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLMYIP_H */
-
/*
- * $Id: ACLMyPort.h,v 1.1 2003/02/25 12:22:33 robertc Exp $
+ * $Id: ACLMyPort.h,v 1.2 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ACLMYPORT_H
#define SQUID_ACLMYPORT_H
+
#include "ACLStrategy.h"
#include "ACLStrategised.h"
+/// \ingroup ACLAPI
class ACLMyPortStrategy : public ACLStrategy<int>
{
public:
virtual int match (ACLData<MatchType> * &, ACLChecklist *);
static ACLMyPortStrategy *Instance();
- /* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
- * private constructors with no friends */
+ /**
+ * Not implemented to prevent copies of the instance.
+ \par
+ * Not private to prevent brain dead g+++ warnings about
+ * private constructors with no friends
+ */
ACLMyPortStrategy(ACLMyPortStrategy const &);
private:
ACLMyPortStrategy&operator=(ACLMyPortStrategy const &);
};
+/// \ingroup ACLAPI
class ACLMyPort
{
/*
- * $Id: ACLProtocolData.cc,v 1.8 2006/05/08 23:38:33 robertc Exp $
+ * $Id: ACLProtocolData.cc,v 1.9 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
/* explicit instantiation required for some systems */
-template cbdata_type List<protocol_t>
-::CBDATA_List;
+/// \cond AUTODOCS-IGNORE
+template cbdata_type List<protocol_t>::CBDATA_List;
+/// \endcond
wordlist *
ACLProtocolData::dump()
-
/*
* $Id$
*
char const *type_;
};
-MEMPROXY_CLASS_INLINE(ACLProxyAuth)
+MEMPROXY_CLASS_INLINE(ACLProxyAuth) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLPROXYAUTH_H */
-
/*
- * $Id: ACLRegexData.h,v 1.6 2005/05/08 06:36:45 hno Exp $
+ * $Id: ACLRegexData.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
relist *data;
};
-MEMPROXY_CLASS_INLINE(ACLRegexData)
+MEMPROXY_CLASS_INLINE(ACLRegexData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLREGEXDATA_H */
-
/*
* $Id$
*
static ACLSourceIP RegistryEntry_;
};
-MEMPROXY_CLASS_INLINE(ACLSourceIP)
+MEMPROXY_CLASS_INLINE(ACLSourceIP) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLSOURCEIP_H */
/*
- * $Id: ACLTimeData.h,v 1.5 2005/05/08 06:36:45 hno Exp $
+ * $Id: ACLTimeData.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
ACLTimeData *next;
};
-MEMPROXY_CLASS_INLINE(ACLTimeData)
+MEMPROXY_CLASS_INLINE(ACLTimeData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLTIMEDATA_H */
flags;
};
-MEMPROXY_CLASS_INLINE(ACLUserData)
+MEMPROXY_CLASS_INLINE(ACLUserData) /**DOCS_NOSEMI*/
#endif /* SQUID_ACLUSERDATA_H */
/*
- * $Id: AsyncCall.cc,v 1.3 2008/02/12 23:40:02 rousskov Exp $
+ * $Id: AsyncCall.cc,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*/
#include "squid.h"
return !isCanceled;
}
-// TODO: make this method const by providing a const getDialer()
+/// \todo make this method const by providing a const getDialer()
void
AsyncCall::print(std::ostream &os)
{
return true;
}
-
/*
- * $Id: AsyncCall.h,v 1.3 2008/02/12 23:40:02 rousskov Exp $
+ * $Id: AsyncCall.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*/
#ifndef SQUID_ASYNCCALL_H
#include "event.h"
//#include "TextException.h"
-// A call is asynchronous if the caller proceeds after the call is made,
-// and the callee receives the call during the next main loop iteration.
-// Asynchronous calls help avoid nasty call-me-when-I-call-you loops
-// that humans often have trouble understanding or implementing correctly.
-
-// Asynchronous calls are currently implemented via Squid events. The call
-// event stores the pointer to the callback function and cbdata-protected
-// callback data. To call a method of an object, the method is wrapped
-// in a method-specific, static callback function and the pointer to the
-// object is passed to the wrapper. For the method call to be safe, the
-// class must be cbdata-enabled.
-
-// You do not have to use the macros below to make or receive asynchronous
-// method calls, but they give you a uniform interface and handy call
-// debugging.
+/**
+ \defgroup AsynCallsAPI Async-Calls API
+ \par
+ * A call is asynchronous if the caller proceeds after the call is made,
+ * and the callee receives the call during the next main loop iteration.
+ * Asynchronous calls help avoid nasty call-me-when-I-call-you loops
+ * that humans often have trouble understanding or implementing correctly.
+ \par
+ * Asynchronous calls are currently implemented via Squid events. The call
+ * event stores the pointer to the callback function and cbdata-protected
+ * callback data. To call a method of an object, the method is wrapped
+ * in a method-specific, static callback function and the pointer to the
+ * object is passed to the wrapper. For the method call to be safe, the
+ * class must be cbdata-enabled.
+ \par
+ * You do not have to use the macros below to make or receive asynchronous
+ * method calls, but they give you a uniform interface and handy call
+ * debugging.
+ */
class CallDialer;
class AsyncCallQueue;
-// TODO: add unique call IDs
-// TODO: CBDATA_CLASS2 kids
+/**
+ \todo add unique call IDs
+ \todo CBDATA_CLASS2 kids
+ \ingroup AsyncCallsAPI
+ */
class AsyncCall: public RefCountable
{
public:
return os;
}
-// Interface for all async call dialers
+/**
+ \ingroup AsyncCallAPI
+ * Interface for all async call dialers
+ */
class CallDialer
{
public:
virtual void print(std::ostream &os) const = 0;
};
-// This template implements an AsyncCall using a specified Dialer class
+/**
+ \ingroup AsyncCallAPI
+ * This template implements an AsyncCall using a specified Dialer class
+ */
template <class Dialer>
class AsyncCallT: public AsyncCall
{
return new AsyncCallT<Dialer>(aDebugSection, aDebugLevel, aName, aDialer);
}
-/* Call scheduling helpers. Use ScheduleCallHere if you can. */
+/** Call scheduling helper. Use ScheduleCallHere if you can. */
extern bool ScheduleCall(const char *fileName, int fileLine, AsyncCall::Pointer &call);
+
+/** Call scheduling helper. */
#define ScheduleCallHere(call) ScheduleCall(__FILE__, __LINE__, (call))
/*
- * $Id: AuthConfig.h,v 1.4 2007/05/09 07:45:58 wessels Exp $
+ * $Id: AuthConfig.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
*/
class AuthUserRequest;
+
+/// \ingroup AuthAPI
class AuthConfig
{
virtual ~AuthConfig(){}
- /* Is this configuration active? (helpers running etc etc */
+ /**
+ * Used by squid to determine whether the auth module has successfully initialised itself with the current configuration.
+ *
+ \retval true Authentication Module loaded and running.
+ \retval false No Authentication Module loaded.
+ */
virtual bool active() const = 0;
- /* new decode API: virtual factory pattern */
+
+ /**
+ * new decode API: virtual factory pattern
+ \par
+ * Responsible for decoding the passed authentication header, creating or
+ * linking to a AuthUser object and for storing any needed details to complete
+ * authentication in AuthUserRequest::authenticate().
+ *
+ \param proxy_auth Login Pattern to parse.
+ \retval * Details needed to authenticate.
+ */
virtual AuthUserRequest *decode(char const *proxy_auth) = 0;
- /* squid is finished with this config, release any unneeded resources.
+
+ /**
+ * squid is finished with this config, release any unneeded resources.
* If a singleton, delete will not occur. if not a singleton (future),
* delete will occur when no references are held.
- * TODO: we need a 'done for reconfigure' and a 'done permanently' concept.
+ *
+ \todo we need a 'done for reconfigure' and a 'done permanently' concept.
*/
virtual void done() = 0;
- /* is this config complete enough to run */
+
+ /**
+ * The configured function is used to see if the auth module has been given valid
+ * parameters and is able to handle authentication requests.
+ *
+ \retval true Authentication Module configured ready for use.
+ \retval false Not configured or Configuration Error.
+ * No other module functions except Shutdown/Dump/Parse/FreeConfig will be called by Squid.
+ */
virtual bool configured() const = 0;
- /* output the parameters */
+
+ /**
+ * Responsible for writing to the StoreEntry the configuration parameters that a user
+ * would put in a config file to recreate the running configuration.
+ */
virtual void dump(StoreEntry *, const char *, AuthConfig *) = 0;
- /* add headers as needed when challenging for auth */
+
+ /** add headers as needed when challenging for auth */
virtual void fixHeader(AuthUserRequest *, HttpReply *, http_hdr_type, HttpRequest *) = 0;
- /* prepare to handle requests */
+ /** prepare to handle requests */
virtual void init(AuthConfig *) = 0;
- /* expose any/all statistics to a CacheManager */
+ /** expose any/all statistics to a CacheManager */
virtual void registerWithCacheManager(CacheManager & manager);
- /* parse config options */
+ /** parse config options */
virtual void parse(AuthConfig *, int, char *) = 0;
- /* the http string id */
+ /** the http string id */
virtual const char * type() const = 0;
};
/*
- * $Id: AuthScheme.h,v 1.1 2004/08/30 03:28:56 robertc Exp $
+ * $Id: AuthScheme.h,v 1.2 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "squid.h"
#include "Array.h"
-/* I represent a authentication scheme. For now my children
- * store both the scheme metadata, and the scheme configuration/
+/**
+ \defgroup AuthSchemeAPI Authentication Scheme API
+ \ingroup AuthAPI
+ */
+
+/**
+ \ingroup AuthAPI
+ \ingroup AuthSchemeAPI
+ \par
+ * I represent an authentication scheme. For now my children
+ * store both the scheme metadata, and the scheme configuration.
+ \par
* Should we need multiple configs of a single scheme,
* a new class AuthConfiguration should be made, and the
* config specific calls on AuthScheme moved to it.
*/
-
class AuthScheme
{
static Vector<AuthScheme*> *_Schemes;
};
-
-
#endif /* SQUID_AUTHSCHEME_H */
/*
- * $Id: AuthUser.h,v 1.6 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: AuthUser.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class AuthUserRequest;
+/**
+ * \ingroup AuthAPI
+ * This is the main user related structure. It stores user-related data,
+ * and is persistent across requests. It can even persist across
+ * multiple external authentications. One major benefit of preserving this
+ * structure is the cached ACL match results. This structure, is private to
+ * the authentication framework.
+ */
class AuthUser
{
/* auth_type and auth_module are deprecated. Do Not add new users of these fields.
* Aim to remove shortly
*/
- /* this determines what scheme owns the user data. */
+ /** \deprecated this determines what scheme owns the user data. */
auth_type_t auth_type;
- /* the config for this user */
+ /** the config for this user */
AuthConfig *config;
- /* we only have one username associated with a given auth_user struct */
+ /** we only have one username associated with a given auth_user struct */
auth_user_hash_pointer *usernamehash;
- /* we may have many proxy-authenticate strings that decode to the same user */
+ /** we may have many proxy-authenticate strings that decode to the same user */
dlink_list proxy_auth_list;
dlink_list proxy_match_cache;
size_t ipcount;
long expiretime;
- /* how many references are outstanding to this instance */
+ /** how many references are outstanding to this instance */
size_t references;
- /* the auth_user_request structures that link to this. Yes it could be a splaytree
+ /** the auth_user_request structures that link to this. Yes it could be a splaytree
* but how many requests will a single username have in parallel? */
dlink_list requests;
static void cacheInit ();
static void CachedACLsReset();
- void absorb(auth_user_t *from);
+ void absorb(AuthUser *from);
virtual ~AuthUser ();
_SQUID_INLINE_ char const *username() const;
_SQUID_INLINE_ void username(char const *);
private:
static void cacheCleanup (void *unused);
- /*
+ /**
* DPW 2007-05-08
* The username_ memory will be allocated via
* xstrdup(). It is our responsibility.
*/
char const *username_;
- /* what ip addresses has this user been seen at?, plus a list length cache */
+ /** what ip addresses has this user been seen at?, plus a list length cache */
dlink_list ip_list;
};
/*
- * $Id: AuthUserRequest.h,v 1.8 2008/02/12 23:29:25 rousskov Exp $
+ * $Id: AuthUserRequest.h,v 1.9 2008/02/26 21:49:34 amosjeffries Exp $
*
* DO NOT MODIFY NEXT 2 LINES:
* arch-tag: 674533af-8b21-4641-b71a-74c4639072a0
time_t ip_expiretime;
};
+/**
+ \ingroup AuthAPI
+ * This is a short lived structure is the visible aspect of the authentication framework.
+ */
class AuthUserRequest
{
public:
- /* this is the object passed around by client_side and acl functions */
- /* it has request specific data, and links to user specific data */
- /* the user */
+ /**
+ * This is the object passed around by client_side and acl functions
+ * it has request specific data, and links to user specific data
+ * the user
+ */
auth_user_t *_auth_user;
+ /**
+ * Used by squid to determine what the next step in performing authentication for a given scheme is.
+ *
+ \retval -2 ERROR in the auth module. Cannot determine request direction.
+ \retval -1 The auth module needs to send data to an external helper.
+ * Squid will prepare for a callback on the request and call the AUTHSSTART function.
+ \retval 0 The auth module has all the information it needs to perform the authentication and provide a succeed/fail result.
+ \retval 1 The auth module needs to send a new challenge to the request originator.
+ * Squid will return the appropriate status code (401 or 407) and call the registered FixError function to allow the auth module to insert it's challenge.
+ */
int direction();
+
+ /**
+ * Used by squid to determine whether the auth scheme has successfully authenticated the user request.
+ *
+ \retval true User has successfully been authenticated.
+ \retval false Timeouts on cached credentials have occurred or for any reason the credentials are not valid.
+ */
virtual int authenticated() const = 0;
virtual void authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type) = 0;
/* template method */
virtual void addHeader(HttpReply * rep, int accel);
virtual void addTrailer(HttpReply * rep, int accel);
virtual void onConnectionClose(ConnStateData *);
- /* template method */
- virtual void module_start(RH *, void *) = 0;
+
+ /**
+ * Called when squid is ready to put the request on hold and wait for a callback from the auth module
+ * when the auth module has performed it's external activities.
+ *
+ \param handler Handler to process the callback when its run
+ \param data CBDATA for handler
+ */
+ virtual void module_start(RH *handler, void *data) = 0;
+
virtual AuthUser *user() {return _auth_user;}
virtual const AuthUser *user() const {return _auth_user;}
void start ( RH * handler, void *data);
char const * denyMessage (char const * const default_message = NULL);
- /* these two are possibly overrideable in future */
+
+ /** Possibly overrideable in future */
void setDenyMessage (char const *);
+
+ /** Possibly overrideable in future */
char const * getDenyMessage ();
size_t refCount() const;
void _lock (); // please use AUTHUSERREQUESTLOCK()
void _unlock (); // please use AUTHUSERREQUESTUNLOCK()
+ /**
+ * Squid does not make assumptions about where the username is stored.
+ * This function must return a pointer to a NULL terminated string to be used in logging the request.
+ * The string should NOT be allocated each time this function is called.
+ *
+ \retval NULL No username/usercode is known.
+ \retval * Null-terminated username string.
+ */
char const *username() const;
AuthScheme *scheme() const;
static auth_acl_t authenticate(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData * conn, IPAddress &src_addr);
- /* return a message on the 407 error pages */
+ /** return a message on the 407 error pages */
char *message;
- /* how many 'processes' are working on this data */
+ /** how many 'processes' are working on this data */
size_t references;
- /* We only attempt authentication once per http request. This
+ /**
+ * We only attempt authentication once per http request. This
* is to allow multiple auth acl references from different _access areas
* when using connection based authentication
*/
};
/* AuthUserRequest */
+
+/**
+ \ingroup AuthAPI
+ \deprecated Use AuthUserRequest::refCount() instead.
+ */
extern size_t authenticateRequestRefCount (AuthUserRequest *);
+/// \ingroup AuthAPI
extern void authenticateFixHeader(HttpReply *, AuthUserRequest *, HttpRequest *, int, int);
+/// \ingroup AuthAPI
extern void authenticateAddTrailer(HttpReply *, AuthUserRequest *, HttpRequest *, int);
+/// \ingroup AuthAPI
extern void authenticateAuthUserRequestRemoveIp(AuthUserRequest *, IPAddress const &);
+/// \ingroup AuthAPI
extern void authenticateAuthUserRequestClearIp(AuthUserRequest *);
+/// \ingroup AuthAPI
extern int authenticateAuthUserRequestIPCount(AuthUserRequest *);
+/// \ingroup AuthAPI
+/// \deprecated Use AuthUserRequest::direction() instead.
extern int authenticateDirection(AuthUserRequest *);
+/// \ingroup AuthAPI
+/// See AuthUserRequest::authenticated()
extern int authenticateUserAuthenticated(AuthUserRequest *);
+/// \ingroup AuthAPI
extern int authenticateValidateUser(AuthUserRequest *);
+/// \todo Drop dead code? or make a debugging option.
#if 0
#define AUTHUSERREQUESTUNLOCK(a,b) if(a){(a)->_unlock();debugs(0,0,HERE << "auth_user_request " << a << " was unlocked for " << b); (a)=NULL;}
#define AUTHUSERREQUESTLOCK(a,b) { (a)->_lock(); debugs(0,0,HERE << "auth_user_request " << a << " was locked for " << b); }
/*
- * $Id: CacheManager.h,v 1.1 2006/05/29 00:14:59 robertc Exp $
+ * $Id: CacheManager.h,v 1.2 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "squid.h"
+/**
+ \defgroup CacheManagerAPI Cache Manager API
+ \ingroup Components
+ */
+/// \ingroup CacheManagerAPI
extern void cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry);
-/*
+/**
+ \ingroup CacheManagerAPI
* A single menu item in the cache manager - an 'action'.
*/
-
class CacheManagerAction
{
};
-/*
+/**
+ \ingroup CacheManagerAPI
* a CacheManager - the menu system for interacting with squid.
* This is currently just an adapter to the global cachemgr* routines to
* provide looser coupling between modules, but once fully transitioned,
* an instance of this class will represent a single independent manager.
*/
-
class CacheManager
{
-
/*
- * $Id: CommonPool.h,v 1.5 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: CommonPool.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
#include "SquidString.h"
#include "CompositePoolNode.h"
-/* Next steps: make this a composite, and TypeLabel a composite method.
+/*
+ \ingroup DelayPoolsAPI
+ *
+ \todo Next steps: make this a composite, and TypeLabel a composite method.
* Then we have a legacy composite which returns class 1/2/3, and new
* composites which return a descriptor of some sort.
*/
-
class CommonPool
{
-
/*
- * $Id: CompositePoolNode.h,v 1.9 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: CompositePoolNode.h,v 1.10 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
class AuthUserRequest;
+/// \ingroup DelayPoolsAPI
class CompositePoolNode : public RefCountable, public Updateable
{
virtual DelayIdComposite::Pointer id(CompositeSelectionDetails &) = 0;
void delayRead(DeferredRead const &);
+ /// \ingroup DelayPoolsAPI
class CompositeSelectionDetails
{
-
/*
- * $Id: DelayBucket.cc,v 1.7 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: DelayBucket.cc,v 1.8 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
#include "DelayBucket.h"
#include "DelaySpec.h"
#include "Store.h"
-/*
+
+#if DEAD_CODE // ?
#include "DelayPools.h"
#include "StoreClient.h"
#include "MemObject.h"
#include "DelayPool.h"
#include "DelayVector.h"
#include "NullDelayId.h"
-*/
+#endif
void
DelayBucket::stats(StoreEntry *entry)const
}
void
-DelayBucket::update (DelaySpec const &rate, int incr)
+DelayBucket::update(DelaySpec const &rate, int incr)
{
if (rate.restore_bps != -1 &&
(level() += rate.restore_bps * incr) > rate.max_bytes)
}
int
-DelayBucket::bytesWanted (int minimum, int maximum) const
+DelayBucket::bytesWanted(int minimum, int maximum) const
{
int result = max(minimum, min(maximum, level()));
return result;
}
void
-DelayBucket::init (DelaySpec const &rate)
+DelayBucket::init(DelaySpec const &rate)
{
level() = (int) (((double)rate.max_bytes *
Config.Delay.initial) / 100);
}
#endif
-
-
/*
- * $Id: DelayBucket.h,v 1.2 2003/02/21 22:50:05 robertc Exp $
+ * $Id: DelayBucket.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class DelaySpec;
/* don't use remote storage for these */
+/// \ingroup DelayPoolsAPI
class DelayBucket
{
/*
- * $Id: DelayConfig.h,v 1.4 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: DelayConfig.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 3 Configuration Settings
* AUTHOR: Robert Collins
class ConfigParser;
+/// \ingroup DelayPoolsAPI
class DelayConfig
{
-
/*
- * $Id: DelayId.h,v 1.3 2003/03/04 01:40:25 robertc Exp $
+ * $Id: DelayId.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class ClientHttpRequest;
#include "DelayIdComposite.h"
+/// \ingroup DelayPoolsAPI
class DelayId
{
-
/*
- * $Id: DelayPool.cc,v 1.7 2007/04/23 06:11:55 wessels Exp $
+ * $Id: DelayPool.cc,v 1.8 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
void
DelayPool::parse()
{
- assert (theComposite() != NULL);
+ assert(theComposite() != NULL);
theComposite()->parse();
}
void
-DelayPool::dump (StoreEntry *entry, unsigned int i) const
+DelayPool::dump(StoreEntry *entry, unsigned int i) const
{
if (theComposite() == NULL)
return;
pool = NULL;
}
-/* XXX create DelayIdComposite.cc */
+/** \todo XXX create DelayIdComposite.cc */
void
CompositePoolNode::delayRead(DeferredRead const &aRead)
{
void
CompositePoolNode::kickReads()
{
- /* we only start one, because delay pools may have **many** attached connections,
+ /**
+ * we only start one, because delay pools may have **many** attached connections,
* and kicking them all off would be chaotic.
* This may need to be reviewed.
*/
/*
- * $Id: DelayPool.h,v 1.2 2003/02/21 22:50:05 robertc Exp $
+ * $Id: DelayPool.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
class acl_access;
+/// \ingroup DelayPoolsAPI
class DelayPool
{
-
/*
- * $Id: DelayPools.h,v 1.4 2006/05/29 00:14:59 robertc Exp $
+ * $Id: DelayPools.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_DELAYPOOLS_H
#define SQUID_DELAYPOOLS_H
-/* forward decls */
+/**
+ \defgroup DelayPoolsAPI Delay Pools API
+ \ingroup Components
+ */
+/* forward decls */
class CacheManager;
#include "Array.h"
+/// \ingroup DelayPoolsAPI
class Updateable
{
class DelayPool;
+/// \ingroup DelayPoolsAPI
class DelayPools
{
-
/*
- * $Id: DelaySpec.h,v 1.2 2003/02/21 22:50:05 robertc Exp $
+ * $Id: DelaySpec.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_DELAYSPEC_H
#define SQUID_DELAYSPEC_H
+/// \ingroup DelyPoolsAPI
class DelaySpec
{
-
/*
- * $Id: DelayTagged.h,v 1.6 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: DelayTagged.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
#include "Array.h"
#include "splay.h"
+/// \ingroup DelayPoolsAPI
class DelayTaggedBucket : public RefCountable
{
String tag;
};
+/// \ingroup DelayPoolsAPI
class DelayTagged : public CompositePoolNode
{
private:
-class Id:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class Id:public DelayIdComposite
{
public:
-
/*
- * $Id: DelayUser.h,v 1.7 2003/08/04 22:14:40 robertc Exp $
+ * $Id: DelayUser.h,v 1.8 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
#include "Array.h"
#include "splay.h"
+/// \ingroup DelayPoolsAPI
class DelayUserBucket : public RefCountable
{
AuthUser *authUser;
};
+/// \ingroup DelayPoolsAPI
class DelayUser : public CompositePoolNode
{
private:
-class Id:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class Id:public DelayIdComposite
{
public:
-
/*
- * $Id: DelayVector.h,v 1.9 2003/08/04 22:14:40 robertc Exp $
+ * $Id: DelayVector.h,v 1.10 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "CompositePoolNode.h"
+/// \ingroup DelayPoolsAPI
class DelayVector : public CompositePoolNode
{
private:
-class Id:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class Id:public DelayIdComposite
{
public:
-
/*
- * $Id: AIODiskFile.cc,v 1.6 2007/05/29 13:31:43 amosjeffries Exp $
+ * $Id: AIODiskFile.cc,v 1.7 2008/02/26 21:49:40 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
*
* Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
*/
-/*
+
+/**
* Author: Adrian Chadd <adrian@squid-cache.org>
*
+ \par
* These routines are simple plugin replacements for the file_* routines
* in disk.c . They back-end into the POSIX AIO routines to provide
* a nice and simple async IO framework for COSS.
*
+ \par
* AIO is suitable for COSS - the only sync operations that the standard
* supports are read/write, and since COSS works on a single file
* per storedir it should work just fine.
CBDATA_CLASS_INIT(AIODiskFile);
void *
-AIODiskFile::operator new (size_t)
+AIODiskFile::operator new(size_t unused)
{
CBDATA_INIT_TYPE(AIODiskFile);
return cbdataAlloc(AIODiskFile);
}
void
-AIODiskFile::operator delete (void *address)
+AIODiskFile::operator delete(void *address)
{
cbdataFree(address);
}
-AIODiskFile::AIODiskFile (char const *aPath, AIODiskIOStrategy *aStrategy) : fd(-1), closed(true), error_(false)
+AIODiskFile::AIODiskFile(char const *aPath, AIODiskIOStrategy *aStrategy) : fd(-1), closed(true), error_(false)
{
assert (aPath);
path = aPath;
}
void
-AIODiskFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
+AIODiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
{
/* Simulate async calls */
#ifdef _SQUID_WIN32_
ioRequestor = callback;
if (fd < 0) {
- debugs(79, 3, "BlockingFile::open: got failure (" << errno << ")");
+ debugs(79, 3, HERE << ": got failure (" << errno << ")");
error(true);
} else {
closed = false;
store_open_disk_fd++;
- debugs(79, 3, "BlockingFile::open: opened FD " << fd);
+ debugs(79, 3, HERE << ": opened FD " << fd);
}
callback->ioCompletedNotification();
}
void
-AIODiskFile::create (int flags, mode_t mode, RefCount<IORequestor> callback)
+AIODiskFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
{
/* We use the same logic path for open */
open(flags, mode, callback);
-
/*
- * $Id: AIODiskFile.h,v 1.4 2007/05/29 13:31:43 amosjeffries Exp $
+ * $Id: AIODiskFile.h,v 1.5 2008/02/26 21:49:40 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
void operator delete (void *);
AIODiskFile (char const *path, AIODiskIOStrategy *);
~AIODiskFile();
- virtual void open (int, mode_t, RefCount<IORequestor>);
+
+ /// \bug the code has this as "IORequestor::Pointer callback"
+ virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
+
virtual void create (int, mode_t, RefCount<IORequestor>);
virtual void read(ReadRequest *);
virtual void write(WriteRequest *);
-
/*
- * $Id: BlockingFile.cc,v 1.4 2007/04/30 16:56:11 wessels Exp $
+ * $Id: BlockingFile.cc,v 1.5 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Robert Collins
#include "DiskIO/WriteRequest.h"
CBDATA_CLASS_INIT(BlockingFile);
+
void *
-BlockingFile::operator new (size_t)
+BlockingFile::operator new(size_t sz)
{
CBDATA_INIT_TYPE(BlockingFile);
BlockingFile *result = cbdataAlloc(BlockingFile);
}
void
-BlockingFile::operator delete (void *address)
+BlockingFile::operator delete(void *address)
{
BlockingFile *t = static_cast<BlockingFile *>(address);
cbdataFree(t);
}
-BlockingFile::BlockingFile (char const *aPath) : fd (-1), closed (true), error_(false)
+BlockingFile::BlockingFile(char const *aPath) : fd (-1), closed (true), error_(false)
{
- assert (aPath);
+ assert(aPath);
debugs(79, 3, "BlockingFile::BlockingFile: " << aPath);
path_ = xstrdup (aPath);
}
}
void
-BlockingFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
+BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
{
/* Simulate async calls */
fd = file_open(path_ , flags);
callback->ioCompletedNotification();
}
+/**
+ * Alias for BlockingFile::open(...)
+ \copydoc BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
+ */
void
-BlockingFile::create (int flags, mode_t mode, IORequestor::Pointer callback)
+BlockingFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
{
/* We use the same logic path for open */
open(flags, mode, callback);
}
void
-BlockingFile::close ()
+BlockingFile::close()
{
debugs(79, 3, "BlockingFile::close: " << this << " closing for " << ioRequestor.getRaw());
doClose();
}
bool
-BlockingFile::ioInProgress()const
+BlockingFile::ioInProgress() const
{
- /* IO is never pending with UFS */
+ /** \retval false IO is never pending with UFS */
return false;
}
-
/*
- * $Id: BlockingFile.h,v 1.2 2006/08/21 00:50:43 robertc Exp $
+ * $Id: BlockingFile.h,v 1.3 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Robert Collins
#include "cbdata.h"
#include "DiskIO/DiskFile.h"
+#include "DiskIO/IORequestor.h"
class BlockingFile : public DiskFile
{
public:
void *operator new(size_t);
void operator delete(void *);
- BlockingFile (char const *path);
+ BlockingFile(char const *path);
~BlockingFile();
- virtual void open (int, mode_t, RefCount<IORequestor>);
- virtual void create (int, mode_t, RefCount<IORequestor>);
+ virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
+ virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
virtual void read(ReadRequest *);
virtual void write(WriteRequest *);
- virtual void close ();
+ virtual void close();
virtual bool error() const;
virtual int getFD() const { return fd;}
virtual bool canRead() const;
- virtual bool ioInProgress()const;
+ virtual bool ioInProgress() const;
private:
static DRCB ReadDone;
-
/*
- * $Id: DiskdFile.cc,v 1.4 2007/08/16 23:32:28 hno Exp $
+ * $Id: DiskdFile.cc,v 1.5 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 79 Squid-side DISKD I/O functions.
* AUTHOR: Duane Wessels
CBDATA_CLASS_INIT(DiskdFile);
void *
-DiskdFile::operator new (size_t)
+DiskdFile::operator new(size_t unused)
{
CBDATA_INIT_TYPE(DiskdFile);
DiskdFile *result = cbdataAlloc(DiskdFile);
}
void
-DiskdFile::operator delete (void *address)
+DiskdFile::operator delete(void *address)
{
DiskdFile *t = static_cast<DiskdFile *>(address);
debugs(79, 3, "diskdFile with base " << t << " deleting");
cbdataFree(t);
}
-DiskdFile::DiskdFile (char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO),
+DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO),
inProgressIOs (0)
{
assert (aPath);
}
void
-DiskdFile::open (int flags, mode_t aMode, IORequestor::Pointer callback)
+DiskdFile::open(int flags, mode_t aMode, RefCount< IORequestor > callback)
{
debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
assert (ioRequestor.getRaw() == NULL);
}
void
-DiskdFile::create (int flags, mode_t aMode, IORequestor::Pointer callback)
+DiskdFile::create(int flags, mode_t aMode, RefCount< IORequestor > callback)
{
debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
assert (ioRequestor.getRaw() == NULL);
-
/*
- * $Id: DiskdFile.h,v 1.2 2006/08/21 00:50:45 robertc Exp $
+ * $Id: DiskdFile.h,v 1.3 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 79 Squid-side DISKD I/O functions.
* AUTHOR: Duane Wessels
struct diomsg;
+/**
+ \ingroup diskd
+ */
class DiskdFile : public DiskFile
{
public:
- void * operator new (size_t);
- void operator delete (void *);
- DiskdFile (char const *path, DiskdIOStrategy *);
+ void * operator new(size_t);
+ void operator delete(void *);
+ DiskdFile(char const *path, DiskdIOStrategy *);
~DiskdFile();
- virtual void open (int, mode_t, RefCount<IORequestor>);
- virtual void create (int, mode_t, RefCount<IORequestor>);
+ virtual void open(int flags, mode_t aMode, RefCount<IORequestor> callback);
+ virtual void create(int flags, mode_t aMode, RefCount<IORequestor> callback);
virtual void read(ReadRequest *);
virtual void write(WriteRequest *);
- virtual void close ();
+ virtual void close();
virtual bool error() const;
virtual bool canRead() const;
- virtual bool ioInProgress()const;
+ virtual bool ioInProgress() const;
/* Temporary */
int getID() const {return id;}
- void completed (diomsg *);
+ void completed(diomsg *);
private:
int id;
/*
- * $Id: DiskdIOStrategy.cc,v 1.12 2007/12/14 23:11:50 amosjeffries Exp $
+ * $Id: DiskdIOStrategy.cc,v 1.13 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 79 Squid-side DISKD I/O functions.
* AUTHOR: Duane Wessels
}
int
-DiskdIOStrategy::send(int mtype, int id, StoreIOState::Pointer sio, size_t size, off_t offset, ssize_t shm_offset)
+DiskdIOStrategy::send(int mtype, int id, RefCount<StoreIOState> sio, size_t size, off_t offset, ssize_t shm_offset)
{
diomsg M;
M.callback_data = cbdataReference(sio.getRaw());
-
/*
- * $Id: DiskdIOStrategy.h,v 1.4 2007/08/16 23:32:28 hno Exp $
+ * $Id: DiskdIOStrategy.h,v 1.5 2008/02/26 21:49:40 amosjeffries Exp $
*
* DEBUG: section 79 Squid-side DISKD I/O functions.
* AUTHOR: Duane Wessels
#ifndef __STORE_DISKDIOSTRATEGY_H__
#define __STORE_DISKDIOSTRATEGY_H__
-/*
- * magic2 is the point at which we start blocking on msgsnd/msgrcv.
- * If a queue has magic2 (or more) messages away, then we read the
- * queue until the level falls below magic2. Recommended value
- * is 75% of SHMBUFS. magic1 is the number of messages away which we
- * stop allowing open/create for.
- */
-
struct diomsg;
+/// \ingroup diskd
class SharedMemory
{
class ReadRequest;
+/// \ingroup diskd
class DiskdIOStrategy : public DiskIOStrategy
{
virtual void sync();
virtual int callback();
virtual void statfs(StoreEntry & sentry)const;
- int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, RefCountable_ *);
- /* public for accessing return address's */
+ int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, RefCountable_ *requestor);
+
+ /** public for accessing return address's */
SharedMemory shm;
private:
int SEND(diomsg * M, int mtype, int id, size_t size, off_t offset, ssize_t shm_offset);
void handle(diomsg * M);
void unlinkDone(diomsg * M);
+
+ /**
+ * magic1 is the number of messages away which we
+ * stop allowing open/create for.
+ */
int magic1;
+
+ /**
+ * magic2 is the point at which we start blocking on msgsnd/msgrcv.
+ * If a queue has magic2 (or more) messages away, then we read the
+ * queue until the level falls below magic2. Recommended value
+ * is 75% of SHMBUFS.
+ */
int magic2;
+
int away;
int smsgid;
int rmsgid;
size_t instanceID;
};
+/// \ingroup diskd
#define SHMBUF_BLKSZ SM_PAGE_SIZE
-
+/// \ingroup diskd
struct diskd_stats_t
{
int open_fail_queue_len;
open, create, close, unlink, read, write;
};
+/// \ingroup diskd
extern diskd_stats_t diskd_stats;
#endif
-
/*
- * $Id: DiskFile.h,v 1.1 2004/12/20 16:30:38 robertc Exp $
+ * $Id: DiskFile.h,v 1.2 2008/02/26 21:49:38 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
public:
typedef RefCount<DiskFile> Pointer;
- virtual void open (int, mode_t, RefCount<IORequestor>) = 0;
- virtual void create (int, mode_t, RefCount<IORequestor>) = 0;
+
+ virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback) = 0;
+ virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback) = 0;
virtual void read(ReadRequest *) = 0;
virtual void write(WriteRequest *) = 0;
- virtual void close () = 0;
+ virtual void close() = 0;
virtual bool canRead() const = 0;
virtual bool canWrite() const {return true;}
- /* During miogration only */
+ /** During migration only */
virtual int getFD() const {return -1;}
virtual bool error() const = 0;
- /* Inform callers if there is IO in progress */
+ /** Inform callers if there is IO in progress */
virtual bool ioInProgress() const = 0;
};
-
/*
- * $Id: DiskIOStrategy.h,v 1.1 2004/12/20 16:30:38 robertc Exp $
+ * $Id: DiskIOStrategy.h,v 1.2 2008/02/26 21:49:38 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
public:
virtual ~DiskIOStrategy(){}
- /* Can the IO Strategy handle more requests ? */
+ /** Can the IO Strategy handle more requests ? */
virtual bool shedLoad() = 0;
- /* What is the current load? 999 = 99.9% */
+
+ /** What is the current load? 999 = 99.9% */
virtual int load() = 0;
- /* Return a handle for performing IO operations */
- virtual RefCount<DiskFile> newFile (char const *path) = 0;
- /* flush all IO operations */
+
+ /** Return a handle for performing IO operations */
+ virtual RefCount<DiskFile> newFile(char const *path) = 0;
+
+ /** flush all IO operations */
virtual void sync() {}
- /* unlink a file by path */
- virtual void unlinkFile (char const *) = 0;
+ /** unlink a file by path */
+ virtual void unlinkFile(char const *) = 0;
- /* perform any pending callbacks */
+ /** perform any pending callbacks */
virtual int callback() { return 0; }
- /* Init per-instance logic */
+ /** Init per-instance logic */
virtual void init() {}
- /* cachemgr output on the IO instance stats */
+ /** cachemgr output on the IO instance stats */
virtual void statfs(StoreEntry & sentry)const {}
- /* module specific options */
+ /** module specific options */
virtual ConfigOption *getOptionTree() const { return NULL;}
};
-
/*
- * $Id: DiskThreadsDiskFile.cc,v 1.10 2007/04/30 16:56:13 wessels Exp $
+ * $Id: DiskThreadsDiskFile.cc,v 1.11 2008/02/26 21:49:41 amosjeffries Exp $
*
* DEBUG: section 79 Disk IO Routines
* AUTHOR: Robert Collins
}
void
-DiskThreadsDiskFile::operator delete (void *address)
+DiskThreadsDiskFile::operator delete(void *address)
{
DiskThreadsDiskFile *t = static_cast<DiskThreadsDiskFile *>(address);
cbdataFree(t);
}
-DiskThreadsDiskFile::DiskThreadsDiskFile (char const *aPath, DiskThreadsIOStrategy *anIO):fd(-1), errorOccured (false), IO(anIO),
+DiskThreadsDiskFile::DiskThreadsDiskFile(char const *aPath, DiskThreadsIOStrategy *anIO):fd(-1), errorOccured (false), IO(anIO),
inProgressIOs (0)
{
assert (aPath);
}
void
-DiskThreadsDiskFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
+DiskThreadsDiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
{
statCounter.syscalls.disk.opens++;
#if !ASYNC_OPEN
}
void
-DiskThreadsDiskFile::create (int flags, mode_t mode, IORequestor::Pointer callback)
+DiskThreadsDiskFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
{
statCounter.syscalls.disk.opens++;
#if !ASYNC_CREATE
}
void
-DiskThreadsDiskFile::close ()
+DiskThreadsDiskFile::close()
{
debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor.getRaw());
}
bool
-DiskThreadsDiskFile::ioInProgress()const
+DiskThreadsDiskFile::ioInProgress() const
{
return inProgressIOs > 0;
}
}
void
-DiskThreadsDiskFile::readDone(int rvfd, const char *buf, int len, int errflag, ReadRequest::Pointer request)
+DiskThreadsDiskFile::readDone(int rvfd, const char *buf, int len, int errflag, RefCount<ReadRequest> request)
{
debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd);
assert (fd == rvfd);
}
void
-DiskThreadsDiskFile::writeDone (int rvfd, int errflag, size_t len, WriteRequest::Pointer request)
+DiskThreadsDiskFile::writeDone(int rvfd, int errflag, size_t len, RefCount<WriteRequest> request)
{
assert (rvfd == fd);
static int loop_detect = 0;
template<class RT>
void *
-IoResult<RT>::operator new (size_t)
+IoResult<RT>::operator new(size_t unused)
{
CBDATA_INIT_TYPE(IoResult);
IoResult<RT> *result = cbdataAlloc(IoResult);
template <class RT>
void
-IoResult<RT>::operator delete (void *address)
+IoResult<RT>::operator delete(void *address)
{
cbdataFree(address);
}
-
-
/*
- * $Id: DiskThreadsDiskFile.h,v 1.2 2006/08/21 00:50:45 robertc Exp $
+ * $Id: DiskThreadsDiskFile.h,v 1.3 2008/02/26 21:49:41 amosjeffries Exp $
*
* DEBUG: section 79 Disk IO Routines
* AUTHOR: Robert Collins
{
public:
- void * operator new (size_t);
- void operator delete (void *);
- DiskThreadsDiskFile (char const *path, DiskThreadsIOStrategy *);
+ void * operator new(size_t);
+ void operator delete(void *);
+ DiskThreadsDiskFile(char const *path, DiskThreadsIOStrategy *);
~DiskThreadsDiskFile();
- virtual void open (int, mode_t, RefCount<IORequestor>);
- virtual void create (int, mode_t, RefCount<IORequestor>);
+ virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
+ virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
virtual void read(ReadRequest *);
virtual void write(WriteRequest *);
- virtual void close ();
+ virtual void close();
virtual bool error() const;
virtual int getFD() const { return fd;}
virtual bool canRead() const;
virtual bool canWrite() const;
- virtual bool ioInProgress()const;
+ virtual bool ioInProgress() const;
private:
#if ASYNC_READ
CBDATA_CLASS(DiskThreadsDiskFile);
void doClose();
- void readDone(int fd, const char *buf, int len, int errflag, RefCount<ReadRequest>);
- void writeDone (int fd, int errflag, size_t len, RefCount<WriteRequest>);
+ void readDone(int fd, const char *buf, int len, int errflag, RefCount<ReadRequest> request);
+ void writeDone(int fd, int errflag, size_t len, RefCount<WriteRequest> request);
};
#include "DiskIO/ReadRequest.h"
template <class RT>
-
class IoResult
{
/*
- * $Id: ESI.cc,v 1.29 2008/01/20 19:46:35 serassio Exp $
+ * $Id: ESI.cc,v 1.30 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
void finish();
};
-MEMPROXY_CLASS_INLINE(esiComment)
+MEMPROXY_CLASS_INLINE(esiComment) /**DOCS_NOSEMI*/
#include "ESILiteral.h"
esiProcessResult_t bestAttemptRV() const;
};
-MEMPROXY_CLASS_INLINE(esiTry)
+MEMPROXY_CLASS_INLINE(esiTry) /**DOCS_NOSEMI*/
#include "ESIVar.h"
void selectElement();
};
-MEMPROXY_CLASS_INLINE(esiChoose)
+MEMPROXY_CLASS_INLINE(esiChoose) /**DOCS_NOSEMI*/
/* esiWhen */
void evaluate();
};
-MEMPROXY_CLASS_INLINE(esiWhen)
+MEMPROXY_CLASS_INLINE(esiWhen) /**DOCS_NOSEMI*/
/* esiOtherwise */
/*
- * $Id: ESIAssign.h,v 1.5 2007/05/29 13:31:37 amosjeffries Exp $
+ * $Id: ESIAssign.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
String unevaluatedVariable;
};
-MEMPROXY_CLASS_INLINE(ESIAssign)
+MEMPROXY_CLASS_INLINE(ESIAssign) /**DOCS_NOSEMI*/
#endif /* SQUID_ESIASSIGN_H */
/*
- * $Id: ESIExpatParser.h,v 1.4 2005/07/03 15:25:08 serassio Exp $
+ * $Id: ESIExpatParser.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
public:
ESIExpatParser(ESIParserClient *);
~ESIExpatParser();
- /* true on success */
+
+ /** \retval true on success */
bool parse(char const *dataToParse, size_t const lengthOfData, bool const endOfStream);
+
long int lineNumber() const;
char const * errorString() const;
private:
ESI_PARSER_TYPE;
- mutable XML_Parser p; /* our parser */
- static void Start(void *data, const char *el, const char **attr);
- static void End(void *data, const char *el);
- static void Default (void *data, const char *s, int len);
- static void Comment (void *data, const char *s);
+ /** our parser */
+ mutable XML_Parser p;
+ static void Start(void *data, const XML_Char *el, const char **attr);
+ static void End(void *data, const XML_Char *el);
+ static void Default (void *data, const XML_Char *s, int len);
+ static void Comment (void *data, const XML_Char *s);
XML_Parser &myParser() const {return p;}
ESIParserClient *theClient;
/*
- * $Id: ESIInclude.h,v 1.3 2004/08/30 05:12:31 robertc Exp $
+ * $Id: ESIInclude.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
void prepareRequestHeaders(HttpHeader &tempheaders, ESIVarState *vars);
};
-MEMPROXY_CLASS_INLINE(ESIInclude)
+MEMPROXY_CLASS_INLINE(ESIInclude) /**DOCS_NOSEMI*/
#endif /* SQUID_ESIINCLUDE_H */
/*
- * $Id: ESILiteral.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: ESILiteral.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
esiLiteral(esiLiteral const &);
};
-MEMPROXY_CLASS_INLINE(esiLiteral)
+MEMPROXY_CLASS_INLINE(esiLiteral) /**DOCS_NOSEMI*/
#endif /* SQUID_ESILITERAL_H */
-
/*
- * $Id: ESIParser.cc,v 1.7 2005/03/29 17:55:42 hno Exp $
+ * $Id: ESIParser.cc,v 1.8 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
/*
- * $Id: ESIParser.h,v 1.5 2005/07/03 15:25:08 serassio Exp $
+ * $Id: ESIParser.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
virtual void end(const char *el) = 0;
virtual void parserDefault (const char *s, int len) =0;
virtual void parserComment (const char *s) = 0;
- virtual ~ESIParserClient() {}}
+ virtual ~ESIParserClient() {};
-;
+};
class ESIParser : public RefCountable
{
/*
- * $Id: ESISequence.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: ESISequence.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 86 ESI processing
* AUTHOR: Robert Collins
void processStep(int dovars);
};
-MEMPROXY_CLASS_INLINE(esiSequence)
+MEMPROXY_CLASS_INLINE(esiSequence) /**DOCS_NOSEMI*/
#endif /* SQUID_ESISEQUENCE_H */
/*
- * $Id: ExternalACL.h,v 1.9 2006/05/29 00:14:59 robertc Exp $
+ * $Id: ExternalACL.h,v 1.10 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
char const *class_;
};
-MEMPROXY_CLASS_INLINE(ACLExternal)
+MEMPROXY_CLASS_INLINE(ACLExternal) /**DOCS_NOSEMI*/
extern void externalAclRegisterWithCacheManager(CacheManager & manager);
-
/*
- * $Id: HttpHeader.h,v 1.25 2008/01/22 19:53:03 rousskov Exp $
+ * $Id: HttpHeader.h,v 1.26 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
/* constant attributes of http header fields */
-/* recognized or "known" header fields; @?@ add more! */
+/** recognized or "known" header fields; @?@ add more! */
typedef enum {
HDR_BAD_HDR = -1,
HDR_ACCEPT = 0,
HDR_PROXY_CONNECTION,
HDR_PUBLIC,
HDR_RANGE,
- HDR_REQUEST_RANGE, /* some clients use this, sigh */
+ HDR_REQUEST_RANGE, /**< some clients use this, sigh */
HDR_REFERER,
HDR_RETRY_AFTER,
HDR_SERVER,
HDR_WWW_AUTHENTICATE,
HDR_AUTHENTICATION_INFO,
HDR_X_CACHE,
- HDR_X_CACHE_LOOKUP, /* tmp hack, remove later */
+ HDR_X_CACHE_LOOKUP, /**< tmp hack, remove later */
HDR_X_FORWARDED_FOR,
- HDR_X_REQUEST_URI, /* appended if ADD_X_REQUEST_URI is #defined */
+ HDR_X_REQUEST_URI, /**< appended if ADD_X_REQUEST_URI is #defined */
HDR_X_SQUID_ERROR,
HDR_NEGOTIATE,
#if X_ACCELERATOR_VARY
HDR_ENUM_END
} http_hdr_type;
-/* possible types for http header fields */
+/** possible types for http header fields */
typedef enum {
- ftInvalid = HDR_ENUM_END, /* to catch nasty errors with hdr_id<->fld_type clashes */
+ ftInvalid = HDR_ENUM_END, /**< to catch nasty errors with hdr_id<->fld_type clashes */
ftInt,
ftInt64,
ftStr,
ftDate_1123_or_ETag
} field_type;
-/* possible owners of http header */
+/** Possible owners of http header */
typedef enum {
hoNone =0,
#if USE_HTCP
class HttpHdrSc;
-/*iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
+/** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
typedef ssize_t HttpHeaderPos;
/* use this and only this to initialize HttpHeaderPos */
String value;
};
-MEMPROXY_CLASS_INLINE(HttpHeaderEntry)
+MEMPROXY_CLASS_INLINE(HttpHeaderEntry);
class HttpHeader
{
int hasListMember(http_hdr_type id, const char *member, const char separator) const;
int hasByNameListMember(const char *name, const char *member, const char separator) const;
void removeHopByHopEntries();
+
/* protected, do not use these, use interface functions instead */
- Vector<HttpHeaderEntry *> entries; /* parsed fields in raw format */
- HttpHeaderMask mask; /* bit set <=> entry present */
- http_hdr_owner_type owner; /* request or reply */
- int len; /* length when packed, not counting terminating '\0' */
+ Vector<HttpHeaderEntry *> entries; /**< parsed fields in raw format */
+ HttpHeaderMask mask; /**< bit set <=> entry present */
+ http_hdr_owner_type owner; /**< request or reply */
+ int len; /**< length when packed, not counting terminating '\0' */
protected:
+ /** \deprecated Public access replaced by removeHopByHopEntries() */
void removeConnectionHeaderEntries();
-
+
private:
HttpHeaderEntry *findLastEntry(http_hdr_type id) const;
- // Make it non-copyable. Our destructor is a bit nasty...
+ /// Made it non-copyable. Our destructor is a bit nasty...
HttpHeader(const HttpHeader &);
//assignment is used by the reset method, can't block it..
//const HttpHeader operator=(const HttpHeader &);
/*
- * $Id: HttpHeaderRange.h,v 1.11 2007/08/13 17:20:51 hno Exp $
+ * $Id: HttpHeaderRange.h,v 1.12 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
int64_t length;
};
-MEMPROXY_CLASS_INLINE(HttpHdrRangeSpec)
+MEMPROXY_CLASS_INLINE(HttpHdrRangeSpec) /**DOCS_NOSEMI*/
-/* There may be more than one byte range specified in the request.
+/**
+ * There may be more than one byte range specified in the request.
* This object holds all range specs in order of their appearence
* in the request because we SHOULD preserve that order.
*/
-
class HttpHdrRange
{
int64_t clen;
};
-MEMPROXY_CLASS_INLINE(HttpHdrRange)
-
-/* data for iterating thru range specs */
+MEMPROXY_CLASS_INLINE(HttpHdrRange) /**DOCS_NOSEMI*/
+/**
+ * Data for iterating thru range specs
+ */
class HttpHdrRangeIter
{
/*
- * $Id: HttpReply.h,v 1.23 2008/02/08 18:27:59 rousskov Exp $
+ * $Id: HttpReply.h,v 1.24 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
virtual void hdrCacheInit();
};
-MEMPROXY_CLASS_INLINE(HttpReply)
+MEMPROXY_CLASS_INLINE(HttpReply) /**DOCS_NOSEMI*/
#endif /* SQUID_HTTPREPLY_H */
/*
- * $Id: HttpRequest.h,v 1.32 2008/01/20 08:54:28 amosjeffries Exp $
+ * $Id: HttpRequest.h,v 1.33 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
};
-MEMPROXY_CLASS_INLINE(HttpRequest)
+MEMPROXY_CLASS_INLINE(HttpRequest) /**DOCS_NOSEMI*/
#endif /* SQUID_HTTPREQUEST_H */
/*
- * $Id: AsyncJob.h,v 1.3 2008/02/12 23:40:02 rousskov Exp $
+ * $Id: AsyncJob.h,v 1.4 2008/02/26 21:49:41 amosjeffries Exp $
*/
#ifndef SQUID_ASYNC_JOB_H
#define SQUID_ASYNC_JOB_H
-// TODO: move src/ICAP/AsyncJob.* to src/
+/// \todo move src/ICAP/AsyncJob.* to src/
#include "AsyncCall.h"
-/*
+/**
+ \defgroup AsyncJobAPI Async-Jobs API
+ \par
* AsyncJob is an API and a base for a class that implements a stand-alone
* "job", "task", or "logical processing thread" which receives asynchronous
* calls.
class TextException;
+/// \ingroup AsyncJobAPI
class AsyncJob
{
};
-/*
+/**
+ \ingroup AsyncJobAPI
* This is a base class for all job call dialers. It does all the job
* dialing logic (debugging, handling exceptions, etc.) except for calling
* the job method. The latter is not possible without templates and we
-
/*
- * $Id: ICP.h,v 1.10 2007/12/14 23:11:45 amosjeffries Exp $
+ * $Id: ICP.h,v 1.11 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_ICP_H
#define SQUID_ICP_H
+/**
+ \defgroup ServerProtocolICPAPI ICP
+ \ingroup ServerProtocol
+ */
+
#include "StoreClient.h"
/**
+ \ingroup ServerProtocolICPAPI
+ *
* This struct is the wire-level header.
* DO NOT add more move fields on pain of breakage.
* DO NOT add virtual methods.
*/
struct _icp_common_t
{
- unsigned char opcode; /* opcode */
- unsigned char version; /* version number */
- unsigned short length; /* total length (bytes) */
- u_int32_t reqnum; /* req number (req'd for UDP) */
+ /** opcode */
+ unsigned char opcode;
+ /** version number */
+ unsigned char version;
+ /** total length (bytes) */
+ unsigned short length;
+ /** req number (req'd for UDP) */
+ u_int32_t reqnum;
u_int32_t flags;
u_int32_t pad;
- u_int32_t shostid; /* sender host id */
+ /** sender host id */
+ u_int32_t shostid;
+
+/// \todo I don't believe this header is included in non-c++ code anywhere
+/// the struct should become a public POD class and kill these #ifdef.
#ifdef __cplusplus
_icp_common_t();
#ifdef __cplusplus
+/// \ingroup ServerProtocolICPAPI
inline icp_opcode & operator++ (icp_opcode & aCode)
{
int tmp = (int) aCode;
}
-/** \todo mempool this */
+/**
+ \ingroup ServerProtocolICPAPI
+ \todo mempool this
+ */
class ICPState
{
public:
- ICPState(icp_common_t &, HttpRequest *);
- virtual ~ ICPState();
+ ICPState(icp_common_t &aHeader, HttpRequest *aRequest);
+ virtual ~ICPState();
icp_common_t header;
HttpRequest *request;
int fd;
#endif
+/// \ingroup ServerProtocolICPAPI
struct icpUdpData
{
IPAddress address;
struct timeval queue_time;
};
-
+/// \ingroup ServerProtocolICPAPI
HttpRequest* icpGetRequest(char *url, int reqnum, int fd, IPAddress &from);
+/// \ingroup ServerProtocolICPAPI
int icpAccessAllowed(IPAddress &from, HttpRequest * icp_request);
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const IPAddress &from);
+
+/// \ingroup ServerProtocolICPAPI
extern icp_opcode icpGetCommonOpcode();
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN int icpUdpSend(int, const IPAddress &, icp_common_t *, log_type, int);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN log_type icpLogFromICPCode(icp_opcode opcode);
+/// \ingroup ServerProtocolICPAPI
void icpDenyAccess(IPAddress &from, char *url, int reqnum, int fd);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN PF icpHandleUdp;
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN PF icpUdpSendQueue;
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN void icpHandleIcpV3(int, IPAddress &, char *, int);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN int icpCheckUdpHit(StoreEntry *, HttpRequest * request);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN void icpConnectionsOpen(void);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN void icpConnectionShutdown(void);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN void icpConnectionClose(void);
+
+/// \ingroup ServerProtocolICPAPI
SQUIDCEXTERN int icpSetCacheKey(const cache_key * key);
-SQUIDCEXTERN const cache_key *icpGetCacheKey(const char *url, int reqnum);
+/// \ingroup ServerProtocolICPAPI
+SQUIDCEXTERN const cache_key *icpGetCacheKey(const char *url, int reqnum);
#endif /* SQUID_ICP_H */
-
/*
- * $Id: Mem.h,v 1.5 2008/01/22 17:13:36 rousskov Exp $
+ * $Id: Mem.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 13 High Level Memory Pool Management
* AUTHOR: Harvest Derived
-
/*
- * $Id: MemBuf.cc,v 1.42 2006/09/20 08:13:38 adrian Exp $
+ * $Id: MemBuf.cc,v 1.43 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 59 auto-growing Memory Buffer with printf
* AUTHOR: Alex Rousskov
*
*/
-/*
- * To-Do: use memory pools for .buf recycling @?@ @?@
+/**
+ \todo use memory pools for .buf recycling @?@ @?@
*/
-/*
+/**
+ \verbatim
* Rationale:
* ----------
*
* -- *iff* you did not give the buffer away, free it yourself
* -- buf.clean();
* }
+ \endverbatim
*/
+
/* if you have configure you can use this */
#if defined(HAVE_CONFIG_H)
#include "config.h"
CBDATA_CLASS_INIT(MemBuf);
-/* init with defaults */
+/** init with defaults */
void
MemBuf::init()
{
}
-/* init with specific sizes */
+/** init with specific sizes */
void
MemBuf::init(mb_size_t szInit, mb_size_t szMax)
{
grow(szInit);
}
-/*
+/**
* cleans the mb; last function to call if you do not give .buf away with
* memBufFreeFunc
*/
}
}
-/* cleans the buffer without changing its capacity
- * if called with a Null buffer, calls memBufDefInit() */
+/**
+ * Cleans the buffer without changing its capacity
+ * if called with a Null buffer, calls memBufDefInit()
+ */
void
MemBuf::reset()
{
}
}
-/* unfortunate hack to test if the buffer has been Init()ialized */
+/**
+ * Unfortunate hack to test if the buffer has been Init()ialized
+ */
int
MemBuf::isNull()
{
return (terminatedSize < max_capacity) ? max_capacity - terminatedSize : 0;
}
-// removes sz bytes and "packs" by moving content left
+/// removes sz bytes and "packs" by moving content left
void MemBuf::consume(mb_size_t shiftSize)
{
const mb_size_t cSize = contentSize();
terminate();
}
-// 0-terminate in case we are used as a string.
-// Extra octet is not counted in the content size (or space size)
-// XXX: but the extra octet is counted when growth decisions are made!
-// This will cause the buffer to grow when spaceSize() == 1 on append,
-// which will assert() if the buffer cannot grow any more.
+/**
+ * Null-terminate in case we are used as a string.
+ * Extra octet is not counted in the content size (or space size)
+ *
+ \note XXX: but the extra octet is counted when growth decisions are made!
+ * This will cause the buffer to grow when spaceSize() == 1 on append,
+ * which will assert() if the buffer cannot grow any more.
+ */
void MemBuf::terminate()
{
assert(size < capacity);
}
-/* vPrintf for other printf()'s to use; calls vsnprintf, extends buf if needed */
+/**
+ * vPrintf for other printf()'s to use; calls vsnprintf, extends buf if needed
+ */
void
MemBuf::vPrintf(const char *fmt, va_list vargs) {
#ifdef VA_COPY
}
}
-/*
- * returns free() function to be used.
+/**
* Important:
* calling this function "freezes" mb,
* do not _update_ mb after that in any way
* (you still can read-access .buf and .size)
+ *
+ \retval free() function to be used.
*/
FREE *
MemBuf::freeFunc() {
return ff;
}
-/* grows (doubles) internal buffer to satisfy required minimal capacity */
+/**
+ * Grows (doubles) internal buffer to satisfy required minimal capacity
+ */
void
MemBuf::grow(mb_size_t min_cap) {
size_t new_cap;
/* Reports */
-/* puts report on MemBuf _module_ usage into mb */
+/**
+ * Puts report on MemBuf _module_ usage into mb
+ */
void
memBufReport(MemBuf * mb) {
assert(mb);
-
-
/*
- * $Id: MemBuf.h,v 1.9 2007/12/21 23:48:04 hno Exp $
+ * $Id: MemBuf.h,v 1.10 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "cbdata.h"
#include "Packer.h"
-/* auto-growing memory-resident buffer with printf interface */
-/* note: when updating this struct, update MemBufNULL #define */
-
+/**
+ * Auto-growing memory-resident buffer with printf interface
+ *
+ \todo XXX: convert global memBuf*() functions into methods
+ */
class MemBuf
{
_SQUID_INLINE_ MemBuf();
_SQUID_INLINE_ ~MemBuf();
- /* use methods instead of deprecated buf and size members */
+ /// start of the added data
+ char *content() { return buf; }
- char *content() { return buf; } // start of the added data
+ /// start of the added data
+ const char *content() const { return buf; }
- const char *content() const { return buf; } // start of the added data
-
- mb_size_t contentSize() const { return size; } // available data size
+ /// available data size
+ mb_size_t contentSize() const { return size; }
+ /**
+ * Whether the buffer contains any data.
+ \retval true if data exists in the buffer
+ \retval false if data exists in the buffer
+ */
bool hasContent() const { return size > 0; }
- // these space-related methods assume no growth and allow 0-termination
+ /// these space-related methods assume no growth and allow 0-termination
char *space() { return buf + size; } // space to add data
char *space(mb_size_t required) { if (size + required > capacity) grow(size + required); return buf + size; } // space to add data
mb_size_t spaceSize() const;
+
+ /**
+ * Whether the buffer contains any data space available.
+ \retval true if data can be added to teh buffer
+ \retval false if teh buffer is full
+ */
bool hasSpace() const { return size+1 < capacity; }
mb_size_t potentialSpaceSize() const; // accounts for possible growth
bool hasPotentialSpace() const { return potentialSpaceSize() > 0; }
- // there is currently no stretch() method to grow without appending
+ /// \note there is currently no stretch() method to grow without appending
void consume(mb_size_t sz); // removes sz bytes, moving content left
void append(const char *c, mb_size_t sz); // grows if needed and possible
void appended(mb_size_t sz); // updates content size after external append
- // XXX: convert global memBuf*() functions into methods
-
void terminate(); // zero-terminates the buffer w/o increasing contentSize
bool wasStolen() const { return stolen; }
- /* init with specific sizes */
+ /** init with specific sizes */
void init(mb_size_t szInit, mb_size_t szMax);
- /* init with defaults */
+ /** init with defaults */
void init();
- /* cleans mb; last function to call if you do not give .buf away */
+ /** cleans mb; last function to call if you do not give .buf away */
void clean();
- /* resets mb preserving (or initializing if needed) memory buffer */
+ /** resets mb preserving (or initializing if needed) memory buffer */
void reset();
- /* unfirtunate hack to test if the buffer has been Init()ialized */
+ /** unfirtunate hack to test if the buffer has been Init()ialized */
int isNull();
- /* calls snprintf, extends buffer if needed */
- /* note we use Printf instead of printf so the compiler won't */
- /* think we're calling the libc printf() */
#if STDC_HEADERS
+ /**
+ * calls snprintf, extends buffer if needed
+ \note we use Printf instead of printf so the compiler won't
+ * think we're calling the libc printf()
+ */
void Printf(const char *fmt,...) PRINTF_FORMAT_ARG2;
#else
+ /**
+ * calls snprintf, extends buffer if needed
+ \note we use Printf instead of printf so the compiler won't
+ * think we're calling the libc printf()
+ */
void Printf();
#endif
- /* vPrintf for other printf()'s to use */
+ /** vPrintf for other printf()'s to use */
void vPrintf(const char *fmt, va_list ap);
- /* returns free() function to be used, _freezes_ the object! */
+ /**
+ * freezes the object! and returns function to clear it up.
+ *
+ \retval free() function to be used.
+ */
FREE *freeFunc();
private:
- /*
+ /**
* private copy constructor and assignment operator generates
* compiler errors if someone tries to copy/assign a MemBuf
*/
CBDATA_CLASS2(MemBuf);
public:
- /* public, read-only, depricated in favor of space*() and content*() */
- // XXX: hide these members completely and remove 0-termination
- // so that consume() does not need to memmove all the time
+ /**
+ \deprecated use space*() and content*() methods to access safely instead.
+ * public, read-only.
+ *
+ \todo XXX: hide these members completely and remove 0-termination
+ * so that consume() does not need to memmove all the time
+ */
char *buf; // available content
mb_size_t size; // used space, does not count 0-terminator
- /* private, stay away; use interface function instead */
- // XXX: make these private after converting memBuf*() functions to methods
- mb_size_t max_capacity; /* when grows: assert(new_capacity <= max_capacity) */
- mb_size_t capacity; /* allocated space */
+ /**
+ * when grows: assert(new_capacity <= max_capacity)
+ \deprecated Use interface function instead
+ \todo XXX: make these private after converting memBuf*() functions to methods
+ */
+ mb_size_t max_capacity;
+
+ /**
+ * allocated space
+ \deprecated Use interface function instead
+ \todo XXX: make these private after converting memBuf*() functions to methods
+ */
+ mb_size_t capacity;
unsigned stolen:
1; /* the buffer has been stolen for use by someone else */
#include "MemBuf.cci"
#endif
-/* returns free() function to be used, _freezes_ the object! */
+/** returns free() function to be used, _freezes_ the object! */
SQUIDCEXTERN void memBufReport(MemBuf * mb);
-/* pack content into a mem buf. */
+/** pack content into a mem buf. */
SQUIDCEXTERN void packerToMemInit(Packer * p, MemBuf * mb);
#endif /* SQUID_MEM_H */
-
/*
- * $Id: MemObject.h,v 1.17 2008/02/26 00:15:48 rousskov Exp $
+ * $Id: MemObject.h,v 1.18 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
mem_hdr data_hdr;
int64_t inmem_lo;
dlink_list clients;
- /* TODO: move into .cc or .cci */
+
+ /** \todo move into .cc or .cci */
size_t clientCount() const {return nclients;}
bool clientIsFirst(void *sc) const {return (clients.head && sc == clients.head->data);}
};
SwapOut swapout;
+
/* Read only - this reply must be preserved by store clients */
/* The original reply. possibly with updated metadata. */
HttpRequest *request;
DeferredReadManager deferredReads;
};
-MEMPROXY_CLASS_INLINE(MemObject)
+MEMPROXY_CLASS_INLINE(MemObject) /**DOCS_NOSEMI*/
-/* global current memory removal policy */
+/** global current memory removal policy */
extern RemovalPolicy *mem_policy;
#endif /* SQUID_MEMOBJECT_H */
-
/*
- * $Id: Store.cci,v 1.2 2005/01/03 16:08:25 robertc Exp $
+ * $Id: Store.cci,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
*
*/
-// #include "squid.h"
-#if 0
-#include "StoreClient.h"
-#include "stmem.h"
-#include "HttpReply.h"
-#include "HttpRequest.h"
-#endif
#include "MemObject.h"
-#if 0
-#include "mem_node.h"
-#include "StoreMeta.h"
-#include "SwapDir.h"
-#endif
+/**
+ \retval true Store contains 0 bytes of data.
+ \retval false Store contains 1 or more bytes of data.
+ \retval false Store contains negative content !!!!!!
+ */
bool
StoreEntry::isEmpty () const
{
return mem_obj->endOffset() == 0;
}
+/// \retval * - Always NULL for 'null' filesystem.
HttpReply const *
NullStoreEntry::getReply() const
{
return NULL;
}
+/// \retval N/A Kills squid with fatal error if called before Store Root is set.
Store &
Store::Root()
{
-
/*
- * $Id: Store.h,v 1.43 2008/02/12 23:33:48 rousskov Exp $
+ * $Id: Store.h,v 1.44 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#ifndef SQUID_STORE_H
#define SQUID_STORE_H
+/**
+ \defgroup StoreAPI Store API
+ \ingroup FileSystems
+ */
+
#include "squid.h"
+/// \todo protect the 'ostream' file includes via configure file tests as per squid conventions.
#include <ostream>
#include "StoreIOBuffer.h"
class StoreSearch;
+/**
+ \ingroup StoreAPI
+ */
class StoreEntry : public hash_link
{
void expireNow();
void releaseRequest();
void negativeCache();
- void cacheNegatively(); /* argh, why both? */
+ void cacheNegatively(); /** \todo argh, why both? */
void invokeHandlers();
void purgeMem();
void swapOut();
void setNoDelay (bool const);
bool modifiedSince(HttpRequest * request) const;
- /* what store does this entry belong too ? */
+
+ /** What store does this entry belong too ? */
virtual RefCount<Store> store() const;
MemObject *mem_obj;
virtual bool isNull()
{
return false;
- }
+ };
void *operator new(size_t byteCount);
void operator delete(void *address);
ESIElement::Pointer cachedESITree;
#endif
- /* append bytes to the buffer */
+ /** append bytes to the buffer */
virtual void append(char const *, int len);
- /* disable sending content to the clients */
+ /** disable sending content to the clients */
virtual void buffer();
- /* flush any buffered content */
+ /** flush any buffered content */
virtual void flush();
- /* reduce the memory lock count on the entry */
+ /** reduce the memory lock count on the entry */
virtual int unlock();
- /* increate the memory lock count on the entry */
+ /** increate the memory lock count on the entry */
virtual int64_t objectLen() const;
virtual int64_t contentLen() const;
- virtual void lock()
-
- ;
+ virtual void lock();
virtual void release();
private:
bool validLength() const;
};
+/// \ingroup StoreAPI
class NullStoreEntry:public StoreEntry
{
static NullStoreEntry _instance;
};
+/// \ingroup StoreAPI
typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata);
-/* Abstract base class that will replace the whole store and swapdir interface. */
-
+/**
+ \ingroup StoreAPI
+ * Abstract base class that will replace the whole store and swapdir interface.
+ */
class Store : public RefCountable
{
public:
- /* The root store */
+ /** The root store */
static _SQUID_INLINE_ Store &Root();
static void Root(Store *);
static void Root(RefCount<Store>);
virtual ~Store() {}
- /* Handle pending callbacks - called by the event loop. */
+ /** Handle pending callbacks - called by the event loop. */
virtual int callback() = 0;
- /* create the resources needed for this store to operate */
+
+ /** create the resources needed for this store to operate */
virtual void create();
- /* notify this store that its disk is full. TODO XXX move into a protected api call
- * between store files and their stores, rather than a top level api call
+
+ /**
+ * Notify this store that its disk is full.
+ \todo XXX move into a protected api call between store files and their stores, rather than a top level api call
*/
virtual void diskFull();
- /* Retrieve a store entry from the store */
+ /** Retrieve a store entry from the store */
virtual StoreEntry * get
(const cache_key *) = 0;
- /* TODO: imeplement the async version */
+ /** \todo imeplement the async version */
virtual void get
(String const key , STOREGETCLIENT callback, void *cbdata) = 0;
*/
virtual void init() = 0;
- /* the maximum size the store will support in normal use. Inaccuracy is permitted,
- * but may throw estimates for memory etc out of whack. */
+ /**
+ * The maximum size the store will support in normal use. Inaccuracy is permitted,
+ * but may throw estimates for memory etc out of whack.
+ */
virtual size_t maxSize() const = 0;
- /* The minimum size the store will shrink to via normal housekeeping */
+ /** The minimum size the store will shrink to via normal housekeeping */
virtual size_t minSize() const = 0;
- /* TODO: make these calls asynchronous */
- virtual void stat(StoreEntry &) const = 0; /* output stats to the provided store entry */
+ /**
+ * Output stats to the provided store entry.
+ \todo make these calls asynchronous
+ */
+ virtual void stat(StoreEntry &) const = 0;
- virtual void sync(); /* Sync the store prior to shutdown */
+ /** Sync the store prior to shutdown */
+ virtual void sync();
- /* remove a Store entry from the store */
+ /** remove a Store entry from the store */
virtual void unlink (StoreEntry &);
/* search in the store */
static RefCount<Store> CurrentRoot;
};
+/// \ingroup StoreAPI
typedef RefCount<Store> StorePointer;
+/// \ingroup StoreAPI
SQUIDCEXTERN size_t storeEntryInUse();
+
+/// \ingroup StoreAPI
SQUIDCEXTERN const char *storeEntryFlags(const StoreEntry *);
+
+/// \ingroup StoreAPI
extern void storeEntryReplaceObject(StoreEntry *, HttpReply *);
+/// \ingroup StoreAPI
SQUIDCEXTERN StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN StoreEntry *storeGetPublicByRequest(HttpRequest * request);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN StoreEntry *storeCreateEntry(const char *, const char *, request_flags, const HttpRequestMethod&);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeInit(void);
+
+/// \ingroup StoreAPI
extern void storeRegisterWithCacheManager(CacheManager & manager);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeConfigure(void);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeFreeMemory(void);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN int expiresMoreThan(time_t, time_t);
+
#if STDC_HEADERS
-SQUIDCEXTERN void
-storeAppendPrintf(StoreEntry *, const char *,...) PRINTF_FORMAT_ARG2;
+/// \ingroup StoreAPI
+SQUIDCEXTERN void storeAppendPrintf(StoreEntry *, const char *,...) PRINTF_FORMAT_ARG2;
#else
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeAppendPrintf();
#endif
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN int storeTooManyDiskFilesOpen(void);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeHeapPositionUpdate(StoreEntry *, SwapDir *);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeSwapFileNumberSet(StoreEntry * e, sfileno filn);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeFsInit(void);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeFsDone(void);
+
+/// \ingroup StoreAPI
SQUIDCEXTERN void storeReplAdd(const char *, REMOVALPOLICYCREATE *);
+
+/// \ingroup StoreAPI
extern FREE destroyStoreEntry;
-/* should be a subclass of Packer perhaps ? */
+/**
+ \ingroup StoreAPI
+ \todo should be a subclass of Packer perhaps ?
+ */
SQUIDCEXTERN void packerToStoreInit(Packer * p, StoreEntry * e);
#ifdef _USE_INLINE_
/*
- * $Id: StoreMetaMD5.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: StoreMetaMD5.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
static int md5_mismatches;
};
-MEMPROXY_CLASS_INLINE(StoreMetaMD5)
+MEMPROXY_CLASS_INLINE(StoreMetaMD5) /**DOCS_NOSEMI*/
#endif /* SQUID_STOREMETAMD5_H */
/*
- * $Id: StoreMetaSTD.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: StoreMetaSTD.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
// bool checkConsistency(StoreEntry *) const;
};
-MEMPROXY_CLASS_INLINE(StoreMetaSTD)
+MEMPROXY_CLASS_INLINE(StoreMetaSTD) /**DOCS_NOSEMI*/
#endif /* SQUID_STOREMETASTD_H */
/*
- * $Id: StoreMetaSTDLFS.h,v 1.1 2007/08/13 17:22:30 hno Exp $
+ * $Id: StoreMetaSTDLFS.h,v 1.2 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
// bool checkConsistency(StoreEntry *) const;
};
-MEMPROXY_CLASS_INLINE(StoreMetaSTDLFS)
+MEMPROXY_CLASS_INLINE(StoreMetaSTDLFS) /**DOCS_NOSEMI*/
#endif /* SQUID_STOREMETASTDLFS_H */
/*
- * $Id: StoreMetaURL.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: StoreMetaURL.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
bool checkConsistency(StoreEntry *) const;
};
-MEMPROXY_CLASS_INLINE(StoreMetaURL)
+MEMPROXY_CLASS_INLINE(StoreMetaURL) /**DOCS_NOSEMI*/
#endif /* SQUID_STOREMETAURL_H */
/*
- * $Id: StoreMetaVary.h,v 1.4 2004/08/30 05:12:31 robertc Exp $
+ * $Id: StoreMetaVary.h,v 1.5 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
bool checkConsistency(StoreEntry *) const;
};
-MEMPROXY_CLASS_INLINE(StoreMetaVary)
+MEMPROXY_CLASS_INLINE(StoreMetaVary) /**DOCS_NOSEMI*/
#endif /* SQUID_STOREMETAVARY_H */
-
/*
- * $Id: StoreSwapLogData.h,v 1.5 2007/11/15 16:47:35 wessels Exp $
+ * $Id: StoreSwapLogData.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#ifndef SQUID_STORESWAPLOGDATA_H
#define SQUID_STORESWAPLOGDATA_H
+/**
+ \defgroup FileFormatSwapStateAPI swap.state File Structure
+ \ingroup FileSystems
+ \section ImplementationNotes Implementation Notes
+ \par
+ * When writing an object to disk, we must first write the meta data.
+ * This is done with a couple of functions. First, storeSwapMetaPack()
+ * takes a StoreEntry as a parameter and returns a tlv linked
+ * list. Second, storeSwapMetaPack() converts the tlv list
+ * into a character buffer that we can write.
+ *
+ \note MemObject has a MemObject::swap_hdr_sz.
+ * This value is the size of that character buffer; the size of the
+ * swap file meta data. The StoreEntry has a member
+ * StoreEntry::swap_file_sz that represents the size of the disk file.
+ * Thus, the size of the object "content" is
+ \code StoreEntry->swap_file_sz - MemObject->swap_hdr_sz; \endcode
+ \note The swap file content includes the HTTP reply headers and the HTTP reply body (if any).
+ *
+ \par
+ * When reading a swap file, there is a similar process to extract
+ * the swap meta data. First, storeSwapMetaUnpack() converts a
+ * character buffer into a tlv linked list. It also tells us
+ * the value for MemObject->swap_hdr_sz.
+ */
+
#include "squid.h"
/*
* Do we need to have the dirn in here? I don't think so, since we already
* know the dirn ..
*/
-/* Binary format on disk.
- * DO NOT randomly alter.
- * DO NOT add ANY virtual's.
+/**
+ \ingroup FielFormatSwapStateAPI
+ \note This information is current as of version 2.2.STABLE4
+ *
+ \li Binary format on disk.
+ \li DO NOT randomly alter.
+ \li DO NOT add ANY virtual's.
+ *
+ \par
+ * Defines the structure of a binary swap.state file entry.
+ *
+ \note StoreSwapLogData entries are written in native machine byte order
+ * They are not necessarily portable across architectures.
*/
-
class StoreSwapLogData
{
public:
MEMPROXY_CLASS(StoreSwapLogData);
StoreSwapLogData();
+
+ /**
+ * Either SWAP_LOG_ADD when an object is added to the disk storage,
+ * or SWAP_LOG_DEL when an object is deleted.
+ */
char op;
+
+ /**
+ * The 32-bit file number which maps to a pathname.
+ * Only the low 24-bits are relevant. The high 8-bits are
+ * used as an index to an array of storage directories, and
+ * are set at run time because the order of storage directories
+ * may change over time.
+ */
sfileno swap_filen;
+
+ /**
+ * A 32-bit Unix time value that represents the time when
+ * the origin server generated this response. If the response
+ * has a valid Date: header, this timestamp corresponds
+ * to that time. Otherwise, it is set to the Squid process time
+ * when the response is read (as soon as the end of headers are found).
+ */
time_t timestamp;
+
+ /**
+ * The last time that a client requested this object.
+ * Strictly speaking, this time is set whenever the StoreEntry
+ * is locked (via storeLockObject()).
+ */
time_t lastref;
+
+ /**
+ * The value of the response's Expires: header, if any.
+ * If the response does not have an Expires: header, this
+ * is set to -1.
+ * If the response has an invalid (unparseable)
+ * Expires: header, it is also set to -1. There are some cases
+ * where Squid sets expires to -2. This happens for the
+ * internal "netdb" object and for FTP URL responses.
+ */
time_t expires;
+
+ /**
+ * The value of the response's Last-modified: header, if any.
+ * This is set to -1 if there is no Last-modified: header,
+ * or if it is unparseable.
+ */
time_t lastmod;
+
+ /**
+ * This is the number of bytes that the object occupies on
+ * disk. It includes the Squid "swap file header".
+ */
uint64_t swap_file_sz;
+
+ /**
+ * The number of times that this object has been accessed (referenced).
+ * Since its a 16-bit quantity, it is susceptible to overflow
+ * if a single object is accessed 65,536 times before being replaced.
+ */
u_short refcount;
+
+ /**
+ * A copy of the StoreEntry flags field. Used as a sanity
+ * check when rebuilding the cache at startup. Objects that
+ * have the KEY_PRIVATE flag set are not added back to the cache.
+ */
u_short flags;
+
+ /**
+ * The 128-bit MD5 hash for this object.
+ */
unsigned char key[SQUID_MD5_DIGEST_LENGTH];
};
-MEMPROXY_CLASS_INLINE(StoreSwapLogData)
+MEMPROXY_CLASS_INLINE(StoreSwapLogData) /**DOCS_NOSEMI*/
+/// \ingroup FileFormatSwapStateAPI
class StoreSwapLogHeader
{
public:
-
/*
- * $Id: URL.h,v 1.1 2006/05/08 23:38:33 robertc Exp $
+ * $Id: URL.h,v 1.2 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "MemPool.h"
#include "URLScheme.h"
-/* The URL class represents a UniformResourceLocation */
-
+/**
+ \ingroup POD
+ *
+ * The URL class represents a Uniform Resource Location
+ */
class URL
{
URLScheme const & getScheme() const {return scheme; }
private:
- /* the scheme of this URL. This has the 'type code' smell about it.
+ /**
+ \par
+ * The scheme of this URL. This has the 'type code' smell about it.
* In future we may want to make the methods that dispatch based on
* the scheme virtual and have a class per protocol.
- * on the other hand, having Protocol as an explicit concept is useful,
+ \par
+ * On the other hand, having Protocol as an explicit concept is useful,
* see for instance the ACLProtocol acl type. One way to represent this
* is to have one prototype URL with no host etc for each scheme,
* another is to have an explicit scheme class, and then each URL class
* could be a subclass of the scheme. Another way is one instance of
* a URLScheme class instance for each URLScheme we support, and one URL
* class for each manner of treating the scheme : a Hierarchical URL, a
- * non-hierarchical URL etc.
+ * non-hierarchical URL etc.
+ \par
* Deferring the decision, its a type code for now. RBC 20060507.
- *
+ \par
* In order to make taking any of these routes easy, scheme is private
* and immutable, only settable at construction time,
*/
/*
- * $Id: asn.cc,v 1.119 2008/01/10 08:13:43 amosjeffries Exp $
+ * $Id: asn.cc,v 1.120 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 53 AS Number handling
* AUTHOR: Duane Wessels, Kostas Anagnostakis
/* explicit instantiation required for some systems */
-template cbdata_type List<int>
-::CBDATA_List;
+/// \cond AUTODOCS-IGNORE
+template cbdata_type List<int>::CBDATA_List;
+/// \endcond
-/*
+/**
* Structure for as number information. it could be simply
* a list but it's coded as a structure for future
* enhancements (e.g. expires)
*/
-
struct as_info
{
List<int> *as_number;
}
-/* add a network (addr, mask) to the radix tree, with matching AS
- * number */
-
+/**
+ * add a network (addr, mask) to the radix tree, with matching AS number
+ */
static int
asnAddNet(char *as_string, int as_number)
{
char const *httpAuthHeader;
};
-MEMPROXY_CLASS_INLINE(BasicUser)
+MEMPROXY_CLASS_INLINE(BasicUser) /**DOCS_NOSEMI*/
typedef class BasicUser basic_data;
BasicUser *_theUser;
};
-MEMPROXY_CLASS_INLINE(AuthBasicUserRequest)
+MEMPROXY_CLASS_INLINE(AuthBasicUserRequest) /**DOCS_NOSEMI*/
/* configuration runtime data */
/*
- * $Id: basicScheme.h,v 1.1 2004/08/30 03:29:00 robertc Exp $
+ * $Id: basicScheme.h,v 1.2 2008/02/26 21:49:41 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "AuthScheme.h"
+/// \ingroup AuthAPI
+/// \ingroup AuthSchemeAPI
class basicScheme : public AuthScheme
{
};
-MEMPROXY_CLASS_INLINE(DigestUser)
+MEMPROXY_CLASS_INLINE(DigestUser) /**DOCS_NOSEMI*/
typedef class DigestUser digest_user_h;
CredentialsState credentials_ok;
};
-MEMPROXY_CLASS_INLINE(AuthDigestUserRequest)
+MEMPROXY_CLASS_INLINE(AuthDigestUserRequest) /**DOCS_NOSEMI*/
/* data to be encoded into the nonce's b64 representation */
/*
- * $Id: digestScheme.h,v 1.1 2004/08/30 03:29:00 robertc Exp $
+ * $Id: digestScheme.h,v 1.2 2008/02/26 21:49:42 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "AuthScheme.h"
+/// \ingroup AuthSchemeAPI
+/// \ingroup AuthAPI
class digestScheme : public AuthScheme
{
/*
- * $Id: auth_negotiate.cc,v 1.29 2008/02/12 23:17:52 rousskov Exp $
+ * $Id: auth_negotiate.cc,v 1.30 2008/02/26 21:49:43 amosjeffries Exp $
*
* DEBUG: section 29 Negotiate Authenticator
* AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
#include "HttpReply.h"
#include "HttpRequest.h"
#include "SquidTime.h"
-/* TODO remove this include */
+/** \todo remove this include */
#include "negotiateScheme.h"
#include "wordlist.h"
+/**
+ \defgroup AuthNegotiateInternal Negotiate Authenticator Internals
+ \ingroup AuthNegotiateAPI
+ */
+
static void
authenticateNegotiateReleaseServer(AuthUserRequest * auth_user_request);
+/// \ingroup AuthNegotiateInternal
static void
authenticateStateFree(authenticateStateData * r)
{
static HLPSCB authenticateNegotiateHandleReply;
static AUTHSSTATS authenticateNegotiateStats;
+/// \ingroup AuthNegotiateInternal
static statefulhelper *negotiateauthenticators = NULL;
CBDATA_TYPE(authenticateStateData);
+/// \ingroup AuthNegotiateInternal
static int authnegotiate_initialised = 0;
+/// \ingroup AuthNegotiateInternal
static auth_negotiate_config negotiateConfig;
+/// \ingroup AuthNegotiateInternal
static hash_table *proxy_auth_cache = NULL;
/*
*
*/
-/* move to negotiateScheme.cc */
+/**
+ \ingroup AuthNegotiateInternal
+ \todo move to negotiateScheme.cc
+ */
void
negotiateScheme::done()
{
debugs(29, 2, "negotiateScheme::done: Negotiate authentication Shutdown.");
}
-/* free any allocated configuration details */
void
AuthNegotiateConfig::done()
{
return negotiateScheme::GetInstance().type();
}
-/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
- * config file */
+/**
+ * Initialize helpers and the like for this auth scheme.
+ * Called AFTER parsing the config file
+ */
void
AuthNegotiateConfig::init(AuthConfig * scheme)
{
#include "AuthConfig.h"
#include "helper.h"
+/**
+ \defgroup AuthNegotiateAPI Negotiate Authentication API
+ \ingroup AuthAPI
+ */
+
+/// \ingroup AuthNegotiateAPI
#define DefaultAuthenticateChildrenMax 32 /* 32 processes */
#ifndef __AUTH_AUTHENTICATE_STATE_T__
#define __AUTH_AUTHENTICATE_STATE_T__
+
+/// \ingroup AuthNegotiateAPI
typedef enum {
AUTHENTICATE_STATE_NONE,
AUTHENTICATE_STATE_INITIAL,
/* Generic */
+/// \ingroup AuthNegotiateAPI
typedef struct
{
void *data;
AuthUserRequest *auth_user_request;
RH *handler;
}
-
authenticateStateData;
#endif
+/// \ingroup AuthNegotiateAPI
class NegotiateUser : public AuthUser
{
dlink_list proxy_auth_list;
};
-MEMPROXY_CLASS_INLINE(NegotiateUser)
+MEMPROXY_CLASS_INLINE(NegotiateUser) /**DOCS_NOSEMI*/
+/// \ingroup AuthNegotiateAPI
typedef class NegotiateUser negotiate_user_t;
+/// \ingroup AuthNegotiateAPI
class AuthNegotiateUserRequest : public AuthUserRequest
{
NegotiateUser * _theUser;
};
-MEMPROXY_CLASS_INLINE(AuthNegotiateUserRequest)
+MEMPROXY_CLASS_INLINE(AuthNegotiateUserRequest) /**DOCS_NOSEMI*/
/* configuration runtime data */
+/// \ingroup AuthNegotiateAPI
class AuthNegotiateConfig : public AuthConfig
{
wordlist *authenticate;
};
+/// \ingroup AuthNegotiateAPI
typedef class AuthNegotiateConfig auth_negotiate_config;
#endif
/*
- * $Id: negotiateScheme.h,v 1.1 2005/10/23 11:55:38 hno Exp $
+ * $Id: negotiateScheme.h,v 1.2 2008/02/26 21:49:43 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "AuthScheme.h"
+/// \ingroup AuthSchemeAPI
+/// \ingroup AuthAPI
class negotiateScheme : public AuthScheme
{
dlink_list proxy_auth_list;
};
-MEMPROXY_CLASS_INLINE(NTLMUser)
+MEMPROXY_CLASS_INLINE(NTLMUser) /**DOCS_NOSEMI*/
typedef class NTLMUser ntlm_user_t;
NTLMUser * _theUser;
};
-MEMPROXY_CLASS_INLINE(AuthNTLMUserRequest)
+MEMPROXY_CLASS_INLINE(AuthNTLMUserRequest) /**DOCS_NOSEMI*/
/* configuration runtime data */
/*
- * $Id: ntlmScheme.h,v 1.1 2004/08/30 03:29:02 robertc Exp $
+ * $Id: ntlmScheme.h,v 1.2 2008/02/26 21:49:43 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "AuthScheme.h"
+/// \ingroup AuthSchemeAPI
+/// \ingroup AuthAPI
class ntlmScheme : public AuthScheme
{
/*
- * $Id: authenticate.cc,v 1.68 2007/04/28 22:26:37 hno Exp $
+ * $Id: authenticate.cc,v 1.69 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 29 Authenticator
* AUTHOR: Robert Collins
AuthUserHashPointer::removeFromCache(void *usernamehash_p)
{
AuthUserHashPointer *usernamehash = static_cast<AuthUserHashPointer *>(usernamehash_p);
- auth_user_t *auth_user = usernamehash->auth_user;
+ AuthUser *auth_user = usernamehash->auth_user;
if ((authenticateAuthUserInuse(auth_user) - 1))
debugs(29, 1, "AuthUserHashPointer::removeFromCache: entry in use - not freeing");
auth_user->unlock();
- /* TODO: change behaviour - we remove from the auth user list here, and then unlock, and the
+ /** \todo change behaviour - we remove from the auth user list here, and then unlock, and the
* delete ourselves.
*/
}
-AuthUserHashPointer::AuthUserHashPointer (auth_user_t * anAuth_user):
+AuthUserHashPointer::AuthUserHashPointer (AuthUser * anAuth_user):
auth_user (anAuth_user)
{
key = (void *)anAuth_user->username();
hash_join(proxy_auth_username_cache, (hash_link *) this);
/* lock for presence in the cache */
- auth_user->lock()
-
- ;
+ auth_user->lock();
}
AuthUser *
-
/*
- * $Id: authenticate.h,v 1.16 2006/05/29 00:15:01 robertc Exp $
+ * $Id: authenticate.h,v 1.17 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class AuthUser;
+/**
+ \ingroup AuthAPI
+ *
+ * This is used to link auth_users into the username cache.
+ * Because some schemes may link in aliases to a user,
+ * the link is not part of the AuthUser structure itself.
+ *
+ \todo Inheritance in a struct? this should be a class.
+ */
struct AuthUserHashPointer : public hash_link
{
/* first two items must be same as hash_link */
AuthUser *auth_user;
};
-MEMPROXY_CLASS_INLINE(AuthUserHashPointer)
+MEMPROXY_CLASS_INLINE(AuthUserHashPointer) /**DOCS_NOSEMI*/
class ConnStateData;
class AuthScheme;
-/* authenticate.c authenticate scheme routines typedefs */
-/* TODO: this should be a generic cachemgr API type ? */
+/**
+ \ingroup AuthAPI
+ \todo this should be a generic cachemgr API type ?
+ */
typedef void AUTHSSTATS(StoreEntry *);
-/* subsumed by the C++ interface */
+/**
+ \ingroup AuthAPI
+ * subsumed by the C++ interface
+ \todo does 'subsumed' mean deprecated use a C++ API call?
+ */
extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *);
+/// \ingroup AuthAPI
extern void authenticateInit(authConfig *);
+/// \ingroup AuthAPI
extern void authenticateRegisterWithCacheManager(authConfig * config, CacheManager & manager);
+/// \ingroup AuthAPI
extern void authenticateShutdown(void);
+/// \ingroup AuthAPI
extern int authenticateAuthUserInuse(auth_user_t * auth_user);
+/// \ingroup AuthAPI
extern void authenticateFreeProxyAuthUserACLResults(void *data);
+/// \ingroup AuthAPI
extern int authenticateActiveSchemeCount(void);
+/// \ingroup AuthAPI
extern int authenticateSchemeCount(void);
+/// \ingroup AuthAPI
extern void authenticateUserCacheRestart(void);
+/// \ingroup AuthAPI
extern void authenticateOnCloseConnection(ConnStateData * conn);
#endif /* SQUID_AUTHENTICATE_H */
/*
- * $Id: cache_manager.cc,v 1.48 2007/10/31 04:52:16 amosjeffries Exp $
+ * $Id: cache_manager.cc,v 1.49 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 16 Cache Manager Objects
* AUTHOR: Duane Wessels
#include "SquidTime.h"
#include "wordlist.h"
+/**
+ \defgroup CacheManagerInternal Cache Manager Internals
+ \ingroup CacheManagerAPI
+ */
+
+/// \ingroup CacheManagerInternal
#define MGR_PASSWD_SZ 128
+/// \ingroup CacheManagerInternal
typedef struct
{
StoreEntry *entry;
char *user_name;
char *passwd;
}
-
cachemgrStateData;
-
static CacheManagerAction *cachemgrFindAction(const char *action);
static cachemgrStateData *cachemgrParseUrl(const char *url);
static void cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request);
static OBJH cachemgrMenu;
static OBJH cachemgrOfflineToggle;
+/// \ingroup CacheManagerInternal
CacheManagerAction *ActionTable = NULL;
CacheManager::CacheManager()
return cachemgrFindAction(action);
}
+/// \ingroup CacheManagerInternal
static CacheManagerAction *
cachemgrFindAction(const char *action)
{
return NULL;
}
+/// \ingroup CacheManagerInternal
static cachemgrStateData *
cachemgrParseUrl(const char *url)
{
return mgr;
}
+/// \ingroup CacheManagerInternal
static void
cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request)
{
debugs(16, 9, "cachemgrParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'");
}
-/*
- * return 0 if mgr->password is good
+/**
+ \ingroup CacheManagerInternal
+ *
+ \retval 0 if mgr->password is good or "none"
+ \retval 1 if mgr->password is "disable"
+ \retval !0 if mgr->password does not match configured password
*/
static int
cachemgrCheckPassword(cachemgrStateData * mgr)
return strcmp(pwd, mgr->passwd);
}
+/// \ingroup CacheManagerInternal
static void
cachemgrStateFree(cachemgrStateData * mgr)
{
xfree(mgr);
}
+// API
void
cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry)
{
cachemgrStateFree(mgr);
}
+/// \ingroup CacheManagerInternal
static void
cachemgrShutdown(StoreEntry * entryunused)
{
shut_down(0);
}
+/// \ingroup CacheManagerInternal
static void
cachemgrOfflineToggle(StoreEntry * sentry)
{
Config.onoff.offline ? "ON" : "OFF");
}
+/// \ingroup CacheManagerInternal
static const char *
cachemgrActionProtection(const CacheManagerAction * at)
{
return "protected";
}
+/// \ingroup CacheManagerInternal
static void
cachemgrMenu(StoreEntry * sentry)
{
}
}
+/// \ingroup CacheManagerInternal
static char *
cachemgrPasswdGet(cachemgr_passwd * a, const char *action)
{
/*
- * $Id: cbdata.cc,v 1.76 2007/04/28 22:26:37 hno Exp $
+ * $Id: cbdata.cc,v 1.77 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 45 Callback Data Registry
* ORIGINAL AUTHOR: Duane Wessels
*
*/
-/*
+/**
+ \defgroup CBDATAInternal Callback Data Allocator Internals
+ \ingroup CBDATAAPI
+ *
* These routines manage a set of registered callback data pointers.
- * One of the easiest ways to make Squid coredump is to issue a
+ * One of the easiest ways to make Squid coredump is to issue a
* callback to for some data structure which has previously been
* freed. With these routines, we register (add) callback data
* pointers, lock them just before registering the callback function,
#endif
+/// \ingroup CBDATAInternal
#define OFFSET_OF(TYPE, MEMBER) ((size_t) &(((TYPE) *)0)->(MEMBER))
+/// \ingroup CBDATAInternal
class cbdata
{
- /* TODO: examine making cbdata templated on this - so we get type
+ /** \todo examine making cbdata templated on this - so we get type
* safe access to data - RBC 20030902 */
public:
#if HASHED_CBDATA
return where;
}
+/**
+ * Only ever invoked when placement new throws
+ * an exception. Used to prevent an incorrect
+ * free.
+ */
void
cbdata::operator delete(void *where, void *where2)
{
- /* Only ever invoked when placement new throws
- * an exception. Used to prevent an incorrect
- * free.
- */
+ ;
}
long
return (long)dataOffset;
}
#else
-MEMPROXY_CLASS_INLINE(cbdata)
+MEMPROXY_CLASS_INLINE(cbdata) /**DOCS_NOSEMI*/
#endif
static OBJH cbdataDump;
static OBJH cbdataDumpHistory;
#endif
+/// \ingroup CBDATAInternal
struct CBDataIndex
{
MemAllocator *pool;
FREE *free_func;
}
-
*cbdata_index = NULL;
+
+/// \ingroup CBDATAInternal
int cbdata_types = 0;
#if HASHED_CBDATA
-
/*
- * $Id: cbdata.h,v 1.2 2008/02/12 23:26:36 rousskov Exp $
+ * $Id: cbdata.h,v 1.3 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "squid.h"
-/*
+/**
+ \defgroup CBDATAAPI Callback Data Allocator API
+ \ingroup Components
+ \par
+ * Squid's extensive use of callback functions makes it very
+ * susceptible to memory access errors. To address this all callback
+ * functions make use of a construct called cbdata. This allows
+ * functions doing callbacks to verify that the caller is still
+ * valid before making the callback.
+ *
+ \note cbdata is intended for callback data and is tailored specifically
+ * to make callbacks less dangerous leaving as few windows of errors as
+ * possible. It is not suitable or intended as a generic RefCount
+ * memory allocator.
+ *
+ \todo CODE: make cbdata a template or class-inheritance system instead of Macros.
+ *
+ \section Examples Examples
+ \par
+ * Here you can find some examples on how to use cbdata, and why.
+ *
+ \subsection AsyncOpWithoutCBDATA Asynchronous operation without cbdata, showing why cbdata is needed
+ \par
+ * For a asyncronous operation with callback functions, the normal
+ * sequence of events in programs NOT using cbdata is as follows:
+ *
+ \code
+ // initialization
+ type_of_data our_data;
+ ...
+ our_data = malloc(...);
+ ...
+ // Initiate a asyncronous operation, with our_data as callback_data
+ fooOperationStart(bar, callback_func, our_data);
+ ...
+ // The asyncronous operation completes and makes the callback
+ callback_func(callback_data, ....);
+ // Some time later we clean up our data
+ free(our_data);
+ \endcode
+ *
+ \par
+ * However, things become more interesting if we want or need
+ * to free the callback_data, or otherwise cancel the callback,
+ * before the operation completes. In constructs like this you
+ * can quite easily end up with having the memory referenced
+ * pointed to by callback_data freed before the callback is invoked
+ * causing a program failure or memory corruption:
+ *
+ \code
+ // initialization
+ type_of_data our_data;
+ ...
+ our_data = malloc(...);
+ ...
+ // Initiate a asyncronous operation, with our_data as callback_data
+ fooOperationStart(bar, callback_func, our_data);
+ ...
+ // ouch, something bad happened elsewhere.. try to cleanup
+ // but the programmer forgot there is a callback pending from
+ // fooOperationsStart() (an easy thing to forget when writing code
+ // to deal with errors, especially if there may be many different
+ // pending operation)
+ free(our_data);
+ ...
+ // The asyncronous operation completes and makes the callback
+ callback_func(callback_data, ....);
+ // CRASH, the memory pointer to by callback_data is no longer valid
+ // at the time of the callback
+ \endcode
+ *
+ \subsection AsyncOpWithCBDATA Asyncronous operation with cbdata
+ *
+ \par
+ * The callback data allocator lets us do this in a uniform and
+ * safe manner. The callback data allocator is used to allocate,
+ * track and free memory pool objects used during callback
+ * operations. Allocated memory is locked while the asyncronous
+ * operation executes elsewhere, and is freed when the operation
+ * completes. The normal sequence of events is:
+ *
+ \code
+ // initialization
+ type_of_data our_data;
+ ...
+ our_data = cbdataAlloc(type_of_data);
+ ...
+ // Initiate a asyncronous operation, with our_data as callback_data
+ fooOperationStart(..., callback_func, our_data);
+ ...
+ // foo
+ void *local_pointer = cbdataReference(callback_data);
+ ....
+ // The asyncronous operation completes and makes the callback
+ void *cbdata;
+ if (cbdataReferenceValidDone(local_pointer, &cbdata))
+ callback_func(...., cbdata);
+ ...
+ cbdataFree(our_data);
+ \endcode
+ *
+ \subsection AsynchronousOpCancelledByCBDATA Asynchronous operation cancelled by cbdata
+ *
+ \par
+ * With this scheme, nothing bad happens if cbdataFree() gets called
+ * before fooOperantionComplete(...).
+ *
+ \par Initalization
+ \code
+ type_of_data our_data;
+ ...
+ our_data = cbdataAlloc(type_of_data);
+ \endcode
+ * Initiate a asyncronous operation, with our_data as callback_data
+ \code
+ fooOperationStart(..., callback_func, our_data);
+ \endcode
+ * do some stuff with it
+ \code
+ void *local_pointer = cbdataReference(callback_data);
+ \endcode
+ * something bad happened elsewhere.. cleanup
+ \code
+ cbdataFree(our_data);
+ \endcode
+ * The asyncronous operation completes and tries to make the callback
+ \code
+ void *cbdata;
+ if (cbdataReferenceValidDone(local_pointer, &cbdata))
+ {
+ \endcode
+ * won't be called, as the data is no longer valid
+ \code
+ callback_func(...., cbdata);
+ }
+ \endcode
+ *
+ \par
+ * In this case, when cbdataFree() is called before
+ * cbdataReferenceValidDone(), the callback_data gets marked as invalid.
+ * When the callback_data is invalid before executing the callback
+ * function, cbdataReferenceValidDone() will return 0 and
+ * callback_func is never executed.
+ *
+ \subsection AddingCBDATAType Adding a new cbdata registered type
+ *
+ \par
+ * To add new module specific data types to the allocator one uses the
+ * macros CBDATA_TYPE() and CBDATA_INIT_TYPE(). These creates a local cbdata
+ * definition (file or block scope). Any cbdataAlloc() calls must be made
+ * within this scope. However, cbdataFree() might be called from anywhere.
+ *
+ \par
+ * First the cbdata type needs to be defined in the module. This
+ * is usually done at file scope, but it can also be local to a
+ * function or block..
+ \code
+ CBDATA_TYPE(type_of_data);
+ \endcode
+ * Then in the code somewhere before the first allocation
+ * (can be called multiple times with only a minimal overhead)
+ \code
+ CBDATA_INIT_TYPE(type_of_data);
+ \endcode
+ * Or if a free function is associated with the data type. This
+ * function is responsible for cleaning up any dependencies etc
+ * referenced by the structure and is called on cbdataFree() or
+ * when the last reference is deleted by cbdataReferenceDone() /
+ * cbdataReferenceValidDone()
+ \code
+ CBDATA_INIT_TYPE_FREECB(type_of_data, free_function);
+ \endcode
+ *
+ \subsection AddingGlobalCBDATATypes Adding a new cbdata registered data type globally
+ *
+ \par
+ * To add new global data types that can be allocated from anywhere
+ * within the code one have to add them to the cbdata_type enum in
+ * enums.h, and a corresponding CREATE_CBDATA() call in
+ * cbdata.c:cbdataInit(). Or alternatively add a CBDATA_GLOBAL_TYPE()
+ * definition to globals.h as shown below and use CBDATA_INIT_TYPE() at
+ * the appropriate location(s) as described above.
+ *
+ \code
+ extern CBDATA_GLOBAL_TYPE(type_of_data); // CBDATA_UNDEF
+ \endcode
+ */
+
+/**
+ *\ingroup CBDATAAPI
* cbdata types. similar to the MEM_* types above, but managed
* in cbdata.c. A big difference is that these types are dynamically
* allocated. This list is only a list of predefined types. Other types
CBDATA_UNKNOWN = 0,
} cbdata_type;
+/// \ingroup CBDATAAPI
extern void cbdataRegisterWithCacheManager(CacheManager & manager);
+
#if CBDATA_DEBUG
extern void *cbdataInternalAllocDbg(cbdata_type type, const char *, int);
extern void *cbdataInternalFreeDbg(void *p, const char *, int);
extern void cbdataInternalUnlockDbg(const void *p, const char *, int);
extern int cbdataInternalReferenceDoneValidDbg(void **p, void **tp, const char *, int);
#else
+
+/// \ingroup CBDATAAPI
extern void *cbdataInternalAlloc(cbdata_type type);
+
+/// \ingroup CBDATAAPI
extern void *cbdataInternalFree(void *p);
+
+/// \ingroup CBDATAAPI
extern void cbdataInternalLock(const void *p);
+
+/// \ingroup CBDATAAPI
extern void cbdataInternalUnlock(const void *p);
+
+/// \ingroup CBDATAAPI
extern int cbdataInternalReferenceDoneValid(void **p, void **tp);
-#endif
+
+#endif /* !CBDATA_DEBUG */
+
+/**
+ \ingroup CBDATAAPI
+ *
+ \param p A cbdata entry reference pointer.
+ *
+ \retval 0 A reference is stale. The pointer refers to a entry freed by cbdataFree().
+ \retval true The reference is valid and active.
+ */
extern int cbdataReferenceValid(const void *p);
+
+/// \ingroup CBDATAAPI
extern cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func);
void *toCbdata() { return this; } \
private:
#else
+
+/**
+ \ingroup CBDATAAPI
+ * Allocates a new entry of a registered CBDATA type.
+ */
#define cbdataAlloc(type) ((type *)cbdataInternalAlloc(CBDATA_##type))
+
+/**
+ \ingroup CBDATAAPI
+ \par
+ * Frees a entry allocated by cbdataAlloc().
+ *
+ \note If there are active references to the entry then the entry
+ * will be freed with the last reference is removed. However,
+ * cbdataReferenceValid() will return false for those references.
+ */
#define cbdataFree(var) do {if (var) {cbdataInternalFree(var); var = NULL;}} while(0)
+
+/**
+ \ingroup CBDATAAPI
+ * Removes a reference created by cbdataReference() and checks
+ * it for validity. Meant to be used on the last dereference,
+ * usually to make a callback.
+ *
+ \code
+ void *cbdata;
+ ...
+ if (cbdataReferenceValidDone(reference, &cbdata)) != NULL)
+ callback(..., cbdata);
+ \endcode
+ *
+ \param var The reference variable. Will be automatically cleared to NULL.
+ \param ptr A temporary pointer to the referenced data (if valid).
+ */
#define cbdataReferenceValidDone(var, ptr) cbdataInternalReferenceDoneValid((void **)&(var), (ptr))
+
+/// \ingroup CBDATAAPI
#define CBDATA_CLASS2(type) \
static cbdata_type CBDATA_##type; \
public: \
} \
void *toCbdata() { return this; } \
private:
-#endif
+#endif /* !CBDATA_DEBUG */
+
+/**
+ \ingroup CBDATAAPI
+ \par
+ * Creates a new reference to a cbdata entry. Used when you need to
+ * store a reference in another structure. The reference can later
+ * be verified for validity by cbdataReferenceValid().
+ *
+ \param var
+ * The reference variable is a pointer to the entry, in all
+ * aspects identical to the original pointer. But semantically it
+ * is quite different. It is best if the reference is thought of
+ * and handled as a "void *".
+ */
#define cbdataReference(var) (cbdataInternalLock(var), var)
+
+/**
+ \ingroup CBDATAAPI
+ * Removes a reference created by cbdataReference().
+ *
+ \param var The reference variable. Will be automatically cleared to NULL.
+ */
#define cbdataReferenceDone(var) do {if (var) {cbdataInternalUnlock(var); var = NULL;}} while(0)
+
+/// \ingroup CBDATAAPI
#define CBDATA_CLASS(type) static cbdata_type CBDATA_##type
+
+/// \ingroup CBDATAAPI
#define CBDATA_CLASS_INIT(type) cbdata_type type::CBDATA_##type = CBDATA_UNKNOWN
+
+/**
+ \ingroup CBDATAAPI
+ * Macro that defines a new cbdata datatype. Similar to a variable
+ * or struct definition. Scope is always local to the file/block
+ * where it is defined and all calls to cbdataAlloc() for this type
+ * must be within the same scope as the CBDATA_TYPE declaration.
+ * Allocated entries may be referenced or freed anywhere with no
+ * restrictions on scope.
+ */
#define CBDATA_TYPE(type) static cbdata_type CBDATA_##type = CBDATA_UNKNOWN
+
+/**
+ \ingroup CBDATAAPI
+ * Defines a global cbdata type that can be referenced anywhere in the code.
+ *
+ \code
+ external CBDATA_GLOBAL_TYPE(datatype);
+ \endcode
+ * Should be added to the module *.h header file.
+ *
+ \code
+ CBDATA_GLOBAL_TYPE(datatype);
+ \endcode
+ *
+ * Should be added to the module main *.cc file.
+ */
#define CBDATA_GLOBAL_TYPE(type) cbdata_type CBDATA_##type
+
+/**
+ \ingroup CBDATAAPI
+ *
+ * Initializes the cbdatatype. Must be called prior to the first use of cbdataAlloc() for the type.
+ *
+ \par
+ * Alternative to CBDATA_INIT_TYPE_FREECB()
+ *
+ \param type Type being initialized
+ */
#define CBDATA_INIT_TYPE(type) (CBDATA_##type ? CBDATA_UNKNOWN : (CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), NULL)))
+
+/**
+ \ingroup CBDATAAPI
+ *
+ * Initializes the cbdatatype. Must be called prior to the first use of cbdataAlloc() for the type.
+ *
+ \par
+ * Alternative to CBDATA_INIT_TYPE()
+ *
+ \param type Type being initialized
+ \param free_func The freehandler called when the last known reference to an allocated entry goes away.
+ */
#define CBDATA_INIT_TYPE_FREECB(type, free_func) (CBDATA_##type ? CBDATA_UNKNOWN : (CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), free_func)))
-/*
- * use this when you need to pass callback data to a blocking
+/**
+ \ingroup CBDATA
+ *
+ * A generic wrapper for passing objects through cbdata.
+ * Use this when you need to pass callback data to a blocking
* operation, but you don't want to/cannot have that pointer be cbdata itself.
*/
-
class generic_cbdata
{
public:
+
generic_cbdata(void * data) : data(data) {}
+
template<typename wrapped_type>void unwrap(wrapped_type **output)
{
*output = static_cast<wrapped_type *>(data);
delete this;
}
- /* the wrapped data - only public to allow the mild abuse of this facility
+
+ /**
+ * The wrapped data - only public to allow the mild abuse of this facility
* done by store_swapout - it gives a wrapped StoreEntry to StoreIO as the
* object to be given to the callbacks. That needs to be fully cleaned up!
* - RBC 20060820
+ \todo CODE: make this a private field.
*/
void *data; /* the wrapped data */
private:
CBDATA_CLASS2(generic_cbdata);
};
-
-
#endif /* SQUID_CBDATA_H */
/*
- * $Id: clientStream.cc,v 1.13 2007/04/28 22:26:37 hno Exp $
+ * $Id: clientStream.cc,v 1.14 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 87 Client-side Stream routines.
* AUTHOR: Robert Collins
*
*/
-/*
+#include "squid.h"
+#include "clientStream.h"
+#include "HttpReply.h"
+#include "HttpRequest.h"
+#include "client_side_request.h"
+
+/**
+ \defgroup ClientStreamInternal Client Streams Internals
+ \ingroup ClientStreamAPI
+ \par
* A client Stream is a uni directional pipe, with the usual non-blocking
* asynchronous approach present elsewhere in squid.
*
+ \par
* Each pipe node has a data push function, and a data request function.
* This limits flexability - the data flow is no longer assembled at each
* step.
*
+ \par
* An alternative approach is to pass each node in the pipe the call-
* back to use on each IO call. This allows the callbacks to be changed
* very easily by a participating node, but requires more maintenance
- * in each node (store the call back to the msot recent IO request in
+ * in each node (store the callback to the most recent IO request in
* the nodes context.) Such an approach also prevents dynamically
* changing the pipeline from outside without an additional interface
* method to extract the callback and context from the next node.
*
+ \par
* One important characteristic of the stream is that the readfunc
* on the terminating node, and the callback on the first node
* will be NULL, and never used.
- */
-
-#include "squid.h"
-#include "clientStream.h"
-#include "HttpReply.h"
-#include "HttpRequest.h"
-#include "client_side_request.h"
-
-CBDATA_TYPE(clientStreamNode);
-
-/*
- * TODO: rather than each node undeleting the next, have a clientStreamDelete
- * that walks the list
- */
-
-/*
- * clientStream quick notes:
*
+ \section QuickNotes Quick Notes
+ \par
* Each node including the HEAD of the clientStream has a cbdataReference
* held by the stream. Freeing the stream then removes that reference
- * and cbdataFrees every node.
+ * and cbdataFree()'s every node.
* Any node with other References, and all nodes downstream will only
* free when those references are released.
* Stream nodes MAY hold references to the data member of the node.
*
+ \par
* Specifically - on creation no reference is made.
* If you pass a data variable to a node, give it an initial reference.
* If the data member is non-null on FREE, cbdataFree WILL be called.
* explicitly setting the stream node data member to NULL and
* cbdataReferenceDone'ing it.
*
+ \par
* No data member may hold a reference to it's stream node.
* The stream guarantees that DETACH will be called before
* freeing the node, alowing data members to cleanup.
*
+ \par
* If a node's data holds a reference to something that needs to
* free the stream a circular reference list will occur.
* This results no data being freed until that reference is removed.
* One way to accomplish thisObject is to explicitly remove the
* data from your own node before freeing the stream.
*
- * (i.e.
- * mycontext = thisObject->data;
- * thisObject->data = NULL;
- * clientStreamFree (thisObject->head);
- * mycontext = NULL;
- * return;
+ \code
+ mycontext = thisObject->data;
+ thisObject->data = NULL;
+ clientStreamFree (thisObject->head);
+ mycontext = NULL;
+ return;
+ \endcode
+ *
+ \todo rather than each node undeleting the next, have a clientStreamDelete that walks the list.
*/
+/// \ingroup ClientStreamInternal
+CBDATA_TYPE(clientStreamNode);
+
+
/* Local functions */
static FREE clientStreamFree;
+/// \ingroup ClientStreamInternal
clientStreamNode *
clientStreamNew(CSR * readfunc, CSCB * callback, CSD * detach, CSS * status,
ClientStreamData data)
return temp;
}
-/*
+/**
+ \ingroup ClientStreamInternal
* Initialise a client Stream.
* list is the stream
* func is the read function for the head
temp->readBuffer = tailBuffer;
}
-/*
+/**
+ \ingroup ClientStreamInternal
* Doesn't actually insert at head. Instead it inserts one *after*
* head. This is because HEAD is a special node, as is tail
* This function is not suitable for inserting the real HEAD.
dlinkAddAfter(cbdataReference(temp), &temp->node, list->head, list);
}
-/*
- * Callback the next node the in chain with it's requested data
- */
+// API
void
clientStreamCallback(clientStreamNode * thisObject, ClientHttpRequest * http,
HttpReply * rep, StoreIOBuffer replyBuffer)
next->callback(next, http, rep, replyBuffer);
}
-/*
+/**
+ \ingroup ClientStreamInternal
* Call the previous node in the chain to read some data
+ *
+ \param thisObject ??
+ \param http ??
+ \param readBuffer ??
*/
void
clientStreamRead(clientStreamNode * thisObject, ClientHttpRequest * http,
prev->readfunc(prev, http);
}
-/*
+/**
+ \ingroup ClientStreamInternal
* Detach from the stream - only allowed for terminal members
+ *
+ \param thisObject ??
+ \param http ??
*/
void
clientStreamDetach(clientStreamNode * thisObject, ClientHttpRequest * http)
}
}
-/*
+/**
+ \ingroup ClientStreamInternal
* Abort the stream - detach every node in the pipeline.
+ *
+ \param thisObject ??
+ \param http ??
*/
void
clientStreamAbort(clientStreamNode * thisObject, ClientHttpRequest * http)
}
}
-/*
- * Call the upstream node to find it's status
+/**
+ \ingroup ClientStreamInternal
+ * Call the upstream node to find it's status
+ *
+ \param thisObject ??
+ \param http ??
*/
clientStream_status_t
clientStreamStatus(clientStreamNode * thisObject, ClientHttpRequest * http)
}
/* Local function bodies */
+
void
clientStreamNode::removeFromStream()
{
head = NULL;
}
+/// \ingroup ClientStreamInternal
void
clientStreamFree(void *foo)
{
/*
- * $Id: clientStream.h,v 1.6 2003/03/15 04:17:39 robertc Exp $
+ * $Id: clientStream.h,v 1.7 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "StoreIOBuffer.h"
#include "RefCount.h"
+/**
+ \defgroup ClientStreamAPI Client Streams API
+ \ingroup Components
+ \section Introduction Introduction
+ \par
+ * A ClientStream implements a unidirectional, non-blocking,
+ * pull pipeline. They allow code to be inserted into the
+ * reply logic on an as-needed basis. For instance,
+ * transfer-encoding logic is only needed when sending a
+ * HTTP/1.1 reply.
+ *
+ \par
+ * Each node consists of four methods - read, callback, detach, and status,
+ * along with the stream housekeeping variables (a dlink node and pointer
+ * to the head of the list), context data for the node, and read request
+ * parameters - readbuf, readlen and readoff (in the body).
+ *
+ \par
+ * clientStream is the basic unit for scheduling, and the clientStreamRead()
+ * and clientStreamCallback() calls allow for deferred scheduled activity if
+ * desired.
+ *
+ \section OperationTheory Theory on stream operation
+ \par
+ \li Something creates a pipeline. At a minimum it needs a head with a
+ * status method and a read method, and a tail with a callback method
+ * and a valid initial read request.
+ \li Other nodes may be added into the pipeline.
+ \li The tail-1th node's read method is called.
+ *
+ \par
+ * For each node going up the pipeline, the node either:
+ \li satisfies the read request, or
+ \li inserts a new node above it and calls clientStreamRead(), or
+ \li calls clientStreamRead()
+ \todo DOCS: make the above list nested.
+ *
+ \par
+ * There is no requirement for the Read parameters from different
+ * nodes to have any correspondence, as long as the callbacks provided are
+ * correct.
+ *
+ \section WhatsInANode Whats in a node
+ *
+ \todo ClientStreams: These details should really be codified as a class which all ClientStream nodes inherit from.
+ *
+ \par Each node must have:
+ \li read method - to allow loose coupling in the pipeline. (The reader may
+ therefore change if the pipeline is altered, even mid-flow).
+ \li callback method - likewise.
+ \li status method - likewise.
+ \li detach method - used to ensure all resources are cleaned up properly.
+ \li dlink head pointer - to allow list inserts and deletes from within a node.
+ \li context data - to allow the called back nodes to maintain their private information.
+ \li read request parameters - For two reasons:
+ \li To allow a node to determine the requested data offset, length and target buffer dynamically. Again, this is to promote loose coupling.
+ \li Because of the callback nature of squid, every node would have to keep these parameters in their context anyway, so this reduces programmer overhead.
+ */
+
+/// \ingroup ClientStreamAPI
typedef RefCount<RefCountable_> ClientStreamData;
class clientStreamNode;
class ClientHttpRequest;
+
/* client stream read callback */
+/// \ingroup ClientStreamAPI
typedef void CSCB(clientStreamNode *, ClientHttpRequest *, HttpReply *, StoreIOBuffer);
+
/* client stream read */
+/// \ingroup ClientStreamAPI
typedef void CSR(clientStreamNode *, ClientHttpRequest *);
+
/* client stream detach */
+/// \ingroup ClientStreamAPI
typedef void CSD(clientStreamNode *, ClientHttpRequest *);
-typedef clientStream_status_t CSS(clientStreamNode *, ClientHttpRequest *);
+/// \ingroup ClientStreamAPI
+typedef clientStream_status_t CSS(clientStreamNode *, ClientHttpRequest *);
+/// \ingroup ClientStreamAPI
class clientStreamNode
{
StoreIOBuffer readBuffer; /* what, where and how much this node wants */
};
-/* clientStream.c */
+/// \ingroup ClientStreamAPI
SQUIDCEXTERN void clientStreamInit(dlink_list *, CSR *, CSD *, CSS *, ClientStreamData, CSCB *, CSD *, ClientStreamData, StoreIOBuffer tailBuffer);
+
+/// \ingroup ClientStreamAPI
SQUIDCEXTERN void clientStreamInsertHead(dlink_list *, CSR *, CSCB *, CSD *, CSS *, ClientStreamData);
+
+/// \ingroup ClientStreamAPI
SQUIDCEXTERN clientStreamNode *clientStreamNew(CSR *, CSCB *, CSD *, CSS *, ClientStreamData);
-SQUIDCEXTERN void clientStreamCallback(clientStreamNode *, ClientHttpRequest *, HttpReply *, StoreIOBuffer replyBuffer);
-SQUIDCEXTERN void clientStreamRead(clientStreamNode *, ClientHttpRequest *, StoreIOBuffer readBuffer);
-SQUIDCEXTERN void clientStreamDetach(clientStreamNode *, ClientHttpRequest *);
-SQUIDCEXTERN void clientStreamAbort(clientStreamNode *, ClientHttpRequest *);
-SQUIDCEXTERN clientStream_status_t clientStreamStatus(clientStreamNode *, ClientHttpRequest *);
+
+/**
+ \ingroup ClientStreamAPI
+ *
+ * Call back the next node the in chain with it's requested data.
+ * Return data to the next node in the stream.
+ * The data may be returned immediately, or may be delayed for a later scheduling cycle.
+ *
+ \param thisObject 'this' reference for the client stream
+ \param http Superset of request data, being winnowed down over time. MUST NOT be NULL.
+ \param rep Not NULL on the first call back only. Ownership is passed down the pipeline.
+ Each node may alter the reply if appropriate.
+ \param replyBuffer - buffer, length - where and how much.
+ */
+SQUIDCEXTERN void clientStreamCallback(clientStreamNode *thisObject, ClientHttpRequest *http, HttpReply *rep, StoreIOBuffer replyBuffer);
+
+/**
+ \ingroup ClientStreamAPI
+ *
+ * Triggers a read of data that satisfies the httpClientRequest
+ * metainformation and (if appropriate) the offset,length and buffer
+ * parameters.
+ *
+ \param thisObject 'this' reference for the client stream
+ \param http Superset of request data, being winnowed down over time. MUST NOT be NULL.
+ \param readBuffer - offset, length, buffer - what, how much and where.
+ */
+SQUIDCEXTERN void clientStreamRead(clientStreamNode *thisObject, ClientHttpRequest *http, StoreIOBuffer readBuffer);
+
+/**
+ \ingroup ClientStreamAPI
+ *
+ * Removes this node from a clientStream. The stream infrastructure handles the removal.
+ * This node MUST have cleaned up all context data, UNLESS scheduled callbacks will take care of that.
+ * Informs the prev node in the list of this nodes detachment.
+ *
+ \param thisObject 'this' reference for the client stream
+ \param http MUST NOT be NULL.
+ */
+SQUIDCEXTERN void clientStreamDetach(clientStreamNode *thisObject, ClientHttpRequest *http);
+
+/**
+ \ingroup ClientStreamAPI
+ *
+ * Detachs the tail of the stream. CURRENTLY DOES NOT clean up the tail node data -
+ * this must be done separately. Thus Abort may ONLY be called by the tail node.
+ *
+ \param thisObject 'this' reference for the client stream
+ \param http MUST NOT be NULL.
+ */
+SQUIDCEXTERN void clientStreamAbort(clientStreamNode *thisObject, ClientHttpRequest *http);
+
+/**
+ \ingroup ClientStreamAPI
+ *
+ * Allows nodes to query the upstream nodes for :
+ \li stream ABORTS - request cancelled for some reason. upstream will not accept further reads().
+ \li stream COMPLETION - upstream has completed and will not accept further reads().
+ \li stream UNPLANNED COMPLETION - upstream has completed, but not at a pre-planned location (used for keepalive checking), and will not accept further reads().
+ \li stream NONE - no special status, further reads permitted.
+ *
+ \param thisObject 'this' reference for the client stream
+ \param http MUST NOT be NULL.
+ */
+SQUIDCEXTERN clientStream_status_t clientStreamStatus(clientStreamNode *thisObject, ClientHttpRequest *http);
#endif /* SQUID_CLIENTSTREAM_H */
-
/*
- * $Id: client_side.cc,v 1.778 2008/02/26 18:43:58 rousskov Exp $
+ * $Id: client_side.cc,v 1.779 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
*
*/
-/* Errors and client side
+/**
+ \defgroup ClientSide Client-Side Logics
+ *
+ \subsection cserrors Errors and client side
*
- * Problem the first: the store entry is no longer authoritative on the
+ \par Problem the first:
+ * the store entry is no longer authoritative on the
* reply status. EBITTEST (E_ABORT) is no longer a valid test outside
* of client_side_reply.c.
* Problem the second: resources are wasted if we delay in cleaning up.
* Problem the third we can't depend on a connection close to clean up.
*
- * Nice thing the first: Any step in the stream can callback with data
+ \par Nice thing the first:
+ * Any step in the stream can callback with data
* representing an error.
* Nice thing the second: once you stop requesting reads from upstream,
* upstream can be stopped too.
*
- * Solution #1: Error has a callback mechanism to hand over a membuf
+ \par Solution #1:
+ * Error has a callback mechanism to hand over a membuf
* with the error content. The failing node pushes that back as the
* reply. Can this be generalised to reduce duplicate efforts?
* A: Possibly. For now, only one location uses this.
* How to deal with pre-stream errors?
* Tell client_side_reply that we *want* an error page before any
* stream calls occur. Then we simply read as normal.
+ *
+ *
+ \subsection pconn_logic Persistent connection logic:
+ *
+ \par
+ * requests (httpClientRequest structs) get added to the connection
+ * list, with the current one being chr
+ *
+ \par
+ * The request is *immediately* kicked off, and data flows through
+ * to clientSocketRecipient.
+ *
+ \par
+ * If the data that arrives at clientSocketRecipient is not for the current
+ * request, clientSocketRecipient simply returns, without requesting more
+ * data, or sending it.
+ *
+ \par
+ * ClientKeepAliveNextRequest will then detect the presence of data in
+ * the next ClientHttpRequest, and will send it, restablishing the
+ * data flow.
*/
#include "squid.h"
#define comm_close comm_lingering_close
#endif
-/* Persistent connection logic:
- *
- * requests (httpClientRequest structs) get added to the connection
- * list, with the current one being chr
- *
- * The request is *immediately* kicked off, and data flows through
- * to clientSocketRecipient.
- *
- * If the data that arrives at clientSocketRecipient is not for the current
- * request, clientSocketRecipient simply returns, without requesting more
- * data, or sending it.
- *
- * ClientKeepAliveNextRequest will then detect the presence of data in
- * the next ClientHttpRequest, and will send it, restablishing the
- * data flow.
- */
-
/* our socket-related context */
return (clientStreamNode *)http->client_stream.tail->prev->data;
}
-/*
+/**
* This routine should be called to grow the inbuf and then
* call comm_read().
*/
clientUpdateStatHistCounters(log_type logType, int svc_time)
{
statHistCount(&statCounter.client_http.all_svc_time, svc_time);
- /*
+ /**
* The idea here is not to be complete, but to get service times
* for only well-defined types. For example, we don't include
* LOG_TCP_REFRESH_FAIL because its not really a cache hit
}
}
-/*
+/**
* clientSetKeepaliveFlag() sets request->flags.proxy_keepalive.
* This is the client-side persistent connection flag. We need
* to set this relatively early in the request processing
writeComplete(fd(), NULL, 0, COMM_OK);
}
-/* put terminating boundary for multiparts */
+/** put terminating boundary for multiparts */
static void
clientPackTermBound(String boundary, MemBuf * mb)
{
debugs(33, 6, "clientPackTermBound: buf offset: " << mb->size);
}
-/* appends a "part" HTTP header (as in a multi-part/range reply) to the buffer */
+/** appends a "part" HTTP header (as in a multi-part/range reply) to the buffer */
static void
clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec, String boundary, MemBuf * mb)
{
mb->Printf("\r\n");
}
-/*
+/**
* extracts a "range" from *buf and appends them to mb, updating
* all offsets and such.
*/
}
}
-/* returns expected content length for multi-range replies
+/** returns expected content length for multi-range replies
* note: assumes that httpHdrRangeCanonize has already been called
* warning: assumes that HTTP headers for individual ranges at the
* time of the actuall assembly will be exactly the same as
return clen;
}
-/*
+/**
* returns true if If-Range specs match reply, false otherwise
*/
static int
return 0;
}
-/* generates a "unique" boundary string for multipart responses
+/**
+ * generates a "unique" boundary string for multipart responses
* the caller is responsible for cleaning the string */
String
ClientHttpRequest::rangeBoundaryStr() const
return b;
}
-/* adds appropriate Range headers if needed */
+/** adds appropriate Range headers if needed */
void
ClientSocketContext::buildRangeHeader(HttpReply * rep)
{
delete mb;
}
-/*
+/**
* Write a chunk of data to a client socket. If the reply is present,
* send the reply headers down the wire too, and clean them up when
* finished.
PROF_stop(clientSocketRecipient);
}
-/* Called when a downstream node is no longer interested in
+/**
+ * Called when a downstream node is no longer interested in
* our data. As we are a terminal node, this means on aborts
* only
*/
debugs(33, 5, "ConnStateData::readNextRequest: FD " << fd << " reading next req");
fd_note(fd, "Waiting for next request");
- /*
+ /**
* Set the timeout BEFORE calling clientReadRequest().
*/
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
commSetTimeout(fd, Config.Timeout.persistent_request, timeoutCall);
readSomeData();
- /* Please don't do anything with the FD past here! */
+ /** Please don't do anything with the FD past here! */
}
void
{
debugs(33, 2, "ClientSocketContextPushDeferredIfNeeded: FD " << conn->fd << " Sending next");
- /* If the client stream is waiting on a socket write to occur, then */
+ /** If the client stream is waiting on a socket write to occur, then */
if (deferredRequest->flags.deferred) {
- /* NO data is allowed to have been sent */
+ /** NO data is allowed to have been sent. */
assert(deferredRequest->http->out.size == 0);
+ /** defer now. */
clientSocketRecipient(deferredRequest->deferredparams.node,
deferredRequest->http,
deferredRequest->deferredparams.rep,
deferredRequest->deferredparams.queuedBuffer);
}
- /* otherwise, the request is still active in a callbacksomewhere,
+ /** otherwise, the request is still active in a callbacksomewhere,
* and we are done
*/
}
debugs(33, 3, "ClientSocketContext::keepaliveNextRequest: FD " << conn->fd);
connIsFinished();
- /*
+ /** \par
* Attempt to parse a request from the request buffer.
* If we've been fed a pipelined request it may already
* be in our read buffer.
*
+ \par
* This needs to fall through - if we're unlucky and parse the _last_ request
* from our read buffer we may never re-register for another client read.
*/
debugs(33, 3, "clientSocketContext::keepaliveNextRequest: FD " << conn->fd << ": parsed next request from buffer");
}
- /*
+ /** \par
* Either we need to kick-start another read or, if we have
* a half-closed connection, kill it after the last request.
* This saves waiting for half-closed connections to finished being
ClientSocketContext::Pointer deferredRequest;
- /*
+ /** \par
* At this point we either have a parsed request (which we've
* kicked off the processing for) or not. If we have a deferred
* request (parsed but deferred for pipeling processing reasons)
kb_incr(&statCounter.client_http.hit_kbytes_out, size);
}
-/* returns true if there is still data available to pack more ranges
+/**
* increments iterator "i"
- * used by clientPackMoreRanges */
+ * used by clientPackMoreRanges
+ *
+ \retval true there is still data available to pack more ranges
+ \retval false
+ */
bool
ClientSocketContext::canPackMoreRanges() const
{
- /* first update "i" if needed */
+ /** first update iterator "i" if needed */
if (!http->range_iter.debt()) {
- debugs(33, 5, "ClientSocketContext::canPackMoreRanges: At end of " <<
- "current range spec for FD " << fd());
+ debugs(33, 5, "ClientSocketContext::canPackMoreRanges: At end of current range spec for FD " << fd());
if (http->range_iter.pos.incrementable())
++http->range_iter.pos;
}
assert(!http->range_iter.debt() == !http->range_iter.currentSpec());
+
/* paranoid sync condition */
/* continue condition: need_more_data */
debugs(33, 5, "ClientSocketContext::canPackMoreRanges: returning " << (http->range_iter.currentSpec() ? true : false));
} else if (reply && reply->content_range) {
/* request does not have ranges, but reply does */
- //FIXME: should use range_iter_pos on reply, as soon as reply->content_range
- // becomes HttpHdrRange rather than HttpHdrRangeSpec.
+ /** \todo FIXME: should use range_iter_pos on reply, as soon as reply->content_range
+ * becomes HttpHdrRange rather than HttpHdrRangeSpec.
+ */
return http->out.offset + reply->content_range->spec.offset;
}
return STREAM_NONE;
}
-/* A write has just completed to the client, or we have just realised there is
+/**
+ * A write has just completed to the client, or we have just realised there is
* no more data to send.
*/
void
return result;
}
-/*
+/**
* 'end' defaults to NULL for backwards compatibility
* remove default value if we ever get rid of NULL-terminated
* request buffers.
}
}
-/*
+/**
* parseHttpRequest()
*
* Returns
return result;
}
-/*
+/**
* bodySizeLeft
*
* Report on the number of bytes of body content that we
return 0;
}
-/*
+/**
* Attempt to parse one or more requests from the input buffer.
* If a request is successfully parsed, even if the next request
* is only partially parsed, it will return TRUE.
clientAfterReadingRequests(do_next_read);
}
-// called when new request data has been read from the socket
+/**
+ * called when new request data has been read from the socket
+ */
void
ConnStateData::handleReadData(char *buf, size_t size)
{
handleRequestBodyData();
}
-// called when new request body data has been buffered in in.buf
-// may close the connection if we were closing and piped everything out
+/**
+ * called when new request body data has been buffered in in.buf
+ * may close the connection if we were closing and piped everything out
+ */
void
ConnStateData::handleRequestBodyData()
{
startClosing("body consumer aborted");
}
-/* general lifetime handler for HTTP requests */
+/** general lifetime handler for HTTP requests */
void
ConnStateData::requestTimeout(const CommTimeoutCbParams &io)
{
return result;
}
-/* Handle a new connection on HTTP socket. */
+/** Handle a new connection on HTTP socket. */
void
httpAccept(int sock, int newfd, ConnectionDetail *details,
comm_err_t flag, int xerrno, void *data)
#if USE_SSL
-// Create SSL connection structure and update fd_table
+/** Create SSL connection structure and update fd_table */
static SSL *
httpsCreate(int newfd, ConnectionDetail *details, SSL_CTX *sslContext)
{
return ssl;
}
-/* negotiate an SSL connection */
+/** negotiate an SSL connection */
static void
clientNegotiateSSL(int fd, void *data)
{
conn->readSomeData();
}
-/* handle a new HTTPS connection */
+/** handle a new HTTPS connection */
static void
httpsAccept(int sock, int newfd, ConnectionDetail *details,
comm_err_t flag, int xerrno, void *data)
return closing_;
}
-// Called by ClientSocketContext to give the connection a chance to read
-// the entire body before closing the socket.
+/**
+ * Called by ClientSocketContext to give the connection a chance to read
+ * the entire body before closing the socket.
+ */
void
ConnStateData::startClosing(const char *reason)
{
/*
- * $Id: client_side.h,v 1.30 2008/02/12 23:07:52 rousskov Exp $
+ * $Id: client_side.h,v 1.31 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class AuthUserRequest;
template <class T>
-
class Range;
class ClientSocketContext : public RefCountable
bool connRegistered_;
};
-/* A connection to a socket */
+/** A connection to a socket */
class ConnStateData : public BodyProducer/*, public RefCountable*/
{
int64_t bodySizeLeft();
- /*
+ /**
* Is this connection based authentication? if so what type it
* is.
*/
auth_type_t auth_type;
- /*
+
+ /**
* note this is ONLY connection based because NTLM is against HTTP spec.
* the user details for connection based authentication
*/
AuthUserRequest *auth_user_request;
- /*
+
+ /**
* used by the owner of the connection, opaque otherwise
* TODO: generalise the connection owner concept.
*/
/*
- * $Id: comm.cc,v 1.446 2008/02/15 09:45:57 amosjeffries Exp $
+ * $Id: comm.cc,v 1.447 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 5 Socket Functions
* AUTHOR: Harvest Derived
/* explicit instantiation required for some systems */
-template cbdata_type List<DeferredRead>
-::CBDATA_List;
+/// \cond AUTODOCS-IGNORE
+template cbdata_type List<DeferredRead>::CBDATA_List;
+/// \endcond
void
DeferredReadManager::delayRead(DeferredRead const &aRead) {
-
/*
- * $Id: delay_pools.cc,v 1.50 2007/12/14 23:11:46 amosjeffries Exp $
+ * $Id: delay_pools.cc,v 1.51 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 77 Delay Pools
* AUTHOR: Robert Collins <robertc@squid-cache.org>
* Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
*/
+/**
+ \defgroup DelayPoolsInternal Delay Pools Internal
+ \ingroup DelayPoolsAPI
+ */
+
#include "config.h"
#if DELAY_POOLS
#include "DelayTagged.h"
#include "IPAddress.h"
+/// \ingroup DelayPoolsInternal
long DelayPools::MemoryUsed = 0;
+/// \ingroup DelayPoolsInternal
class Aggregate : public CompositePoolNode
{
private:
-class AggregateId:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class AggregateId:public DelayIdComposite
{
public:
DelaySpec spec;
};
+/// \ingroup DelayPoolsInternal
template <class Key, class Value>
-
class VectorMap
{
unsigned int nextMapPosition;
};
+/// \ingroup DelayPoolsInternal
class VectorPool : public CompositePoolNode
{
DelaySpec spec;
-class Id:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class Id:public DelayIdComposite
{
public:
};
};
+/// \ingroup DelayPoolsInternal
class IndividualPool : public VectorPool
{
};
+/// \ingroup DelayPoolsInternal
class ClassCNetPool : public VectorPool
{
};
/* don't use remote storage for these */
-
+/// \ingroup DelayPoolsInternal
class ClassCBucket
{
VectorMap<unsigned char, DelayBucket> individuals;
};
+/// \ingroup DelayPoolsInternal
class ClassCHostPool : public CompositePoolNode
{
friend class ClassCHostPool::Id;
-class Id:public DelayIdComposite
+ /// \ingroup DelayPoolsInternal
+ class Id:public DelayIdComposite
{
public:
return index < size();
}
-/* returns the used position, or the position to allocate */
+/** returns the used position, or the position to allocate */
template <class Key, class Value>
unsigned char
VectorMap<Key,Value>::findKeyIndex (Key const key) const
/*
- * $Id: dnsserver.cc,v 1.73 2007/12/14 23:11:46 amosjeffries Exp $
+ * $Id: dnsserver.cc,v 1.74 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 0 DNS Resolver
* AUTHOR: Harvest Derived
#endif
#include "util.h"
+
+/**
+ \defgroup dnsserver dnsserver
+ \ingroup ExternalPrograms
+ \par
+ Because the standard gethostbyname() library call
+ blocks, Squid must use external processes to actually make
+ these calls. Typically there will be ten dnsserver
+ processes spawned from Squid. Communication occurs via
+ TCP sockets bound to the loopback interface. The functions
+ in dns.cc are primarily concerned with starting and
+ stopping the dnsservers. Reading and writing to and from
+ the dnsservers occurs in the \link IPCacheAPI IP\endlink and
+ \link FQDNCacheAPI FQDN\endlink cache modules.
+
+ \section dnsserverInterface Command Line Interface
+ \verbatim
+usage: dnsserver -Dhv -s nameserver
+ -D Enable resolver RES_DEFNAMES and RES_DNSRCH options
+ -h Help
+ -v Version
+ -s nameserver Specify alternate name server(s). 'nameserver'
+ must be an IP address, -s option may be repeated
+ \endverbatim
+ */
+
#include "IPAddress.h"
#if LIBRESOLV_DNS_TTL_HACK
+/// \ingroup dnsserver
extern int _dns_ttl_; /* this is a really *dirty* hack - bne */
#endif
#define HAVE_RES_INIT HAVE___RES_INIT
#endif
-
+/// \ingroup dnsserver
#define REQ_SZ 512
+/**
+ \ingroup dnsserver
+ */
static void
lookup(const char *buf)
{
xfreeaddrinfo(AI);
}
+/**
+ \ingroup dnsserver
+ */
static void
usage(void)
{
}
#ifdef _SQUID_RES_NSADDR6_LARRAY
+/// \ingroup dnsserver
#define _SQUID_RES_NSADDR6_LIST(i) _SQUID_RES_NSADDR6_LARRAY[i].sin6_addr
#endif
#ifdef _SQUID_RES_NSADDR6_LPTR
+/// \ingroup dnsserver
#define _SQUID_RES_NSADDR6_LIST(i) _SQUID_RES_NSADDR6_LPTR[i]->sin6_addr
#endif
+/**
+ \ingroup dnsserver
+ *
+ * This is the external dnsserver process.
+ */
int
main(int argc, char *argv[])
{
/*
- * $Id: enums.h,v 1.261 2008/02/11 22:26:39 rousskov Exp $
+ * $Id: enums.h,v 1.262 2008/02/26 21:49:34 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
HIER_MAX
} hier_code;
+/// \ingroup ServerProtocolICPAPI
typedef enum {
ICP_INVALID,
ICP_QUERY,
MEM_MAX
} mem_type;
-/*
- * NOTE! We must preserve the order of this list!
+/**
+ \ingroup SwapStoreAPI
+ \todo AYJ: for critical lists like this we should use A=64,B=65 etc to enforce and reserve values.
+ \note NOTE! We must preserve the order of this list!
+ *
+ \section StoreSwapMeta Store "swap meta" Description
+ \par
+ * "swap meta" refers to a section of meta data stored at the beginning
+ * of an object that is stored on disk. This meta data includes information
+ * such as the object's cache key (MD5), URL, and part of the StoreEntry
+ * structure.
+ *
+ \par
+ * The meta data is stored using a TYPE-LENGTH-VALUE format. That is,
+ * each chunk of meta information consists of a TYPE identifier, a
+ * LENGTH field, and then the VALUE (which is LENGTH octets long).
*/
enum {
- STORE_META_VOID, /* should not come up */
- STORE_META_KEY_URL, /* key w/ keytype */
+ /**
+ * Just a placeholder for the zeroth value. It is never used on disk.
+ */
+ STORE_META_VOID,
+
+ /**
+ \deprecated
+ * This represents the case when we use the URL as the cache
+ * key, as Squid-1.1 does. Currently we don't support using
+ * a URL as a cache key, so this is not used.
+ */
+ STORE_META_KEY_URL,
+
+ /**
+ \deprecated
+ * For a brief time we considered supporting SHA (secure
+ * hash algorithm) as a cache key. Nobody liked it, and
+ * this type is not currently used.
+ */
STORE_META_KEY_SHA,
+
+ /**
+ * This represents the MD5 cache key that Squid currently uses.
+ * When Squid opens a disk file for reading, it can check that
+ * this MD5 matches the MD5 of the user's request. If not, then
+ * something went wrong and this is probably the wrong object.
+ */
STORE_META_KEY_MD5,
- STORE_META_URL, /* the url , if not in the header */
- STORE_META_STD, /* standard metadata */
- STORE_META_HITMETERING, /* reserved for hit metering */
+
+ /**
+ * The object's URL. This also may be matched against a user's
+ * request for cache hits to make sure we got the right object.
+ */
+ STORE_META_URL,
+
+ /**
+ * This is the "standard metadata" for an object.
+ * Really its just this middle chunk of the StoreEntry structure:
+ \code
+ time_t timestamp;
+ time_t lastref;
+ time_t expires;
+ time_t lastmod;
+ size_t swap_file_sz;
+ u_short refcount;
+ u_short flags;
+ \endcode
+ */
+ STORE_META_STD,
+
+ /**
+ * Reserved for future hit-metering (RFC 2227) stuff
+ */
+ STORE_META_HITMETERING,
+
+ /// \todo DOCS: document.
STORE_META_VALID,
- STORE_META_VARY_HEADERS, /* Stores Vary request headers */
- STORE_META_STD_LFS, /* standard metadata in lfs format */
- STORE_META_OBJSIZE, /* object size, not impleemented, squid26 compatibility */
+
+ /**
+ * Stores Vary request headers
+ */
+ STORE_META_VARY_HEADERS,
+
+ /**
+ * Updated version of STORE_META_STD, with support for >2GB objects.
+ * As STORE_META_STD except that the swap_file_sz is a 64-bit integer instead of 32-bit.
+ */
+ STORE_META_STD_LFS,
+
+ /**
+ \deprecated
+ * Object size, not implemented, squid26 compatibility
+ */
+ STORE_META_OBJSIZE,
+
STORE_META_STOREURL, /* the store url, if different to the normal URL */
STORE_META_VARY_ID, /* Unique ID linking variants */
STORE_META_END
/*
- * $Id: errorpage.cc,v 1.229 2008/01/20 08:54:28 amosjeffries Exp $
+ * $Id: errorpage.cc,v 1.230 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 4 Error Generation
* AUTHOR: Duane Wessels
*
*/
-/*
- * Abstract: These routines are used to generate error messages to be
- * sent to clients. The error type is used to select between
- * the various message formats. (formats are stored in the
- * Config.errorDirectory)
- */
-
#include "errorpage.h"
#include "AuthUserRequest.h"
#include "SquidTime.h"
#include "URLScheme.h"
#include "wordlist.h"
+/**
+ \defgroup ErrorPageInternal Error Page Internals
+ \ingroup ErrorPageAPI
+ *
+ \section Abstract Abstract:
+ * These routines are used to generate error messages to be
+ * sent to clients. The error type is used to select between
+ * the various message formats. (formats are stored in the
+ * Config.errorDirectory)
+ */
+
+
+/// \ingroup ErrorPageInternal
CBDATA_CLASS_INIT(ErrorState);
/* local types */
+/// \ingroup ErrorPageInternal
typedef struct
{
int id;
char *page_name;
}
-
ErrorDynamicPageInfo;
/* local constant and vars */
-/*
- * note: hard coded error messages are not appended with %S automagically
- * to give you more control on the format
+/**
+/// \ingroup ErrorPageInternal
+ *
+ \note hard coded error messages are not appended with %S
+ * automagically to give you more control on the format
*/
-
static const struct
{
int type; /* and page_id */
}
};
+/// \ingroup ErrorPageInternal
static Vector<ErrorDynamicPageInfo *> ErrorDynamicPages;
/* local prototypes */
+/// \ingroup ErrorPageInternal
static const int error_hard_text_count = sizeof(error_hard_text) / sizeof(*error_hard_text);
+
+/// \ingroup ErrorPageInternal
static char **error_text = NULL;
+
+/// \ingroup ErrorPageInternal
static int error_page_count = 0;
static char *errorTryLoadText(const char *page_name, const char *dir);
static IOCB errorSendComplete;
+/// \ingroup ErrorPageInternal
err_type &operator++ (err_type &anErr)
{
int tmp = (int)anErr;
return anErr;
}
+/// \ingroup ErrorPageInternal
int operator - (err_type const &anErr, err_type const &anErr2)
{
return (int)anErr - (int)anErr2;
}
-/*
- * Function: errorInitialize
- *
- * Abstract: This function finds the error messages formats, and stores
- * them in error_text[];
- *
- * Global effects:
- * error_text[] - is modified
- */
void
errorInitialize(void)
{
error_page_count = 0;
}
+/// \ingroup ErrorPageInternal
static const char *
errorFindHardText(err_type type)
{
}
+/// \ingroup ErrorPageInternal
static char *
errorLoadText(const char *page_name)
{
return text;
}
+/// \ingroup ErrorPageInternal
static char *
errorTryLoadText(const char *page_name, const char *dir)
{
return text;
}
+/// \ingroup ErrorPageInternal
static ErrorDynamicPageInfo *
errorDynamicPageInfoCreate(int id, const char *page_name)
{
return info;
}
+/// \ingroup ErrorPageInternal
static void
errorDynamicPageInfoDestroy(ErrorDynamicPageInfo * info)
{
delete info;
}
+/// \ingroup ErrorPageInternal
static int
errorPageId(const char *page_name)
{
return (err_type)id;
}
+/// \ingroup ErrorPageInternal
static const char *
errorPageName(int pageId)
{
return "ERR_UNKNOWN"; /* should not happen */
}
-/*
- * Function: errorCon
- *
- * Abstract: This function creates a ErrorState object.
- */
ErrorState *
errorCon(err_type type, http_status status, HttpRequest * request)
{
return err;
}
-/*
- * Function: errorAppendEntry
- *
- * Arguments: err - This object is destroyed after use in this function.
- *
- * Abstract: This function generates a error page from the info contained
- * by 'err' and then stores the text in the specified store
- * entry. This function should only be called by ``server
- * side routines'' which need to communicate errors to the
- * client side. It should also be called from client_side.c
- * because we now support persistent connections, and
- * cannot assume that we can immediately write to the socket
- * for an error.
- */
void
errorAppendEntry(StoreEntry * entry, ErrorState * err)
{
entry->buffer();
rep = errorBuildReply(err);
/* Add authentication header */
- /* TODO: alter errorstate to be accel on|off aware. The 0 on the next line
+ /*! \todo alter errorstate to be accel on|off aware. The 0 on the next line
* depends on authenticate behaviour: all schemes to date send no extra
* data on 407/401 responses, and do not check the accel state on 401/407
* responses
errorStateFree(err);
}
-/*
- * Function: errorSend
- *
- * Arguments: err - This object is destroyed after use in this function.
- *
- * Abstract: This function generates a error page from the info contained
- * by 'err' and then sends it to the client.
- * The callback function errorSendComplete() is called after
- * the page has been written to the client socket (fd).
- * errorSendComplete() deallocates 'err'. We need to add
- * 'err' to the cbdata because comm_write() requires it
- * for all callback data pointers.
- *
- * Note, normally errorSend() should only be called from
- * routines in ssl.c and pass.c, where we don't have any
- * StoreEntry's. In client_side.c we must allocate a StoreEntry
- * for errors and use errorAppendEntry() to account for
- * persistent/pipeline connections.
- */
void
errorSend(int fd, ErrorState * err)
{
delete rep;
}
-/*
- * Function: errorSendComplete
+/**
+ \ingroup ErrorPageAPI
*
- * Abstract: Called by commHandleWrite() after data has been written
- * to the client socket.
+ * Called by commHandleWrite() after data has been written
+ * to the client socket.
*
- * Note: If there is a callback, the callback is responsible for
- * closeing the FD, otherwise we do it ourseves.
+ \note If there is a callback, the callback is responsible for
+ * closeing the FD, otherwise we do it ourseves.
*/
static void
errorSendComplete(int fd, char *bufnotused, size_t size, comm_err_t errflag, int xerrno, void *data)
cbdataFree(err);
}
+/// \ingroup ErrorPageInternal
static int
errorDump(ErrorState * err, MemBuf * mb)
{
return 0;
}
+/// \ingroup ErrorPageInternal
#define CVT_BUF_SZ 512
-/*
- * a - User identity x
- * B - URL with FTP %2f hack x
- * c - Squid error code x
- * d - seconds elapsed since request received x
- * e - errno x
- * E - strerror() x
- * f - FTP request line x
- * F - FTP reply line x
- * g - FTP server message x
- * h - cache hostname x
- * H - server host name x
- * i - client IP address x
- * I - server IP address x
- * L - HREF link for more info/contact x
- * M - Request Method x
- * m - Error message returned by auth helper x
- * o - Message returned external acl helper x
- * p - URL port # x
- * P - Protocol x
- * R - Full HTTP Request x
- * S - squid signature from ERR_SIGNATURE x
- * s - caching proxy software with version x
- * t - local time x
- * T - UTC x
- * U - URL without password x
- * u - URL with password x
- * w - cachemgr email address x
- * W - error data (to be included in the mailto links)
- * z - dns server error message x
- * Z - Preformatted error message x
- */
-
+/// \ingroup ErrorPageInternal
static const char *
errorConvert(char token, ErrorState * err)
{
return p;
}
-/* allocates and initializes an error response */
HttpReply *
errorBuildReply(ErrorState * err)
{
return rep;
}
+/// \ingroup ErrorPageInternal
static MemBuf *
errorBuildContent(ErrorState * err)
{
-
/*
- * $Id: errorpage.h,v 1.5 2007/12/14 23:11:46 amosjeffries Exp $
+ * $Id: errorpage.h,v 1.6 2008/02/26 21:49:34 amosjeffries Exp $
*
+ * DEBUG: section 4 Error Generation
+ * AUTHOR: Duane Wessels
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#include "cbdata.h"
#include "IPAddress.h"
+/**
+ \defgroup ErrorPageAPI Error Pages API
+ \ingroup Components
+ \section ErrorPageStringCodes Error Page % codes for text insertion.
+ *
+ \verbatim
+ a - User identity x
+ B - URL with FTP %2f hack x
+ c - Squid error code x
+ d - seconds elapsed since request received x
+ e - errno x
+ E - strerror() x
+ f - FTP request line x
+ F - FTP reply line x
+ g - FTP server message x
+ h - cache hostname x
+ H - server host name x
+ i - client IP address x
+ I - server IP address x
+ L - HREF link for more info/contact x
+ M - Request Method x
+ m - Error message returned by auth helper x
+ o - Message returned external acl helper x
+ p - URL port # x
+ P - Protocol x
+ R - Full HTTP Request x
+ S - squid signature from ERR_SIGNATURE x
+ s - caching proxy software with version x
+ t - local time x
+ T - UTC x
+ U - URL without password x
+ u - URL with password x
+ w - cachemgr email address x
+ W - error data (to be included in the mailto links)
+ z - dns server error message x
+ Z - Preformatted error message x
+ \endverbatim
+ */
+
class AuthUserRequest;
+/// \ingroup ErrorPageAPI
class ErrorState
{
CBDATA_CLASS2(ErrorState);
};
+/**
+ \ingroup ErrorPageAPI
+ *
+ * This function finds the error messages formats, and stores
+ * them in error_text[]
+ *
+ \par Global effects:
+ * error_text[] - is modified
+ */
SQUIDCEXTERN void errorInitialize(void);
+
+/// \ingroup ErrorPageAPI
SQUIDCEXTERN void errorClean(void);
+
+/**
+ \ingroup ErrorPageInternal
+ * Allocates and initializes an error response
+ */
SQUIDCEXTERN HttpReply *errorBuildReply(ErrorState * err);
-SQUIDCEXTERN void errorSend(int fd, ErrorState *);
-SQUIDCEXTERN void errorAppendEntry(StoreEntry *, ErrorState *);
+
+/**
+ \ingroup ErrorPageAPI
+ *
+ * This function generates a error page from the info contained
+ * by err and then sends it to the client.
+ * The callback function errorSendComplete() is called after
+ * the page has been written to the client socket (fd).
+ * errorSendComplete() deallocates err. We need to add
+ * err to the cbdata because comm_write() requires it
+ * for all callback data pointers.
+ *
+ \note normally errorSend() should only be called from
+ * routines in ssl.c and pass.c, where we don't have any
+ * StoreEntry's. In client_side.c we must allocate a StoreEntry
+ * for errors and use errorAppendEntry() to account for
+ * persistent/pipeline connections.
+ *
+ \param fd socket where page object is to be written
+ \param err This object is destroyed after use in this function.
+ */
+SQUIDCEXTERN void errorSend(int fd, ErrorState *err);
+
+/**
+ \ingroup ErrorPageAPI
+ *
+ * This function generates a error page from the info contained
+ * by err and then stores the text in the specified store
+ * entry.
+ * This function should only be called by "server
+ * side routines" which need to communicate errors to the
+ * client side. It should also be called from client_side.c
+ * because we now support persistent connections, and
+ * cannot assume that we can immediately write to the socket
+ * for an error.
+ *
+ \param entry ??
+ \param err This object is destroyed after use in this function.
+ */
+SQUIDCEXTERN void errorAppendEntry(StoreEntry *entry, ErrorState *err);
+
+/// \ingroup ErrorPageAPI
SQUIDCEXTERN void errorStateFree(ErrorState * err);
+
+/// \ingroup ErrorPageAPI
SQUIDCEXTERN err_type errorReservePageId(const char *page_name);
-SQUIDCEXTERN ErrorState *errorCon(err_type type, http_status, HttpRequest * request);
+/**
+ \ingroup ErrorPageAPI
+ *
+ * This function creates a ErrorState object.
+ */
+SQUIDCEXTERN ErrorState *errorCon(err_type type, http_status, HttpRequest * request);
#endif /* SQUID_ERRORPAGE_H */
#if WIP_FWD_LOG
- void uninit
- static void logRotate
- void status()
+ void uninit /**DOCS_NOSEMI*/
+ static void logRotate /**DOCS_NOSEMI*/
+ void status() /**DOCS_NOSEMI*/
#endif
public:
-
/*
- * $Id: fqdncache.cc,v 1.177 2007/12/16 22:32:10 amosjeffries Exp $
+ * $Id: fqdncache.cc,v 1.178 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 35 FQDN Cache
* AUTHOR: Harvest Derived
#include "Store.h"
#include "wordlist.h"
+/**
+ \defgroup FQDNCacheAPI FQDN Cache API
+ \ingroup Components
+ \section Introduction Introduction
+ \par
+ * The FQDN cache is a built-in component of squid providing
+ * Hostname to IP-Number translation functionality and managing
+ * the involved data-structures. Efficiency concerns require
+ * mechanisms that allow non-blocking access to these mappings.
+ * The FQDN cache usually doesn't block on a request except for
+ * special cases where this is desired (see below).
+ *
+ \todo FQDN Cache should have its own API *.h file.
+ */
+
+/**
+ \defgroup FQDNCacheInternal FQDN Cache Internals
+ \ingroup FQDNCacheAPI
+ \par
+ * Internally, the execution flow is as follows:
+ * On a miss, fqdncache_nbgethostbyaddr() checks whether a request
+ * for this name is already pending, and if positive, it creates a
+ * new entry using fqdncacheAddEntry(). Then it calls
+ * fqdncacheAddPending() to add a request to the queue together
+ * with data and handler. Else, ifqdncache_dnsDispatch() is called
+ * to directly create a DNS query or to fqdncacheEnqueue() if all
+ * no DNS port is free.
+ *
+ \par
+ * fqdncacheCallback() is called regularly to walk down the pending
+ * list and call handlers.
+ *
+ \par
+ * LRU clean-up is performed through fqdncache_purgelru() according
+ * to the fqdncache_high threshold.
+ */
+
+/// \ingroup FQDNCacheInternal
#define FQDN_LOW_WATER 90
+
+/// \ingroup FQDNCacheInternal
#define FQDN_HIGH_WATER 95
+/// \ingroup FQDNCacheAPI
typedef struct _fqdncache_entry fqdncache_entry;
+/**
+ \ingroup FQDNCacheAPI
+ * The data structure used for storing name-address mappings
+ * is a small hashtable (static hash_table *fqdn_table),
+ * where structures of type fqdncache_entry whose most
+ * interesting members are:
+ */
struct _fqdncache_entry
{
hash_link hash; /* must be first */
flags;
};
-static struct
+/// \ingroup FQDNCacheInternal
+static struct _fqdn_cache_stats
{
int requests;
int replies;
int misses;
int negative_hits;
}
-
FqdncacheStats;
+/// \ingroup FQDNCacheInternal
static dlink_list lru_list;
#if USE_DNSSERVERS
static FREE fqdncacheFreeEntry;
static void fqdncacheAddEntry(fqdncache_entry * f);
+/// \ingroup FQDNCacheInternal
static hash_table *fqdn_table = NULL;
+/// \ingroup FQDNCacheInternal
static long fqdncache_low = 180;
+
+/// \ingroup FQDNCacheInternal
static long fqdncache_high = 200;
-/* removes the given fqdncache entry */
+/**
+ \ingroup FQDNCacheInternal
+ * Removes the given fqdncache entry
+ */
static void
fqdncacheRelease(fqdncache_entry * f)
{
memFree(f, MEM_FQDNCACHE_ENTRY);
}
-/* return match for given name */
+/**
+ \ingroup FQDNCacheInternal
+ \param name FQDN hash string.
+ \retval Match for given name
+ */
static fqdncache_entry *
fqdncache_get(const char *name)
{
return f;
}
+/// \ingroup FQDNCacheInternal
static int
fqdncacheExpiredEntry(const fqdncache_entry * f)
{
return 1;
}
+/// \ingroup FQDNCacheAPI
void
fqdncache_purgelru(void *notused)
{
debugs(35, 9, "fqdncache_purgelru: removed " << removed << " entries");
}
+/// \ingroup FQDNCacheAPI
static void
purge_entries_fromhosts(void)
{
fqdncacheRelease(i);
}
-/* create blank fqdncache_entry */
+/**
+ \ingroup FQDNCacheInternal
+ *
+ * Create blank fqdncache_entry
+ */
static fqdncache_entry *
fqdncacheCreateEntry(const char *name)
{
return f;
}
+/// \ingroup FQDNCacheInternal
static void
fqdncacheAddEntry(fqdncache_entry * f)
{
f->lastref = squid_curtime;
}
-/* walks down the pending list, calling handlers */
+/**
+ \ingroup FQDNCacheInternal
+ *
+ * Walks down the pending list, calling handlers
+ */
static void
fqdncacheCallback(fqdncache_entry * f)
{
fqdncacheUnlockEntry(f);
}
+/// \ingroup FQDNCacheInternal
#if USE_DNSSERVERS
static int
fqdncacheParse(fqdncache_entry *f, const char *inbuf)
#endif
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Callback for handling DNS results.
+ */
static void
#if USE_DNSSERVERS
fqdncacheHandleReply(void *data, char *reply)
fqdncacheCallback(f);
}
+/**
+ \ingroup FQDNCacheAPI
+ *
+ \param addr IP address of domain to resolve.
+ \param handler A pointer to the function to be called when
+ * the reply from the FQDN cache
+ * (or the DNS if the FQDN cache misses)
+ \param handlerData Information that is passed to the handler
+ * and does not affect the FQDN cache.
+ */
void
fqdncache_nbgethostbyaddr(IPAddress &addr, FQDNH * handler, void *handlerData)
{
#endif
}
-/* initialize the fqdncache */
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Initialize the fqdncache.
+ * Called after IP cache initialization.
+ */
void
fqdncache_init(void)
{
sizeof(fqdncache_entry), 0);
}
+/// \ingroup FQDNCacheAPI
void
fqdncacheRegisterWithCacheManager(CacheManager & manager)
{
}
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Is different in that it only checks if an entry exists in
+ * it's data-structures and does not by default contact the
+ * DNS, unless this is requested, by setting the flags
+ * to FQDN_LOOKUP_IF_MISS.
+ *
+ \param addr address of the FQDN being resolved
+ \param flags values are NULL or FQDN_LOOKUP_IF_MISS. default is NULL.
+ *
+ */
const char *
fqdncache_gethostbyaddr(IPAddress &addr, int flags)
{
}
-/* process objects list */
+/**
+ \ingroup FQDNCacheInternal
+ *
+ * Process objects list
+ */
void
fqdnStats(StoreEntry * sentry)
{
}
}
+/// \ingroup FQDNCacheInternal
static void
dummy_handler(const char *bufnotused, void *datanotused)
{
return;
}
+/// \ingroup FQDNCacheAPI
const char *
fqdnFromAddr(IPAddress &addr)
{
if (Config.onoff.log_fqdn && (n = fqdncache_gethostbyaddr(addr, 0)))
return n;
-/// \todo Perhaose this should use toHostname() instead of straight NtoA.
+/// \todo Perhapse this should use toHostname() instead of straight NtoA.
/// that would wrap the IPv6 properly when raw.
addr.NtoA(buf, MAX_IPSTRLEN);
return buf;
}
+/// \ingroup FQDNCacheInternal
static void
fqdncacheLockEntry(fqdncache_entry * f)
{
}
}
+/// \ingroup FQDNCacheInternal
static void
fqdncacheUnlockEntry(fqdncache_entry * f)
{
fqdncacheRelease(f);
}
+/// \ingroup FQDNCacheInternal
static void
fqdncacheFreeEntry(void *data)
{
memFree(f, MEM_FQDNCACHE_ENTRY);
}
+/// \ingroup FQDNCacheAPI
void
fqdncacheFreeMemory(void)
{
fqdn_table = NULL;
}
-/* Recalculate FQDN cache size upon reconfigure */
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Recalculate FQDN cache size upon reconfigure.
+ * Is called to clear the FQDN cache's data structures,
+ * cancel all pending requests.
+ */
void
fqdncache_restart(void)
{
purge_entries_fromhosts();
}
-/*
- * adds a "static" entry from /etc/hosts. the worldist is to be
- * managed by the caller, including pointed-to strings
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Adds a "static" entry from /etc/hosts.
+ \par
+ * The worldist is to be managed by the caller,
+ * including pointed-to strings
+ *
+ \param addr FQDN name to be added.
+ \param hostnames ??
*/
void
fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
#ifdef SQUID_SNMP
-/*
- * The function to return the fqdn statistics via SNMP
+/**
+ * \ingroup FQDNCacheAPI
+ * The function to return the FQDN statistics via SNMP
*/
-
variable_list *
snmp_netFqdnFn(variable_list * Var, snint * ErrP)
{
/*
- * $Id: StoreFSaufs.cc,v 1.2 2004/12/20 16:30:40 robertc Exp $
+ * $Id: StoreFSaufs.cc,v 1.3 2008/02/26 21:49:43 amosjeffries Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Robert Collins
#include "fs/ufs/StoreFSufs.h"
#include "DiskIO/DiskIOModule.h"
+/**
+ \defgroup AUFS AUFS Storage Filesystem (UFS Based)
+ \ingroup UFS, FileSystems
+ */
+
+/// \ingroup AUFS
static StoreFSufs<UFSSwapDir> AufsInstance("DiskThreads", "aufs");
#include "DiskIO/DiskFile.h"
#include "DiskIO/IORequestor.h"
+/// \ingroup COSS
class CossSwapDir : public SwapDir, public IORequestor
{
const char *stripe_path;
};
+/// \ingroup COSS
extern void storeCossAdd(CossSwapDir *, StoreEntry *);
+/// \ingroup COSS
extern void storeCossRemove(CossSwapDir *, StoreEntry *);
+/// \ingroup COSS
extern void storeCossStartMembuf(CossSwapDir * SD);
+/// \ingroup COSS
class StoreSearchCoss : public StoreSearch
{
/*
- * $Id: StoreFScoss.h,v 1.3 2006/05/29 00:15:09 robertc Exp $
+ * $Id: StoreFScoss.h,v 1.4 2008/02/26 21:49:43 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#include "StoreFileSystem.h"
+/**
+ \defgroup COSS COSS Storage Filesystem
+ \ingroup FileSystems
+ */
+
+/// \ingroup COSS
class CossStats
{
open, create, close, unlink, read, write, stripe_write;
};
+/// \ingroup COSS, FileSystems
class StoreFScoss : public StoreFileSystem
{
#define COSS_MEMBUF_SZ 1048576
#endif
-/* Note that swap_filen in sio/e are actually disk offsets too! */
+/** \note swap_filen in sio/e are actually disk offsets too! */
-/* What we're doing in storeCossAllocate() */
+/** What we're doing in storeCossAllocate() */
#define COSS_ALLOC_NOTIFY 0
+
+/** What we're doing in storeCossAllocate() */
#define COSS_ALLOC_ALLOCATE 1
+
+/** What we're doing in storeCossAllocate() */
#define COSS_ALLOC_REALLOC 2
class CossSwapDir;
+/// \ingroup COSS
class CossMemBuf
{
} flags;
};
+/// \ingroup COSS
struct _cossindex
{
- /* Note: the dlink_node MUST be the first member of the structure.
- * This member is later pointer typecasted to coss_index_node *.
+ /**
+ \note The dlink_node MUST be the first member of the structure.
+ * This member is later pointer typecasted to coss_index_node *.
*/
dlink_node node;
};
-/* Per-storeiostate info */
-
+/**
+ \ingroup COSS
+ * Per-storeiostate info
+ */
class CossState : public StoreIOState
{
CossSwapDir *SD;
};
-MEMPROXY_CLASS_INLINE(CossState)
+MEMPROXY_CLASS_INLINE(CossState) /**DOCS_NOSEMI*/
+/// \ingroup COSS
typedef struct _cossindex CossIndexNode;
-/* Whether the coss system has been setup or not */
+
+/**
+ \ingroup COSS
+ * Whether the coss system has been setup or not
+ */
extern int coss_initialised;
+/// \ingroup COSS
extern MemAllocator *coss_membuf_pool;
+/// \ingroup COSS
extern MemAllocator *coss_index_pool;
#include "DiskIO/ReadRequest.h"
+/// \ingroup COSS
class CossRead : public ReadRequest
{
#include "DiskIO/WriteRequest.h"
+/// \ingroup COSS
class CossWrite : public WriteRequest
{
/*
- * $Id: StoreFSdiskd.cc,v 1.2 2004/12/20 16:30:43 robertc Exp $
+ * $Id: StoreFSdiskd.cc,v 1.3 2008/02/26 21:49:44 amosjeffries Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Robert Collins
#include "fs/ufs/StoreFSufs.h"
#include "DiskIO/DiskIOModule.h"
+/**
+ \defgroup diskd diskd Storage Filesystem (UFS Based)
+ \ingroup FileSystems, UFS
+ */
+
+/// \ingroup diskd
static StoreFSufs<UFSSwapDir> DiskdInstance("DiskDaemon", "diskd");
/*
- * $Id: StoreFSufs.h,v 1.5 2006/09/14 00:51:12 robertc Exp $
+ * $Id: StoreFSufs.h,v 1.6 2008/02/26 21:49:45 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#include "ufscommon.h"
#include "DiskIO/DiskIOModule.h"
+/**
+ \defgroup UFS UFS Storage Filesystem
+ \ingroup FileSystems
+ */
-/* core UFS class. This template provides compile time aliases for
+/**
+ \ingroup UFS, FileSystems
+ *
+ * Core UFS class. This template provides compile time aliases for
* ufs/aufs/diskd to ease configuration conversion - each becomes a
* StoreFS module whose createSwapDir method parameterises the common
* UFSSwapDir with an IO module instance.
virtual SwapDir *createSwapDir();
virtual void done();
virtual void setup();
- /* Not implemented */
+ /** Not implemented */
StoreFSufs (StoreFSufs const &);
StoreFSufs &operator=(StoreFSufs const &);
/*
- * $Id: ufscommon.h,v 1.12 2007/08/13 17:20:57 hno Exp $
+ * $Id: ufscommon.h,v 1.13 2008/02/26 21:49:45 amosjeffries Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
class DiskIOModule;
+/// \ingroup UFS
class UFSSwapDir : public SwapDir
{
#include "RefCount.h"
#include "DiskIO/IORequestor.h"
-/* UFS dir specific IO calls
+/**
+ * UFS dir specific IO calls
*
- * This should be whittled away - DiskIOModule should be providing the
- * entire needed api.
+ \todo This should be whittled away.
+ * DiskIOModule should be providing the entire needed API.
*/
class DiskIOStrategy;
class DiskFile;
+/// \ingroup UFS
class UFSStrategy
{
virtual int callback();
- /* Init per-instance logic */
+ /** Init per-instance logic */
virtual void init();
- /* cachemgr output on the IO instance stats */
+ /** cachemgr output on the IO instance stats */
virtual void statfs(StoreEntry & sentry)const;
- /* The io strategy in use */
+ /** The io strategy in use */
DiskIOStrategy *io;
protected:
friend class UFSSwapDir;
};
-/* Common ufs-store-dir logic */
+/** Common ufs-store-dir logic */
class ReadRequest;
+/// \ingroup UFS
class UFSStoreState : public StoreIOState, public IORequestor
{
};
- /* These should be in the IO strategy */
+ /** \todo These should be in the IO strategy */
struct
{
- /*
+ /**
* DPW 2006-05-24
* the write_draining flag is used to avoid recursion inside
* the UFSStoreState::drainWriteQueue() method.
*/
bool write_draining;
- /*
+ /**
* DPW 2006-05-24
* The try_closing flag is set by UFSStoreState::tryClosing()
* when UFSStoreState wants to close the file, but cannot
void doWrite();
};
-MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_read)
-MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_write)
+MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_read) /**DOCS_NOSEMI*/
+MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_write) /**DOCS_NOSEMI*/
+/// \ingroup UFS
class StoreSearchUFS : public StoreSearch
{
StoreSearchUFS(RefCount<UFSSwapDir> sd);
StoreSearchUFS(StoreSearchUFS const &);
virtual ~StoreSearchUFS();
- /* Iterator API - garh, wrong place */
- /* callback the client when a new StoreEntry is available
- * or an error occurs
+
+ /** \todo Iterator API - garh, wrong place */
+ /**
+ * callback the client when a new StoreEntry is available
+ * or an error occurs
*/
virtual void next(void (callback)(void *cbdata), void *cbdata);
- /* return true if a new StoreEntry is immediately available */
+
+ /**
+ \retval true if a new StoreEntry is immediately available
+ \retval false if a new StoreEntry is NOT immediately available
+ */
virtual bool next();
+
virtual bool error() const;
virtual bool isDone() const;
virtual StoreEntry *currentItem();
private:
CBDATA_CLASS2(StoreSearchUFS);
+ /// \bug (callback) should be hidden behind a proper human readable name
void (callback)(void *cbdata);
void *cbdata;
StoreEntry * current;
};
class StoreSwapLogData;
-class UFSSwapLogParser{
+
+/// \ingroup UFS
+class UFSSwapLogParser
+{
public:
FILE *log;
int SwapLogEntries();
void Close()
{
- if(log){
+ if(log){
fclose(log);
log = NULL;
}
}
};
+/// \ingroup UFS
class RebuildState : public RefCountable
{
RebuildState(RefCount<UFSSwapDir> sd);
~RebuildState();
- /* Iterator API - garh, wrong place */
- /* callback the client when a new StoreEntry is available
+ /** \todo Iterator API - garh, wrong place */
+ /**
+ * callback the client when a new StoreEntry is available
* or an error occurs
*/
virtual void next(void (callback)(void *cbdata), void *cbdata);
- /* return true if a new StoreEntry is immediately available */
+
+ /**
+ \retval true if a new StoreEntry is immediately available
+ \retval false if a new StoreEntry is NOT immediately available
+ */
virtual bool next();
virtual bool error() const;
virtual bool isDone() const;
StoreEntry *e;
bool fromLog;
bool _done;
+ /// \bug (callback) should be hidden behind a proper human readable name
void (callback)(void *cbdata);
void *cbdata;
};
/*
- * $Id: ftp.cc,v 1.445 2008/02/12 23:55:26 rousskov Exp $
+ * $Id: ftp.cc,v 1.446 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
#include "SquidTime.h"
#include "URLScheme.h"
+/**
+ \defgroup ServerProtocolFTPInternal Server-Side FTP Internals
+ \ingroup ServerProtocolFTPAPI
+ */
+
+/// \ingroup ServerProtocolFTPInternal
static const char *const crlf = "\r\n";
+
+/// \ingroup ServerProtocolFTPInternal
static char cbuf[1024];
+/// \ingroup ServerProtocolFTPInternal
typedef enum {
BEGIN,
SENT_USER,
SENT_MKDIR
} ftp_state_t;
+/// \ingroup ServerProtocolFTPInternal
struct _ftp_flags
{
bool isdir;
};
class FtpStateData;
+
+/// \ingroup ServerProtocolFTPInternal
typedef void (FTPSM) (FtpStateData *);
+/// \ingroup ServerProtocolFTPInternal
class FtpStateData : public ServerStateData
{
cbdataFree(t);
}
+/// \ingroup ServerProtocolFTPInternal
typedef struct
{
char type;
char *showname;
char *link;
}
-
ftpListParts;
+/// \ingroup ServerProtocolFTPInternal
#define FTP_LOGIN_ESCAPED 1
+
+/// \ingroup ServerProtocolFTPInternal
#define FTP_LOGIN_NOT_ESCAPED 0
/*
Quit -
************************************************/
+/// \ingroup ServerProtocolFTPInternal
FTPSM *FTP_SM_FUNCS[] =
{
ftpReadWelcome, /* BEGIN */
printfReplyBody("</ADDRESS></BODY></HTML>\n");
}
+/// \ingroup ServerProtocolFTPInternal
static const char *Month[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
+/// \ingroup ServerProtocolFTPInternal
static int
is_month(const char *buf)
{
return 0;
}
-
+/// \ingroup ServerProtocolFTPInternal
static void
ftpListPartsFree(ftpListParts ** parts)
{
safe_free(*parts);
}
+/// \ingroup ServerProtocolFTPInternal
#define MAX_TOKENS 64
+/// \ingroup ServerProtocolFTPInternal
static ftpListParts *
-
ftpListParseParts(const char *buf, struct _ftp_flags flags)
{
ftpListParts *p = NULL;
return p;
}
+/// \ingroup ServerProtocolFTPInternal
static const char *
dots_fill(size_t len)
{
maybeReadVirginBody();
}
-/*
- * ftpCheckAuth
- *
- * Return 1 if we have everything needed to complete this request.
- * Return 0 if something is missing.
+/**
+ \retval 1 if we have everything needed to complete this request.
+ \retval 0 if something is missing.
*/
int
FtpStateData::checkAuth(const HttpHeader * req_hdr)
base_href.append("/");
}
+/// \ingroup ServerProtocolFTPAPI
void
ftpStart(FwdState * fwd)
{
/* ====================================================================== */
+/// \ingroup ServerProtocolFTPInternal
static char *
escapeIAC(const char *buf)
{
return head;
}
-/*
+/**
* DPW 2007-04-23
* Looks like there are no longer anymore callers that set
* buffered_ok=1. Perhaps it can be removed at some point.
/* ====================================================================== */
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadWelcome(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendUser(FtpStateData * ftpState)
{
ftpState->state = SENT_USER;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadUser(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendPass(FtpStateData * ftpState)
{
ftpState->state = SENT_PASS;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPass(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendType(FtpStateData * ftpState)
{
ftpState->state = SENT_TYPE;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadType(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpTraverseDirectory(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendCwd(FtpStateData * ftpState)
{
ftpState->state = SENT_CWD;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadCwd(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendMkdir(FtpStateData * ftpState)
{
ftpState->state = SENT_MKDIR;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadMkdir(FtpStateData * ftpState)
{
ftpSendReply(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpGetFile(FtpStateData * ftpState)
{
ftpSendMdtm(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpListDir(FtpStateData * ftpState)
{
ftpSendPassive(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendMdtm(FtpStateData * ftpState)
{
ftpState->state = SENT_MDTM;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadMdtm(FtpStateData * ftpState)
{
ftpSendSize(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendSize(FtpStateData * ftpState)
{
ftpSendPassive(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadSize(FtpStateData * ftpState)
{
ftpSendPassive(ftpState);
}
+/**
+ \ingroup ServerProtocolFTPInternal
+ */
static void
ftpReadEPSV(FtpStateData* ftpState)
{
commConnectStart(fd, ftpState->data.host, port, FtpStateData::ftpPasvCallback, ftpState);
}
-/**
+/** \ingroup ServerProtocolFTPInternal
+ *
* Send Passive connection request.
* Default method is to use modern EPSV request.
* The failover mechanism should check for previous state and re-call with alternates on failure.
processReplyBody();
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPasv(FtpStateData * ftpState)
{
ftpRestOrList(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static int
ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
{
return fd;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendPORT(FtpStateData * ftpState)
{
ipa.FreeAddrInfo(AI);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPORT(FtpStateData * ftpState)
{
ftpRestOrList(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendEPRT(FtpStateData * ftpState)
{
}
/**
- \ingroup FTPCallback
+ \ingroup ServerProtocolFTPInternal
\par
* "read" handler to accept FTP data connections.
*
- \param io comm accept(2) callback parameters
+ \param io comm accept(2) callback parameters
*/
void FtpStateData::ftpAcceptDataConnection(const CommAcceptCbParams &io)
{
FTP_SM_FUNCS[state] (this);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpRestOrList(FtpStateData * ftpState)
{
ftpSendRetr(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendStor(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
+/// \deprecated use ftpState->readStor() instead.
static void
ftpReadStor(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendRest(FtpStateData * ftpState)
{
return 1;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadRest(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendList(FtpStateData * ftpState)
{
ftpState->state = SENT_LIST;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendNlst(FtpStateData * ftpState)
{
ftpState->state = SENT_NLST;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadList(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendRetr(FtpStateData * ftpState)
{
ftpState->state = SENT_RETR;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadRetr(FtpStateData * ftpState)
{
}
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadTransferDone(FtpStateData * ftpState)
{
failed(ERR_READ_ERROR, 0);
}
-/* This will be called when the put write is completed */
+/**
+ * This will be called when the put write is completed
+ */
void
FtpStateData::sentRequestBody(const CommIoCbParams &io)
{
ServerStateData::sentRequestBody(io);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpWriteTransferDone(FtpStateData * ftpState)
{
ftpSendReply(ftpState);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendQuit(FtpStateData * ftpState)
{
ftpState->state = SENT_QUIT;
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpReadQuit(FtpStateData * ftpState)
{
- /* XXX should this just be a case of abortTransaction? */
+ /** \todo XXX should this just be a case of abortTransaction? */
ftpState->serverComplete();
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpTrySlashHack(FtpStateData * ftpState)
{
ftpGetFile(ftpState);
}
-/* Forget hack status. Next error is shown to the user */
+/**
+ * Forget hack status. Next error is shown to the user
+ */
void
FtpStateData::unhack()
{
nextState(this);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpFail(FtpStateData *ftpState)
{
fwd->fail(err);
}
+/// \ingroup ServerProtocolFTPInternal
static void
ftpSendReply(FtpStateData * ftpState)
{
}
/**
+ \ingroup ServerProtocolFTPAPI
+ \todo Should be a URL class API call.
+ *
* Construct an URI with leading / in PATH portion for use by CWD command
* possibly others. FTP encodes absolute paths as beginning with '/'
* after the initial URI path delimiter, which happens to be / itself.
writeReplyBody(buf, strlen(buf));
}
-/*
+/**
* Call this when there is data from the origin server
* which should be sent to either StoreEntry, or to ICAP...
*/
addVirginReplyBody(data, len);
}
-// called after we wrote the last byte of the request body
+/**
+ * called after we wrote the last byte of the request body
+ */
void
FtpStateData::doneSendingRequestBody()
{
ftpWriteTransferDone(this);
}
-// a hack to ensure we do not double-complete on the forward entry.
-// TODO: FtpStateData logic should probably be rewritten to avoid
-// double-completion or FwdState should be rewritten to allow it.
+/**
+ * A hack to ensure we do not double-complete on the forward entry.
+ *
+ \todo FtpStateData logic should probably be rewritten to avoid
+ * double-completion or FwdState should be rewritten to allow it.
+ */
void
FtpStateData::completeForwarding()
{
ServerStateData::completeForwarding();
}
-// Close the FTP server connection(s). Used by serverComplete().
+/**
+ * Close the FTP server connection(s). Used by serverComplete().
+ */
void
FtpStateData::closeServer()
{
}
}
-// Did we close all FTP server connection(s)?
+/**
+ * Did we close all FTP server connection(s)?
+ *
+ \retval true Both server control and data channels are closed.
+ \retval false Either control channel or data is still active.
+ */
bool
FtpStateData::doneWithServer() const
{
return ctrl.fd < 0 && data.fd < 0;
}
+/**
+ * Have we lost the FTP server control channel?
+ *
+ \retval true The server control channel is available.
+ \retval false The server control channel is not available.
+ */
bool
FtpStateData::haveControlChannel(const char *caller_name) const
{
return true;
}
-// Quickly abort the transaction
-// TODO: destruction should be sufficient as the destructor should cleanup,
-// including canceling close handlers
+/**
+ * Quickly abort the transaction
+ *
+ \todo destruction should be sufficient as the destructor should cleanup,
+ * including canceling close handlers
+ */
void
FtpStateData::abortTransaction(const char *reason)
{
/*
- * $Id: gopher.cc,v 1.210 2008/02/12 23:33:48 rousskov Exp $
+ * $Id: gopher.cc,v 1.211 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
#include "forward.h"
#include "SquidTime.h"
+/**
+ \defgroup ServerProtocolGopherInternal Server-Side Gopher Internals
+ \ingroup ServerProtocolGopherAPI
+ * Gopher is somewhat complex and gross because it must convert from
+ * the Gopher protocol to HTTP.
+ */
+
/* gopher type code from rfc. Anawat. */
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_FILE '0'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_DIRECTORY '1'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_CSO '2'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_ERROR '3'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_MACBINHEX '4'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_DOSBIN '5'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_UUENCODED '6'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_INDEX '7'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_TELNET '8'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_BIN '9'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_REDUNT '+'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_3270 'T'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_GIF 'g'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_IMAGE 'I'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_HTML 'h' /* HTML */
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_INFO 'i'
-#define GOPHER_WWW 'w' /* W3 address */
+/**
+ \ingroup ServerProtocolGopherInternal
+ W3 address
+ */
+#define GOPHER_WWW 'w'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_SOUND 's'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_PLUS_IMAGE ':'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_PLUS_MOVIE ';'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_PLUS_SOUND '<'
+/// \ingroup ServerProtocolGopherInternal
#define GOPHER_PORT 70
+/// \ingroup ServerProtocolGopherInternal
#define TAB '\t'
+/// \ingroup ServerProtocolGopherInternal
+/// \todo CODE: should this be a protocol-specific thing?
#define TEMP_BUF_SIZE 4096
+/// \ingroup ServerProtocolGopherInternal
#define MAX_CSO_RESULT 1024
+/// \ingroup ServerProtocolGopherInternal
typedef struct gopher_ds
{
StoreEntry *entry;
static IOCB gopherSendComplete;
static PF gopherSendRequest;
+/// \ingroup ServerProtocolGopherInternal
static char def_gopher_bin[] = "www/unknown";
+
+/// \ingroup ServerProtocolGopherInternal
static char def_gopher_text[] = "text/plain";
+/// \ingroup ServerProtocolGopherInternal
static void
gopherStateFree(int fdnotused, void *data)
{
}
-/* figure out content type from file extension */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * Figure out content type from file extension
+ */
static void
gopher_mime_content(MemBuf * mb, const char *name, const char *def_ctype)
{
-/* create MIME Header for Gopher Data */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * Create MIME Header for Gopher Data
+ */
static void
gopherMimeCreate(GopherStateData * gopherState)
{
mb.clean();
}
-/* Parse a gopher request into components. By Anawat. */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * Parse a gopher request into components. By Anawat.
+ */
static void
gopher_request_parse(const HttpRequest * req, char *type_id, char *request)
{
}
}
+/**
+ \ingroup ServerProtocolGopherAPI
+ * Parse the request to determine whether it is cachable.
+ *
+ \param req Request data.
+ \retval 0 Not cachable.
+ \retval 1 Cachable.
+ */
int
gopherCachable(const HttpRequest * req)
{
return cachable;
}
+/// \ingroup ServerProtocolGopherInternal
static void
gopherHTMLHeader(StoreEntry * e, const char *title, const char *substring)
{
storeAppendPrintf(e, "</H1>\n");
}
+/// \ingroup ServerProtocolGopherInternal
static void
gopherHTMLFooter(StoreEntry * e)
{
storeAppendPrintf(e, "</ADDRESS></BODY></HTML>\n");
}
+/// \ingroup ServerProtocolGopherInternal
static void
gopherEndHTML(GopherStateData * gopherState)
{
gopherHTMLFooter(e);
}
-
-/* Convert Gopher to HTML */
-/* Borrow part of code from libwww2 came with Mosaic distribution */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * Convert Gopher to HTML.
+ \par
+ * Borrow part of code from libwww2 came with Mosaic distribution.
+ */
static void
gopherToHTML(GopherStateData * gopherState, char *inbuf, int len)
{
return;
}
+/// \ingroup ServerProtocolGopherInternal
static void
gopherTimeout(int fd, void *data)
{
comm_close(fd);
}
-/* This will be called when data is ready to be read from fd. Read until
- * error or connection closed. */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * This will be called when data is ready to be read from fd.
+ * Read until error or connection closed.
+ */
static void
gopherReadReply(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
{
return;
}
-/* This will be called when request write is complete. Schedule read of
- * reply. */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * This will be called when request write is complete. Schedule read of reply.
+ */
static void
gopherSendComplete(int fd, char *buf, size_t size, comm_err_t errflag, int xerrno, void *data)
{
memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */
}
-/* This will be called when connect completes. Write request. */
+/**
+ \ingroup ServerProtocolGopherInternal
+ * This will be called when connect completes. Write request.
+ */
static void
gopherSendRequest(int fd, void *data)
{
gopherState->entry->setPublicKey(); /* Make it public */
}
+/// \ingroup ServerProtocolGopherInternal
CBDATA_TYPE(GopherStateData);
+/// \ingroup ServerProtocolGopherAPI
void
gopherStart(FwdState * fwd)
{
/*
- * $Id: helper.h,v 1.11 2008/01/07 17:12:28 hno Exp $
+ * $Id: helper.h,v 1.12 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 84 Helper process maintenance
* AUTHOR: Harvest Derived?
struct timeval dispatch_time;
};
-MEMPROXY_CLASS_INLINE(helper_request)
+MEMPROXY_CLASS_INLINE(helper_request) /**DOCS_NOSEMI*/
class helper_stateful_request
{
void *data;
};
-MEMPROXY_CLASS_INLINE(helper_stateful_request)
+MEMPROXY_CLASS_INLINE(helper_stateful_request) /**DOCS_NOSEMI*/
/* helper.c */
SQUIDCEXTERN void helperOpenServers(helper * hlp);
/*
- * $Id: htcp.cc,v 1.80 2008/02/03 10:00:30 amosjeffries Exp $
+ * $Id: htcp.cc,v 1.81 2008/02/26 21:49:34 amosjeffries Exp $
*
* DEBUG: section 31 Hypertext Caching Protocol
* AUTHOR: Duane Wesssels
htcpDataHeader *dhdr;
};
-MEMPROXY_CLASS_INLINE(htcpSpecifier)
+MEMPROXY_CLASS_INLINE(htcpSpecifier) /**DOCS_NOSEMI*/
struct _htcpDetail
{
-
/*
- * $Id: htcp.h,v 1.6 2007/12/14 23:11:47 amosjeffries Exp $
+ * $Id: htcp.h,v 1.7 2008/02/26 21:49:35 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#include "HttpHeader.h"
#include "IPAddress.h"
+/// \ingroup ServerProtocolHTCP
class HtcpReplyData
{
u_int32_t msg_id;
double version;
- struct
+ struct cto_t
{
/* cache-to-origin */
double rtt;
cto;
};
+/// \bug redundant typedef
typedef class HtcpReplyData htcpReplyData;
+/// \ingroup ServerProtocolHTCP
SQUIDCEXTERN void neighborsHtcpReply(const cache_key *, htcpReplyData *, const IPAddress &);
+
+/// \ingroup ServerProtocolHTCP
SQUIDCEXTERN void htcpInit(void);
+
+/// \ingroup ServerProtocolHTCP
SQUIDCEXTERN void htcpQuery(StoreEntry * e, HttpRequest * req, peer * p);
+
+/// \ingroup ServerProtocolHTCP
SQUIDCEXTERN void htcpSocketShutdown(void);
+
+/// \ingroup ServerProtocolHTCP
SQUIDCEXTERN void htcpSocketClose(void);
-#endif
+#endif /* USE_HTCP */
#endif /* SQUID_HTCP_H */
-
/*
- * $Id: icp_v2.cc,v 1.102 2007/12/14 23:11:47 amosjeffries Exp $
+ * $Id: icp_v2.cc,v 1.103 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: section 12 Internet Cache Protocol (ICP)
* AUTHOR: Duane Wessels
*
*/
+/**
+ \defgroup ServerProtocolICPInternal2 ICPv2 Internals
+ \ingroup ServerProtocolICPAPI
+ */
+
#include "squid.h"
#include "Store.h"
#include "comm.h"
#include "SquidTime.h"
#include "SwapDir.h"
+/// \ingroup ServerProtocolICPInternal2
static void icpLogIcp(const IPAddress &, log_type, int, const char *, int);
+/// \ingroup ServerProtocolICPInternal2
static void icpHandleIcpV2(int, IPAddress &, char *, int);
+
+/// \ingroup ServerProtocolICPInternal2
static void icpCount(void *, int, size_t, int);
-/*
+/**
+ \ingroup ServerProtocolICPInternal2
* IcpQueueHead is global so comm_incoming() knows whether or not
* to call icpUdpSendQueue.
*/
-static icpUdpData *IcpQueueTail = NULL;
static icpUdpData *IcpQueueHead = NULL;
+/// \ingroup ServerProtocolICPInternal2
+static icpUdpData *IcpQueueTail = NULL;
/* icp_common_t */
_icp_common_t::_icp_common_t() : opcode(ICP_INVALID), version(0), length(0), reqnum(0), flags(0), pad(0), shostid(0)
/* ICPState */
-ICPState:: ICPState(icp_common_t & aHeader, HttpRequest *aRequest):
+ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest):
header(aHeader),
request(HTTPMSGLOCK(aRequest)),
fd(-1),
/* ICP2State */
-class ICP2State:public ICPState, public StoreClient
+/// \ingroup ServerProtocolICPInternal2
+class ICP2State : public ICPState, public StoreClient
{
public:
u_int32_t flags;
};
-ICP2State::~ICP2State ()
+ICP2State::~ICP2State()
{}
void
-ICP2State::created (StoreEntry *newEntry)
+ICP2State::created(StoreEntry *newEntry)
{
StoreEntry *entry = newEntry->isNull () ? NULL : newEntry;
debugs(12, 5, "icpHandleIcpV2: OPCODE " << icp_opcode_str[header.opcode]);
/* End ICP2State */
+/// \ingroup ServerProtocolICPInternal2
static void
-
icpLogIcp(const IPAddress &caddr, log_type logcode, int len, const char *url, int delay)
{
AccessLogEntry al;
accessLogLog(&al, NULL);
}
+/// \ingroup ServerProtocolICPInternal2
void
icpUdpSendQueue(int fd, void *unused)
{
return 1;
}
-/* ICP_ERR means no opcode selected here
- *
+/**
* This routine selects an ICP opcode for ICP misses.
+ *
+ \retval ICP_ERR no opcode selected here
+ \retval ICP_MISS_NOFETCH store is rebuilding, no fetch is possible yet
*/
icp_opcode
icpGetCommonOpcode()
}
void
-
icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const IPAddress &from)
{
icp_common_t *reply = _icp_common_t::createMessage(opcode, flags, url, reqnum, pad);
}
void
-
icpDenyAccess(IPAddress &from, char *url, int reqnum, int fd)
{
debugs(12, 2, "icpDenyAccess: Access Denied for " << from << " by " << AclMatchedName << ".");
}
int
-
icpAccessAllowed(IPAddress &from, HttpRequest * icp_request)
{
ACLChecklist checklist;
}
HttpRequest *
-
icpGetRequest(char *url, int reqnum, int fd, IPAddress &from)
{
if (strpbrk(url, w_space))
}
static void
-
doV2Query(int fd, IPAddress &from, char *buf, icp_common_t header)
{
int rtt = 0;
}
void
-
_icp_common_t::handleReply(char *buf, IPAddress &from)
{
if (neighbors_do_private_keys && reqnum == 0)
}
static void
-
icpHandleIcpV2(int fd, IPAddress &from, char *buf, int len)
{
if (len <= 0)
theOutICPAddr.FreeAddrInfo(xai);
}
-/*
+/**
* icpConnectionShutdown only closes the 'in' socket if it is
* different than the 'out' socket.
*/
comm_close(theInIcpConnection);
}
- /*
+ /**
* Here we set 'theInIcpConnection' to -1 even though the ICP 'in'
* and 'out' sockets might be just one FD. This prevents this
* function from executing repeatedly. When we are really ready to
*/
theInIcpConnection = -1;
- /*
+ /**
* Normally we only write to the outgoing ICP socket, but
* we also have a read handler there to catch messages sent
* to that specific interface. During shutdown, we must
-
/*
- * $Id: icp_v3.cc,v 1.43 2007/12/14 23:11:47 amosjeffries Exp $
+ * $Id: icp_v3.cc,v 1.44 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: section 12 Internet Cache Protocol (ICP)
* AUTHOR: Duane Wessels
*
*/
+/**
+ \defgroup ServerProtocolICPInternal3 ICPv3 Internals
+ \ingroup ServerProtocolICPAPI
+ */
+
#include "squid.h"
#include "Store.h"
#include "ICP.h"
#include "HttpRequest.h"
+/// \ingroup ServerProtocolICPInternal3
class ICP3State : public ICPState, public StoreClient
{
public:
- ICP3State(icp_common_t &aHeader, HttpRequest *aRequest):
+ ICP3State(icp_common_t &aHeader, HttpRequest *aRequest) :
ICPState(aHeader, aRequest)
{}
void created (StoreEntry *newEntry);
};
+/// \ingroup ServerProtocolICPInternal3
static void
-
doV3Query(int fd, IPAddress &from, char *buf, icp_common_t header)
{
/* We have a valid packet */
StoreEntry::getPublic (state, url, METHOD_GET);
}
-ICP3State::~ICP3State ()
+ICP3State::~ICP3State()
{}
void
-ICP3State::created (StoreEntry *newEntry)
+ICP3State::created(StoreEntry *newEntry)
{
StoreEntry *entry = newEntry->isNull () ? NULL : newEntry;
debugs(12, 5, "icpHandleIcpV3: OPCODE " << icp_opcode_str[header.opcode]);
delete this;
}
+
+/// \ingroup ServerProtocolICPInternal3
/* Currently Harvest cached-2.x uses ICP_VERSION_3 */
void
-
icpHandleIcpV3(int fd, IPAddress&from, char *buf, int len)
{
if (len <= 0)
/*
- * $Id: ipcache.cc,v 1.268 2008/01/12 13:17:41 amosjeffries Exp $
+ * $Id: ipcache.cc,v 1.269 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
#include "wordlist.h"
#include "IPAddress.h"
+/**
+ \defgroup IPCacheAPI IP Cache API
+ \ingroup Components
+ \section Introduction Introduction
+ \par
+ * The IP cache is a built-in component of squid providing
+ * Hostname to IP-Number translation functionality and managing
+ * the involved data-structures. Efficiency concerns require
+ * mechanisms that allow non-blocking access to these mappings.
+ * The IP cache usually doesn't block on a request except for
+ * special cases where this is desired (see below).
+ *
+ \todo IP Cache should have its own API *.h header file.
+ */
+
+/**
+ \defgroup IPCacheInternal IP Cache Internals
+ \ingroup IPCacheAPI
+ \todo when IP cache is provided as a class. These sub-groups will be obsolete
+ * for now they are used to seperate the public and private functions.
+ * with the private ones all being in IPCachInternal and public in IPCacheAPI
+ *
+ \section InternalOperation Internal Operation
+ *
+ * Internally, the execution flow is as follows: On a miss,
+ * ipcache_getnbhostbyname checks whether a request for
+ * this name is already pending, and if positive, it creates
+ * a new entry using ipcacheAddNew with the IP_PENDING
+ * flag set . Then it calls ipcacheAddPending to add a
+ * request to the queue together with data and handler. Else,
+ * ipcache_dnsDispatch() is called to directly create a
+ * DNS query or to ipcacheEnqueue() if all no DNS port
+ * is free. ipcache_call_pending() is called regularly
+ * to walk down the pending list and call handlers. LRU clean-up
+ * is performed through ipcache_purgelru() according to
+ * the ipcache_high threshold.
+ */
+
+/// \ingroup IPCacheAPI
typedef struct _ipcache_entry ipcache_entry;
+/**
+ \ingroup IPCacheAPI
+ *
+ * The data structure used for storing name-address mappings
+ * is a small hashtable (static hash_table *ip_table),
+ * where structures of type ipcache_entry whose most
+ * interesting members are:
+ */
struct _ipcache_entry
{
hash_link hash; /* must be first */
flags;
};
-static struct
+/// \ingroup IPCacheInternal
+static struct _ipcache_stats
{
int requests;
int replies;
}
IpcacheStats;
+/// \ingroup IPCacheInternal
static dlink_list lru_list;
static FREE ipcacheFreeEntry;
static void ipcacheUnlockEntry(ipcache_entry *);
static void ipcacheRelease(ipcache_entry *, bool dofree = true);
+/// \ingroup IPCacheInternal
static ipcache_addrs static_addrs;
+/// \ingroup IPCacheInternal
static hash_table *ip_table = NULL;
+/// \ingroup IPCacheInternal
static long ipcache_low = 180;
+/// \ingroup IPCacheInternal
static long ipcache_high = 200;
#if LIBRESOLV_DNS_TTL_HACK
extern int _dns_ttl_;
#endif
+/// \ingroup IPCacheInternal
static int
ipcache_testname(void)
{
return 0;
}
-/* removes the given ipcache entry */
+/**
+ \ingroup IPCacheInternal
+ *
+ * removes the given ipcache entry
+ */
static void
ipcacheRelease(ipcache_entry * i, bool dofree)
{
ipcacheFreeEntry(i);
}
+/// \ingroup IPCacheInternal
static ipcache_entry *
ipcache_get(const char *name)
{
return NULL;
}
+/// \ingroup IPCacheInternal
static int
ipcacheExpiredEntry(ipcache_entry * i)
{
return 1;
}
+/// \ingroup IPCacheAPI
void
ipcache_purgelru(void *voidnotused)
{
debugs(14, 9, "ipcache_purgelru: removed " << removed << " entries");
}
-/* purges entries added from /etc/hosts (or whatever). */
+/**
+ \ingroup IPCacheInternal
+ *
+ * purges entries added from /etc/hosts (or whatever).
+ */
static void
purge_entries_fromhosts(void)
{
ipcacheRelease(i);
}
-/* create blank ipcache_entry */
+/**
+ \ingroup IPCacheInternal
+ *
+ * create blank ipcache_entry
+ */
static ipcache_entry *
ipcacheCreateEntry(const char *name)
{
return i;
}
+/// \ingroup IPCacheInternal
static void
ipcacheAddEntry(ipcache_entry * i)
{
i->lastref = squid_curtime;
}
-/* walks down the pending list, calling handlers */
+/**
+ \ingroup IPCacheInternal
+ *
+ * walks down the pending list, calling handlers
+ */
static void
ipcacheCallback(ipcache_entry * i)
{
ipcacheUnlockEntry(i);
}
+/// \ingroup IPCacheAPI
#if USE_DNSSERVERS
static int
ipcacheParse(ipcache_entry *i, const char *inbuf)
#endif
+/// \ingroup IPCacheInternal
static void
#if USE_DNSSERVERS
ipcacheHandleReply(void *data, char *reply)
}
}
+/**
+ \ingroup IPCacheAPI
+ *
+ \param name Host to resolve.
+ \param handler Pointer to the function to be called when the reply
+ * from the IP cache (or the DNS if the IP cache misses)
+ \param handlerData Information that is passed to the handler and does not affect the IP cache.
+ */
void
ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData)
{
#endif
}
-/* initialize the ipcache */
+/**
+ \ingroup IPCacheAPI
+ *
+ * Initialize the ipcache.
+ * Is called from mainInitialize() after disk initialization
+ * and prior to the reverse FQDNCache initialization
+ */
void
ipcache_init(void)
{
memDataInit(MEM_IPCACHE_ENTRY, "ipcache_entry", sizeof(ipcache_entry), 0);
}
+/// \ingroup IPCacheAPI
void
ipcacheRegisterWithCacheManager(CacheManager & manager)
{
stat_ipcache_get, 0, 1);
}
+/**
+ \ingroup IPCacheAPI
+ *
+ * Is different from ipcache_nbgethostbyname in that it only checks
+ * if an entry exists in the cache and does not by default contact the DNS,
+ * unless this is requested, by setting the flags.
+ *
+ \param name Host name to resolve.
+ \param flags Default is NULL, set to IP_LOOKUP_IF_MISS
+ * to explicitly perform DNS lookups.
+ *
+ \retval NULL An error occured during lookup
+ \retval NULL No results available in cache and no lookup specified
+ \retval * Pointer to the ipcahce_addrs structure containing the lookup results
+ */
const ipcache_addrs *
ipcache_gethostbyname(const char *name, int flags)
{
return NULL;
}
+/// \ingroup IPCacheInternal
static void
ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry)
{
}
}
-/* process objects list */
+/**
+ \ingroup IPCacheInternal
+ *
+ * process objects list
+ */
void
stat_ipcache_get(StoreEntry * sentry)
{
}
#endif /* DNS_CNAME */
+/// \ingroup IPCacheInternal
+/// Callback.
static void
ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, void *cbdata)
{
#endif /* DNS_CNAME */
}
+/// \ingroup IPCacheAPI
void
ipcacheInvalidate(const char *name)
{
i->expires = squid_curtime;
/*
- * NOTE, don't call ipcacheRelease here becuase we might be here due
+ * NOTE, don't call ipcacheRelease here because we might be here due
* to a thread started from a callback.
*/
}
+/// \ingroup IPCacheAPI
void
ipcacheInvalidateNegative(const char *name)
{
i->expires = squid_curtime;
/*
- * NOTE, don't call ipcacheRelease here becuase we might be here due
+ * NOTE, don't call ipcacheRelease here because we might be here due
* to a thread started from a callback.
*/
}
+/// \ingroup IPCacheAPI
ipcache_addrs *
ipcacheCheckNumeric(const char *name)
{
return &static_addrs;
}
+/// \ingroup IPCacheInternal
static void
ipcacheLockEntry(ipcache_entry * i)
{
}
}
+/// \ingroup IPCacheInternal
static void
ipcacheUnlockEntry(ipcache_entry * i)
{
ipcacheRelease(i);
}
+/// \ingroup IPCacheAPI
void
ipcacheCycleAddr(const char *name, ipcache_addrs * ia)
{
debugs(14, 3, "ipcacheCycleAddr: " << name << " now at " << ia->in_addrs[ia->cur] << " (" << ia->cur << " of " << ia->count << ")");
}
-/*
- * Marks the given address as BAD and calls ipcacheCycleAddr to
- * advance the current pointer to the next OK address.
+/**
+ \ingroup IPCacheAPI
+ *
+ \param name domain name to have an IP marked bad
+ \param addr specific addres to be marked bad
*/
void
ipcacheMarkBadAddr(const char *name, IPAddress &addr)
ipcache_addrs *ia;
int k;
+ /** Does nothing if the domain name does not exist. */
if ((i = ipcache_get(name)) == NULL)
return;
break;
}
- if (k == (int) ia->count) /* not found */
+ /** Does nothing if the IP does not exist for the doamin. */
+ if (k == (int) ia->count)
return;
+ /** Marks the given address as BAD */
if (!ia->bad_mask[k])
{
ia->bad_mask[k] = TRUE;
debugs(14, 2, "ipcacheMarkBadAddr: " << name << " " << addr );
}
+ /** then calls ipcacheCycleAddr() to advance the current pointer to the next OK address. */
ipcacheCycleAddr(name, ia);
}
+/// \ingroup IPCacheAPI
void
-
ipcacheMarkGoodAddr(const char *name, IPAddress &addr)
{
ipcache_entry *i;
debugs(14, 2, "ipcacheMarkGoodAddr: " << name << " " << addr );
}
+/// \ingroup IPCacheInternal
static void
ipcacheFreeEntry(void *data)
{
memFree(i, MEM_IPCACHE_ENTRY);
}
+/// \ingroup IPCacheAPI
void
ipcacheFreeMemory(void)
{
ip_table = NULL;
}
-/* Recalculate IP cache size upon reconfigure */
+/**
+ \ingroup IPCacheAPI
+ *
+ * Recalculate IP cache size upon reconfigure.
+ * Is called to clear the IPCache's data structures,
+ * cancel all pending requests.
+ */
void
ipcache_restart(void)
{
purge_entries_fromhosts();
}
-/*
- * adds a "static" entry from /etc/hosts.
- * returns 0 upon success, 1 if the ip address is invalid
+/**
+ \ingroup IPCacheAPI
+ *
+ * Adds a "static" entry from /etc/hosts
+ *
+ \param name Hostname to be linked with IP
+ \param ipaddr IP Address to be cached.
+ *
+ \retval 0 Success.
+ \retval 1 IP address is invalid or other error.
*/
int
ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
}
#ifdef SQUID_SNMP
-/*
+/**
+ \ingroup IPCacheAPI
+ *
* The function to return the ip cache statistics to via SNMP
*/
-
variable_list *
snmp_netIpFn(variable_list * Var, snint * ErrP)
{
-
/*
- * $Id: main.cc,v 1.458 2008/02/17 19:42:02 serassio Exp $
+ * $Id: main.cc,v 1.459 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
#endif
-/* for error reporting from xmalloc and friends */
+/** for error reporting from xmalloc and friends */
SQUIDCEXTERN void (*failure_notify) (const char *);
static int opt_parse_cfg_only = 0;
static void mainReconfigure(void);
static void mainInitialize(void);
static void usage(void);
-static void mainParseOptions(int, char **);
+static void mainParseOptions(int argc, char *argv[]);
static void sendSignal(void);
static void serverConnectionsOpen(void);
static void watch_child(char **);
#include "test_access.c"
#endif
-/* temporary thunk across to the unrefactored store interface */
+/** temporary thunk across to the unrefactored store interface */
class StoreRootEngine : public AsyncEngine
{
exit(1);
}
+/**
+ * Parse the parameters received via command line interface.
+ *
+ \param argc[in] Number of options received on command line
+ \param argv[in] List of parameters received on command line
+ */
static void
mainParseOptions(int argc, char *argv[])
{
int c;
#if USE_WIN32_SERVICE
-
while ((c = getopt(argc, argv, "CDFNO:RSVYXa:d:f:hik:m::n:rsl:u:vz?")) != -1)
#else
-
while ((c = getopt(argc, argv, "CDFNRSYXa:d:f:hk:m::sl:u:vz?")) != -1)
#endif
-
{
switch (c)
{
case 'C':
+ /** \par C
+ * Unset/disabel global option for catchign signals. opt_catch_signals */
opt_catch_signals = 0;
break;
case 'D':
+ /** \par D
+ * Unset/disable global option for optional DNS tests. opt_dns_tests */
opt_dns_tests = 0;
break;
case 'F':
+ /** \par F
+ * Set global option for foreground rebuild. opt_foreground_rebuild */
opt_foreground_rebuild = 1;
break;
case 'N':
+ /** \par N
+ * Set global option for 'no_daemon' mode. opt_no_daemon */
opt_no_daemon = 1;
break;
+
#if USE_WIN32_SERVICE
case 'O':
+ /** \par O
+ * Set global option. opt_command_lin and WIN32_Command_Line */
opt_command_line = 1;
WIN32_Command_Line = xstrdup(optarg);
break;
#endif
case 'R':
+ /** \par R
+ * Unset/disable global option opt_reuseaddr */
opt_reuseaddr = 0;
break;
case 'S':
+ /** \par S
+ * Set global option opt_store_doublecheck */
opt_store_doublecheck = 1;
break;
case 'X':
- /* force full debugging */
+ /** \par X
+ * Force full debugging */
Debug::parseOptions("debug_options ALL,9");
Config.onoff.debug_override_X = 1;
sigusr2_handle(SIGUSR2);
break;
case 'Y':
+ /** \par Y
+ * Set global option opt_reload_hit_only */
opt_reload_hit_only = 1;
-
break;
#if USE_WIN32_SERVICE
case 'i':
+ /** \par i
+ * Set global option opt_install_service (to TRUE) */
opt_install_service = TRUE;
-
break;
-
#endif
case 'a':
+ /** \par a
+ * Add optional HTTP port as given following the option */
add_http_port(optarg);
-
break;
case 'd':
+ /** \par d
+ * Set global option opt_debug_stderr to the number given follwoign the option */
opt_debug_stderr = atoi(optarg);
-
break;
case 'f':
+ /** \par f
+ * Load the file given instead of the default squid.conf. */
xfree(ConfigFile);
-
ConfigFile = xstrdup(optarg);
-
- break;
-
- case 'h':
- usage();
-
break;
case 'k':
+ /** \par k
+ * Run the administrative action given following the option */
+ /** \li When its an unknown option display the usage help. */
if ((int) strlen(optarg) < 1)
usage();
if (!strncmp(optarg, "reconfigure", strlen(optarg)))
+ /** \li On reconfigure send SIGHUP. */
opt_send_signal = SIGHUP;
else if (!strncmp(optarg, "rotate", strlen(optarg)))
+ /** \li On rotate send SIGQUIT or SIGUSR1. */
#ifdef _SQUID_LINUX_THREADS_
opt_send_signal = SIGQUIT;
#endif
else if (!strncmp(optarg, "debug", strlen(optarg)))
+ /** \li On debug send SIGTRAP or SIGUSR2. */
#ifdef _SQUID_LINUX_THREADS_
opt_send_signal = SIGTRAP;
#endif
else if (!strncmp(optarg, "shutdown", strlen(optarg)))
+ /** \li On shutdown send SIGTERM. */
opt_send_signal = SIGTERM;
else if (!strncmp(optarg, "interrupt", strlen(optarg)))
+ /** \li On interrupt send SIGINT. */
opt_send_signal = SIGINT;
else if (!strncmp(optarg, "kill", strlen(optarg)))
+ /** \li On kill send SIGKILL. */
opt_send_signal = SIGKILL;
#ifdef SIGTTIN
else if (!strncmp(optarg, "restart", strlen(optarg)))
- opt_send_signal = SIGTTIN; /* exit and restart by parent */
+ /** \li On restart send SIGTTIN. (exit and restart by parent) */
+ opt_send_signal = SIGTTIN;
#endif
else if (!strncmp(optarg, "check", strlen(optarg)))
+ /** \li On check send 0 / SIGNULL. */
opt_send_signal = 0; /* SIGNULL */
else if (!strncmp(optarg, "parse", strlen(optarg)))
- opt_parse_cfg_only = 1; /* parse cfg file only */
+ /** \li On parse set global flag to re-parse the config file only. */
+ opt_parse_cfg_only = 1;
else
usage();
break;
case 'm':
+ /** \par m
+ * Set global malloc_debug_level to the value given following the option.
+ * if none is given it toggles the xmalloc_trace option on/off */
if (optarg) {
#if MALLOC_DBG
malloc_debug_level = atoi(optarg);
#else
-
fatal("Need to add -DMALLOC_DBG when compiling to use -mX option");
#endif
#if XMALLOC_TRACE
xmalloc_trace = !xmalloc_trace;
#else
-
fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
#endif
-
}
-
break;
- /* NOTREACHED */
#if USE_WIN32_SERVICE
case 'n':
+ /** \par n
+ * Set global option opt_signal_service (to TRUE).
+ * Stores the additional parameter given in global WIN32_Service_name */
xfree(WIN32_Service_name);
WIN32_Service_name = xstrdup(optarg);
break;
case 'r':
+ /** \par r
+ * Set global option opt_remove_service (to TRUE) */
opt_remove_service = TRUE;
break;
#endif
case 'l':
+ /** \par l
+ * Stores the syslog facility name in global opt_syslog_facility
+ * then performs actions for -s option. */
opt_syslog_facility = xstrdup(optarg);
case 's':
+ /** \par s
+ * Initialize the syslog for output */
#if HAVE_SYSLOG
_db_set_syslog(opt_syslog_facility);
#endif
case 'u':
+ /** \par u
+ * Store the ICP port number given in global option icpPortNumOverride
+ * ensuring its a positive number. */
icpPortNumOverride = atoi(optarg);
if (icpPortNumOverride < 0)
break;
case 'v':
+ /** \par v
+ * Display squid version and build information. Then exit. */
printf("Squid Cache: Version %s\nconfigure options: %s\n", version_string, SQUID_CONFIGURE_OPTIONS);
#if USE_WIN32_SERVICE
/* NOTREACHED */
case 'z':
+ /** \par z
+ * Set global option opt_debug_stderr and opt_create_swap_dirs */
opt_debug_stderr = 1;
opt_create_swap_dirs = 1;
break;
+ case 'h':
+
case '?':
default:
+ /** \par h,?, or unknown
+ * \copydoc usage() */
usage();
break;
/*
- * $Id: mem_node.h,v 1.11 2007/12/27 01:58:19 hno Exp $
+ * $Id: mem_node.h,v 1.12 2008/02/26 21:49:35 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
1;
};
-MEMPROXY_CLASS_INLINE(mem_node)
+MEMPROXY_CLASS_INLINE(mem_node) /**DOCS_NOSEMI*/
inline std::ostream &
operator << (std::ostream &os, mem_node &aNode)
/*
- * $Id: pinger.cc,v 1.61 2008/01/08 11:10:48 amosjeffries Exp $
+ * $Id: pinger.cc,v 1.62 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: section 42 ICMP Pinger program
* AUTHOR: Duane Wessels
#define SQUID_HELPER 1
+/**
+ \defgroup pinger pinger
+ \ingroup ExternalPrograms
+ \par
+ * Although it would be possible for Squid to send and receive
+ * ICMP messages directly, we use an external process for
+ * two important reasons:
+ *
+ \li Because squid handles many filedescriptors simultaneously,
+ * we get much more accurate RTT measurements when ICMP is
+ * handled by a separate process.
+ *
+ \li Superuser privileges are required to send and receive ICMP.
+ * Rather than require Squid to be started as root, we prefer
+ * to have the smaller and simpler pinger program installed
+ * with setuid permissions.
+ *
+ \par
+ * If you want to use Squid's ICMP features (highly recommended!)
+ * When USE_ICMP is defined, Squid will send ICMP pings
+ * to origin server sites.
+ * This information is used in numerous ways:
+ \li - Sent in ICP replies so neighbor caches know how close
+ * you are to the source.
+ \li - For finding the closest instance of a URN.
+ \li - With the 'test_reachability' option. Squid will return
+ * ICP_OP_MISS_NOFETCH for sites which it cannot ping.
+ */
+
#include "squid.h"
#include "SquidTime.h"
int icmp_pkts_sent = 0;
+/**
+ \ingroup pinger
+ \par This is the pinger external process.
+ *
+ \param argc Ignored.
+ \param argv Ignored.
+ */
int
main(int argc, char *argv[])
{
#endif
int squid_link = -1;
- /* start by initializing the pinger debug cache.log-pinger */
+ /** start by initializing the pinger debug cache.log-pinger. */
if ((t = getenv("SQUID_DEBUG")))
debug_args = xstrdup(t);
max_fd = max(max_fd, icmp6_worker);
#endif
- // abort if neither worker could open a socket.
+ /** abort if neither worker could open a socket. */
if(icmp4_worker == -1) {
#if USE_IPV6
if(icmp6_worker == -1)
-
/*
- * $Id: protos.h,v 1.556 2008/02/26 00:15:48 rousskov Exp $
+ * $Id: protos.h,v 1.557 2008/02/26 21:49:35 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
SQUIDCEXTERN void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames);
class FwdState;
+
+/**
+ \defgroup ServerProtocolFTPAPI Server-Side FTP API
+ \ingroup ServerProtocol
+ */
+
+/// \ingroup ServerProtocolFTPAPI
SQUIDCEXTERN void ftpStart(FwdState *);
+
+/// \ingroup ServerProtocolFTPAPI
SQUIDCEXTERN const char *ftpUrlWith2f(HttpRequest *);
+
+/**
+ \defgroup ServerProtocolGopherAPI Server-Side Gopher API
+ \ingroup ServerProtocol
+ */
+
+/// \ingroup ServerProtocolGopherAPI
SQUIDCEXTERN void gopherStart(FwdState *);
+
+/// \ingroup ServerProtocolGopherAPI
SQUIDCEXTERN int gopherCachable(const HttpRequest *);
+/**
+ \defgroup ServerProtocolWhoisAPI Server-Side WHOIS API
+ \ingroup ServerProtocol
+ */
+
+/// \ingroup ServerProtocolWhoisAPI
SQUIDCEXTERN void whoisStart(FwdState *);
+
/* http.c */
SQUIDCEXTERN int httpCachable(const HttpRequestMethod&);
SQUIDCEXTERN void httpStart(FwdState *);
/*
- * $Id: squid.h,v 1.271 2008/01/22 15:34:28 hno Exp $
+ * $Id: squid.h,v 1.272 2008/02/26 21:49:35 amosjeffries Exp $
*
* AUTHOR: Duane Wessels
*
#include "config.h"
#ifdef _SQUID_MSWIN_
+/** \cond AUTODOCS-IGNORE */
using namespace Squid;
+/** \endcond */
#endif
#include "assert.h"
/*
- * $Id: ssl_support.cc,v 1.37 2008/02/11 22:41:52 rousskov Exp $
+ * $Id: ssl_support.cc,v 1.38 2008/02/26 21:49:35 amosjeffries Exp $
*
* AUTHOR: Benno Rice
* DEBUG: section 83 SSL accelerator support
#include "fde.h"
#include "ACLChecklist.h"
+/**
+ \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
+ \ingroup ServerProtocolSSLAPI
+ */
+
+/// \ingroup ServerProtocolSSLInternal
static int
ssl_ask_password_cb(char *buf, int size, int rwflag, void *userdata)
{
return len;
}
+/// \ingroup ServerProtocolSSLInternal
static void
ssl_ask_password(SSL_CTX * context, const char * prompt)
{
}
}
+/// \ingroup ServerProtocolSSLInternal
static RSA *
ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
{
return rsa;
}
+/// \ingroup ServerProtocolSSLInternal
static int
ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
{
return ok;
}
+/// \ingroup ServerProtocolSSLInternal
static struct ssl_option
{
const char *name;
}
};
+/// \ingroup ServerProtocolSSLInternal
static long
ssl_parse_options(const char *options)
{
return op;
}
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_DELAYED_AUTH (1<<1)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_NO_SESSION_REUSE (1<<4)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_VERIFY_CRL (1<<5)
+/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
+/// \ingroup ServerProtocolSSLInternal
static long
ssl_parse_flags(const char *flags)
{
delete static_cast<ACLChecklist *>(ptr); // may be NULL
}
+/// \ingroup ServerProtocolSSLInternal
static void
ssl_initialize(void)
{
ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
}
+/// \ingroup ServerProtocolSSLInternal
static int
ssl_load_crl(SSL_CTX *sslContext, const char *CRLfile)
{
return sslContext;
}
+/// \ingroup ServerProtocolSSLInternal
int
ssl_read_method(int fd, char *buf, int len)
{
return i;
}
+/// \ingroup ServerProtocolSSLInternal
int
ssl_write_method(int fd, const char *buf, int len)
{
SSL_shutdown(ssl);
}
+/// \ingroup ServerProtocolSSLInternal
static const char *
ssl_get_attribute(X509_NAME * name, const char *attribute_name)
{
return *buffer ? buffer : NULL;
}
+/// \ingroup ServerProtocolSSLInternal
const char *
sslGetUserAttribute(SSL * ssl, const char *attribute_name)
{
return ret;
}
+/// \ingroup ServerProtocolSSLInternal
const char *
sslGetCAAttribute(SSL * ssl, const char *attribute_name)
{
/*
- * $Id: ssl_support.h,v 1.14 2008/02/11 22:41:52 rousskov Exp $
+ * $Id: ssl_support.h,v 1.15 2008/02/26 21:49:35 amosjeffries Exp $
*
* AUTHOR: Benno Rice
*
#include <openssl/engine.h>
#endif
+/**
+ \defgroup ServerProtocolSSLAPI Server-Side SSL API
+ \ingroup ServerProtocol
+ */
+
+/// \ingroup ServerProtocolSSLAPI
SSL_CTX *sslCreateServerContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *clientCA, const char *CAfile, const char *CApath, const char *CRLfile, const char *dhpath, const char *context);
+
+/// \ingroup ServerProtocolSSLAPI
SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
+
+/// \ingroup ServerProtocolSSLAPI
int ssl_read_method(int, char *, int);
+
+/// \ingroup ServerProtocolSSLAPI
int ssl_write_method(int, const char *, int);
+
+/// \ingroup ServerProtocolSSLAPI
void ssl_shutdown_method(int);
+
+/// \ingroup ServerProtocolSSLAPI
const char *sslGetUserEmail(SSL *ssl);
+
+/// \ingroup ServerProtocolSSLAPI
typedef char const *SSLGETATTRIBUTE(SSL *, const char *);
+
+/// \ingroup ServerProtocolSSLAPI
SSLGETATTRIBUTE sslGetUserAttribute;
+
+/// \ingroup ServerProtocolSSLAPI
SSLGETATTRIBUTE sslGetCAAttribute;
+
+/// \ingroup ServerProtocolSSLAPI
const char *sslGetUserCertificatePEM(SSL *ssl);
+
+/// \ingroup ServerProtocolSSLAPI
const char *sslGetUserCertificateChainPEM(SSL *ssl);
typedef int ssl_error_t;
#ifdef __cplusplus
+/** \cond AUTODOCS-IGNORE */
namespace Squid {
+/** \endcond */
+/// \ingroup ServerProtocolSSLAPI
inline
int SSL_set_fd(SSL *ssl, int fd)
{
return ::SSL_set_fd(ssl, _get_osfhandle(fd));
}
+/// \ingroup ServerProtocolSSLAPI
#define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
} /* namespace Squid */
#else
+/// \ingroup ServerProtocolSSLAPI
#define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
#endif /* __cplusplus */
/*
- * $Id: stub_mem_node.cc,v 1.1 2005/01/03 16:08:27 robertc Exp $
+ * $Id: stub_mem_node.cc,v 1.2 2008/02/26 21:49:45 amosjeffries Exp $
*
* DEBUG: section 84 Helper process maintenance
* AUTHOR: Robert Collins
#include "squid.h"
#include "mem_node.h"
-mem_node::mem_node(off_t offset):nodeBuffer(0,offset,data)
+mem_node::mem_node(int64_t offset):nodeBuffer(0,offset,data)
{
fatal ("Not implemented");
}
/*
- * $Id: typedefs.h,v 1.193 2008/02/11 22:28:47 rousskov Exp $
+ * $Id: typedefs.h,v 1.194 2008/02/26 21:49:35 amosjeffries Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
typedef struct _acl_deny_info_list acl_deny_info_list;
+/// \ingroup AuthAPI
+/// \deprecated Use AuthUser instead.
typedef class AuthUser auth_user_t;
+/// \ingroup AuthAPI
+/// \deprecated Use AuthUserHashPointer instead.
typedef struct AuthUserHashPointer auth_user_hash_pointer;
+/// \ingroup AuthAPI
+/// \deprecated Use AuthUserIP instead.
typedef struct AuthUserIP auth_user_ip_t;
/* temporary: once Config is fully hidden, this shouldn't be needed */
typedef struct _StatCounters StatCounters;
+/// \todo DROP: deprecated and no longer used.
typedef struct _storeSwapLogData storeSwapLogData;
typedef struct _StatHist StatHist;
/*
- * $Id: unlinkd_daemon.cc,v 1.1 2007/04/24 15:04:22 hno Exp $
+ * $Id: unlinkd_daemon.cc,v 1.2 2008/02/26 21:49:35 amosjeffries Exp $
*
* DEBUG: - Unlink Daemon
* AUTHOR: Duane Wessels
#include "squid.h"
-/* This is the external unlinkd process */
+/**
+ \defgroup unlinkd unlinkd
+ \ingroup ExternalPrograms
+ \par
+ The unlink(2) system call can cause a process to block
+ for a significant amount of time. Therefore we do not want
+ to make unlink() calls from Squid. Instead we pass them
+ to this external process.
+ */
+/// \ingroup unlinkd
#define UNLINK_BUF_LEN 1024
+/**
+ \ingroup unlinkd
+ \par This is the unlinkd external process.
+ *
+ \par
+ * unlinkd receives the full path of any files to be removed
+ * from stdin, each on its own line.
+ *
+ \par
+ * The results for each file are printed to stdout in the order
+ * they were received
+ *
+ \param argc Ignored.
+ \param argv Ignored.
+ \retval ERR An error occured removing the file.
+ \retval OK The file has been removed.
+ */
int
main(int argc, char *argv[])
{
exit(0);
}
-
/*
- * $Id: squidclient.cc,v 1.10 2007/12/14 23:11:53 amosjeffries Exp $
+ * $Id: squidclient.cc,v 1.11 2008/02/26 21:49:46 amosjeffries Exp $
*
* DEBUG: section 0 WWW Client
* AUTHOR: Harvest Derived
#include "config.h"
#ifdef _SQUID_MSWIN_
+/** \cond AUTODOCS-IGNORE */
using namespace Squid;
+/** \endcond */
#endif
#ifdef _SQUID_WIN32_