mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Ensure we discard unread/unsent data when abandoning a connection attempt.
There are assorted situations wherein PQconnectPoll() will abandon a connection attempt and try again with different parameters (eg, SSL versus not SSL). However, the code forgot to discard any pending data in libpq's I/O buffers when doing this. In at least one case (server returns E message during SSL negotiation), there is unread input data which bollixes the next connection attempt. I have not checked to see whether this is possible in the other cases where we close the socket and retry, but it seems like a matter of good defensive programming to add explicit buffer-flushing code to all of them. This is one of several issues exposed by Daniel Farina's report of misbehavior after a server-side fork failure. This has been wrong since forever, so back-patch to all supported branches.
This commit is contained in:
		@@ -2068,6 +2068,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
						closesocket(conn->sock);
 | 
											closesocket(conn->sock);
 | 
				
			||||||
						conn->sock = -1;
 | 
											conn->sock = -1;
 | 
				
			||||||
						conn->status = CONNECTION_NEEDED;
 | 
											conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
											/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
											conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
											conn->outCount = 0;
 | 
				
			||||||
						goto keep_going;
 | 
											goto keep_going;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
@@ -2105,6 +2108,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
						closesocket(conn->sock);
 | 
											closesocket(conn->sock);
 | 
				
			||||||
						conn->sock = -1;
 | 
											conn->sock = -1;
 | 
				
			||||||
						conn->status = CONNECTION_NEEDED;
 | 
											conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
											/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
											conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
											conn->outCount = 0;
 | 
				
			||||||
						goto keep_going;
 | 
											goto keep_going;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -2218,6 +2224,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
						closesocket(conn->sock);
 | 
											closesocket(conn->sock);
 | 
				
			||||||
						conn->sock = -1;
 | 
											conn->sock = -1;
 | 
				
			||||||
						conn->status = CONNECTION_NEEDED;
 | 
											conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
											/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
											conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
											conn->outCount = 0;
 | 
				
			||||||
						goto keep_going;
 | 
											goto keep_going;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2285,6 +2294,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
						closesocket(conn->sock);
 | 
											closesocket(conn->sock);
 | 
				
			||||||
						conn->sock = -1;
 | 
											conn->sock = -1;
 | 
				
			||||||
						conn->status = CONNECTION_NEEDED;
 | 
											conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
											/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
											conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
											conn->outCount = 0;
 | 
				
			||||||
						goto keep_going;
 | 
											goto keep_going;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2304,6 +2316,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
						closesocket(conn->sock);
 | 
											closesocket(conn->sock);
 | 
				
			||||||
						conn->sock = -1;
 | 
											conn->sock = -1;
 | 
				
			||||||
						conn->status = CONNECTION_NEEDED;
 | 
											conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
											/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
											conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
											conn->outCount = 0;
 | 
				
			||||||
						goto keep_going;
 | 
											goto keep_going;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -2467,6 +2482,9 @@ keep_going:						/* We will come back to here until there is
 | 
				
			|||||||
							closesocket(conn->sock);
 | 
												closesocket(conn->sock);
 | 
				
			||||||
							conn->sock = -1;
 | 
												conn->sock = -1;
 | 
				
			||||||
							conn->status = CONNECTION_NEEDED;
 | 
												conn->status = CONNECTION_NEEDED;
 | 
				
			||||||
 | 
												/* Discard any unread/unsent data */
 | 
				
			||||||
 | 
												conn->inStart = conn->inCursor = conn->inEnd = 0;
 | 
				
			||||||
 | 
												conn->outCount = 0;
 | 
				
			||||||
							goto keep_going;
 | 
												goto keep_going;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user