OSDN Git Service

Add description of SSL request protocol. Miscellaneous copy-editing.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 22 Nov 2001 01:22:10 +0000 (01:22 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 22 Nov 2001 01:22:10 +0000 (01:22 +0000)
doc/src/sgml/protocol.sgml

index 822b562..f8848a3 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.22 2001/11/21 05:53:41 thomas Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.23 2001/11/22 01:22:10 tgl Exp $ -->
 
 <chapter id="protocol">
  <title>Frontend/Backend Protocol</title>
@@ -38,7 +38,7 @@
 
   <para>
    A frontend opens a connection to the server and sends a start-up
-   packet.  This includes the names of the user and the database the
+   packet.  This includes the names of the user and of the database the
    user wants to connect to.  The server then uses this, and the
    information in the <filename>pg_hba.conf</filename> file to
    determine what further authentication information it requires the
   </para>
 
   <para>
-   In order to serve multiple clients efficiently, the server would
-   normally create a new child process to handle each incoming
-   connection.  However, this is not required.  In the current
-   implementation, a new child process is created immediately after an
-   incoming connection is detected.  In earlier versions of
-   <productname>PostgreSQL</> 
-   (7.1 and earlier), the child process was created after sending the
-   authentication confirmation message.
+   In order to serve multiple clients efficiently, the server launches
+   a new <quote>backend</> process for each client.  This is transparent
+   to the protocol, however.  In the current implementation, a new child
+   process is created immediately after an incoming connection is detected.
   </para>
 
   <para>
    When the frontend wishes to disconnect it sends an appropriate packet and
-   closes the connection without waiting for a response for the backend.
+   closes the connection without waiting for a response from the backend.
   </para>
 
   <para>
       <Term>CursorResponse</Term>
       <ListItem>
        <Para>
-        The query was either an <literal>INSERT</literal>,
-        <literal>UPDATE</literal>, <literal>DELETE</literal>,
-        <literal>FETCH</literal>, or a <literal>SELECT</literal>
-        command.  If the transaction has been aborted then the backend
-        sends a CompletedResponse message with a tag of <literal>*ABORT
-        STATE*</literal>.  Otherwise the following responses are sent.
-       </Para>
-
-       <Para>
-        For an <literal>INSERT</literal> command, the backend then
-        sends a CompletedResponse message with a tag of
-        <literal>INSERT <replaceable>oid</replaceable>
-        <replaceable>rows</replaceable></literal>, where
-        <replaceable>rows</replaceable> is the number of rows
-        inserted, and <replaceable>oid</replaceable> is the object ID
-        of the inserted row if <Replaceable>rows</Replaceable> is 1,
-        otherwise <Replaceable>oid</Replaceable> is 0.
-       </Para>
-
-       <Para>
-        For a <literal>DELETE</literal> command, the backend then
-        sends a CompletedResponse message with a tag of <literal>DELETE
-        <Replaceable>rows</Replaceable></literal> where
-        <Replaceable>rows</Replaceable> is the number of rows deleted.
-       </Para>
-
-       <Para>
-        For an <literal>UPDATE</literal> command, the backend then
-        sends a CompletedResponse message with a tag of <literal>UPDATE
-        <Replaceable>rows</Replaceable></literal> where
-        <Replaceable>rows</Replaceable> is the number of rows affected
-        by the update.
+        Beginning of the response to a <command>SELECT</command>,
+        <command>FETCH</command>, <command>INSERT</command>,
+        <command>UPDATE</command>, or <command>DELETE</command>
+        query.  In the <command>FETCH</command> case the name of the
+       cursor being fetched from is included in the message.  Otherwise
+       the message always mentions the <quote>blank</> cursor.
        </Para>
+      </ListItem>
+     </VarListEntry>
 
+     <VarListEntry>
+      <Term>RowDescription</Term>
+      <ListItem>
        <Para>
-        For a <literal>FETCH</literal> or <literal>SELECT</literal>
-        command, the backend sends a RowDescription message.  This is
-        then followed by an AsciiRow or BinaryRow message (depending
-        on whether a binary cursor was specified) for each row being
-        returned to the frontend.  Finally, the backend sends a
-        CompletedResponse message with a tag of <literal>SELECT</literal>.
+        Indicates that rows are about to be returned in response to
+       a <command>SELECT</command> or <command>FETCH</command> query.
+       The message contents describe the layout of the rows.  This
+       will be followed by an AsciiRow or BinaryRow message (depending on
+       whether a binary cursor was specified) for each row being returned
+        to the frontend.
        </Para>
       </ListItem>
      </VarListEntry>
       <Term>EmptyQueryResponse</Term>
       <ListItem>
        <Para>
-        An empty query string was recognized.  (The need to specially
-        distinguish this case is historical.)
+        An empty query string was recognized.
        </Para>
       </ListItem>
      </VarListEntry>
     </VariableList>
    </Para>
 
+   <Para>
+    The response to a <command>SELECT</> or <command>FETCH</> query
+    normally consists of CursorResponse, RowDescription, zero or more
+    AsciiRow or BinaryRow messages, and finally CompletedResponse.
+    <command>INSERT</command>, <command>UPDATE</command>, and
+    <command>DELETE</command> queries produce CursorResponse followed by
+    CompletedResponse.
+    <command>COPY</> to or from the frontend invokes special protocol
+    as mentioned above.
+    All other query types normally produce only
+    a CompletedResponse message.
+   </Para>
+
+   <Para>
+    Since a query string could contain several queries (separated by
+    semicolons), there might be several such response sequences before the
+    backend finishes processing the query string.  ReadyForQuery is issued
+    when the entire string has been processed and the backend is ready to
+    accept a new query string.
+   </Para>
+
+   <Para>
+    If a completely empty (no contents other than whitespace) query string
+    is received, the response is EmptyQueryResponse followed by ReadyForQuery.
+    (The need to specially distinguish this case is historical.)
+   </Para>
+
+   <Para>
+    In the event of an error, ErrorResponse is issued followed by
+    ReadyForQuery.  All further processing of the query string is aborted by
+    ErrorResponse (even if more queries remained in it).  Note that this
+    may occur partway through the sequence of messages generated by an
+    individual query.
+   </Para>
+
    <para>
     A frontend must be prepared to accept ErrorResponse and
     NoticeResponse messages whenever it is expecting any other type of
    </para>
 
    <Para>
-    Also, if the frontend issues any <literal>LISTEN</literal>
+    Also, if the frontend issues any <command>LISTEN</command>
     commands then it must be prepared to accept NotificationResponse
     messages at any time; see below.
    </para>
+
+   <para>
+    Recommended practice is to code frontends in a state-machine style
+    that will accept any message type at any time that it could make sense,
+    rather than wiring in assumptions about the exact sequence of messages.
+   </para>
   </sect2>
 
   <Sect2>
    <para>
     A frontend must be prepared to accept ErrorResponse and
     NoticeResponse messages whenever it is expecting any other type of
-    message.  Also, if it issues any <literal>LISTEN</literal>
+    message.  Also, if it issues any <command>LISTEN</command>
     commands then it must be prepared to accept NotificationResponse
     messages at any time; see below.
    </para>
    <title>Notification Responses</title>
 
    <Para>
-    If a frontend issues a <literal>LISTEN</literal> command, then the
+    If a frontend issues a <command>LISTEN</command> command, then the
     backend will send a NotificationResponse message (not to be
     confused with NoticeResponse!)  whenever a
-    <literal>NOTIFY</literal> command is executed for the same
+    <command>NOTIFY</command> command is executed for the same
     notification name.
    </para>
 
       <Term>NotificationResponse</Term>
       <ListItem>
        <Para>
-        A <literal>NOTIFY</literal> command has been executed for a
-        name for which a previous <literal>LISTEN</literal> command
+        A <command>NOTIFY</command> command has been executed for a
+        name for which a previous <command>LISTEN</command> command
         was executed.  Notifications may be sent at any time.
        </Para>
       </ListItem>
     same key data (PID and secret key) passed to the frontend during
     connection start-up.  If the request matches the PID and secret
     key for a currently executing backend, the processing of the
-    current query is aborted.  (In the existing implemenation, this is
+    current query is aborted.  (In the existing implementation, this is
     done by sending a special signal to the backend process that is
     processing the query.)
    </para>
     by recontacting the server if it doesn't want to terminate
     itself.
    </para>
+
+   <para>
+    For either normal or abnormal termination, any open transaction is
+    rolled back, not committed.  One should note however that if a
+    frontend disconnects while a query is being processed, the backend
+    will probably finish the query before noticing the disconnection.
+    If the query is outside any transaction block (<command>BEGIN</>
+    ... <command>COMMIT</> sequence) then its results may be committed
+    before the disconnection is recognized.
+   </para>
+  </sect2>
+
+  <Sect2>
+   <Title>SSL Session Encryption</Title>
+
+   <Para>
+    Recent releases of <productname>PostgreSQL</> allow frontend/backend
+    communication to be encrypted using SSL.  This provides communication
+    security in environments where attackers might be able to capture the
+    session traffic.
+   </para>
+
+   <para>
+    To initiate an SSL-encrypted connection, the frontend initially sends
+    an SSLRequest message rather than a StartupPacket.  The server then
+    responds with a single byte containing <literal>Y</> or <literal>N</>,
+    indicating that it is willing or unwilling to perform SSL, respectively.
+    The frontend may close the connection at this point if it is dissatisfied
+    with the response.  To continue after <literal>Y</>, perform an SSL
+    startup handshake (not described here, part of the SSL specification)
+    with the server.  If this is successful, continue with
+    sending the usual StartupPacket.  In this case the StartupPacket and
+    all subsequent data will be SSL-encrypted.  To continue after
+    <literal>N</>, send the usual StartupPacket and proceed without
+    encryption.
+   </para>
+
+   <para>
+    The frontend should also be prepared to handle an ErrorMessage response
+    to SSLRequest from the server.  This would only occur if the server
+    predates the addition of SSL support to <productname>PostgreSQL</>.
+    In this case the connection must be closed, but the frontend may choose
+    to open a fresh connection and proceed without requesting SSL.
+   </para>
+
+   <para>
+    An initial SSLRequest may also be used in a connection that is being
+    opened to send a CancelRequest message.
+   </para>
+
+   <para>
+    While the protocol itself does not provide a way for the server to
+    force SSL encryption, the administrator may configure the server to
+    reject unencrypted sessions as a byproduct of authentication checking.
+   </para>
   </sect2>
  </sect1>
 
@@ -1240,8 +1310,30 @@ CompletedResponse (B)
 </Term>
 <ListItem>
 <Para>
-                The command tag.  This is usually (but not always) a single
-                word that identifies which SQL command was completed.
+        The command tag.  This is usually a single
+        word that identifies which SQL command was completed.
+       </Para>
+
+       <Para>
+        For an <command>INSERT</command> command, the tag is
+        <literal>INSERT <replaceable>oid</replaceable>
+        <replaceable>rows</replaceable></literal>, where
+        <replaceable>rows</replaceable> is the number of rows
+        inserted, and <replaceable>oid</replaceable> is the object ID
+        of the inserted row if <Replaceable>rows</Replaceable> is 1,
+        otherwise <Replaceable>oid</Replaceable> is 0.
+       </Para>
+
+       <Para>
+        For a <command>DELETE</command> command, the tag is
+       <literal>DELETE <Replaceable>rows</Replaceable></literal> where
+        <Replaceable>rows</Replaceable> is the number of rows deleted.
+       </Para>
+
+       <Para>
+        For an <command>UPDATE</command> command, the tag is
+       <literal>UPDATE <Replaceable>rows</Replaceable></literal> where
+        <Replaceable>rows</Replaceable> is the number of rows updated.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1853,6 +1945,44 @@ RowDescription (B)
 </Para>
 </ListItem>
 </VarListEntry>
+
+<VarListEntry>
+<Term>
+SSLRequest (F)
+</Term>
+<ListItem>
+<Para>
+
+<VariableList>
+<VarListEntry>
+<Term>
+        Int32(8)
+</Term>
+<ListItem>
+<Para>
+                The size of the packet in bytes.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>
+        Int32(80877103)
+</Term>
+<ListItem>
+<Para>
+                The SSL request code.  The value is chosen to contain
+                <literal>1234</> in the most significant 16 bits, and <literal>5679</> in the
+                least 16 significant bits.  (To avoid confusion, this code
+                must not be the same as any protocol version number.)
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+
+</Para>
+</ListItem>
+</VarListEntry>
+
 <VarListEntry>
 <Term>
 StartupPacket (F)
@@ -1931,6 +2061,7 @@ StartupPacket (F)
 <ListItem>
 <Para>
                 The optional tty the backend should use for debugging messages.
+               (Currently, this field is unsupported and ignored.)
 </Para>
 </ListItem>
 </VarListEntry>