Update doc
diff --git a/doc/pragrammers-guide.rst b/doc/pragrammers-guide.rst
new file mode 100644
index 0000000..7a764fc
--- /dev/null
+++ b/doc/pragrammers-guide.rst
@@ -0,0 +1,276 @@
+The ngtcp2 programmers' guide for early adopters
+================================================
+
+This document is written for early adopters of ngtcp2 library.  It
+describes a brief introduction of programming ngtcp2.
+
+Prerequisites
+-------------
+
+Reading QUIC transport and TLS draft helps you a lot to write QUIC
+application.  They describes how TLS is integrated into QUIC and why
+the existing TLS stack cannot be used with QUIC.
+
+QUIC requires the special interface from TLS stack, which is probably
+not available from most of the existing TLS stacks.  As far as I know,
+the TLS stacks maintained by the active participants of QUIC working
+group only get this interface at the time of this writing.  In order
+to build QUIC application you have to choose one of them.  Here is the
+list of TLS stacks which are supposed to provide such interface.
+Please note that I only use my hacked OpenSSL.  Don't ask me how to
+use other TLS libraries:
+
+* `my OpenSSL fork
+  <https://github.com/tatsuhiro-t/openssl/tree/quic-draft-15>`_
+* picotls
+* nss
+* BoringSSL
+
+You should use ngtcp2 draft-15 branch.  At the time of this writing,
+interop is done with draft-15 or -16.
+
+Creating ngtcp2_conn object
+---------------------------
+
+In order to start handshake, you need to first create ``ngtcp2_conn``
+object.  Use `ngtcp2_conn_client_new()` for client application, and
+`ngtcp2_conn_server_new()` for server.
+
+They require ``ngtcp2_conn_callback`` and ``ngtcp2_settings`` objects.
+
+The ``ngtcp2_conn_callback`` contains the callback functions which
+``ngtcp2_conn`` calls when a specific event happens, say, receiving
+stream data or stream is closed, etc.
+
+In order to make handshake work for client application, at least the
+following fields of ``ngtcp2_conn_callbacks`` must be set:
+
+* client_initial
+* recv_crypto_data
+* in_encrypt
+* in_decrypt
+* encrypt
+* decrypt
+* in_encrypt_pn
+* encrypt_pn
+* acked_crypto_offset
+* recv_retry
+
+For server application:
+
+* recv_client_initial
+* recv_crypto_data
+* in_encrypt
+* in_decrypt
+* encrypt
+* decrypt
+* in_encrypt_pn
+* encrypt_pn
+* acked_crypto_offset
+
+``ngtcp2_settings`` contains the settings for QUIC connection.  All
+fields must be set.  It would be very useful to enable debug logging
+by setting logging function to ``log_printf`` field.  ngtcp2 library
+relies on the timestamp fed from application.  The initial timestamp
+must be passed to ``initial_ts`` field in nanosecond resolution.
+ngtcp2 cares about the difference from that initial value.  It could
+be any timestamp which increases monotonically, and actual value does
+not matter.  ``max_packet_size``, ``ack_delay_component``, and
+``max_ack_delay`` should be set to the draft default,
+``NGTCP2_MAX_PKT_SIZE``, ``NGTCP2_DEFAULT_ACK_DELAY_EXPONENT``, and
+``NGTCP2_DEFAULT_MAX_ACK_DELAY`` respectively.  Of course, you can
+tweak these values if you know what you are doing.
+
+Client application has to supply Connection IDs to
+`ngtcp2_conn_client_new()`.  The *dcid* parameter is the destination
+connection ID (DCID), and which should be random byte string and at
+least 8 bytes long.  The *scid* is the source connection ID (SCID)
+which identifies the client itself.  The *version* parameter is the
+QUIC version to use.  It should be ``NGTCP2_PROTO_VER_MAX``.
+
+Similarly, server application has to supply these parameters.  But the
+*dcid* must be the same value which is received from client (which is
+client SCID).  The *scid* is chosen by server.  Don't use DCID in
+client packet as server SCID.  The *version* parameter is the QUIC
+version to use.  It should be ``NGTCP2_PROTO_VER_MAX``.
+
+Client application must create initial secret and derives packet
+protection key and IV, and packet number encryption key.  See
+https://tools.ietf.org/html/draft-ietf-quic-tls-16#section-5.2
+
+TLS integration
+---------------
+
+QUIC uses modified version of TLSv1.3.  The differences are:
+
+* QUIC does not use TLS record layer protocol.  Each TLS message is
+  directly encoded and encrypted by QUIC transport.
+* QUIC does not use End of Early Data TLS message.
+* QUIC does not send early (0-RTT) data through TLSv1.3 application
+  message.  It is sent outside TLS.
+* QUIC uses ``quic`` label instead of ``tls13`` to derive keying
+  materials (this might change in the future).
+
+QUIC has 4 types of packets: Initial, Handshake, 0-RTT Protected, and
+Short.  They are encrypted with their own keys.
+
+Initial packet is encrypted by the Initial key which is derived from
+client DCID and static salt.
+
+Handshake packet is encrypted by the Handshake key which is fed by TLS
+stack.  It is the same key and IV derived from
+client_handshake_traffic_secret for client and
+server_handshake_traffic_secret for server.
+
+0-RTT Protected packet is encrypted by the 0RTT key which is fed by
+TLS stack.  It is the same key and IV derived from
+client_early_traffic_secret.
+
+Short packet is encrypted by the 1RTT key which is fed by TLS stack.
+It is the same key and IV derived from
+client_application_traffic_secret for client and
+server_application_traffic_secret for server.
+
+TLS stack has to implement the interface which notify these keying
+materials.  They must be installed to `ngtcp2_conn` using the
+following functions:
+
+* `ngtcp2_conn_install_initial_tx_keys()`: Set encryption key for
+  Initial packet.
+* `ngtcp2_conn_install_initial_rx_keys()`: Set decryption key for
+  Initial packet.
+* `ngtcp2_conn_install_handshake_tx_keys()`: Set encryption key for
+  Handshake packet.
+* `ngtcp2_conn_install_handshake_rx_keys()`: Set decryption key for
+  Handshake packet.
+* `ngtcp2_conn_install_early_keys()`: Set key for 0RTT Protected
+  packet for encryption and decryption.
+* `ngtcp2_conn_install_tx_keys()`: Set encryption key for Short
+  packet.
+* `ngtcp2_conn_install_rx_keys()`: Set decryption key for Short
+  packet.
+
+Clarification of encryption and decryption keys: For client
+application, encryption keys are derived from client_*_traffic_secret,
+and decryption keys are derived from server_*_traffic_secret.  For
+server application, encryption keys are derived from
+server_*_traffic_secret, and decryption keys are derived from
+client_*_traffic_secret.
+
+After Handshake key is available, set AEAD overhead (tag length) using
+`ngtcp2_conn_set_aead_overhead()` function.
+
+`ngtcp2_conn_write_handshake()` initiates QUIC handshake.  The Initial
+keys must be installed before calling this function.
+
+For client application, it first calls
+``ngtcp2_conn_callbacks.client_initial`` callback.  The callback must
+ask TLS stack to produce first TLS message, which is typically
+ClientHello.  The message must be passed to ``ngtcp2_conn`` object
+using `ngtcp2_conn_submit_crypto_data()` function.  The function does
+not own the passed data.  The application should keep the data alive
+until ``ngtcp2_conn_callbacks.acked_crypto_offset`` callback tells
+that the data is acknowledged by the peer and no longer used.  Next,
+``ngtcp2_conn_callbacks.in_encrypt`` callback is called to tell
+application to encrypt the data using AEAD_AES_128_GCM.  And then,
+``ngtcp2_conn_callbacks.in_encrypt_pn`` callback is called to tell
+application to encrypt the packet number using AES-CTR.  After
+negotiated Handshake keys are available,
+``ngtcp2_conn_callbacks.encrypt`` and
+``ngtcp2_conn_callbacks.encrypt_pn`` are called instead.  Use the
+negotiated cipher suites.  If ChaCha20 based cipher suite is
+negotiated, ChaCha20 is used to protect packet number.
+
+`ngtcp2_conn_read_handshake()` reads QUIC handshake packets.
+
+For server application, it first calls
+``ngtcp2_conn_callbacks.recv_client_initial`` callback.  The callback
+must create the Initial key using client DCID and install it to
+``ngtcp2_conn``.  The library calls
+``ngtcp2_conn_callbacks.in_encrypt_pn`` callback to decrypt packet
+number.  Then ``ngtcp2_conn_callbacks.in_decrypt`` callback is called
+to decrypt packet payload.  ``ngtcp2_conn_callbacks.recv_crypto_data``
+callback is called with the received TLS messages.  Feed them to TLS
+stack.  If TLS stack produces any TLS message other than Alert, passes
+them to ``ngtcp2_conn`` through `ngtcp2_conn_submit_crypto_data()`
+function.  After negotiated Handshake keys are available,
+``ngtcp2_conn_callbacks.encrypt_pn`` and
+``ngtcp2_conn_callbacks.decrypt`` are called instead.  When peer
+acknowledges TLS messages,
+``ngtcp2_conn_callbacks.acked_crypto_offset`` callback is called.  The
+application can throw away data acknowledged.
+
+`ngtcp2_conn_read_handshake()` and `ngtcp2_conn_write_handshake()`
+should be called until `ngtcp2_conn_get_handshake_completed()` returns
+nonzero which means QUIC handshake has completed.
+
+0RTT data transmission
+----------------------
+
+In order for client to send 0RTT data, it should use
+`ngtcp2_conn_client_write_handshake()` function instead of
+`ngtcp2_conn_write_handshake()`.
+`ngtcp2_conn_client_write_handshake()` accepts 0RTT data to send.
+
+Client application has to load resumed TLS session.  It also has to
+set the remembered transport parameter using
+`ngtcp2_conn_set_early_remote_transport_params()` function.
+
+Before calling `ngtcp2_conn_client_write_handshake()`, client
+application has to open stream to send data using
+`ngtcp2_conn_open_bidi_stream()` (or `ngtcp2_conn_open_uni_stream()`
+for unidirectional stream).
+
+Stateless Retry
+---------------
+
+QUIC allows server to validate client address in a stateless manner.
+When a client receives client address validation request from server,
+``ngtcp2_conn_callbacks.recv_retry`` callback is called.  Most of the
+retry logic is done by the library, but the client application has to
+recreate TLS session from scratch to produce fresh keying materials.
+
+0RTT data that has already passed to ``ngtcp2_conn`` is still alive.
+Client application must not free them until
+``ngtcp2_conn_callbacks.acked_stream_data_offset`` callback is called.
+
+After QUIC handshake
+--------------------
+
+After QUIC handshake completed, call `ngtcp2_conn_read_pkt()` to read
+incoming QUIC packets.  To write QUIC packets, call
+`ngtcp2_conn_write_pkt()`.
+
+In order to send stream data, the application has to first open a
+stream.  Use `ngtcp2_conn_open_bidi_stream()` to open bidirectional
+stream.  For unidirectional stream, call
+`ngtcp2_conn_open_uni_stream()`.  Call `ngtcp2_conn_write_stream()` to
+send stream data.
+
+Closing connection
+------------------
+
+In order to close QUIC connection, call
+`ngtcp2_conn_write_connection_close()` or
+`ngtcp2_conn_write_application_close()`.
+
+Error handling in general
+-------------------------
+
+In general, when error is returned from the ngtcp2 library function,
+just close QUIC connection.
+
+If `ngtcp2_err_is_fatal()` returns true with the returned error code,
+``ngtcp2_conn`` object must be deleted with `ngtcp2_conn_del` without
+any ngtcp2 library functions.  Otherwise, call
+`ngtcp2_conn_write_connection_close()` to get terminal packet.
+Sending it finishes QUIC connection.
+
+The following error codes must be considered as transitional, and
+application should keep connection alive:
+
+* ``NGTCP2_ERR_EARLY_DATA_REJECTED``
+* ``NGTCP2_ERR_STREAM_DATA_BLOCKED``
+* ``NGTCP2_ERR_STREAM_SHUT_WR``
+* ``NGTCP2_ERR_STREAM_NOT_FOUND``
+* ``NGTCP2_ERR_STREAM_ID_BLOCKED``