* Read a client's startup packet and do something according to it. * * Returns STATUS_OK or STATUS_ERROR, or might call ereport(FATAL) and * not return at all. * * (Note that ereport(FATAL) stuff is sent to the client, so only use it * if that's what you want. Return STATUS_ERROR if you don't want to * send anything to the client, which would typically be appropriate * if we detect a comm
| 2289 | * requests. |
| 2290 | */ |
| 2291 | static int |
| 2292 | ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) |
| 2293 | { |
| 2294 | int32 len; |
| 2295 | char *buf; |
| 2296 | ProtocolVersion proto; |
| 2297 | MemoryContext oldcontext; |
| 2298 | char *gpqeid = NULL; |
| 2299 | XLogRecPtr recptr; |
| 2300 | |
| 2301 | pq_startmsgread(); |
| 2302 | |
| 2303 | /* |
| 2304 | * Grab the first byte of the length word separately, so that we can tell |
| 2305 | * whether we have no data at all or an incomplete packet. (This might |
| 2306 | * sound inefficient, but it's not really, because of buffering in |
| 2307 | * pqcomm.c.) |
| 2308 | */ |
| 2309 | if (pq_getbytes((char *) &len, 1) == EOF) |
| 2310 | { |
| 2311 | /* |
| 2312 | * If we get no data at all, don't clutter the log with a complaint; |
| 2313 | * such cases often occur for legitimate reasons. An example is that |
| 2314 | * we might be here after responding to NEGOTIATE_SSL_CODE, and if the |
| 2315 | * client didn't like our response, it'll probably just drop the |
| 2316 | * connection. Service-monitoring software also often just opens and |
| 2317 | * closes a connection without sending anything. (So do port |
| 2318 | * scanners, which may be less benign, but it's not really our job to |
| 2319 | * notice those.) |
| 2320 | */ |
| 2321 | return STATUS_ERROR; |
| 2322 | } |
| 2323 | |
| 2324 | if (pq_getbytes(((char *) &len) + 1, 3) == EOF) |
| 2325 | { |
| 2326 | /* Got a partial length word, so bleat about that */ |
| 2327 | if (!ssl_done && !gss_done) |
| 2328 | ereport(COMMERROR, |
| 2329 | (errcode(ERRCODE_PROTOCOL_VIOLATION), |
| 2330 | errmsg("incomplete startup packet"))); |
| 2331 | return STATUS_ERROR; |
| 2332 | } |
| 2333 | |
| 2334 | len = pg_ntoh32(len); |
| 2335 | len -= 4; |
| 2336 | |
| 2337 | if (len < (int32) sizeof(ProtocolVersion) || |
| 2338 | len > MAX_STARTUP_PACKET_LENGTH) |
| 2339 | { |
| 2340 | ereport(COMMERROR, |
| 2341 | (errcode(ERRCODE_PROTOCOL_VIOLATION), |
| 2342 | errmsg("invalid length of startup packet %ld",(long)len))); |
| 2343 | return STATUS_ERROR; |
| 2344 | } |
| 2345 | |
| 2346 | /* |
| 2347 | * Allocate space to hold the startup packet, plus one extra byte that's |
| 2348 | * initialized to be zero. This ensures we will have null termination of |
no test coverage detected