mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-30 00:04:49 -04:00 
			
		
		
		
	Add description of SSL request protocol. Miscellaneous copy-editing.
This commit is contained in:
		
							parent
							
								
									24451cd47b
								
							
						
					
					
						commit
						e7243dce47
					
				| @ -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 | ||||
| @ -53,19 +53,15 @@ | ||||
|   </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> | ||||
| @ -319,47 +315,26 @@ | ||||
|       <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. | ||||
|         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 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. | ||||
|        </Para> | ||||
| 
 | ||||
|        <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> | ||||
| @ -368,8 +343,7 @@ | ||||
|       <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> | ||||
| @ -411,6 +385,41 @@ | ||||
|     </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 | ||||
| @ -428,10 +437,16 @@ | ||||
|    </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> | ||||
| @ -504,7 +519,7 @@ | ||||
|    <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> | ||||
| @ -514,10 +529,10 @@ | ||||
|    <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> | ||||
| 
 | ||||
| @ -534,8 +549,8 @@ | ||||
|       <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> | ||||
| @ -579,7 +594,7 @@ | ||||
|     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> | ||||
| @ -633,6 +648,61 @@ | ||||
|     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> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user