You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2015/11/03 07:09:55 UTC

[19/51] trafficserver git commit: Documentation reorganization

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/host-resolution-proposal.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/host-resolution-proposal.en.rst b/doc/developer-guide/host-resolution-proposal.en.rst
new file mode 100644
index 0000000..af34e6f
--- /dev/null
+++ b/doc/developer-guide/host-resolution-proposal.en.rst
@@ -0,0 +1,170 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../common.defs
+
+Host Resolution Proposal
+************************
+
+Introduction
+------------
+
+The current mechanism for resolving host names to IP addresses for Traffic Server is contained the HostDB and DNS
+libraries. These take hostnames and provide IP addresses for them.
+
+The current implementation is generally considered inadequate, both from a functionality point of view and difficulty in
+working with it in other parts of Traffic Server. As Traffic Server is used in more complex situtations this inadequacy
+presents increasing problems.
+
+Goals
+-----
+
+Updating the host name resolution (currently referred to as "HostDB") has several functions goals
+
+*  Enable additional processing layers to be easily added.
+*  Enable plugins to directly access the name resolution logic
+*  Enable plugins to provide name resolution
+*  Asynchronous (immediate resolve or callback on block)
+*  Minimize allocations -- in particular no allocations for cached resolutions
+*  Simplify interactions with the resolution, particularly with regard to nameservers, origin server failover, and
+   address family handling.
+
+It is also necessary to support a number of specific features that are either currently available or strongly desired.
+
+*  SplitDNS or its equivalent
+*  Use of a hosts file (e.g. ``/etc/hosts``)
+*  Simultaneous IPv4 and IPv6 queries
+*  IP family control
+*  Negative caching
+   *  Server connection failures
+   *  Query failures
+   *  Nameserver failures.
+*  Address validity time out control
+*  Address round robin support
+*  SRV record support (weighted records)
+*  Nameserver round robin
+*  Plugin access to nameserver data (add, remove, enumerate)
+*  Plugin provision of resolvers.
+*  Hooks for plugin detection / recovery from resolution events.
+
+One issue is persistence of the cached resolutions. This creates problems for the current implementation (because of
+size limits it imposes on the cached data) but also allows for quicker restarts in a busy environment.
+
+Basics
+------
+
+The basic design is to separate the functionality into chainable layers so that a resolver with the desired attributes
+can be assembled from those layers. The core interface is that of a lazy iterator. This object returns one of four
+results when asked for an address
+
+* An IP address
+* Done(no more addresses are available)
+* Wait(an address may be available in the future)
+* Fail (no address is available and none will be so in the future)
+
+Each layer (except the bottom) uses this API and also provides it. This enables higher level logic such as the state
+machine to simply use the resolver as a list without having to backtrack states in the case of failures, or have special
+cases for different resolution sources.
+
+To perform a resolution, a client creates a query object (potentially on the stack), initializes it with the required
+data (at least the hostname) and then starts the resolution. Methods on the query object allow its state and IP address
+data to be accessed.
+
+Required Resolvers
+------------------
+
+Nameserver
+   A bottom level resolver that directly queries a nameserver for DNS data. This contains much of the functionality
+   currently in the ``iocore/dns`` directory.
+
+SplitDNS
+   A resolver that directs requests to one of several resolvers. To emulate current behavior these would be Nameserver
+   instances.
+
+NameserverGroup
+   A grouping mechanism for Nameserver instances that provides failover, round robin, and ordering capabilities. It may be
+   reasonable to merge this with the SplitDNS resolver.
+
+HostFile
+   A resolver that uses a local file to resolve names.
+
+AddressCache
+   A resolver that also has a cache for resolution results. It requires another resolver instance to perform the actual
+   resolution.
+
+Preloaded
+   A resolver that can contain one or more explicitly set IP addresses which are returned. When those are exhausted it
+   falls back to another resolver.
+
+Configuration
+-------------
+
+To configuration the resolution, each resolver would be assigned a tag. It is not, however, sufficient to simply provide
+the list of resolver tags because some resolvers require additional configuration. Unfortunately this will likely
+require a separate configuration file outside of :file:`records.config`, although we would be able to remove
+:file:`splitdns.config`. In this case we would need chain start / end markers around a list of resolver tags. Each tag
+would the be able to take additional resolver configuration data. For instance, for a SplitDNS resolver the nameservers.
+
+Examples
+--------
+
+Transparent operations would benefit from the *Preloaded* resolver. This would be loaded with the origin host address
+provided by the client connection. This could be done early in processing and then no more logic would be required to
+skip DNS processing as it would happen without additional action by the state machine. It would handle the problem of de
+facto denial of service if an origin server becomes unavailable in that configuration, as *Preloaded* would switch to
+alternate addresses automatically.
+
+Adding host file access would be easier as well, as it could be done in a much more modular fashion and then added to
+the stack at configuration time. Whether such addresses were cached would be controlled by chain arrangement rather yet
+more configuration knobs.
+
+The default configuration would be *Preloaded* : *AddressCache* : *Nameserver*.
+
+In all cases the state machine makes requests against the request object to get IP addresses as needed.
+
+Issues
+------
+
+Request object allocation
+=========================
+
+The biggest hurdle is being able to unwind a resolver chain when a block is encountered. There are some ways to deal with this.
+
+1) Set a maximum resolver chain length and declare the request instance so that there is storage for state for that many
+resolvers. If needed and additional value of maximum storage per chain could be set as well. The expected number of
+elements in a chain is expected to be limited, 10 would likely be a reaosnable limit. If settable at source
+configuration time this should be sufficient.
+
+2) Embed class allocators in resolver chains and mark the top / outermost / first resolver. The maximum state size for a
+resolution can be calculated when the chain is created and then the top level resolver can use an allocation pool to
+efficiently allocate request objects. This has an advantage that with a wrapper class the request object can be passed
+along cheaply. Whether that's an advantage in practice is unclear.
+
+Plugin resolvers
+================
+
+If plugins can provide resolvers, how can these can integrated in to existing resolver chains for use by the HTTP SM for
+instance?
+
+Feedback
+========
+
+It should be possible for a client to provide feedback about addresses (e.g., the origin server at this address is not
+available). Not all resolvers will handle feedback but some will and that must be possible.
+
+Related to this is that caching resolvers (such as *AddressCache*) must be able to iterator over all resolved addresses
+even if their client does not ask for them. In effect they must background fill the address data.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/index.en.rst b/doc/developer-guide/index.en.rst
new file mode 100644
index 0000000..5abe670
--- /dev/null
+++ b/doc/developer-guide/index.en.rst
@@ -0,0 +1,53 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../common.defs
+
+.. _developer-guide:
+
+Developer's Guide
+*****************
+
+This documentation is a work in progress. It was originally written for
+a previous, commercially-available version of Traffic Server that
+supported different operating systems and more functions than the
+current version. As a result, some of the sections may refer to
+functionality that no longer exists.
+
+If you find any such issues, you may want to submit a `bug or a
+patch <https://issues.apache.org/jira/secure/CreateIssue!default.jspa?pid=12310963>`__.
+We also have a Wiki page explaining how to `create useful bug reports
+<https://cwiki.apache.org/confluence/display/TS/Filing+useful+bug+reports>`__.
+We encourage everyone to file tickets, early and often. Looking for existing,
+duplicate bugs is encouraged, but not required.
+
+.. toctree::
+   :maxdepth: 2
+
+   introduction/index.en
+   release-process/index.en
+   contributing/index.en
+   testing-with-vagrant/index.en
+   debugging/index.en
+   architecture/index.en
+   plugins/index.en
+   config-vars.en
+   api/index.en
+   continuous-integration/index.en
+   documentation/index.en
+   host-resolution-proposal.en
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/introduction/audience.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/introduction/audience.en.rst b/doc/developer-guide/introduction/audience.en.rst
new file mode 100644
index 0000000..540d08e
--- /dev/null
+++ b/doc/developer-guide/introduction/audience.en.rst
@@ -0,0 +1,53 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-preface:
+
+Preface
+********
+
+.. toctree::
+   :maxdepth: 2
+
+   preface/how-to-use-this-book.en
+   preface/typographical-conventions.en
+
+The |TS| Software Developer's Kit is a reference for creating plugins.
+*Plugins* are programs that add services (such as filtering or content
+transformation) or entire features (such as new protocol support) to |TS|. If
+you are new to writing |TS| plugins, then read the first two chapters,
+:ref:`developer-plugins-getting-started` and
+:ref:`developer-plugins-introduction`, and use the remaining chapters as
+needed. :ref:`developer-plugins-header-based-examples` provides details about
+plugins that work on HTTP headers, while
+:ref:`developer-plugins-http-transformations` explains how to write a plugin
+that transforms or scans the body of an HTTP response. If you want to support
+your own protocol on Traffic Server, then reference
+:ref:`developer-plugins-new-protocol-plugins`.
+
+.. _developer-audience:
+
+Audience
+--------
+
+This manual is intended for programmers who want to write plugin
+programs that add services or features to Traffic Server. It assumes a
+cursory knowledge of the C programming language, Hyper-Text Transfer
+Protocol (HTTP), and Multipurpose Internet Mail Extensions (MIME).
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/introduction/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/introduction/index.en.rst b/doc/developer-guide/introduction/index.en.rst
new file mode 100644
index 0000000..d5f2415
--- /dev/null
+++ b/doc/developer-guide/introduction/index.en.rst
@@ -0,0 +1,117 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-introduction:
+
+Introduction
+************
+
+This book has the following basic components:
+
+-  Introduction and overview
+
+-  Tutorials about writing specific kinds of plugins: HTTP header-based
+   plugins, content transformation plugins, and protocol plugins
+
+-  Guides about specific interfaces
+
+-  Reference material
+
+If you're new to writing |TS| plugins, :ref:`developer-plugins-getting-started`
+should be your starting point. :ref:`developer-plugins-header-based-examples`
+provides details about plugins that work on HTTP headers, while
+:ref:`developer-plugins-http-transformations` explains how to write a plugin
+that transforms or scans the body of an HTTP response.
+:ref:`developer-plugins-new-protocol-plugins` provides essential information if
+you want to support your own protocol on |TS|.
+
+For a reference to the C API functions and types that your plugin will use,
+refer to the :ref:`developer-api-reference`.
+
+Below is a section-by-section breakdown of this guide:
+
+:ref:`developer-plugins-getting-started`
+   How to compile and load plugins. Walks through a simple "hello world"
+   example; explains how to initialize and register plugins. Basic structures
+   that all plugins use: events, continuations, and how to hook on to |TS|
+   processes. Detailed explication of a sample blacklisting plugin.
+
+:ref:`developer-plugins-examples-query-remap`
+   This chapter demonstrates on a practical example how you can
+   exploit the Traffic Server remap API for your plugins.
+
+:ref:`developer-plugins-header-based-examples`
+   Detailed explanation about writing plugins that work on HTTP
+   headers; discusses sample blacklisting and basic authorization
+   plugins.
+
+:ref:`developer-plugins-http-transformations`
+   Detailed explanation of the null-transform example; also discusses
+   ``VConnections``, ``VIOs``, and IO buffers.
+
+:ref:`developer-plugins-new-protocol-plugins`
+   Detailed explanation of a sample protocol plugin that supports a
+   synthetic protocol. Discusses ``VConnections`` and mutexes, as well
+   as the new ``NetConnection``, DNS lookup, logging, and cache APIs.
+
+The remaining sections comprise the API function reference and are organized by
+function type:
+
+:ref:`developer-plugins-interfaces`
+   Details error-writing and tracing functions, thread functions, and |TS| API
+   versions of the ``malloc`` and ``fopen`` families. The |TS| API versions
+   overcome various C library limitations.
+
+:ref:`developer-plugins-hooks-and-transactions`
+   Functions in this chapter hook your plugin to Traffic Server HTTP processes.
+
+:ref:`developer-plugins-http-headers`
+   Contains instructions for implementing performance enhancements for
+   all plugins that manipulate HTTP headers. These functions examine and
+   modify HTTP headers, MIME headers, URLs, and the marshal buffers that
+   contain header information. If you are working with headers, then be
+   sure to read this chapter.
+
+:ref:`developer-plugins-mutexes`
+
+:ref:`developer-plugins-continuations`
+   Continuations provide the basic callback mechanism and data
+   abstractions used in Traffic Server.
+
+:ref:`developer-plugins-configuration`
+
+:ref:`developer-plugins-actions`
+   Describes how to use ``TSActions`` and the ``TSDNSLookup`` API.
+
+:ref:`developer-plugins-io`
+   Describes how to use the Traffic Server IO interfaces:
+   ``TSVConnection``, ``TSVIO``, ``TSIOBuffer``, ``TSNetVConnection``,
+   the Cache API.
+
+:ref:`developer-plugins-management`
+   These functions enable you to set up a configuration interface for
+   plugins, access installed plugin files, and set up plugin licensing.
+
+:ref:`developer-plugins-add-statistics`
+   These functions add statistics to your plugin.
+
+:ref:`developer-api-ref-functions`
+   Traffic Server API Function Documentation.
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst b/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
new file mode 100644
index 0000000..5b2fe4e
--- /dev/null
+++ b/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
@@ -0,0 +1,32 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-actions-hosts-lookup:
+
+Hosts Lookup API
+****************
+
+The hosts lookup enables plugins to ask Traffic Server to do a host
+lookup of a host name, much like a DNS lookup.
+
+The hosts lookup functions are as follows:
+
+-  :c:func:`TSHostLookup`
+-  :c:func:`TSHostLookupResultAddrGet`
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/actions/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/actions/index.en.rst b/doc/developer-guide/plugins/actions/index.en.rst
new file mode 100644
index 0000000..12eeb24
--- /dev/null
+++ b/doc/developer-guide/plugins/actions/index.en.rst
@@ -0,0 +1,178 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-actions:
+
+Actions
+*******
+
+.. toctree::
+   :maxdepth: 2
+
+   hosts-lookup-api.en
+
+An **action** is a handle to an operation initiated by a plugin that has
+not yet completed. For example: when a plugin connects to a remote
+server, it uses the call ``TSNetConnect`` - which takes ``TSCont`` as an
+argument to call back when the connection is established.
+``TSNetConnect`` might not call the continuation back immediately and
+will return an ``TSAction`` structure that the caller can use to cancel
+the operation. Cancelling the operation does not necessarily mean that
+the operation will not occur; it simply means that the continuation
+passed into the operation will not be called back. In such an example,
+the connection might still occur if the action is cancelled; however,
+the continuation that initiated the connection would not be called back.
+
+In the preceding example, it is also possible that the connection will
+complete and call back the continuation before ``TSNetConnect`` returns.
+If that occurs, then ``TSNetConnect`` returns a special action that
+causes ``TSActionDone`` to return ``1``. This specifies that the
+operation has already completed, so it's pointless to try to cancel the
+operation. Also note that an action will never change from non-completed
+to completed. When the operation actually succeeds and the continuation
+is called back, the continuation must zero out its action pointer to
+indicate to itself that the operation succeeded.
+
+The asynchronous nature of all operations in Traffic Server necessitates
+actions. You should notice from the above discussion that once a call to
+a function like ``TSNetConnect`` is made by a continuation and that
+function returns a valid action (``TSActionDone`` returns ``0``), it is
+not safe for the continuation to do anything else except return from its
+handler function. It is not safe to modify or examine the continuation's
+data because the continuation may have already been destroyed.
+
+Below is an example of typical usage for an action:
+
+.. code-block:: c
+
+        #include <ts/ts.h>
+        static int
+        handler (TSCont contp, TSEvent event, void *edata)
+        {
+            if (event == TS_EVENT_IMMEDIATE) {
+                TSAction actionp = TSNetConnect (contp, 127.0.0.1, 9999);
+                if (!TSActionDone (actionp)) {
+                    TSContDataSet (contp, actionp);
+                } else {
+                    /* We've already been called back... */
+                    return 0;
+                }
+            } else if (event == TS_EVENT_NET_CONNECT) {
+                /* Net connection succeeded */
+                TSContDataSet (contp, NULL);
+                return 0;
+            } else if (event == TS_EVENT_NET_CONNECT_FAILED) {
+                /* Net connection failed */
+                TSContDataSet (contp, NULL);
+                return 0;
+            } 
+            return 0;
+        }
+
+        void
+        TSPluginInit (int argc, const char *argv[])
+        {
+            TSCont contp;
+
+            contp = TSContCreate (handler, TSMutexCreate ());
+
+            /* We don't want to call things out of TSPluginInit
+               directly since it's called before the rest of the
+               system is initialized. We'll simply schedule an event
+               on the continuation to occur as soon as the rest of
+               the system is started up. */
+            TSContSchedule (contp, 0);
+        }
+
+The example above shows a simple plugin that creates a continuation and
+then schedules it to be called immediately. When the plugin's handler
+function is called the first time, the event is ``TS_EVENT_IMMEDIATE``.
+The plugin then tries to open a net connection to port 9999 on
+``localhost`` (127.0.0.1). The IP description was left in cider notation
+to further clarify what is going on; also note that the above won't
+actually compile until the IP address is modified. The action returned
+from ``TSNetConnect`` is examined by the plugin. If the operation has
+not completed, then the plugin stores the action in its continuation.
+Otherwise, the plugin knows it has already been called back and there is
+no reason to store the action pointer.
+
+A final question might be, "why would a plugin want to cancel an
+action?" In the above example, a valid reason could be to place a limit
+on the length of time it takes to open a connection. The plugin could
+schedule itself to get called back in 30 seconds and then initiate the
+net connection. If the timeout expires first, then the plugin would
+cancel the action. The following sample code implements this:
+
+.. code-block:: c
+
+        #include <ts/ts.h>
+        static int
+        handler (TSCont contp, TSEvent event, void *edata)
+        {
+            switch (event) {
+                case (TS_EVENT_IMMEDIATE):
+                    TSContSchedule (contp, 30000);
+                    TSAction actionp = TSNetConnect(contp, 127.0.0.1, 9999);
+                    if (!TSActionDone (actionp)) {
+                        TSContDataSet (contp, actionp);
+                    } else {
+                        /* We've already been called back ... */
+                    }
+                    break;
+
+                case (TS_EVENT_TIMEOUT):
+                    TSAction actionp = TSContDataGet (contp);
+                    if (!TSActionDone(actionp)) {
+                        TSActionCancel (actionp);
+                    }
+                    break;
+
+                case (TS_EVENT_NET_CONNECT):
+                    /* Net connection succeeded */
+                    TSContDataSet (contp, NULL);
+                    break;
+
+                case (TS_EVENT_NET_CONNECT_FAILED):
+                    /* Net connection failed */
+                    TSContDataSet (contp, NULL);
+                    break;
+
+            } 
+            return 0;
+        }
+
+        void
+        TSPluginInit (int argc, const char *argv[])
+        {
+            TSCont contp;
+
+            contp = TSContCreate (handler, TSMutexCreate ());
+            /* We don't want to call things out of TSPluginInit
+               directly since it's called before the rest of the
+               system is initialized. We'll simply schedule an event
+               on the continuation to occur as soon as the rest of
+               the system is started up. */
+            TSContSchedule (contp, 0);
+        }
+
+The action functions are:
+
+-  :c:func:`TSActionCancel`
+-  :c:func:`TSActionDone`
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/adding-statistics.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/adding-statistics.en.rst b/doc/developer-guide/plugins/adding-statistics.en.rst
new file mode 100644
index 0000000..b0c5480
--- /dev/null
+++ b/doc/developer-guide/plugins/adding-statistics.en.rst
@@ -0,0 +1,190 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-add-statistics:
+
+Adding Statistics
+*****************
+
+This chapter describes how to add statistics to your plugins. Statistics
+can be coupled or uncoupled. *Coupled* statistics are quantities that
+are related and must therefore be updated together. The Traffic Server
+API statistics functions add your plugin's statistics to the Traffic
+Server statistics system. You can view your plugin statistics as you
+would any other Traffic Server statistic, using Traffic Line (Traffic
+Server's command line interface). This chapter contains the following
+topics:
+
+.. toctree::
+   :maxdepth: 2
+
+   adding-statistics/coupled-statistics.en
+   adding-statistics/viewing-statistics-using-traffic-line.en
+
+
+Uncoupled Statistics
+====================
+
+A statistic is an object of type ``TSStat``. The value of the statistic
+is of type ``TSStatType``. The possible ``TSStatTypes`` are:
+
+-  ``TSSTAT_TYPE_INT64``
+
+-  ``TSSTAT_TYPE_FLOAT``
+
+There is *no* ``TSSTAT_TYPE_INT32``.
+
+To add uncoupled statistics, follow the steps below:
+
+1. Declare your statistic as a global variable in your plugin. For
+   example:
+
+   .. code-block:: c
+
+      static TSStat my_statistic;
+
+2. In ``TSPluginInit``, create new statistics using ``TSStatCreate``.
+   When you create a new statistic, you need to give it an "external"
+   name that the Traffic Server command line interface (Traffic Line)
+   uses to access the statistic. For example:
+
+   .. code-block:: c
+
+      my_statistic = TSStatCreate ("my.statistic", TSSTAT_TYPE_INT64);
+
+3. Modify (increment, decrement, or other modification) your statistic
+   in plugin functions.
+
+Coupled Statistics
+==================
+
+Use coupled statistics for quantities that are related and therefore
+must be updated jointly.
+
+As a very simple example, suppose you have three statistics: ``sum``,
+``part_1``, and ``part_2``. They must always preserve the relationship
+that ``sum = part_1  + part_2``. If you update ``part_1`` without
+updating ``sum`` at the same time, then the equation becomes untrue.
+Therefore, the statistics are said to be *coupled*.
+
+The mechanism for updating coupled statistics jointly is to create local
+copies of global coupled statistics in the routines that modifiy them.
+When each local copy is updated appropriately, do a global update using
+``TSStatsCoupledUpdate``. To specify which statistics are related to one
+another, establish a coupled statistic category and make sure that each
+coupled statistic belongs to the appropriate category. When it is time
+to do the global update, specify the category to be updated.
+
+.. note::
+
+   The local statistic copy must have a duplicate set of statistics as that
+   of the master copy. Local statistics must also be added to the local
+   statistic category in the same order as their master copy counterparts
+   were originally added.
+
+Below are the steps you need to follow, along with a code example taken
+from the ``redirect-1.c`` sample plugin.
+
+To add coupled statistics
+-------------------------
+
+1. Declare the global category for your coupled statistics as a global
+   ``TSCoupledStat`` variable in your plugin.
+
+2. Declare your coupled statistics as global ``TSStat`` variables in
+   your plugin.
+
+3. In ``TSPluginInit``, create a new global coupled category using
+   ``TSStatCoupledGlobalCategoryCreate``.
+
+4. In ``TSPluginInit``, create new global coupled statistics using
+   ``TSStatCoupledGlobalAdd``. When you create a new statistic, you need
+   to give it an "external" name that the Traffic Server command line
+   interface (Traffic Line) uses to access the statistic.
+
+5. In any routine wherein you want to modify (increment, decrement, or
+   other modification) your coupled statistics, declare local copies of
+   the coupled category and coupled statistics.
+
+6. Create local copies using ``TSStatCoupledLocalCopyCreate`` and
+   ``TSStatCoupledLocalAdd``.
+
+7. Modify the local copies of your statistics. Then call
+   ``TSStatsCoupledUpdate`` to update the global copies jointly.
+
+8. When you are finished, you must destroy all of the local copies in
+   the category via ``TSStatCoupledLocalCopyDestroy``.
+
+Example Using the redirect-1.c Sample Plugin
+--------------------------------------------
+
+.. code-block:: c
+
+    static TSCoupledStat request_outcomes;
+
+    static TSStat requests_all;
+    static TSStat requests_redirects;
+    static TSStat requests_unchanged;
+
+    request_outcomes = TSStatCoupledGlobalCategoryCreate ("request_outcomes"); 
+
+    requests_all = TSStatCoupledGlobalAdd (request_outcomes, "requests.all", TSSTAT_TYPE_FLOAT);
+    requests_redirects = TSStatCoupledGlobalAdd (request_outcomes, "requests.redirects",
+        TSSTAT_TYPE_INT64);
+    requests_unchanged = TSStatCoupledGlobalAdd (request_outcomes, "requests.unchanged", 
+        TSSTAT_TYPE_INT64);
+
+    TSCoupledStat local_request_outcomes;
+    TSStat local_requests_all;
+    TSStat local_requests_redirects;
+    TSStat local_requests_unchanged;
+
+    local_request_outcomes = TSStatCoupledLocalCopyCreate("local_request_outcomes", 
+        request_outcomes); 
+    local_requests_all = TSStatCoupledLocalAdd(local_request_outcomes, "requests.all.local", 
+        TSSTAT_TYPE_FLOAT);
+    local_requests_redirects = TSStatCoupledLocalAdd(local_request_outcomes, 
+        "requests.redirects.local", TSSTAT_TYPE_INT64);
+    local_requests_unchanged = TSStatCoupledLocalAdd(local_request_outcomes, 
+        "requests.unchanged.local", TSSTAT_TYPE_INT64);
+
+    TSStatFloatAddTo( local_requests_all, 1.0 ) ; 
+    ...
+    TSStatIncrement (local_requests_unchanged); 
+    TSStatsCoupledUpdate(local_request_outcomes); 
+
+    TSStatCoupledLocalCopyDestroy(local_request_outcomes); 
+
+Viewing Statistics Using Traffic Line
+=====================================
+
+.. XXX: This documentation seems to be duplicated from the admin docs.
+
+To view statistics for your plugin, follow the steps below:
+
+1. Make sure you know the name of your statistic (i.e., the name used in
+   the ``TSStatCoupledGlobalAdd``, ``TSStatCreate``, or
+   ``TSStatCoupledGlobalCategoryCreate`` call).
+
+2. In your ``<Traffic Server>/bin`` directory, enter the following:
+
+   ::
+
+       ./traffic\_line -r the\_name
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/building-plugins.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/building-plugins.en.rst b/doc/developer-guide/plugins/building-plugins.en.rst
new file mode 100644
index 0000000..5494e40
--- /dev/null
+++ b/doc/developer-guide/plugins/building-plugins.en.rst
@@ -0,0 +1,24 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-building:
+
+Building Plugins
+****************
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/configuration.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/configuration.en.rst b/doc/developer-guide/plugins/configuration.en.rst
new file mode 100644
index 0000000..409df3e
--- /dev/null
+++ b/doc/developer-guide/plugins/configuration.en.rst
@@ -0,0 +1,105 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-configuration:
+
+Plugin Configuration
+********************
+
+The functions discussed in this section do not examine or modify |TS|
+configuration variables. To examine |TS| configuration and statistics
+variables, see :ref:`developer-plugins-management-settings-and-statistics`.
+
+The collection of ``TSConfig*`` functions are designed to provide a fast and
+efficient mechanism for accessing and changing global configuration information
+within a plugin. Such a mechanism is simple enough to provide in a
+single-threaded program, but the translation to a multi-threaded program such
+as |TS| is difficult. A common technique is to have a single mutex protect the
+global configuration information; however, the problem with this solution is
+that a single mutex becomes a performance bottleneck very quickly.
+
+These functions define an interface to storing and retrieving an opaque data
+pointer. Internally, |TS| maintains reference count information about the data
+pointer so that a call to :c:func:`TSConfigSet` will not disturb another thread
+using the current data pointer. The philosophy is that once a user has a hold
+of the configuration pointer, it is okay for it to be used even if the
+configuration changes. All that a user typically wants is a non-changing
+snapshot of the configuration. You should use :c:func:`TSConfigSet` for all
+global data updates.
+
+Here's how the interface works:
+
+.. code-block:: c
+
+    /* Assume that you have previously defined a plugin configuration
+     * data structure named ConfigData, along with its constructor
+     * plugin_config_allocator () and its destructor 
+     * plugin_config_destructor (ConfigData *data)
+     */
+    ConfigData *plugin_config;
+
+    /* You will need to assign plugin_config a unique identifier of type
+     * unsigned int. It is important to initialize this identifier to zero
+     * (see the documentation of the  function). 
+     */
+    static unsigned int   my_id = 0;
+
+    /* You will need an TSConfig pointer to access a snapshot of the 
+     * current plugin_config. 
+     */
+    TSConfig config_ptr;
+
+    /* Initialize plugin_config. */
+    plugin_config = plugin_config_allocator();
+
+    /* Assign plugin_config an identifier using TSConfigSet. */
+    my_id = TSConfigSet (my_id, plugin_config, plugin_config_destructor);
+
+    /* Get a snapshot of the current configuration using TSConfigGet. */
+    config_ptr = TSConfigGet (my_id);
+
+    /* With an TSConfig pointer to the current configuration, you can 
+     * retrieve the configuration's current data using TSConfigDataGet. 
+     */
+    plugin_config = (ConfigData*) TSConfigDataGet (config_ptr);
+
+    /* Do something with plugin_config here. */
+
+    /* When you are done with retrieving or modifying the plugin data, you
+     * release the pointers to the data with a call to TSConfigRelease.
+     */
+    TSConfigRelease (my_id, config_ptr);
+
+    /* Any time you want to modify plugin_config, you must repeat these
+     * steps, starting with 
+     * my_id = TSConfigSet (my_id,plugin_config, plugin_config_destructor);
+     * and continuing up to TSConfigRelease. 
+     */
+
+The configuration functions are:
+
+-  :c:func:`TSConfigDataGet`
+
+-  :c:func:`TSConfigGet`
+
+-  :c:func:`TSConfigRelease`
+
+-  :c:func:`TSConfigSet`
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/activating-continuations.en.rst b/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
new file mode 100644
index 0000000..6b4135f
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
@@ -0,0 +1,40 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-continuations-activate:
+
+Activating Continuations
+************************
+
+Continuations are activated when they receive an event or by
+``TSContSchedule`` (which schedules a continuation to receive an event).
+Continuations might receive an event because:
+
+-  Your plugin calls ``TSContCall``
+
+-  The Traffic Server HTTP state machine sends an event corresponding to
+   a particular HTTP hook
+
+-  A Traffic Server IO processor (such as a cache processor or net
+   processor) is letting a continuation know there is data (cache or
+   network) available to read or write. These callbacks are a result of
+   using functions such ``TSVConnRead``/``Write`` or
+   ``TSCacheRead``/``Write``
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/index.en.rst b/doc/developer-guide/plugins/continuations/index.en.rst
new file mode 100644
index 0000000..94bd132
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/index.en.rst
@@ -0,0 +1,135 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-continuations:
+
+Continuations
+*************
+
+.. toctree::
+   :maxdepth: 2
+
+   activating-continuations.en
+   writing-handler-functions.en
+
+The continuation interface is Traffic Server's basic callback mechanism.
+**Continuations** are instances of the opaque data type ``TSCont``. In
+its basic form, a continuation represents a handler function and a
+mutex.
+
+This chapter covers the following topics:
+
+-  `Mutexes and Data`_
+
+-  :ref:`developer-plugins-continuations-activate`
+
+-  :ref:`developer-plugins-continuations-handler-functions`
+
+Mutexes and Data
+================
+
+A continuation must be created with a mutex if your continuation does
+one of the following:
+
+-  is registered globally (``TSHttpHookAdd`` or ``TSHttpSsnHookAdd``) to
+   an HTTP hook and uses ``TSContDataSet/Get``
+
+-  is registered locally (``TSHttpTxnHookAdd``), but for multiple
+   transactions uses ``TSContDataSet/Get``
+
+-  uses ``TSCacheXXX``, ``TSNetXXX``, ``TSHostLookup``, or
+   ``TSContSchedule`` APIs
+
+Before being activated, a caller must grab the continuation's mutex.
+This requirement makes it possible for a continuation's handler function
+to safely access its data and to prevent multiple callers from running
+it at the same time (see the :ref:`about-the-sample-protocol` for usage). The
+data protected by the mutex is any global or continuation data
+associated to the continuation by ``TSContDataSet``. This does not
+include the local data created by the continuation handler function. A
+typical example of continuations created with associated data structures
+and mutexes is the transaction state machine created in the sample
+Protocol plugin (see :ref:`one-way-to-implement-a-transaction-state-machine`).
+
+A reentrant call occurs when the continuation passed as an argument to
+the API can be called in the same stack trace as the function calling
+the API. For example, if you call ``TSCacheRead`` (``contp, mykey``), it
+is possible that ``contp``'s handler will be called directly and then
+``TSCacheRead`` returns.
+
+Caveats that could cause issues include the following:
+
+-  a continuation has data associated with it (``TSContDataGet``).
+
+-  the reentrant call passes itself as a continuation to the reentrant
+   API. In this case, the continuation should not try to access its data
+   after calling the reentrant API. The reason for this is that data may be
+   modified by the section of code in the continuation's handler that
+   handles the event sent by the API. It is recommended that you always
+   return after a reentrant call to avoid accessing something that has been
+   deallocated.
+
+Below is an example, followed by an explanation.
+
+.. code-block:: c
+
+    continuation_handler (TSCont contp, TSEvent event, void *edata) {
+        switch (event) {
+            case event1:
+                TSReentrantCall (contp);
+                /* Return right away after this call */
+                break;
+            case event2:
+                TSContDestroy (contp);
+                break;
+        }
+    }
+
+The above example first assumes that the continuation is called back
+with ``event1``; it then does the first reentrant call that schedules
+the continuation to receive ``event2``. Because the call is reentrant,
+the processor calls back the continuation right away with ``event2`` and
+the continuation is destroyed. If you try to access the continuation or
+one of its members after the reentrant call, then you might access
+something that has been deallocated. To avoid accessing something that
+has been deallocated, never access the continuation or any of its
+members after a reentrant call - just exit the handler.
+
+**Note:** Most HTTP transaction plugin continuations do not need
+non-null mutexes because they're called within the processing of an HTTP
+transaction, and therefore have the transaction's mutex.
+
+It is also possible to specify a continuation's mutex as ``NULL``. This
+should be done only when registering a continuation to a global hook, by
+a call to ``TSHttpHookAdd``. In this case, the continuation can be
+called simultaneously by different instances of HTTP SM running on
+different threads. Having a mutex here would slow and/or hinder Traffic
+Server performance, since all the threads will try to lock the same
+mutex. The drawback of not having a mutex is that such a continuation
+cannot have data associated with it (i.e., ``TSContDataGet/Set`` cannot
+be used).
+
+When using a ``NULL`` mutex it is dangerous to access the continuation's
+data, but usually continuations with ``NULL`` mutexes have no data
+associated with them anyway. An example of such a continuation is one
+that gets called back every time an HTTP request is read, and then
+determines from the request alone if the request should go through or be
+rejected. An HTTP transaction gives its continuation data to the
+``contp``.
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst b/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
new file mode 100644
index 0000000..c8cf516
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
@@ -0,0 +1,129 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-continuations-handler-functions:
+
+Writing Handler Functions
+*************************
+
+.. default-domain:: c
+
+The handler function is the key component of a continuation. It is
+supposed to examine the event and event data, and then do something
+appropriate. The probable action might be to schedule another event for
+the continuation to received, to open up a connection to a server, or
+simply to destroy itself.
+
+The continuation's handler function is a function of type
+:type:`TSEventFunc`. Its arguments are a continuation, an event, and a
+pointer to some data (this data is passed to the continuation by the
+caller - do not confuse this data with the continuation's own data,
+associated by :func:`TSContDataSet`). When the continuation is called back,
+the continuation and an event are passed to the handler function. The
+continuation is a handle to the same continuation that is invoked. The
+handler function typically has a switch statement to handle the events
+it receives:
+
+.. code-block:: c
+
+   static int some_handler (TScont contp, TSEvent event, void *edata)
+   {
+      // .....
+      switch(event) {
+         case TS_EVENT_SOME_EVENT_1:
+            do_some_thing_1;
+            return;
+         case TS_EVENT_SOME_EVENT_2:
+            do_some_thing_2;
+            return;
+         case TS_EVENT_SOME_EVENT_3:
+            do_some_thing_3;
+            return;
+         default: break;
+      }
+      return 0;
+   }
+
+.. caution::
+
+   You might notice that a continuation cannot determine if more events are
+   "in flight" toward it. Do not use :func:`TSContDestroy` to delete a
+   continuation before you make sure that all incoming events, such as
+   those sent because of :func:`TSHttpTxnHookAdd`, have been handled.
+
+The following table lists events and the corresponding type of
+`void* data` passed to handler functions:
+
+============================================ =========================================== ==========================
+Event                                        Event Sender                                Data Type
+============================================ =========================================== ==========================
+:data:`TS_EVENT_HTTP_READ_REQUEST_HDR`       :data:`TS_HTTP_READ_REQUEST_HDR_HOOK`       :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_OS_DNS`                 :data:`TS_HTTP_OS_DNS_HOOK`                 :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SEND_REQUEST_HDR`       :data:`TS_HTTP_SEND_REQUEST_HDR_HOOK`       :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_READ_CACHE_HDR`         :data:`TS_HTTP_READ_CACHE_HDR_HOOK`         :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_READ_RESPONSE_HDR`      :data:`TS_HTTP_READ_RESPONSE_HDR_HOOK`      :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SEND_RESPONSE_HDR`      :data:`TS_HTTP_SEND_RESPONSE_HDR_HOOK`      :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SELECT_ALT`             :data:`TS_HTTP_SELECT_ALT_HOOK`             :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_TXN_START`              :data:`TS_HTTP_TXN_START_HOOK`              :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_TXN_CLOSE`              :data:`TS_HTTP_TXN_CLOSE_HOOK`              :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SSN_START`              :data:`TS_HTTP_SSN_START_HOOK`              :type:`TSHttpSsn`
+:data:`TS_EVENT_HTTP_SSN_CLOSE`              :data:`TS_HTTP_SSN_CLOSE_HOOK`              :type:`TSHttpSsn`
+:data:`TS_EVENT_NONE`
+:data:`TS_EVENT_CACHE_LOOKUP_COMPLETE`       :data:`TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK`  :type:`TSHttpTxn`
+:data:`TS_EVENT_IMMEDIATE`                   :func:`TSVConnClose`
+                                             :func:`TSVIOReenable`
+                                             :func:`TSContSchedule`
+:data:`TS_EVENT_IMMEDIATE`                   :data:`TS_HTTP_REQUEST_TRANSFORM_HOOK`
+:data:`TS_EVENT_IMMEDIATE`                   :data:`TS_HTTP_RESPONSE_TRANSFORM_HOOK`
+:data:`TS_EVENT_CACHE_OPEN_READ`             :func:`TSCacheRead`                         Cache VC
+:data:`TS_EVENT_CACHE_OPEN_READ_FAILED`      :func:`TSCacheRead`                         TS_CACHE_ERROR code
+:data:`TS_EVENT_CACHE_OPEN_WRITE`            :func:`TSCacheWrite`                        Cache VC
+:data:`TS_EVENT_CACHE_OPEN_WRITE_FAILED`     :func:`TSCacheWrite`                        TS_CACHE_ERROR code
+:data:`TS_EVENT_CACHE_REMOVE`                :func:`TSCacheRemove`
+:data:`TS_EVENT_CACHE_REMOVE_FAILED`         :func:`TSCacheRemove`                       TS_CACHE_ERROR code
+:data:`TS_EVENT_NET_ACCEPT`                  :func:`TSNetAccept`                         :type:`TSNetVConnection`
+                                             :func:`TSHttpTxnServerIntercept`
+                                             :func:`TSHttpTxnIntercept`
+:data:`TS_EVENT_NET_ACCEPT_FAILED`           :func:`TSNetAccept`
+                                             :func:`TSHttpTxnServerIntercept`
+                                             :func:`TSHttpTxnIntercept`
+:data:`TS_EVENT_HOST_LOOKUP`                 :func:`TSHostLookup`                        :type:`TSHostLookupResult`
+:data:`TS_EVENT_TIMEOUT`                     :func:`TSContSchedule`
+:data:`TS_EVENT_ERROR`
+:data:`TS_EVENT_VCONN_READ_READY`            :func:`TSVConnRead`                         :type:`TSVIO`
+:data:`TS_EVENT_VCONN_WRITE_READY`           :func:`TSVConnWrite`                        :type:`TSVIO`
+:data:`TS_EVENT_VCONN_READ_COMPLETE`         :func:`TSVConnRead`                         :type:`TSVIO`
+:data:`TS_EVENT_VCONN_WRITE_COMPLETE`        :func:`TSVConnWrite`                        :type:`TSVIO`
+:data:`TS_EVENT_VCONN_EOS`                   :func:`TSVConnRead`                         :type:`TSVIO`
+:data:`TS_EVENT_NET_CONNECT`                 :func:`TSNetConnect`                        :type:`TSVConn`
+:data:`TS_EVENT_NET_CONNECT_FAILED`          :func:`TSNetConnect`                        :type:`TSVConn`
+:data:`TS_EVENT_HTTP_CONTINUE`
+:data:`TS_EVENT_HTTP_ERROR`
+:data:`TS_EVENT_MGMT_UPDATE`                 :func:`TSMgmtUpdateRegister`
+============================================ =========================================== ==========================
+
+The continuation functions are listed below:
+
+-  :func:`TSContCall`
+-  :func:`TSContCreate`
+-  :func:`TSContDataGet`
+-  :func:`TSContDataSet`
+-  :func:`TSContDestroy`
+-  :func:`TSContMutexGet`
+-  :func:`TSContSchedule`

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
new file mode 100644
index 0000000..6258557
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
@@ -0,0 +1,46 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+Implementing the Handler and Getting a Handle to the Transaction
+****************************************************************
+
+The handler function for the plugin's parent continuation is implemented
+as follows:
+
+.. code-block:: c
+
+    static int
+    auth_plugin (TSCont contp, TSEvent event, void *edata)
+    {
+
+         TSHttpTxn txnp = (TSHttpTxn) edata;
+         switch (event) {
+         case TS_EVENT_HTTP_OS_DNS:
+              handle_dns (txnp, contp);
+              return 0;
+         case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+              handle_response (txnp);
+              return 0;
+         default:
+              break;
+         }
+
+         return 0;
+    }
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
new file mode 100644
index 0000000..553aeb1
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
@@ -0,0 +1,48 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+.. _developer-plugins-examples-basic-auth:
+
+Basic Authorization Plugin
+**************************
+
+The sample basic authorization plugin, ``basic-auth.c``, checks for
+basic HTTP proxy authorization. In HTTP basic proxy authorization,
+client user names and passwords are contained in the
+``Proxy-Authorization`` header. The password is encoded using base64
+encoding. The plugin checks all incoming requests for the authorization
+header, user name, and password. If the plugin does not find all of the
+these, then it reenables with an error (effectively stopping the
+transaction) and adds a transaction hook to the send response header
+event.
+
+Creating the Plugin's Parent Continuation and Global Hook
+=========================================================
+
+The parent continuation and global hook are created as follows:
+
+``TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, TSContCreate (auth_plugin, NULL));``
+
+.. toctree::
+   :maxdepth: 2
+
+   implementing-the-handler-and-getting-a-handle-to-the-transaction.en
+   working-with-http-headers.en
+   setting-a-transaction-hook.en
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
new file mode 100644
index 0000000..793260a
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
@@ -0,0 +1,58 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+Setting a Transaction Hook
+**************************
+
+If the request does not have the ``Proxy-Authorization`` field set to
+Basic authorization or a valid username/password, then the plugin sends
+the 407 Proxy authorization ``required`` status code back to the client.
+The client will then prompt the user for a username and password, and
+then resend the request.
+
+In the ``handle_dns`` routine, the following lines handle the
+authorization error case:
+
+.. code-block:: c
+
+    done:
+         TSHttpTxnHookAdd (txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
+         TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
+
+If ``handle_dns`` does not find the ``Proxy-Authorization`` field set to
+Basic authorization or a valid username/password, then it adds a
+``SEND_RESPONSE_HDR_HOOK`` to the transaction being processed. This
+means that Traffic Server will call the plugin back when sending the
+client response. ``handle_dns`` reenables the transaction with
+``TS_EVENT_HTTP_ERROR``, which means that the plugin wants Traffic
+Server to terminate the transaction.
+
+When Traffic Server terminates the transaction, it sends the client an
+error message. Because of the ``SEND_RESPONSE_HDR_HOOK``, Traffic Server
+calls the plugin back. The ``auth-plugin`` routine calls
+``handle_response`` to send the client a ``407`` status code. When the
+client resends the request with the ``Proxy-Authorization`` field, a new
+transaction begins.
+
+``handle_dns`` calls ``base64_decode`` to decode the username and
+password; ``handle_dns`` also calls ``authorized`` to validate the
+username and password. In this plugin, sample NT code is provided for
+password validation. UNIX programmers can supply their own validation
+mechanism.
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
new file mode 100644
index 0000000..bae0b9e
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
@@ -0,0 +1,98 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+Working With HTTP Headers
+*************************
+
+The plugin checks all client request headers for the Proxy-Authorization
+MIME field, which should contain the user name and password. The
+plugin's continuation handler, ``auth-plugin``, calls ``handle_dns`` to
+check the ``Proxy-Authorization`` field. The ``handle_dns`` routine uses
+``TSHttpTxnClientReqGet`` and ``TSMimeHdrFieldFind`` to obtain the
+``Proxy-Authorization`` field:
+
+.. code-block:: c
+
+    {
+        TSMBuffer bufp;
+        TSMLoc hdr_loc;
+        TSMLoc field_loc;
+        const char *val;
+        char *user, *password;
+
+        if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
+            TSError ("[basic_authorization] Couldn't retrieve client request header");
+            goto done;
+        }
+
+        field_loc = TSMimeHdrFieldFind (bufp, hdr_loc,
+                TS_MIME_FIELD_PROXY_AUTHORIZATION);
+
+If the ``Proxy-Authorization`` field is present, then the plugin checks
+that the authentication type is "Basic", and the user name and password
+are present and valid:
+
+.. code-block:: c
+
+    val = TSMimeHdrFieldValueStringGet (bufp, hdr_loc, field_loc, -1, &authval_length);
+    if (!val) {
+        TSError ("[basic_authorization] No value in Proxy-Authorization field");
+        TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+        goto done;
+    }
+
+    if (strncmp (val, "Basic", 5) != 0) {
+        TSError ("[basic_authorization] No Basic auth type in Proxy-Authorization");
+        TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+        goto done;
+    }
+
+    val += 5;
+    while ((*val == ' ') || (*val == '\t')) {
+        val += 1;
+    }
+
+    user = base64_decode (val);
+    password = strchr (user, ':');
+    if (!password) {
+        TSError ("[basic_authorization] No password in authorization information");
+        TSfree (user);
+        TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+        goto done;
+    }
+    *password = '\0';
+    password += 1;
+
+    if (!authorized (user, password)) {
+        TSError ("[basic_authorization] %s:%s not authorized", user, password);
+        TSfree (user);
+        TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+        goto done;
+    }
+
+    TSfree (user);
+    TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+    TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+    TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+    return;
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
new file mode 100644
index 0000000..46d2a54
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
@@ -0,0 +1,64 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+.. _developer-plugins-blacklist-access-process-txn:
+
+Accessing the Transaction Being Processed
+*****************************************
+
+A continuation's handler function is of type ``TSEventFunc``; the
+prototype is as follows:
+
+``static int function_name (TSCont contp, TSEvent event, void *edata)``
+
+In general, the return value of the handler function is not used. The
+continuation argument is the continuation being called back, the event
+is the event being sent to the continuation, and the data pointed to by
+``void *edata`` depends on the type of event. The data types for each
+event type are listed in :doc:`Writing Handler
+Functions <../../continuations/writing-handler-functions.en>`
+
+The key here is that if the event is an HTTP transaction event, then the
+data passed to the continuation's handler is of type ``TSHttpTxn`` (a
+data type that represents HTTP transactions). Your plugin can then do
+things with the transaction. Here's how it looks in the code for the
+Blacklist plugin's handler:
+
+.. code-block:: c
+
+   static int
+   blacklist_plugin (TSCont contp, TSEvent event, void *edata)
+   {
+      TSHttpTxn txnp = (TSHttpTxn) edata;
+      switch (event) {
+         case TS_EVENT_HTTP_OS_DNS:
+            handle_dns (txnp, contp);
+            return 0;
+         case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+            handle_response (txnp);
+            return 0;
+         default:
+            break;
+      }
+      return 0;
+   }
+
+For example: when the origin server DNS lookup event is sent,
+``blacklist_plugin`` can call ``handle_dns``\ and pass ``txnp`` as an
+argument.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
new file mode 100644
index 0000000..624c22c
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
@@ -0,0 +1,111 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+.. _developer-plugins-examples-blacklist:
+
+Blacklist Plugin
+****************
+
+The sample blacklisting plugin included in the Traffic Server SDK is
+``blacklist-1.c``. This plugin checks every incoming HTTP client request
+against a list of blacklisted web sites. If the client requests a
+blacklisted site, then the plugin returns an ``Access forbidden``
+message to the client.
+
+The flow of HTTP processing with the blacklist plugin is illustrated in
+the figure titled :ref:`BlackListPlugin`.
+This example also contains a simple configuration management interface.
+It can read a list of blacklisted sites from a file (``blacklist.txt``)
+that can be updated by a Traffic Server administrator. When the
+configuration file is updated, Traffic Server sends an event to the
+plugin that wakes it up to do some work.
+
+Creating the Parent Continuation
+================================
+
+You create the static parent continuation in the mandatory
+``TSPluginInit`` function. This parent continuation effectively **is**
+the plugin: the plugin executes only when this continuation receives an
+event from Traffic Server. Traffic Server passes the event as an
+argument to the continuation's handler function. When you create
+continuations, you must create and specify their handler functions.
+
+You can specify an optional mutex lock when you create continuations.
+The mutex lock protects data shared by asynchronous processes. Because
+Traffic Server has a multi-threaded design, race conditions can occur if
+several threads try to access the same continuation's data.
+
+Here is how the static parent continuation is created in
+``blacklist-1.c``:
+
+.. code-block:: c
+
+   void
+   TSPluginInit (int argc, const char *argv[])
+   {
+      // ...
+      TSCont contp;
+          
+      contp = TSContCreate (blacklist_plugin, NULL);
+      // ...
+   }
+
+The handler function for the plugin is ``blacklist_plugin``, and the
+mutex is null. The continuation handler function's job is to handle the
+events that are sent to it; accordingly, the ``blacklist_plugin``
+routine consists of a switch statement that covers each of the events
+that might be sent to it:
+
+.. code-block:: c
+
+   static int
+   blacklist_plugin (TSCont contp, TSEvent event, void *edata)
+   {
+      TSHttpTxn txnp = (TSHttpTxn) edata;
+      switch (event) {
+         case TS_EVENT_HTTP_OS_DNS:
+            handle_dns (txnp, contp);
+            return 0;
+         case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+            handle_response (txnp);
+            return 0;
+         default:
+            TSDebug ("blacklist_plugin", "This event was unexpected: %d\n", );
+            break;
+      }
+      return 0;
+   }
+
+When you write handler functions, you have to anticipate any events that
+might be sent to the handler by hooks or by other functions. In the
+Blacklist plugin, ``TS_EVENT_OS_DNS`` is sent because of the global hook
+established in ``TSPluginInit``, ``TS_EVENT_HTTP_SEND_RESPONSE_HDR`` is
+sent because the plugin contains a transaction hook
+(see :ref:`developer-plugins-examples-blacklist-txn-hook`).
+It is good practice to have a default case in your switch statements.
+
+.. toctree::
+   :maxdepth: 2
+
+   setting-a-global-hook.en
+   accessing-the-transaction-being-processed.en
+   setting-up-a-transaction-hook.en
+   working-with-http-header-functions.en
+   source-code.en
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
new file mode 100644
index 0000000..65bc059
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
@@ -0,0 +1,38 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+Setting a Global Hook
+*********************
+
+Global hooks are always added in ``TSPluginInit`` using
+``TSHttpHookAdd``. The two arguments of ``TSHttpHookAdd`` are the hook
+ID and the continuation to call when processing the event corresponding
+to the hook. In ``blacklist-1.c``, the global hook is added as follows:
+
+.. code-block:: c
+
+   TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, contp);
+
+Above, ``TS_HTTP_OS_DNS_HOOK`` is the ID for the origin server DNS
+lookup hook and ``contp`` is the parent continuation created earlier.
+
+This means that the Blacklist plugin is called at every origin server
+DNS lookup. When it is called, the handler functio ``blacklist_plugin``
+receives ``TS_EVENT_HTTP_OS_DNS`` and calls ``handle_dns`` to see if the
+request is forbidden.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
new file mode 100644
index 0000000..7f89d31
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
@@ -0,0 +1,84 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../../common.defs
+
+.. _developer-plugins-examples-blacklist-txn-hook:
+
+Setting Up a Transaction Hook
+*****************************
+
+The Blacklist plugin sends "access forbidden" messages to clients if
+their requests are directed to blacklisted hosts. Therefore, the plugin
+needs a transaction hook so it will be called back when Traffic Server's
+HTTP state machine reaches the "send response header" event. In the
+Blacklist plugin's ``handle_dns`` routine, the transaction hook is added
+as follows:
+
+.. code-block:: c
+
+   TSMutexLock (sites_mutex);
+   for (i = 0; i < nsites; i++) {
+      if (strncmp (host, sites[i], host_length) == 0) {
+         printf ("blacklisting site: %s\n", sites[i]);
+         TSHttpTxnHookAdd (txnp,
+            TS_HTTP_SEND_RESPONSE_HDR_HOOK,
+            contp);
+         TSHandleMLocRelease (bufp, hdr_loc, url_loc);
+         TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+         TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
+         TSMutexUnlock (sites_mutex);
+         return;
+      }
+   }
+   TSMutexUnlock (sites_mutex);
+   done:
+   TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+
+This code fragment shows some interesting features. The plugin is
+comparing the requested site to the list of blacklisted sites. While the
+plugin is using the blacklist, it must acquire the mutex lock for the
+blacklist to prevent configuration changes in the middle of a
+blacklisting operation. If the requested site is blacklisted, then the
+following things happen:
+
+#. A transaction hook is added with ``TSHttpTxnHookAdd``; the plugin is
+   called back at the "send response header" event (i.e., the plugin
+   sends an Access forbidden message to the client). You can see that in
+   order to add a transaction hook, you need a handle to the transaction
+   being processed.
+
+#. The transaction is reenabled using ``TSHttpTxnReenable`` with
+   ``TS_EVENT_HTTP_ERROR`` as its event argument. Reenabling with an
+   error event tells the HTTP state machine to stop the transaction and
+   jump to the "send response header" state. Notice that if the
+   requested site is not blacklisted, then the transaction is reenabled
+   with the ``TS_EVENT_HTTP_CONTINUE`` event.
+
+#. The string and ``TSMLoc`` data stored in the marshal buffer ``bufp`` is
+   released by ``TSHandleMLocRelease`` (see
+   :ref:`developer-plugins-http-headers-marshal-buffers`). Release these
+   handles before re-enabling the transaction.
+
+In general, whenever the plugin is doing something to a transaction, it
+must reenable the transaction when it is finished. In other words: every
+time your handler function handles a transaction event, it must call
+``TSHttpTxnReenable`` when it is finished. Similarly, after your plugin
+handles session events (``TS_EVENT_HTTP_SSN_START`` and
+``TS_EVENT_HTTP_SSN_CLOSE``), it must reenable the session with
+``TSHttpSsnReenable``. Reenabling the transaction twice in the same
+plugin routine is a bad error.