LCOV - differential code coverage report
Current view: top level - src/backend/libpq - pqcomm.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 60.0 % 560 336 1 37 162 24 27 225 26 58 167 236 6 5
Current Date: 2023-04-08 17:13:01 Functions: 89.4 % 47 42 5 34 8 5 42
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 50.0 % 2 1 1 1 1
Legend: Lines: hit not hit (180,240] days: 100.0 % 25 25 25
(240..) days: 58.2 % 533 310 37 162 24 27 225 58 156 223
Function coverage date bins:
(180,240] days: 100.0 % 8 8 8
(240..) days: 42.0 % 81 34 5 34 4 38

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * pqcomm.c
                                  4                 :  *    Communication functions between the Frontend and the Backend
                                  5                 :  *
                                  6                 :  * These routines handle the low-level details of communication between
                                  7                 :  * frontend and backend.  They just shove data across the communication
                                  8                 :  * channel, and are ignorant of the semantics of the data.
                                  9                 :  *
                                 10                 :  * To emit an outgoing message, use the routines in pqformat.c to construct
                                 11                 :  * the message in a buffer and then emit it in one call to pq_putmessage.
                                 12                 :  * There are no functions to send raw bytes or partial messages; this
                                 13                 :  * ensures that the channel will not be clogged by an incomplete message if
                                 14                 :  * execution is aborted by ereport(ERROR) partway through the message.
                                 15                 :  *
                                 16                 :  * At one time, libpq was shared between frontend and backend, but now
                                 17                 :  * the backend's "backend/libpq" is quite separate from "interfaces/libpq".
                                 18                 :  * All that remains is similarities of names to trap the unwary...
                                 19                 :  *
                                 20                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 21                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 22                 :  *
                                 23                 :  *  src/backend/libpq/pqcomm.c
                                 24                 :  *
                                 25                 :  *-------------------------------------------------------------------------
                                 26                 :  */
                                 27                 : 
                                 28                 : /*------------------------
                                 29                 :  * INTERFACE ROUTINES
                                 30                 :  *
                                 31                 :  * setup/teardown:
                                 32                 :  *      StreamServerPort    - Open postmaster's server port
                                 33                 :  *      StreamConnection    - Create new connection with client
                                 34                 :  *      StreamClose         - Close a client/backend connection
                                 35                 :  *      TouchSocketFiles    - Protect socket files against /tmp cleaners
                                 36                 :  *      pq_init         - initialize libpq at backend startup
                                 37                 :  *      socket_comm_reset   - reset libpq during error recovery
                                 38                 :  *      socket_close        - shutdown libpq at backend exit
                                 39                 :  *
                                 40                 :  * low-level I/O:
                                 41                 :  *      pq_getbytes     - get a known number of bytes from connection
                                 42                 :  *      pq_getmessage   - get a message with length word from connection
                                 43                 :  *      pq_getbyte      - get next byte from connection
                                 44                 :  *      pq_peekbyte     - peek at next byte from connection
                                 45                 :  *      pq_flush        - flush pending output
                                 46                 :  *      pq_flush_if_writable - flush pending output if writable without blocking
                                 47                 :  *      pq_getbyte_if_available - get a byte if available without blocking
                                 48                 :  *
                                 49                 :  * message-level I/O
                                 50                 :  *      pq_putmessage   - send a normal message (suppressed in COPY OUT mode)
                                 51                 :  *      pq_putmessage_noblock - buffer a normal message (suppressed in COPY OUT)
                                 52                 :  *
                                 53                 :  *------------------------
                                 54                 :  */
                                 55                 : #include "postgres.h"
                                 56                 : 
                                 57                 : #ifdef HAVE_POLL_H
                                 58                 : #include <poll.h>
                                 59                 : #endif
                                 60                 : #include <signal.h>
                                 61                 : #include <fcntl.h>
                                 62                 : #include <grp.h>
                                 63                 : #include <unistd.h>
                                 64                 : #include <sys/file.h>
                                 65                 : #include <sys/socket.h>
                                 66                 : #include <sys/stat.h>
                                 67                 : #include <sys/time.h>
                                 68                 : #include <netdb.h>
                                 69                 : #include <netinet/in.h>
                                 70                 : #include <netinet/tcp.h>
                                 71                 : #include <utime.h>
                                 72                 : #ifdef WIN32
                                 73                 : #include <mstcpip.h>
                                 74                 : #endif
                                 75                 : 
                                 76                 : #include "common/ip.h"
                                 77                 : #include "libpq/libpq.h"
                                 78                 : #include "miscadmin.h"
                                 79                 : #include "port/pg_bswap.h"
                                 80                 : #include "storage/ipc.h"
                                 81                 : #include "utils/guc_hooks.h"
                                 82                 : #include "utils/memutils.h"
                                 83                 : 
                                 84                 : /*
                                 85                 :  * Cope with the various platform-specific ways to spell TCP keepalive socket
                                 86                 :  * options.  This doesn't cover Windows, which as usual does its own thing.
                                 87                 :  */
                                 88                 : #if defined(TCP_KEEPIDLE)
                                 89                 : /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
                                 90                 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
                                 91                 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
                                 92                 : #elif defined(TCP_KEEPALIVE_THRESHOLD)
                                 93                 : /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
                                 94                 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
                                 95                 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
                                 96                 : #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
                                 97                 : /* TCP_KEEPALIVE is the name of this option on macOS */
                                 98                 : /* Caution: Solaris has this symbol but it means something different */
                                 99                 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
                                100                 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
                                101                 : #endif
                                102                 : 
                                103                 : /*
                                104                 :  * Configuration options
                                105                 :  */
                                106                 : int         Unix_socket_permissions;
                                107                 : char       *Unix_socket_group;
                                108                 : 
                                109                 : /* Where the Unix socket files are (list of palloc'd strings) */
                                110                 : static List *sock_paths = NIL;
                                111                 : 
                                112                 : /*
                                113                 :  * Buffers for low-level I/O.
                                114                 :  *
                                115                 :  * The receive buffer is fixed size. Send buffer is usually 8k, but can be
                                116                 :  * enlarged by pq_putmessage_noblock() if the message doesn't fit otherwise.
                                117                 :  */
                                118                 : 
                                119                 : #define PQ_SEND_BUFFER_SIZE 8192
                                120                 : #define PQ_RECV_BUFFER_SIZE 8192
                                121                 : 
                                122                 : static char *PqSendBuffer;
                                123                 : static int  PqSendBufferSize;   /* Size send buffer */
                                124                 : static int  PqSendPointer;      /* Next index to store a byte in PqSendBuffer */
                                125                 : static int  PqSendStart;        /* Next index to send a byte in PqSendBuffer */
                                126                 : 
                                127                 : static char PqRecvBuffer[PQ_RECV_BUFFER_SIZE];
                                128                 : static int  PqRecvPointer;      /* Next index to read a byte from PqRecvBuffer */
                                129                 : static int  PqRecvLength;       /* End of data available in PqRecvBuffer */
                                130                 : 
                                131                 : /*
                                132                 :  * Message status
                                133                 :  */
                                134                 : static bool PqCommBusy;         /* busy sending data to the client */
                                135                 : static bool PqCommReadingMsg;   /* in the middle of reading a message */
                                136                 : 
                                137                 : 
                                138                 : /* Internal functions */
                                139                 : static void socket_comm_reset(void);
                                140                 : static void socket_close(int code, Datum arg);
                                141                 : static void socket_set_nonblocking(bool nonblocking);
                                142                 : static int  socket_flush(void);
                                143                 : static int  socket_flush_if_writable(void);
                                144                 : static bool socket_is_send_pending(void);
                                145                 : static int  socket_putmessage(char msgtype, const char *s, size_t len);
                                146                 : static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
                                147                 : static int  internal_putbytes(const char *s, size_t len);
                                148                 : static int  internal_flush(void);
                                149                 : 
                                150                 : static int  Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath);
                                151                 : static int  Setup_AF_UNIX(const char *sock_path);
                                152                 : 
                                153                 : static const PQcommMethods PqCommSocketMethods = {
                                154                 :     socket_comm_reset,
                                155                 :     socket_flush,
                                156                 :     socket_flush_if_writable,
                                157                 :     socket_is_send_pending,
                                158                 :     socket_putmessage,
                                159                 :     socket_putmessage_noblock
                                160                 : };
                                161                 : 
                                162                 : const PQcommMethods *PqCommMethods = &PqCommSocketMethods;
                                163                 : 
                                164                 : WaitEventSet *FeBeWaitSet;
                                165                 : 
                                166                 : 
                                167                 : /* --------------------------------
 8750 tgl                       168 ECB             :  *      pq_init - initialize libpq at backend startup
                                169                 :  * --------------------------------
                                170                 :  */
                                171                 : void
 8750 tgl                       172 GIC        8662 : pq_init(void)
                                173                 : {
  697 tgl                       174 ECB             :     int         socket_pos PG_USED_FOR_ASSERTS_ONLY;
                                175                 :     int         latch_pos PG_USED_FOR_ASSERTS_ONLY;
  769 tmunro                    176                 : 
 2807 tgl                       177                 :     /* initialize state variables */
 4393 heikki.linnakangas        178 CBC        8662 :     PqSendBufferSize = PQ_SEND_BUFFER_SIZE;
 4393 heikki.linnakangas        179 GIC        8662 :     PqSendBuffer = MemoryContextAlloc(TopMemoryContext, PqSendBufferSize);
                                180            8662 :     PqSendPointer = PqSendStart = PqRecvPointer = PqRecvLength = 0;
 6769 tgl                       181 CBC        8662 :     PqCommBusy = false;
 2988 heikki.linnakangas        182 GIC        8662 :     PqCommReadingMsg = false;
                                183                 : 
                                184                 :     /* set up process-exit hook to close the socket */
 3082 rhaas                     185            8662 :     on_proc_exit(socket_close, 0);
                                186                 : 
                                187                 :     /*
                                188                 :      * In backends (as soon as forked) we operate the underlying socket in
                                189                 :      * nonblocking mode and use latches to implement blocking semantics if
                                190                 :      * needed. That allows us to provide safely interruptible reads and
                                191                 :      * writes.
                                192                 :      *
                                193                 :      * Use COMMERROR on failure, because ERROR would try to send the error to
 2987 andres                    194 ECB             :      * the client, which might require changing the mode again, leading to
 2987 andres                    195 EUB             :      * infinite recursion.
                                196                 :      */
                                197                 : #ifndef WIN32
 2987 andres                    198 GIC        8662 :     if (!pg_set_noblock(MyProcPort->sock))
 2987 andres                    199 UIC           0 :         ereport(COMMERROR,
                                200                 :                 (errmsg("could not set socket to nonblocking mode: %m")));
                                201                 : #endif
   37 tmunro                    202 ECB             : 
                                203                 : #ifndef WIN32
                                204                 : 
                                205                 :     /* Don't give the socket to any subprograms we execute. */
   37 tmunro                    206 GNC        8662 :     if (fcntl(MyProcPort->sock, F_SETFD, FD_CLOEXEC) < 0)
   37 tmunro                    207 UNC           0 :         elog(FATAL, "fcntl(F_SETFD) failed on socket: %m");
                                208                 : #endif
                                209                 : 
  419 tmunro                    210 GBC        8662 :     FeBeWaitSet = CreateWaitEventSet(TopMemoryContext, FeBeWaitSetNEvents);
  769 tmunro                    211 GIC        8662 :     socket_pos = AddWaitEventToSet(FeBeWaitSet, WL_SOCKET_WRITEABLE,
                                212            8662 :                                    MyProcPort->sock, NULL, NULL);
  769 tmunro                    213 CBC        8662 :     latch_pos = AddWaitEventToSet(FeBeWaitSet, WL_LATCH_SET, PGINVALID_SOCKET,
  769 tmunro                    214 ECB             :                                   MyLatch, NULL);
  769 tmunro                    215 CBC        8662 :     AddWaitEventToSet(FeBeWaitSet, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
 2575 andres                    216 ECB             :                       NULL, NULL);
                                217                 : 
  769 tmunro                    218                 :     /*
                                219                 :      * The event positions match the order we added them, but let's sanity
                                220                 :      * check them to be sure.
                                221                 :      */
  769 tmunro                    222 GIC        8662 :     Assert(socket_pos == FeBeWaitSetSocketPos);
                                223            8662 :     Assert(latch_pos == FeBeWaitSetLatchPos);
 9770 scrappy                   224            8662 : }
 9770 scrappy                   225 ECB             : 
 6769 tgl                       226                 : /* --------------------------------
 3082 rhaas                     227                 :  *      socket_comm_reset - reset libpq during error recovery
                                228                 :  *
                                229                 :  * This is called from error recovery at the outer idle loop.  It's
                                230                 :  * just to get us out of trouble if we somehow manage to elog() from
                                231                 :  * inside a pqcomm.c routine (which ideally will never happen, but...)
                                232                 :  * --------------------------------
                                233                 :  */
                                234                 : static void
 3082 rhaas                     235 GIC       17741 : socket_comm_reset(void)
                                236                 : {
                                237                 :     /* Do not throw away pending data, but do reset the busy flag */
 6769 tgl                       238 CBC       17741 :     PqCommBusy = false;
 6769 tgl                       239 GIC       17741 : }
                                240                 : 
 9770 scrappy                   241 ECB             : /* --------------------------------
 3082 rhaas                     242                 :  *      socket_close - shutdown libpq at backend exit
                                243                 :  *
                                244                 :  * This is the one pg_on_exit_callback in place during BackendInitialize().
                                245                 :  * That function's unusual signal handling constrains that this callback be
                                246                 :  * safe to run at any instant.
                                247                 :  * --------------------------------
                                248                 :  */
                                249                 : static void
 3082 rhaas                     250 GIC        8662 : socket_close(int code, Datum arg)
                                251                 : {
                                252                 :     /* Nothing to do in a standalone backend, where MyProcPort is NULL. */
 8661 tgl                       253 CBC        8662 :     if (MyProcPort != NULL)
                                254                 :     {
                                255                 : #ifdef ENABLE_GSS
 2883 noah                      256 ECB             :         /*
                                257                 :          * Shutdown GSSAPI layer.  This section does nothing when interrupting
                                258                 :          * BackendInitialize(), because pg_GSS_recvauth() makes first use of
                                259                 :          * "ctx" and "cred".
                                260                 :          *
                                261                 :          * Note that we don't bother to free MyProcPort->gss, since we're
                                262                 :          * about to exit anyway.
                                263                 :          */
  832 tgl                       264 GIC        8662 :         if (MyProcPort->gss)
                                265                 :         {
                                266                 :             OM_uint32   min_s;
 5752 magnus                    267 ECB             : 
  832 tgl                       268 GIC          23 :             if (MyProcPort->gss->ctx != GSS_C_NO_CONTEXT)
                                269              21 :                 gss_delete_sec_context(&min_s, &MyProcPort->gss->ctx, NULL);
                                270                 : 
  832 tgl                       271 CBC          23 :             if (MyProcPort->gss->cred != GSS_C_NO_CREDENTIAL)
  832 tgl                       272 LBC           0 :                 gss_release_cred(&min_s, &MyProcPort->gss->cred);
                                273                 :         }
  832 tgl                       274 ECB             : #endif                          /* ENABLE_GSS */
 5752 magnus                    275 EUB             : 
                                276                 :         /*
                                277                 :          * Cleanly shut down SSL layer.  Nowhere else does a postmaster child
                                278                 :          * call this, so this is safe when interrupting BackendInitialize().
                                279                 :          */
 7604 bruce                     280 GIC        8662 :         secure_close(MyProcPort);
                                281                 : 
                                282                 :         /*
  383 tgl                       283 ECB             :          * Formerly we did an explicit close() here, but it seems better to
                                284                 :          * leave the socket open until the process dies.  This allows clients
                                285                 :          * to perform a "synchronous close" if they care --- wait till the
                                286                 :          * transport layer reports connection closure, and you can be sure the
                                287                 :          * backend has exited.
                                288                 :          *
                                289                 :          * We do set sock to PGINVALID_SOCKET to prevent any further I/O,
                                290                 :          * though.
                                291                 :          */
 4837 magnus                    292 GIC        8662 :         MyProcPort->sock = PGINVALID_SOCKET;
                                293                 :     }
 9770 scrappy                   294            8662 : }
 9770 scrappy                   295 ECB             : 
                                296                 : 
                                297                 : 
                                298                 : /*
                                299                 :  * Streams -- wrapper around Unix socket system calls
                                300                 :  *
                                301                 :  *
                                302                 :  *      Stream functions are used for vanilla TCP connection protocol.
                                303                 :  */
                                304                 : 
                                305                 : 
                                306                 : /*
                                307                 :  * StreamServerPort -- open a "listening" port to accept connections.
                                308                 :  *
                                309                 :  * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
                                310                 :  * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
                                311                 :  * specified.  For TCP ports, hostName is either NULL for all interfaces or
                                312                 :  * the interface to listen on, and unixSocketDir is ignored (can be NULL).
                                313                 :  *
                                314                 :  * Successfully opened sockets are added to the ListenSocket[] array (of
                                315                 :  * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
                                316                 :  *
                                317                 :  * RETURNS: STATUS_OK or STATUS_ERROR
                                318                 :  */
                                319                 : 
                                320                 : int
 1164 peter                     321 GIC         624 : StreamServerPort(int family, const char *hostName, unsigned short portNumber,
                                322                 :                  const char *unixSocketDir,
                                323                 :                  pgsocket ListenSocket[], int MaxListen)
 9770 scrappy                   324 ECB             : {
                                325                 :     pgsocket    fd;
                                326                 :     int         err;
                                327                 :     int         maxconn;
                                328                 :     int         ret;
                                329                 :     char        portNumberStr[32];
                                330                 :     const char *familyDesc;
                                331                 :     char        familyDescBuf[64];
                                332                 :     const char *addrDesc;
                                333                 :     char        addrBuf[NI_MAXHOST];
                                334                 :     char       *service;
 7188 bruce                     335 GIC         624 :     struct addrinfo *addrs = NULL,
                                336                 :                *addr;
                                337                 :     struct addrinfo hint;
 7241 bruce                     338 CBC         624 :     int         listen_index = 0;
 7241 bruce                     339 GIC         624 :     int         added = 0;
 3894 tgl                       340 ECB             :     char        unixSocketPath[MAXPGPATH];
                                341                 : #if !defined(WIN32) || defined(IPV6_V6ONLY)
 5738 magnus                    342 CBC         624 :     int         one = 1;
                                343                 : #endif
                                344                 : 
                                345                 :     /* Initialize hint structure */
 7398 bruce                     346            4368 :     MemSet(&hint, 0, sizeof(hint));
                                347             624 :     hint.ai_family = family;
 7200 tgl                       348             624 :     hint.ai_flags = AI_PASSIVE;
 7398 bruce                     349             624 :     hint.ai_socktype = SOCK_STREAM;
                                350                 : 
 7429 bruce                     351 GIC         624 :     if (family == AF_UNIX)
                                352                 :     {
                                353                 :         /*
                                354                 :          * Create unixSocketPath from portNumber and unixSocketDir and lock
                                355                 :          * that file path
 3894 tgl                       356 ECB             :          */
 3894 tgl                       357 CBC         590 :         UNIXSOCK_PATH(unixSocketPath, portNumber, unixSocketDir);
 3783 tgl                       358 GIC         590 :         if (strlen(unixSocketPath) >= UNIXSOCK_PATH_BUFLEN)
 3783 tgl                       359 EUB             :         {
 3783 tgl                       360 UIC           0 :             ereport(LOG,
                                361                 :                     (errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
                                362                 :                             unixSocketPath,
 3783 tgl                       363 EUB             :                             (int) (UNIXSOCK_PATH_BUFLEN - 1))));
 3783 tgl                       364 UIC           0 :             return STATUS_ERROR;
 3783 tgl                       365 ECB             :         }
 3894 tgl                       366 GBC         590 :         if (Lock_AF_UNIX(unixSocketDir, unixSocketPath) != STATUS_OK)
 7398 bruce                     367 LBC           0 :             return STATUS_ERROR;
 3894 tgl                       368 GIC         590 :         service = unixSocketPath;
                                369                 :     }
                                370                 :     else
 7398 bruce                     371 ECB             :     {
 7398 bruce                     372 GIC          34 :         snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
                                373              34 :         service = portNumberStr;
 7398 bruce                     374 ECB             :     }
 7289                           375                 : 
 6383 tgl                       376 GIC         624 :     ret = pg_getaddrinfo_all(hostName, service, &hint, &addrs);
 7200 tgl                       377 GBC         624 :     if (ret || !addrs)
 7398 bruce                     378 EUB             :     {
 7200 tgl                       379 UIC           0 :         if (hostName)
                                380               0 :             ereport(LOG,
                                381                 :                     (errmsg("could not translate host name \"%s\", service \"%s\" to address: %s",
 7200 tgl                       382 EUB             :                             hostName, service, gai_strerror(ret))));
                                383                 :         else
 7200 tgl                       384 UIC           0 :             ereport(LOG,
 2118 tgl                       385 EUB             :                     (errmsg("could not translate service \"%s\" to address: %s",
                                386                 :                             service, gai_strerror(ret))));
 6892 bruce                     387 UBC           0 :         if (addrs)
 6383 tgl                       388 UIC           0 :             pg_freeaddrinfo_all(hint.ai_family, addrs);
 7398 bruce                     389               0 :         return STATUS_ERROR;
 7398 bruce                     390 ECB             :     }
                                391                 : 
 7241 bruce                     392 CBC        1248 :     for (addr = addrs; addr; addr = addr->ai_next)
                                393                 :     {
  418 peter                     394 GIC         624 :         if (family != AF_UNIX && addr->ai_family == AF_UNIX)
                                395                 :         {
                                396                 :             /*
                                397                 :              * Only set up a unix domain socket when they really asked for it.
 6385 bruce                     398 EUB             :              * The service/port is different in that case.
                                399                 :              */
 7241 bruce                     400 UIC           0 :             continue;
                                401                 :         }
 7429 bruce                     402 ECB             : 
                                403                 :         /* See if there is still room to add 1 more socket. */
 7241 bruce                     404 CBC         655 :         for (; listen_index < MaxListen; listen_index++)
 7241 bruce                     405 ECB             :         {
 4837 magnus                    406 GIC         655 :             if (ListenSocket[listen_index] == PGINVALID_SOCKET)
 7241 bruce                     407 CBC         624 :                 break;
                                408                 :         }
 7200 tgl                       409 GBC         624 :         if (listen_index >= MaxListen)
                                410                 :         {
 6661 tgl                       411 UIC           0 :             ereport(LOG,
 6661 tgl                       412 EUB             :                     (errmsg("could not bind to all requested addresses: MAXLISTEN (%d) exceeded",
                                413                 :                             MaxListen)));
 7241 bruce                     414 UIC           0 :             break;
                                415                 :         }
 7200 tgl                       416 ECB             : 
                                417                 :         /* set up address family name for log messages */
 7180 tgl                       418 CBC         624 :         switch (addr->ai_family)
 7180 tgl                       419 ECB             :         {
 7180 tgl                       420 CBC          34 :             case AF_INET:
 6620 bruce                     421 GBC          34 :                 familyDesc = _("IPv4");
 7180 tgl                       422              34 :                 break;
 7180 tgl                       423 LBC           0 :             case AF_INET6:
 6620 bruce                     424               0 :                 familyDesc = _("IPv6");
 7180 tgl                       425               0 :                 break;
 7180 tgl                       426 GBC         590 :             case AF_UNIX:
 6620 bruce                     427 GIC         590 :                 familyDesc = _("Unix");
 7180 tgl                       428 GBC         590 :                 break;
 7180 tgl                       429 UIC           0 :             default:
                                430               0 :                 snprintf(familyDescBuf, sizeof(familyDescBuf),
 6620 bruce                     431               0 :                          _("unrecognized address family %d"),
 7180 tgl                       432 ECB             :                          addr->ai_family);
 7180 tgl                       433 LBC           0 :                 familyDesc = familyDescBuf;
 7180 tgl                       434 UIC           0 :                 break;
                                435                 :         }
 7180 tgl                       436 ECB             : 
 2221                           437                 :         /* set up text form of address for log messages */
 2221 tgl                       438 GIC         624 :         if (addr->ai_family == AF_UNIX)
                                439             590 :             addrDesc = unixSocketPath;
 2221 tgl                       440 ECB             :         else
                                441                 :         {
 2221 tgl                       442 CBC          34 :             pg_getnameinfo_all((const struct sockaddr_storage *) addr->ai_addr,
 2221 tgl                       443 GIC          34 :                                addr->ai_addrlen,
 2221 tgl                       444 EUB             :                                addrBuf, sizeof(addrBuf),
                                445                 :                                NULL, 0,
                                446                 :                                NI_NUMERICHOST);
 2221 tgl                       447 GIC          34 :             addrDesc = addrBuf;
                                448                 :         }
 2221 tgl                       449 EUB             : 
 3280 bruce                     450 GIC         624 :         if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
                                451                 :         {
 7201 tgl                       452 UIC           0 :             ereport(LOG,
                                453                 :                     (errcode_for_socket_access(),
                                454                 :             /* translator: first %s is IPv4, IPv6, or Unix */
                                455                 :                      errmsg("could not create %s socket for address \"%s\": %m",
                                456                 :                             familyDesc, addrDesc)));
 7241 bruce                     457               0 :             continue;
                                458                 :         }
                                459                 : 
                                460                 : #ifndef WIN32
                                461                 : 
                                462                 :         /*
                                463                 :          * Without the SO_REUSEADDR flag, a new postmaster can't be started
                                464                 :          * right away after a stop or crash, giving "address already in use"
 5624 bruce                     465 ECB             :          * error on TCP ports.
                                466                 :          *
                                467                 :          * On win32, however, this behavior only happens if the
                                468                 :          * SO_EXCLUSIVEADDRUSE is set. With SO_REUSEADDR, win32 allows
                                469                 :          * multiple servers to listen on the same address, resulting in
 1335 michael                   470 EUB             :          * unpredictable behavior. With no flags at all, win32 behaves as Unix
                                471                 :          * with SO_REUSEADDR.
                                472                 :          */
  418 peter                     473 GIC         624 :         if (addr->ai_family != AF_UNIX)
                                474                 :         {
 7241 bruce                     475              34 :             if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
 7188 bruce                     476 EUB             :                             (char *) &one, sizeof(one))) == -1)
 7241                           477                 :             {
 7201 tgl                       478 UIC           0 :                 ereport(LOG,
                                479                 :                         (errcode_for_socket_access(),
                                480                 :                 /* translator: third %s is IPv4, IPv6, or Unix */
                                481                 :                          errmsg("%s(%s) failed for %s address \"%s\": %m",
                                482                 :                                 "setsockopt", "SO_REUSEADDR",
 2221 tgl                       483 ECB             :                                 familyDesc, addrDesc)));
 7241 bruce                     484 UIC           0 :                 closesocket(fd);
 7241 bruce                     485 UBC           0 :                 continue;
                                486                 :             }
                                487                 :         }
 5788 magnus                    488 EUB             : #endif
                                489                 : 
                                490                 : #ifdef IPV6_V6ONLY
 7241 bruce                     491 GIC         624 :         if (addr->ai_family == AF_INET6)
                                492                 :         {
 7241 bruce                     493 UIC           0 :             if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
 7188 bruce                     494 EUB             :                            (char *) &one, sizeof(one)) == -1)
 7241                           495                 :             {
 7201 tgl                       496 UIC           0 :                 ereport(LOG,
                                497                 :                         (errcode_for_socket_access(),
                                498                 :                 /* translator: third %s is IPv4, IPv6, or Unix */
                                499                 :                          errmsg("%s(%s) failed for %s address \"%s\": %m",
                                500                 :                                 "setsockopt", "IPV6_V6ONLY",
                                501                 :                                 familyDesc, addrDesc)));
 7241 bruce                     502               0 :                 closesocket(fd);
                                503               0 :                 continue;
                                504                 :             }
                                505                 :         }
 7241 bruce                     506 ECB             : #endif
                                507                 : 
 7241 bruce                     508 EUB             :         /*
 7188                           509                 :          * Note: This might fail on some OS's, like Linux older than
                                510                 :          * 2.4.21-pre3, that don't have the IPV6_V6ONLY socket option, and map
 3260                           511                 :          * ipv4 addresses to ipv6.  It will show ::ffff:ipv4 for all ipv4
                                512                 :          * connections.
                                513                 :          */
 7241 bruce                     514 GIC         624 :         err = bind(fd, addr->ai_addr, addr->ai_addrlen);
                                515             624 :         if (err < 0)
 7241 bruce                     516 UIC           0 :         {
  865 peter                     517               0 :             int         saved_errno = errno;
                                518                 : 
 7201 tgl                       519               0 :             ereport(LOG,
                                520                 :                     (errcode_for_socket_access(),
                                521                 :             /* translator: first %s is IPv4, IPv6, or Unix */
                                522                 :                      errmsg("could not bind %s address \"%s\": %m",
 2221 tgl                       523 EUB             :                             familyDesc, addrDesc),
  865 peter                     524                 :                      saved_errno == EADDRINUSE ?
                                525                 :                      (addr->ai_family == AF_UNIX ?
                                526                 :                       errhint("Is another postmaster already running on port %d?",
  865 peter                     527 ECB             :                               (int) portNumber) :
                                528                 :                       errhint("Is another postmaster already running on port %d?"
                                529                 :                               " If not, wait a few seconds and retry.",
                                530                 :                               (int) portNumber)) : 0));
 7241 bruce                     531 UBC           0 :             closesocket(fd);
                                532               0 :             continue;
                                533                 :         }
                                534                 : 
 7241 bruce                     535 GIC         624 :         if (addr->ai_family == AF_UNIX)
                                536                 :         {
 3894 tgl                       537             590 :             if (Setup_AF_UNIX(service) != STATUS_OK)
                                538                 :             {
 7241 bruce                     539 UIC           0 :                 closesocket(fd);
 7241 bruce                     540 LBC           0 :                 break;
                                541                 :             }
 7429 bruce                     542 ECB             :         }
                                543                 : 
 7241 bruce                     544 EUB             :         /*
                                545                 :          * Select appropriate accept-queue length limit.  It seems reasonable
                                546                 :          * to use a value similar to the maximum number of child processes
                                547                 :          * that the postmaster will permit.
                                548                 :          */
  229 tgl                       549 GNC         624 :         maxconn = MaxConnections * 2;
                                550                 : 
 7241 bruce                     551 CBC         624 :         err = listen(fd, maxconn);
                                552             624 :         if (err < 0)
                                553                 :         {
 7201 tgl                       554 UIC           0 :             ereport(LOG,
                                555                 :                     (errcode_for_socket_access(),
 2221 tgl                       556 ECB             :             /* translator: first %s is IPv4, IPv6, or Unix */
                                557                 :                      errmsg("could not listen on %s address \"%s\": %m",
                                558                 :                             familyDesc, addrDesc)));
 7241 bruce                     559 UIC           0 :             closesocket(fd);
                                560               0 :             continue;
 7241 bruce                     561 ECB             :         }
 2221 tgl                       562                 : 
 2217 tgl                       563 GIC         624 :         if (addr->ai_family == AF_UNIX)
 2217 tgl                       564 CBC         590 :             ereport(LOG,
                                565                 :                     (errmsg("listening on Unix socket \"%s\"",
 2217 tgl                       566 ECB             :                             addrDesc)));
 2217 tgl                       567 EUB             :         else
 2217 tgl                       568 CBC          34 :             ereport(LOG,
                                569                 :             /* translator: first %s is IPv4 or IPv6 */
                                570                 :                     (errmsg("listening on %s address \"%s\", port %d",
                                571                 :                             familyDesc, addrDesc, (int) portNumber)));
                                572                 : 
 7241 bruce                     573 GIC         624 :         ListenSocket[listen_index] = fd;
                                574             624 :         added++;
                                575                 :     }
 7942 tgl                       576 ECB             : 
 6383 tgl                       577 GIC         624 :     pg_freeaddrinfo_all(hint.ai_family, addrs);
                                578                 : 
 7241 bruce                     579 CBC         624 :     if (!added)
 7429 bruce                     580 UBC           0 :         return STATUS_ERROR;
                                581                 : 
 7398 bruce                     582 GIC         624 :     return STATUS_OK;
                                583                 : }
                                584                 : 
                                585                 : 
                                586                 : /*
                                587                 :  * Lock_AF_UNIX -- configure unix socket file path
 7398 bruce                     588 ECB             :  */
                                589                 : static int
 1164 peter                     590 GIC         590 : Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath)
                                591                 : {
                                592                 :     /* no lock file for abstract sockets */
  865                           593             590 :     if (unixSocketPath[0] == '@')
  865 peter                     594 LBC           0 :         return STATUS_OK;
                                595                 : 
                                596                 :     /*
                                597                 :      * Grab an interlock file associated with the socket file.
                                598                 :      *
 4609 tgl                       599 ECB             :      * Note: there are two reasons for using a socket lock file, rather than
                                600                 :      * trying to interlock directly on the socket itself.  First, it's a lot
                                601                 :      * more portable, and second, it lets us remove any pre-existing socket
                                602                 :      * file without race conditions.
                                603                 :      */
 3894 tgl                       604 GIC         590 :     CreateSocketLockFile(unixSocketPath, true, unixSocketDir);
                                605                 : 
                                606                 :     /*
                                607                 :      * Once we have the interlock, we can safely delete any pre-existing
                                608                 :      * socket file to avoid failure at bind() time.
 7398 bruce                     609 ECB             :      */
 2807 tgl                       610 GIC         590 :     (void) unlink(unixSocketPath);
                                611                 : 
 3894 tgl                       612 ECB             :     /*
 2807 tgl                       613 EUB             :      * Remember socket file pathnames for later maintenance.
                                614                 :      */
 3894 tgl                       615 GIC         590 :     sock_paths = lappend(sock_paths, pstrdup(unixSocketPath));
                                616                 : 
 7398 bruce                     617             590 :     return STATUS_OK;
                                618                 : }
                                619                 : 
 7398 bruce                     620 ECB             : 
                                621                 : /*
                                622                 :  * Setup_AF_UNIX -- configure unix socket permissions
                                623                 :  */
                                624                 : static int
 1164 peter                     625 GIC         590 : Setup_AF_UNIX(const char *sock_path)
                                626                 : {
                                627                 :     /* no file system permissions for abstract sockets */
  865                           628             590 :     if (sock_path[0] == '@')
  865 peter                     629 UIC           0 :         return STATUS_OK;
  865 peter                     630 EUB             : 
 7398 bruce                     631                 :     /*
                                632                 :      * Fix socket ownership/permission if requested.  Note we must do this
 6385                           633                 :      * before we listen() to avoid a window where unwanted connections could
                                634                 :      * get accepted.
                                635                 :      */
 7398 bruce                     636 GIC         590 :     Assert(Unix_socket_group);
                                637             590 :     if (Unix_socket_group[0] != '\0')
                                638                 :     {
 7269 bruce                     639 EUB             : #ifdef WIN32
 7201 tgl                       640                 :         elog(WARNING, "configuration item unix_socket_group is not supported on this platform");
                                641                 : #else
 7398 bruce                     642                 :         char       *endptr;
                                643                 :         unsigned long val;
                                644                 :         gid_t       gid;
                                645                 : 
 7398 bruce                     646 UIC           0 :         val = strtoul(Unix_socket_group, &endptr, 10);
 7398 bruce                     647 UBC           0 :         if (*endptr == '\0')
                                648                 :         {                       /* numeric group id */
                                649               0 :             gid = val;
                                650                 :         }
 7398 bruce                     651 EUB             :         else
                                652                 :         {                       /* convert group name to id */
                                653                 :             struct group *gr;
                                654                 : 
 7398 bruce                     655 UBC           0 :             gr = getgrnam(Unix_socket_group);
 7398 bruce                     656 UIC           0 :             if (!gr)
                                657                 :             {
 7201 tgl                       658               0 :                 ereport(LOG,
                                659                 :                         (errmsg("group \"%s\" does not exist",
 7201 tgl                       660 ECB             :                                 Unix_socket_group)));
 7398 bruce                     661 UIC           0 :                 return STATUS_ERROR;
 7398 bruce                     662 EUB             :             }
 7398 bruce                     663 UIC           0 :             gid = gr->gr_gid;
                                664                 :         }
                                665               0 :         if (chown(sock_path, -1, gid) == -1)
 7398 bruce                     666 EUB             :         {
 7201 tgl                       667 UIC           0 :             ereport(LOG,
 7201 tgl                       668 ECB             :                     (errcode_for_file_access(),
                                669                 :                      errmsg("could not set group of file \"%s\": %m",
                                670                 :                             sock_path)));
 7398 bruce                     671 UIC           0 :             return STATUS_ERROR;
                                672                 :         }
                                673                 : #endif
                                674                 :     }
                                675                 : 
 7398 bruce                     676 GIC         590 :     if (chmod(sock_path, Unix_socket_permissions) == -1)
                                677                 :     {
 7201 tgl                       678 UIC           0 :         ereport(LOG,
                                679                 :                 (errcode_for_file_access(),
                                680                 :                  errmsg("could not set permissions of file \"%s\": %m",
                                681                 :                         sock_path)));
 7398 bruce                     682 LBC           0 :         return STATUS_ERROR;
                                683                 :     }
 7429 bruce                     684 GIC         590 :     return STATUS_OK;
 9770 scrappy                   685 ECB             : }
 7398 bruce                     686                 : 
                                687                 : 
                                688                 : /*
 9770 scrappy                   689 EUB             :  * StreamConnection -- create a new connection with client using
                                690                 :  *      server port.  Set port->sock to the FD of the new connection.
                                691                 :  *
                                692                 :  * ASSUME: that this doesn't need to be non-blocking because
                                693                 :  *      the Postmaster waits for the socket to be ready to accept().
                                694                 :  *
                                695                 :  * RETURNS: STATUS_OK or STATUS_ERROR
                                696                 :  */
                                697                 : int
 4837 magnus                    698 GIC        8835 : StreamConnection(pgsocket server_fd, Port *port)
 9770 scrappy                   699 EUB             : {
 7201 tgl                       700                 :     /* accept connection and fill in the client (remote) address */
 7241 bruce                     701 GIC        8835 :     port->raddr.salen = sizeof(port->raddr.addr);
 9345                           702            8835 :     if ((port->sock = accept(server_fd,
 2118 tgl                       703            8835 :                              (struct sockaddr *) &port->raddr.addr,
 3280 bruce                     704 ECB             :                              &port->raddr.salen)) == PGINVALID_SOCKET)
 9345                           705                 :     {
 7201 tgl                       706 LBC           0 :         ereport(LOG,
                                707                 :                 (errcode_for_socket_access(),
                                708                 :                  errmsg("could not accept new connection: %m")));
 5624 bruce                     709 EUB             : 
                                710                 :         /*
 5899 tgl                       711                 :          * If accept() fails then postmaster.c will still see the server
                                712                 :          * socket as read-ready, and will immediately try again.  To avoid
                                713                 :          * uselessly sucking lots of CPU, delay a bit before trying again.
                                714                 :          * (The most likely reason for failure is being out of kernel file
 5899 tgl                       715 ECB             :          * table slots; we can do little except hope some will get freed up.)
                                716                 :          */
 5899 tgl                       717 UIC           0 :         pg_usleep(100000L);     /* wait 0.1 sec */
 8986 bruce                     718               0 :         return STATUS_ERROR;
                                719                 :     }
                                720                 : 
                                721                 :     /* fill in the server (local) address */
 7241 bruce                     722 GIC        8835 :     port->laddr.salen = sizeof(port->laddr.addr);
 7201 tgl                       723            8835 :     if (getsockname(port->sock,
 2118                           724            8835 :                     (struct sockaddr *) &port->laddr.addr,
 7241 bruce                     725 ECB             :                     &port->laddr.salen) < 0)
 9345                           726                 :     {
  856 peter                     727 UIC           0 :         ereport(LOG,
                                728                 :                 (errmsg("%s() failed: %m", "getsockname")));
 8986 bruce                     729 UBC           0 :         return STATUS_ERROR;
                                730                 :     }
 8848 tgl                       731 EUB             : 
                                732                 :     /* select NODELAY and KEEPALIVE options if it's a TCP connection */
  418 peter                     733 GIC        8835 :     if (port->laddr.addr.ss_family != AF_UNIX)
 9345 bruce                     734 ECB             :     {
 7201 tgl                       735                 :         int         on;
                                736                 : #ifdef WIN32
                                737                 :         int         oldopt;
 2834 heikki.linnakangas        738 EUB             :         int         optlen;
                                739                 :         int         newopt;
                                740                 : #endif
                                741                 : 
                                742                 : #ifdef  TCP_NODELAY
 7201 tgl                       743 GIC         200 :         on = 1;
 8358                           744             200 :         if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY,
                                745                 :                        (char *) &on, sizeof(on)) < 0)
                                746                 :         {
  856 peter                     747 UIC           0 :             ereport(LOG,
                                748                 :                     (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_NODELAY")));
 8359 ishii                     749               0 :             return STATUS_ERROR;
                                750                 :         }
                                751                 : #endif
 7201 tgl                       752 GIC         200 :         on = 1;
 8359 ishii                     753             200 :         if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE,
                                754                 :                        (char *) &on, sizeof(on)) < 0)
                                755                 :         {
  856 peter                     756 UIC           0 :             ereport(LOG,
                                757                 :                     (errmsg("%s(%s) failed: %m", "setsockopt", "SO_KEEPALIVE")));
 8986 bruce                     758               0 :             return STATUS_ERROR;
                                759                 :         }
                                760                 : 
                                761                 : #ifdef WIN32
                                762                 : 
                                763                 :         /*
                                764                 :          * This is a Win32 socket optimization.  The OS send buffer should be
                                765                 :          * large enough to send the whole Postgres send buffer in one go, or
                                766                 :          * performance suffers.  The Postgres send buffer can be enlarged if a
                                767                 :          * very large message needs to be sent, but we won't attempt to
                                768                 :          * enlarge the OS buffer if that happens, so somewhat arbitrarily
                                769                 :          * ensure that the OS buffer is at least PQ_SEND_BUFFER_SIZE * 4.
                                770                 :          * (That's 32kB with the current default).
                                771                 :          *
                                772                 :          * The default OS buffer size used to be 8kB in earlier Windows
                                773                 :          * versions, but was raised to 64kB in Windows 2012.  So it shouldn't
                                774                 :          * be necessary to change it in later versions anymore.  Changing it
                                775                 :          * unnecessarily can even reduce performance, because setting
                                776                 :          * SO_SNDBUF in the application disables the "dynamic send buffering"
                                777                 :          * feature that was introduced in Windows 7.  So before fiddling with
                                778                 :          * SO_SNDBUF, check if the current buffer size is already large enough
                                779                 :          * and only increase it if necessary.
                                780                 :          *
                                781                 :          * See https://support.microsoft.com/kb/823764/EN-US/ and
                                782                 :          * https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
                                783                 :          */
                                784                 :         optlen = sizeof(oldopt);
                                785                 :         if (getsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt,
                                786                 :                        &optlen) < 0)
                                787                 :         {
                                788                 :             ereport(LOG,
                                789                 :                     (errmsg("%s(%s) failed: %m", "getsockopt", "SO_SNDBUF")));
                                790                 :             return STATUS_ERROR;
                                791                 :         }
                                792                 :         newopt = PQ_SEND_BUFFER_SIZE * 4;
                                793                 :         if (oldopt < newopt)
 2834 heikki.linnakangas        794 ECB             :         {
                                795                 :             if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt,
                                796                 :                            sizeof(newopt)) < 0)
                                797                 :             {
                                798                 :                 ereport(LOG,
                                799                 :                         (errmsg("%s(%s) failed: %m", "setsockopt", "SO_SNDBUF")));
                                800                 :                 return STATUS_ERROR;
                                801                 :             }
                                802                 :         }
                                803                 : #endif
                                804                 : 
                                805                 :         /*
                                806                 :          * Also apply the current keepalive parameters.  If we fail to set a
                                807                 :          * parameter, don't error out, because these aren't universally
                                808                 :          * supported.  (Note: you might think we need to reset the GUC
                                809                 :          * variables to 0 in such a case, but it's not necessary because the
                                810                 :          * show hooks for these variables report the truth anyway.)
                                811                 :          */
 6418 tgl                       812 GIC         200 :         (void) pq_setkeepalivesidle(tcp_keepalives_idle, port);
                                813             200 :         (void) pq_setkeepalivesinterval(tcp_keepalives_interval, port);
 6418 tgl                       814 CBC         200 :         (void) pq_setkeepalivescount(tcp_keepalives_count, port);
 1464 michael                   815 GIC         200 :         (void) pq_settcpusertimeout(tcp_user_timeout, port);
 9489 vadim4o                   816 ECB             :     }
 9345 bruce                     817                 : 
 8986 bruce                     818 GIC        8835 :     return STATUS_OK;
                                819                 : }
                                820                 : 
                                821                 : /*
                                822                 :  * StreamClose -- close a client/backend connection
                                823                 :  *
                                824                 :  * NOTE: this is NOT used to terminate a session; it is just used to release
                                825                 :  * the file descriptor in a process that should no longer have the socket
                                826                 :  * open.  (For example, the postmaster calls this after passing ownership
                                827                 :  * of the connection to a child process.)  It is expected that someone else
                                828                 :  * still has the socket open.  So, we only want to close the descriptor,
 7255 tgl                       829 EUB             :  * we do NOT want to send anything to the far end.
                                830                 :  */
                                831                 : void
 4837 magnus                    832 GIC       22543 : StreamClose(pgsocket sock)
                                833                 : {
 7289 bruce                     834 GBC       22543 :     closesocket(sock);
 9770 scrappy                   835 GIC       22543 : }
 9770 scrappy                   836 EUB             : 
                                837                 : /*
                                838                 :  * TouchSocketFiles -- mark socket files as recently accessed
 7379 tgl                       839                 :  *
                                840                 :  * This routine should be called every so often to ensure that the socket
 3894                           841                 :  * files have a recent mod date (ordinary operations on sockets usually won't
                                842                 :  * change the mod date).  That saves them from being removed by
                                843                 :  * overenthusiastic /tmp-directory-cleaner daemons.  (Another reason we should
                                844                 :  * never have put the socket file in /tmp...)
                                845                 :  */
                                846                 : void
 3894 tgl                       847 LBC           0 : TouchSocketFiles(void)
                                848                 : {
                                849                 :     ListCell   *l;
                                850                 : 
                                851                 :     /* Loop through all created sockets... */
                                852               0 :     foreach(l, sock_paths)
                                853                 :     {
                                854               0 :         char       *sock_path = (char *) lfirst(l);
                                855                 : 
                                856                 :         /* Ignore errors; there's no point in complaining */
 1143                           857               0 :         (void) utime(sock_path, NULL);
                                858                 :     }
 7379 tgl                       859 UIC           0 : }
 7379 tgl                       860 ECB             : 
 2807                           861                 : /*
                                862                 :  * RemoveSocketFiles -- unlink socket files at postmaster shutdown
                                863                 :  */
                                864                 : void
 2807 tgl                       865 GIC         593 : RemoveSocketFiles(void)
                                866                 : {
                                867                 :     ListCell   *l;
                                868                 : 
                                869                 :     /* Loop through all created sockets... */
                                870            1183 :     foreach(l, sock_paths)
                                871                 :     {
                                872             590 :         char       *sock_path = (char *) lfirst(l);
                                873                 : 
                                874                 :         /* Ignore any error. */
                                875             590 :         (void) unlink(sock_path);
                                876                 :     }
                                877                 :     /* Since we're about to exit, no need to reclaim storage */
                                878             593 :     sock_paths = NIL;
                                879             593 : }
 2807 tgl                       880 ECB             : 
                                881                 : 
 8750                           882                 : /* --------------------------------
 8750 tgl                       883 EUB             :  * Low-level I/O routines begin here.
                                884                 :  *
                                885                 :  * These routines communicate with a frontend client across a connection
                                886                 :  * already established by the preceding routines.
 8750 tgl                       887 ECB             :  * --------------------------------
                                888                 :  */
                                889                 : 
                                890                 : /* --------------------------------
                                891                 :  *            socket_set_nonblocking - set socket blocking/non-blocking
                                892                 :  *
                                893                 :  * Sets the socket non-blocking if nonblocking is true, or sets it
                                894                 :  * blocking otherwise.
                                895                 :  * --------------------------------
                                896                 :  */
 4393 heikki.linnakangas        897                 : static void
 3082 rhaas                     898 GIC     2193246 : socket_set_nonblocking(bool nonblocking)
 4393 heikki.linnakangas        899 ECB             : {
 3082 rhaas                     900 GIC     2193246 :     if (MyProcPort == NULL)
 3082 rhaas                     901 LBC           0 :         ereport(ERROR,
                                902                 :                 (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
                                903                 :                  errmsg("there is no client connection")));
 3082 rhaas                     904 EUB             : 
 4393 heikki.linnakangas        905 GBC     2193246 :     MyProcPort->noblock = nonblocking;
                                906         2193246 : }
 8750 tgl                       907 EUB             : 
                                908                 : /* --------------------------------
                                909                 :  *      pq_recvbuf - load some bytes into the input buffer
 8750 tgl                       910 ECB             :  *
                                911                 :  *      returns 0 if OK, EOF if trouble
                                912                 :  * --------------------------------
                                913                 :  */
                                914                 : static int
 8750 tgl                       915 GIC      297406 : pq_recvbuf(void)
                                916                 : {
                                917          297406 :     if (PqRecvPointer > 0)
 8750 tgl                       918 EUB             :     {
 8750 tgl                       919 GIC      288744 :         if (PqRecvLength > PqRecvPointer)
                                920                 :         {
 8750 tgl                       921 ECB             :             /* still some unread data, left-justify it in the buffer */
 8720 bruce                     922 LBC           0 :             memmove(PqRecvBuffer, PqRecvBuffer + PqRecvPointer,
 8720 bruce                     923 UIC           0 :                     PqRecvLength - PqRecvPointer);
 8750 tgl                       924 LBC           0 :             PqRecvLength -= PqRecvPointer;
 8750 tgl                       925 UIC           0 :             PqRecvPointer = 0;
 8750 tgl                       926 ECB             :         }
 8750 tgl                       927 EUB             :         else
 8750 tgl                       928 GIC      288744 :             PqRecvLength = PqRecvPointer = 0;
                                929                 :     }
                                930                 : 
                                931                 :     /* Ensure that we're in blocking mode */
 3082 rhaas                     932          297406 :     socket_set_nonblocking(false);
                                933                 : 
 8750 tgl                       934 ECB             :     /* Can fill buffer from PqRecvLength and upwards */
                                935                 :     for (;;)
 8750 tgl                       936 UIC           0 :     {
 8595 bruce                     937 ECB             :         int         r;
                                938                 : 
 7604 bruce                     939 CBC      594776 :         r = secure_read(MyProcPort, PqRecvBuffer + PqRecvLength,
 4393 heikki.linnakangas        940 GIC      297406 :                         PQ_RECV_BUFFER_SIZE - PqRecvLength);
                                941                 : 
 8750 tgl                       942          297370 :         if (r < 0)
                                943                 :         {
                                944               1 :             if (errno == EINTR)
 8750 tgl                       945 LBC           0 :                 continue;       /* Ok if interrupted */
                                946                 : 
                                947                 :             /*
 6385 bruce                     948 ECB             :              * Careful: an ereport() that tries to write to the client would
                                949                 :              * cause recursion to here, leading to stack overflow and core
                                950                 :              * dump!  This message must go *only* to the postmaster log.
                                951                 :              */
 7201 tgl                       952 GIC           1 :             ereport(COMMERROR,
                                953                 :                     (errcode_for_socket_access(),
                                954                 :                      errmsg("could not receive data from client: %m")));
 8750                           955               1 :             return EOF;
                                956                 :         }
                                957          297369 :         if (r == 0)
 8750 tgl                       958 ECB             :         {
                                959                 :             /*
 6385 bruce                     960                 :              * EOF detected.  We used to write a log message here, but it's
                                961                 :              * better to expect the ultimate caller to do that.
 7295 tgl                       962                 :              */
 8750 tgl                       963 GIC          62 :             return EOF;
 8750 tgl                       964 ECB             :         }
                                965                 :         /* r contains number of bytes read, so just incr length */
 8750 tgl                       966 GIC      297307 :         PqRecvLength += r;
 8750 tgl                       967 CBC      297307 :         return 0;
                                968                 :     }
                                969                 : }
                                970                 : 
                                971                 : /* --------------------------------
                                972                 :  *      pq_getbyte  - get a single byte from connection, or return EOF
                                973                 :  * --------------------------------
                                974                 :  */
                                975                 : int
 8750 tgl                       976 GIC      486559 : pq_getbyte(void)
 8750 tgl                       977 EUB             : {
 2988 heikki.linnakangas        978 GIC      486559 :     Assert(PqCommReadingMsg);
 2988 heikki.linnakangas        979 EUB             : 
 8750 tgl                       980 GIC      737364 :     while (PqRecvPointer >= PqRecvLength)
 8750 tgl                       981 EUB             :     {
 8750 tgl                       982 GIC      250891 :         if (pq_recvbuf())       /* If nothing in buffer, then recv some */
 8750 tgl                       983 GBC          50 :             return EOF;         /* Failed to recv data */
 8750 tgl                       984 EUB             :     }
 6406 tgl                       985 GIC      486473 :     return (unsigned char) PqRecvBuffer[PqRecvPointer++];
 8750 tgl                       986 EUB             : }
                                987                 : 
                                988                 : /* --------------------------------
                                989                 :  *      pq_peekbyte     - peek at next byte from connection
                                990                 :  *
                                991                 :  *   Same as pq_getbyte() except we don't advance the pointer.
                                992                 :  * --------------------------------
                                993                 :  */
                                994                 : int
 8750 tgl                       995 UIC           0 : pq_peekbyte(void)
                                996                 : {
 2984 noah                      997               0 :     Assert(PqCommReadingMsg);
 2984 noah                      998 ECB             : 
 8750 tgl                       999 UIC           0 :     while (PqRecvPointer >= PqRecvLength)
                               1000                 :     {
                               1001               0 :         if (pq_recvbuf())       /* If nothing in buffer, then recv some */
 8750 tgl                      1002 LBC           0 :             return EOF;         /* Failed to recv data */
                               1003                 :     }
 6406                          1004               0 :     return (unsigned char) PqRecvBuffer[PqRecvPointer];
                               1005                 : }
 8977 vadim4o                  1006 ECB             : 
 4832 heikki.linnakangas       1007                 : /* --------------------------------
                               1008                 :  *      pq_getbyte_if_available - get a single byte from connection,
                               1009                 :  *          if available
                               1010                 :  *
 4798                          1011                 :  * The received byte is stored in *c. Returns 1 if a byte was read,
                               1012                 :  * 0 if no data was available, or EOF if trouble.
 4832                          1013                 :  * --------------------------------
                               1014                 :  */
                               1015                 : int
 4832 heikki.linnakangas       1016 GIC     1045101 : pq_getbyte_if_available(unsigned char *c)
                               1017                 : {
                               1018                 :     int         r;
                               1019                 : 
 2988                          1020         1045101 :     Assert(PqCommReadingMsg);
 2988 heikki.linnakangas       1021 ECB             : 
 4832 heikki.linnakangas       1022 CBC     1045101 :     if (PqRecvPointer < PqRecvLength)
                               1023                 :     {
 4832 heikki.linnakangas       1024 GIC       55270 :         *c = PqRecvBuffer[PqRecvPointer++];
                               1025           55270 :         return 1;
                               1026                 :     }
                               1027                 : 
                               1028                 :     /* Put the socket into non-blocking mode */
 3082 rhaas                    1029          989831 :     socket_set_nonblocking(true);
 4393 heikki.linnakangas       1030 ECB             : 
 4393 heikki.linnakangas       1031 GIC      989831 :     r = secure_read(MyProcPort, c, 1);
                               1032          989831 :     if (r < 0)
 4832 heikki.linnakangas       1033 ECB             :     {
                               1034                 :         /*
                               1035                 :          * Ok if no data available without blocking or interrupted (though
 4382 bruce                    1036                 :          * EINTR really shouldn't happen with a non-blocking socket). Report
                               1037                 :          * other errors.
                               1038                 :          */
 4393 heikki.linnakangas       1039 CBC      953409 :         if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
 4393 heikki.linnakangas       1040 GIC      953408 :             r = 0;
                               1041                 :         else
 4798 heikki.linnakangas       1042 ECB             :         {
                               1043                 :             /*
                               1044                 :              * Careful: an ereport() that tries to write to the client would
                               1045                 :              * cause recursion to here, leading to stack overflow and core
                               1046                 :              * dump!  This message must go *only* to the postmaster log.
                               1047                 :              */
 4393 heikki.linnakangas       1048 GIC           1 :             ereport(COMMERROR,
                               1049                 :                     (errcode_for_socket_access(),
                               1050                 :                      errmsg("could not receive data from client: %m")));
 4798                          1051               1 :             r = EOF;
 4798 heikki.linnakangas       1052 ECB             :         }
                               1053                 :     }
 4393 heikki.linnakangas       1054 GIC       36422 :     else if (r == 0)
                               1055                 :     {
 4393 heikki.linnakangas       1056 ECB             :         /* EOF detected */
 4393 heikki.linnakangas       1057 GIC          14 :         r = EOF;
 4832 heikki.linnakangas       1058 ECB             :     }
                               1059                 : 
 4832 heikki.linnakangas       1060 CBC      989831 :     return r;
                               1061                 : }
 4832 heikki.linnakangas       1062 ECB             : 
 8750 tgl                      1063                 : /* --------------------------------
                               1064                 :  *      pq_getbytes     - get a known number of bytes from connection
                               1065                 :  *
                               1066                 :  *      returns 0 if OK, EOF if trouble
                               1067                 :  * --------------------------------
 8853 scrappy                  1068                 :  */
 8750 tgl                      1069                 : int
 8750 tgl                      1070 CBC     1163683 : pq_getbytes(char *s, size_t len)
 8853 scrappy                  1071 ECB             : {
                               1072                 :     size_t      amount;
 8750 tgl                      1073                 : 
 2988 heikki.linnakangas       1074 GIC     1163683 :     Assert(PqCommReadingMsg);
                               1075                 : 
 8750 tgl                      1076         2328616 :     while (len > 0)
                               1077                 :     {
                               1078         1211448 :         while (PqRecvPointer >= PqRecvLength)
                               1079                 :         {
                               1080           46515 :             if (pq_recvbuf())   /* If nothing in buffer, then recv some */
                               1081              13 :                 return EOF;     /* Failed to recv data */
                               1082                 :         }
                               1083         1164933 :         amount = PqRecvLength - PqRecvPointer;
                               1084         1164933 :         if (amount > len)
                               1085          867657 :             amount = len;
 8750 tgl                      1086 GBC     1164933 :         memcpy(s, PqRecvBuffer + PqRecvPointer, amount);
 8750 tgl                      1087 GIC     1164933 :         PqRecvPointer += amount;
                               1088         1164933 :         s += amount;
                               1089         1164933 :         len -= amount;
 8750 tgl                      1090 EUB             :     }
 8750 tgl                      1091 GIC     1163670 :     return 0;
 8750 tgl                      1092 EUB             : }
                               1093                 : 
 6747                          1094                 : /* --------------------------------
                               1095                 :  *      pq_discardbytes     - throw away a known number of bytes
                               1096                 :  *
                               1097                 :  *      same as pq_getbytes except we do not copy the data to anyplace.
                               1098                 :  *      this is used for resynchronizing after read errors.
                               1099                 :  *
                               1100                 :  *      returns 0 if OK, EOF if trouble
                               1101                 :  * --------------------------------
                               1102                 :  */
                               1103                 : static int
 6747 tgl                      1104 UIC           0 : pq_discardbytes(size_t len)
 6747 tgl                      1105 EUB             : {
                               1106                 :     size_t      amount;
                               1107                 : 
 2988 heikki.linnakangas       1108 UIC           0 :     Assert(PqCommReadingMsg);
                               1109                 : 
 6747 tgl                      1110               0 :     while (len > 0)
                               1111                 :     {
                               1112               0 :         while (PqRecvPointer >= PqRecvLength)
                               1113                 :         {
                               1114               0 :             if (pq_recvbuf())   /* If nothing in buffer, then recv some */
 6747 tgl                      1115 LBC           0 :                 return EOF;     /* Failed to recv data */
                               1116                 :         }
                               1117               0 :         amount = PqRecvLength - PqRecvPointer;
 6747 tgl                      1118 UIC           0 :         if (amount > len)
                               1119               0 :             amount = len;
                               1120               0 :         PqRecvPointer += amount;
                               1121               0 :         len -= amount;
                               1122                 :     }
                               1123               0 :     return 0;
                               1124                 : }
                               1125                 : 
                               1126                 : /* --------------------------------
                               1127                 :  *      pq_buffer_has_data      - is any buffered data available to read?
  517 tgl                      1128 ECB             :  *
                               1129                 :  * This will *not* attempt to read more data.
                               1130                 :  * --------------------------------
                               1131                 :  */
                               1132                 : bool
  517 tgl                      1133 GIC         175 : pq_buffer_has_data(void)
  517 tgl                      1134 ECB             : {
  517 tgl                      1135 GBC         175 :     return (PqRecvPointer < PqRecvLength);
                               1136                 : }
                               1137                 : 
                               1138                 : 
 2988 heikki.linnakangas       1139 ECB             : /* --------------------------------
 2878 bruce                    1140                 :  *      pq_startmsgread - begin reading a message from the client.
                               1141                 :  *
                               1142                 :  *      This must be called before any of the pq_get* functions.
                               1143                 :  * --------------------------------
                               1144                 :  */
                               1145                 : void
 2988 heikki.linnakangas       1146 GIC     1540497 : pq_startmsgread(void)
                               1147                 : {
                               1148                 :     /*
                               1149                 :      * There shouldn't be a read active already, but let's check just to be
                               1150                 :      * sure.
                               1151                 :      */
 2988 heikki.linnakangas       1152 CBC     1540497 :     if (PqCommReadingMsg)
 2988 heikki.linnakangas       1153 UIC           0 :         ereport(FATAL,
 2988 heikki.linnakangas       1154 ECB             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                               1155                 :                  errmsg("terminating connection because protocol synchronization was lost")));
                               1156                 : 
 2988 heikki.linnakangas       1157 CBC     1540497 :     PqCommReadingMsg = true;
 2988 heikki.linnakangas       1158 GIC     1540497 : }
                               1159                 : 
                               1160                 : 
                               1161                 : /* --------------------------------
                               1162                 :  *      pq_endmsgread   - finish reading message.
                               1163                 :  *
                               1164                 :  *      This must be called after reading a message with pq_getbytes()
                               1165                 :  *      and friends, to indicate that we have read the whole message.
                               1166                 :  *      pq_getmessage() does this implicitly.
                               1167                 :  * --------------------------------
 2988 heikki.linnakangas       1168 ECB             :  */
                               1169                 : void
 2988 heikki.linnakangas       1170 CBC      962232 : pq_endmsgread(void)
                               1171                 : {
 2988 heikki.linnakangas       1172 GIC      962232 :     Assert(PqCommReadingMsg);
                               1173                 : 
                               1174          962232 :     PqCommReadingMsg = false;
                               1175          962232 : }
                               1176                 : 
                               1177                 : /* --------------------------------
                               1178                 :  *      pq_is_reading_msg - are we currently reading a message?
                               1179                 :  *
                               1180                 :  * This is used in error recovery at the outer idle loop to detect if we have
                               1181                 :  * lost protocol sync, and need to terminate the connection. pq_startmsgread()
                               1182                 :  * will check for that too, but it's nicer to detect it earlier.
                               1183                 :  * --------------------------------
                               1184                 :  */
                               1185                 : bool
                               1186           17741 : pq_is_reading_msg(void)
                               1187                 : {
                               1188           17741 :     return PqCommReadingMsg;
                               1189                 : }
 2988 heikki.linnakangas       1190 ECB             : 
                               1191                 : /* --------------------------------
                               1192                 :  *      pq_getmessage   - get a message with length word from connection
                               1193                 :  *
 7295 tgl                      1194                 :  *      The return value is placed in an expansible StringInfo, which has
                               1195                 :  *      already been initialized by the caller.
                               1196                 :  *      Only the message body is placed in the StringInfo; the length word
                               1197                 :  *      is removed.  Also, s->cursor is initialized to zero for convenience
                               1198                 :  *      in scanning the message contents.
                               1199                 :  *
                               1200                 :  *      maxlen is the upper limit on the length of the
 7295 tgl                      1201 EUB             :  *      message we are willing to accept.  We abort the connection (by
                               1202                 :  *      returning EOF) if client tries to send more than that.
                               1203                 :  *
                               1204                 :  *      returns 0 if OK, EOF if trouble
                               1205                 :  * --------------------------------
                               1206                 :  */
 7295 tgl                      1207 ECB             : int
 7295 tgl                      1208 GIC      578151 : pq_getmessage(StringInfo s, int maxlen)
 7295 tgl                      1209 ECB             : {
                               1210                 :     int32       len;
 7295 tgl                      1211 EUB             : 
 2988 heikki.linnakangas       1212 GIC      578151 :     Assert(PqCommReadingMsg);
                               1213                 : 
 5881 neilc                    1214 GBC      578151 :     resetStringInfo(s);
                               1215                 : 
                               1216                 :     /* Read message length word */
 7295 tgl                      1217 CBC      578151 :     if (pq_getbytes((char *) &len, 4) == EOF)
                               1218                 :     {
 7201 tgl                      1219 LBC           0 :         ereport(COMMERROR,
                               1220                 :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                               1221                 :                  errmsg("unexpected EOF within message length word")));
 7295 tgl                      1222 UIC           0 :         return EOF;
                               1223                 :     }
                               1224                 : 
 2016 andres                   1225 GIC      578151 :     len = pg_ntoh32(len);
 7295 tgl                      1226 ECB             : 
  711 tgl                      1227 GIC      578151 :     if (len < 4 || len > maxlen)
 7295 tgl                      1228 ECB             :     {
 7201 tgl                      1229 UIC           0 :         ereport(COMMERROR,
 7201 tgl                      1230 EUB             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                               1231                 :                  errmsg("invalid message length")));
 7295 tgl                      1232 UBC           0 :         return EOF;
 7295 tgl                      1233 EUB             :     }
                               1234                 : 
 6747 tgl                      1235 GIC      578151 :     len -= 4;                   /* discount length itself */
                               1236                 : 
 7295                          1237          578151 :     if (len > 0)
 7295 tgl                      1238 EUB             :     {
 6747                          1239                 :         /*
                               1240                 :          * Allocate space for message.  If we run out of room (ridiculously
 6747 tgl                      1241 ECB             :          * large message), we will elog(ERROR), but we want to discard the
                               1242                 :          * message body so as not to lose communication sync.
                               1243                 :          */
 6747 tgl                      1244 CBC      559047 :         PG_TRY();
                               1245                 :         {
 6747 tgl                      1246 GBC      559047 :             enlargeStringInfo(s, len);
                               1247                 :         }
 6747 tgl                      1248 UIC           0 :         PG_CATCH();
 6747 tgl                      1249 EUB             :         {
 6747 tgl                      1250 UIC           0 :             if (pq_discardbytes(len) == EOF)
 6747 tgl                      1251 LBC           0 :                 ereport(COMMERROR,
                               1252                 :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
 6747 tgl                      1253 ECB             :                          errmsg("incomplete message from client")));
                               1254                 : 
                               1255                 :             /* we discarded the rest of the message so we're back in sync. */
 2988 heikki.linnakangas       1256 UIC           0 :             PqCommReadingMsg = false;
 6747 tgl                      1257 LBC           0 :             PG_RE_THROW();
                               1258                 :         }
 6747 tgl                      1259 CBC      559047 :         PG_END_TRY();
                               1260                 : 
                               1261                 :         /* And grab the message */
 7295 tgl                      1262 GIC      559047 :         if (pq_getbytes(s->data, len) == EOF)
                               1263                 :         {
 7201 tgl                      1264 LBC           0 :             ereport(COMMERROR,
                               1265                 :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
                               1266                 :                      errmsg("incomplete message from client")));
 7522 tgl                      1267 UIC           0 :             return EOF;
 7295 tgl                      1268 ECB             :         }
 7295 tgl                      1269 GIC      559047 :         s->len = len;
                               1270                 :         /* Place a trailing null per StringInfo convention */
 7295 tgl                      1271 CBC      559047 :         s->data[len] = '\0';
                               1272                 :     }
 7295 tgl                      1273 ECB             : 
 2988 heikki.linnakangas       1274                 :     /* finished reading the message. */
 2988 heikki.linnakangas       1275 CBC      578151 :     PqCommReadingMsg = false;
                               1276                 : 
 7295 tgl                      1277          578151 :     return 0;
 8750 tgl                      1278 ECB             : }
                               1279                 : 
                               1280                 : 
 6769                          1281                 : static int
 6769 tgl                      1282 CBC    20368017 : internal_putbytes(const char *s, size_t len)
 8750 tgl                      1283 ECB             : {
                               1284                 :     size_t      amount;
                               1285                 : 
 8750 tgl                      1286 GIC    41120142 :     while (len > 0)
                               1287                 :     {
                               1288                 :         /* If buffer is full, then flush it out */
 4393 heikki.linnakangas       1289        20752130 :         if (PqSendPointer >= PqSendBufferSize)
                               1290                 :         {
 3082 rhaas                    1291          408483 :             socket_set_nonblocking(false);
 6769 tgl                      1292          408483 :             if (internal_flush())
 8750                          1293               5 :                 return EOF;
                               1294                 :         }
 4393 heikki.linnakangas       1295 CBC    20752125 :         amount = PqSendBufferSize - PqSendPointer;
 8750 tgl                      1296 GIC    20752125 :         if (amount > len)
                               1297        20334961 :             amount = len;
                               1298        20752125 :         memcpy(PqSendBuffer + PqSendPointer, s, amount);
                               1299        20752125 :         PqSendPointer += amount;
 8750 tgl                      1300 CBC    20752125 :         s += amount;
 8750 tgl                      1301 GBC    20752125 :         len -= amount;
 8750 tgl                      1302 ECB             :     }
 8750 tgl                      1303 CBC    20368012 :     return 0;
 8750 tgl                      1304 ECB             : }
                               1305                 : 
                               1306                 : /* --------------------------------
                               1307                 :  *      socket_flush        - flush pending output
                               1308                 :  *
                               1309                 :  *      returns 0 if OK, EOF if trouble
                               1310                 :  * --------------------------------
                               1311                 :  */
                               1312                 : static int
 3082 rhaas                    1313 GIC      279645 : socket_flush(void)
                               1314                 : {
                               1315                 :     int         res;
                               1316                 : 
 6769 tgl                      1317 ECB             :     /* No-op if reentrant call */
 6769 tgl                      1318 GIC      279645 :     if (PqCommBusy)
 6769 tgl                      1319 UIC           0 :         return 0;
 6769 tgl                      1320 GIC      279645 :     PqCommBusy = true;
 3082 rhaas                    1321 CBC      279645 :     socket_set_nonblocking(false);
 6769 tgl                      1322          279645 :     res = internal_flush();
 6769 tgl                      1323 GIC      279645 :     PqCommBusy = false;
 6769 tgl                      1324 CBC      279645 :     return res;
                               1325                 : }
                               1326                 : 
                               1327                 : /* --------------------------------
 4393 heikki.linnakangas       1328 ECB             :  *      internal_flush - flush pending output
                               1329                 :  *
                               1330                 :  * Returns 0 if OK (meaning everything was sent, or operation would block
                               1331                 :  * and the socket is in non-blocking mode), or EOF if trouble.
                               1332                 :  * --------------------------------
 4393 heikki.linnakangas       1333 EUB             :  */
                               1334                 : static int
 6769 tgl                      1335 GIC      906009 : internal_flush(void)
                               1336                 : {
                               1337                 :     static int  last_reported_send_errno = 0;
                               1338                 : 
 4393 heikki.linnakangas       1339 CBC      906009 :     char       *bufptr = PqSendBuffer + PqSendStart;
 6406 tgl                      1340          906009 :     char       *bufend = PqSendBuffer + PqSendPointer;
                               1341                 : 
 8750                          1342         1810814 :     while (bufptr < bufend)
                               1343                 :     {
                               1344                 :         int         r;
                               1345                 : 
 7604 bruce                    1346 GIC      909157 :         r = secure_write(MyProcPort, bufptr, bufend - bufptr);
                               1347                 : 
 8750 tgl                      1348          909157 :         if (r <= 0)
                               1349                 :         {
                               1350            4352 :             if (errno == EINTR)
 8750 tgl                      1351 UIC           0 :                 continue;       /* Ok if we were interrupted */
                               1352                 : 
                               1353                 :             /*
 4382 bruce                    1354 ECB             :              * Ok if no data writable without blocking, and the socket is in
                               1355                 :              * non-blocking mode.
 4393 heikki.linnakangas       1356                 :              */
 4393 heikki.linnakangas       1357 CBC        4352 :             if (errno == EAGAIN ||
 4393 heikki.linnakangas       1358 GIC          36 :                 errno == EWOULDBLOCK)
                               1359                 :             {
                               1360            4316 :                 return 0;
                               1361                 :             }
                               1362                 : 
                               1363                 :             /*
                               1364                 :              * Careful: an ereport() that tries to write to the client would
                               1365                 :              * cause recursion to here, leading to stack overflow and core
                               1366                 :              * dump!  This message must go *only* to the postmaster log.
                               1367                 :              *
 7522 bruce                    1368 ECB             :              * If a client disconnects while we're in the midst of output, we
 6385                          1369                 :              * might write quite a bit of data before we get to a safe query
                               1370                 :              * abort point.  So, suppress duplicate log messages.
 8750 tgl                      1371                 :              */
 7818 tgl                      1372 GIC          36 :             if (errno != last_reported_send_errno)
                               1373                 :             {
 7818 tgl                      1374 CBC          36 :                 last_reported_send_errno = errno;
 7201                          1375              36 :                 ereport(COMMERROR,
 7201 tgl                      1376 ECB             :                         (errcode_for_socket_access(),
                               1377                 :                          errmsg("could not send data to client: %m")));
                               1378                 :             }
 8720 bruce                    1379                 : 
                               1380                 :             /*
                               1381                 :              * We drop the buffered data anyway so that processing can
                               1382                 :              * continue, even though we'll probably quit soon. We also set a
                               1383                 :              * flag that'll cause the next CHECK_FOR_INTERRUPTS to terminate
                               1384                 :              * the connection.
                               1385                 :              */
 4393 heikki.linnakangas       1386 GIC          36 :             PqSendStart = PqSendPointer = 0;
 4139                          1387              36 :             ClientConnectionLost = 1;
                               1388              36 :             InterruptPending = 1;
 8750 tgl                      1389              36 :             return EOF;
 8750 tgl                      1390 ECB             :         }
                               1391                 : 
 7522 bruce                    1392 GIC      904805 :         last_reported_send_errno = 0;   /* reset after any successful send */
 8750 tgl                      1393          904805 :         bufptr += r;
 4393 heikki.linnakangas       1394          904805 :         PqSendStart += r;
 8750 tgl                      1395 ECB             :     }
 7818                          1396                 : 
 4393 heikki.linnakangas       1397 GIC      901657 :     PqSendStart = PqSendPointer = 0;
 8750 tgl                      1398          901657 :     return 0;
 8750 tgl                      1399 ECB             : }
 8750 tgl                      1400 EUB             : 
                               1401                 : /* --------------------------------
                               1402                 :  *      pq_flush_if_writable - flush pending output if writable without blocking
 4393 heikki.linnakangas       1403 ECB             :  *
                               1404                 :  * Returns 0 if OK, or EOF if trouble.
                               1405                 :  * --------------------------------
                               1406                 :  */
 3082 rhaas                    1407                 : static int
 3082 rhaas                    1408 CBC     1136342 : socket_flush_if_writable(void)
                               1409                 : {
                               1410                 :     int         res;
                               1411                 : 
                               1412                 :     /* Quick exit if nothing to do */
 4393 heikki.linnakangas       1413 GIC     1136342 :     if (PqSendPointer == PqSendStart)
                               1414          918461 :         return 0;
                               1415                 : 
 4393 heikki.linnakangas       1416 ECB             :     /* No-op if reentrant call */
 4393 heikki.linnakangas       1417 GIC      217881 :     if (PqCommBusy)
 4393 heikki.linnakangas       1418 LBC           0 :         return 0;
                               1419                 : 
                               1420                 :     /* Temporarily put the socket into non-blocking mode */
 3082 rhaas                    1421 GIC      217881 :     socket_set_nonblocking(true);
                               1422                 : 
 4393 heikki.linnakangas       1423          217881 :     PqCommBusy = true;
                               1424          217881 :     res = internal_flush();
                               1425          217881 :     PqCommBusy = false;
                               1426          217881 :     return res;
                               1427                 : }
                               1428                 : 
                               1429                 : /* --------------------------------
                               1430                 :  *  socket_is_send_pending  - is there any pending data in the output buffer?
                               1431                 :  * --------------------------------
                               1432                 :  */
                               1433                 : static bool
 3082 rhaas                    1434         2198296 : socket_is_send_pending(void)
                               1435                 : {
 4393 heikki.linnakangas       1436         2198296 :     return (PqSendStart < PqSendPointer);
                               1437                 : }
                               1438                 : 
                               1439                 : /* --------------------------------
                               1440                 :  * Message-level I/O routines begin here.
                               1441                 :  * --------------------------------
                               1442                 :  */
                               1443                 : 
                               1444                 : 
                               1445                 : /* --------------------------------
 3082 rhaas                    1446 ECB             :  *      socket_putmessage - send a normal message (suppressed in COPY OUT mode)
                               1447                 :  *
                               1448                 :  *      msgtype is a message type code to place before the message body.
                               1449                 :  *
  766 heikki.linnakangas       1450                 :  *      len is the length of the message body data at *s.  A message length
                               1451                 :  *      word (equal to len+4 because it counts itself too) is inserted by this
                               1452                 :  *      routine.
 8750 tgl                      1453 EUB             :  *
  766 heikki.linnakangas       1454 ECB             :  *      We suppress messages generated while pqcomm.c is busy.  This
 6769 tgl                      1455                 :  *      avoids any possibility of messages being inserted within other
 6769 tgl                      1456 EUB             :  *      messages.  The only known trouble case arises if SIGQUIT occurs
                               1457                 :  *      during a pqcomm.c routine --- quickdie() will try to send a warning
 6769 tgl                      1458 ECB             :  *      message, and the most reasonable approach seems to be to drop it.
                               1459                 :  *
 8750 tgl                      1460 EUB             :  *      returns 0 if OK, EOF if trouble
                               1461                 :  * --------------------------------
 8750 tgl                      1462 ECB             :  */
 3082 rhaas                    1463                 : static int
 3082 rhaas                    1464 CBC     6789339 : socket_putmessage(char msgtype, const char *s, size_t len)
 8750 tgl                      1465 ECB             : {
                               1466                 :     uint32      n32;
  766 heikki.linnakangas       1467                 : 
  766 heikki.linnakangas       1468 CBC     6789339 :     Assert(msgtype != 0);
  766 heikki.linnakangas       1469 ECB             : 
  766 heikki.linnakangas       1470 GIC     6789339 :     if (PqCommBusy)
 8750 tgl                      1471 UIC           0 :         return 0;
 6769 tgl                      1472 GIC     6789339 :     PqCommBusy = true;
  766 heikki.linnakangas       1473         6789339 :     if (internal_putbytes(&msgtype, 1))
  766 heikki.linnakangas       1474 UIC           0 :         goto fail;
                               1475                 : 
  766 heikki.linnakangas       1476 GIC     6789339 :     n32 = pg_hton32((uint32) (len + 4));
                               1477         6789339 :     if (internal_putbytes((char *) &n32, 4))
  766 heikki.linnakangas       1478 UIC           0 :         goto fail;
 7292 tgl                      1479 ECB             : 
 6769 tgl                      1480 GIC     6789339 :     if (internal_putbytes(s, len))
                               1481               5 :         goto fail;
                               1482         6789334 :     PqCommBusy = false;
                               1483         6789334 :     return 0;
                               1484                 : 
                               1485               5 : fail:
                               1486               5 :     PqCommBusy = false;
                               1487               5 :     return EOF;
 8750 tgl                      1488 ECB             : }
                               1489                 : 
                               1490                 : /* --------------------------------
 4393 heikki.linnakangas       1491                 :  *      pq_putmessage_noblock   - like pq_putmessage, but never blocks
                               1492                 :  *
                               1493                 :  *      If the output buffer is too small to hold the message, the buffer
                               1494                 :  *      is enlarged.
                               1495                 :  */
                               1496                 : static void
 3082 rhaas                    1497 CBC      213466 : socket_putmessage_noblock(char msgtype, const char *s, size_t len)
                               1498                 : {
                               1499                 :     int         res PG_USED_FOR_ASSERTS_ONLY;
                               1500                 :     int         required;
                               1501                 : 
                               1502                 :     /*
                               1503                 :      * Ensure we have enough space in the output buffer for the message header
                               1504                 :      * as well as the message itself.
                               1505                 :      */
 4393 heikki.linnakangas       1506 GIC      213466 :     required = PqSendPointer + 1 + 4 + len;
                               1507          213466 :     if (required > PqSendBufferSize)
                               1508                 :     {
                               1509             331 :         PqSendBuffer = repalloc(PqSendBuffer, required);
                               1510             331 :         PqSendBufferSize = required;
                               1511                 :     }
                               1512          213466 :     res = pq_putmessage(msgtype, s, len);
 4382 bruce                    1513          213466 :     Assert(res == 0);           /* should not fail when the message fits in
                               1514                 :                                  * buffer */
 4393 heikki.linnakangas       1515          213466 : }
 4393 heikki.linnakangas       1516 EUB             : 
                               1517                 : /* --------------------------------
  766                          1518                 :  *      pq_putmessage_v2 - send a message in protocol version 2
                               1519                 :  *
                               1520                 :  *      msgtype is a message type code to place before the message body.
 8750 tgl                      1521                 :  *
  766 heikki.linnakangas       1522                 :  *      We no longer support protocol version 2, but we have kept this
                               1523                 :  *      function so that if a client tries to connect with protocol version 2,
                               1524                 :  *      as a courtesy we can still send the "unsupported protocol version"
                               1525                 :  *      error to the client in the old format.
                               1526                 :  *
                               1527                 :  *      Like in pq_putmessage(), we suppress messages generated while
                               1528                 :  *      pqcomm.c is busy.
                               1529                 :  *
                               1530                 :  *      returns 0 if OK, EOF if trouble
 8750 tgl                      1531                 :  * --------------------------------
                               1532                 :  */
  766 heikki.linnakangas       1533                 : int
  766 heikki.linnakangas       1534 UIC           0 : pq_putmessage_v2(char msgtype, const char *s, size_t len)
                               1535                 : {
                               1536               0 :     Assert(msgtype != 0);
                               1537                 : 
                               1538               0 :     if (PqCommBusy)
                               1539               0 :         return 0;
                               1540               0 :     PqCommBusy = true;
                               1541               0 :     if (internal_putbytes(&msgtype, 1))
                               1542               0 :         goto fail;
                               1543                 : 
                               1544               0 :     if (internal_putbytes(s, len))
                               1545               0 :         goto fail;
                               1546               0 :     PqCommBusy = false;
                               1547               0 :     return 0;
                               1548                 : 
                               1549               0 : fail:
                               1550               0 :     PqCommBusy = false;
                               1551               0 :     return EOF;
                               1552                 : }
                               1553                 : 
                               1554                 : /*
                               1555                 :  * Support for TCP Keepalive parameters
                               1556                 :  */
                               1557                 : 
                               1558                 : /*
                               1559                 :  * On Windows, we need to set both idle and interval at the same time.
                               1560                 :  * We also cannot reset them to the default (setting to zero will
                               1561                 :  * actually set them to zero, not default), therefore we fallback to
                               1562                 :  * the out-of-the-box default instead.
                               1563                 :  */
                               1564                 : #if defined(WIN32) && defined(SIO_KEEPALIVE_VALS)
                               1565                 : static int
                               1566                 : pq_setkeepaliveswin32(Port *port, int idle, int interval)
                               1567                 : {
                               1568                 :     struct tcp_keepalive ka;
                               1569                 :     DWORD       retsize;
                               1570                 : 
                               1571                 :     if (idle <= 0)
                               1572                 :         idle = 2 * 60 * 60;     /* default = 2 hours */
                               1573                 :     if (interval <= 0)
                               1574                 :         interval = 1;           /* default = 1 second */
                               1575                 : 
                               1576                 :     ka.onoff = 1;
                               1577                 :     ka.keepalivetime = idle * 1000;
                               1578                 :     ka.keepaliveinterval = interval * 1000;
                               1579                 : 
                               1580                 :     if (WSAIoctl(port->sock,
                               1581                 :                  SIO_KEEPALIVE_VALS,
                               1582                 :                  (LPVOID) &ka,
                               1583                 :                  sizeof(ka),
                               1584                 :                  NULL,
                               1585                 :                  0,
                               1586                 :                  &retsize,
 4658 magnus                   1587 ECB             :                  NULL,
                               1588                 :                  NULL)
                               1589                 :         != 0)
                               1590                 :     {
  856 peter                    1591                 :         ereport(LOG,
                               1592                 :                 (errmsg("%s(%s) failed: error code %d",
  716 peter                    1593 EUB             :                         "WSAIoctl", "SIO_KEEPALIVE_VALS", WSAGetLastError())));
 4658 magnus                   1594                 :         return STATUS_ERROR;
                               1595                 :     }
                               1596                 :     if (port->keepalives_idle != idle)
                               1597                 :         port->keepalives_idle = idle;
                               1598                 :     if (port->keepalives_interval != interval)
                               1599                 :         port->keepalives_interval = interval;
                               1600                 :     return STATUS_OK;
                               1601                 : }
                               1602                 : #endif
                               1603                 : 
                               1604                 : int
 6462 bruce                    1605 GBC        1088 : pq_getkeepalivesidle(Port *port)
                               1606                 : {
 2111 tgl                      1607 EUB             : #if defined(PG_TCP_KEEPALIVE_IDLE) || defined(SIO_KEEPALIVE_VALS)
  418 peter                    1608 GIC        1088 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1609            1088 :         return 0;
                               1610                 : 
 6462 bruce                    1611 UIC           0 :     if (port->keepalives_idle != 0)
                               1612               0 :         return port->keepalives_idle;
                               1613                 : 
                               1614               0 :     if (port->default_keepalives_idle == 0)
 6462 bruce                    1615 EUB             :     {
                               1616                 : #ifndef WIN32
  516 peter                    1617 UIC           0 :         socklen_t   size = sizeof(port->default_keepalives_idle);
                               1618                 : 
 2111 tgl                      1619               0 :         if (getsockopt(port->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
 2112                          1620               0 :                        (char *) &port->default_keepalives_idle,
                               1621                 :                        &size) < 0)
 2112 tgl                      1622 ECB             :         {
  856 peter                    1623 UIC           0 :             ereport(LOG,
  716 peter                    1624 ECB             :                     (errmsg("%s(%s) failed: %m", "getsockopt", PG_TCP_KEEPALIVE_IDLE_STR)));
 2112 tgl                      1625 LBC           0 :             port->default_keepalives_idle = -1; /* don't know */
                               1626                 :         }
                               1627                 : #else                           /* WIN32 */
                               1628                 :         /* We can't get the defaults on Windows, so return "don't know" */
 4658 magnus                   1629 ECB             :         port->default_keepalives_idle = -1;
 2118 tgl                      1630                 : #endif                          /* WIN32 */
                               1631                 :     }
                               1632                 : 
 6462 bruce                    1633 UBC           0 :     return port->default_keepalives_idle;
                               1634                 : #else
 6462 bruce                    1635 EUB             :     return 0;
                               1636                 : #endif
                               1637                 : }
 6418 tgl                      1638                 : 
                               1639                 : int
 6462 bruce                    1640 GBC        2057 : pq_setkeepalivesidle(int idle, Port *port)
                               1641                 : {
  418 peter                    1642 GIC        2057 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1643            1857 :         return STATUS_OK;
 6462 bruce                    1644 EUB             : 
 2112 tgl                      1645                 : /* check SIO_KEEPALIVE_VALS here, not just WIN32, as some toolchains lack it */
                               1646                 : #if defined(PG_TCP_KEEPALIVE_IDLE) || defined(SIO_KEEPALIVE_VALS)
 6462 bruce                    1647 GBC         200 :     if (idle == port->keepalives_idle)
 6462 bruce                    1648 GIC         200 :         return STATUS_OK;
                               1649                 : 
 4658 magnus                   1650 EUB             : #ifndef WIN32
 6418 tgl                      1651 UIC           0 :     if (port->default_keepalives_idle <= 0)
 6462 bruce                    1652 EUB             :     {
 6462 bruce                    1653 UIC           0 :         if (pq_getkeepalivesidle(port) < 0)
                               1654                 :         {
 6418 tgl                      1655 UBC           0 :             if (idle == 0)
 2118 tgl                      1656 UIC           0 :                 return STATUS_OK;   /* default is set but unknown */
                               1657                 :             else
 6418                          1658               0 :                 return STATUS_ERROR;
                               1659                 :         }
                               1660                 :     }
                               1661                 : 
 6462 bruce                    1662               0 :     if (idle == 0)
                               1663               0 :         idle = port->default_keepalives_idle;
                               1664                 : 
 2111 tgl                      1665               0 :     if (setsockopt(port->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
                               1666                 :                    (char *) &idle, sizeof(idle)) < 0)
                               1667                 :     {
  856 peter                    1668 UBC           0 :         ereport(LOG,
                               1669                 :                 (errmsg("%s(%s) failed: %m", "setsockopt", PG_TCP_KEEPALIVE_IDLE_STR)));
 2112 tgl                      1670 UIC           0 :         return STATUS_ERROR;
                               1671                 :     }
 6462 bruce                    1672 ECB             : 
 6462 bruce                    1673 UIC           0 :     port->keepalives_idle = idle;
                               1674                 : #else                           /* WIN32 */
 4658 magnus                   1675 ECB             :     return pq_setkeepaliveswin32(port, idle, port->keepalives_interval);
                               1676                 : #endif
                               1677                 : #else
 6462 bruce                    1678 EUB             :     if (idle != 0)
                               1679                 :     {
                               1680                 :         ereport(LOG,
  856 peter                    1681                 :                 (errmsg("setting the keepalive idle time is not supported")));
                               1682                 :         return STATUS_ERROR;
                               1683                 :     }
 6462 bruce                    1684                 : #endif
                               1685                 : 
 6462 bruce                    1686 UBC           0 :     return STATUS_OK;
 6462 bruce                    1687 EUB             : }
                               1688                 : 
                               1689                 : int
 6462 bruce                    1690 GBC        1088 : pq_getkeepalivesinterval(Port *port)
                               1691                 : {
 4658 magnus                   1692 EUB             : #if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
  418 peter                    1693 GIC        1088 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1694            1088 :         return 0;
                               1695                 : 
 6462 bruce                    1696 UIC           0 :     if (port->keepalives_interval != 0)
                               1697               0 :         return port->keepalives_interval;
                               1698                 : 
                               1699               0 :     if (port->default_keepalives_interval == 0)
 6462 bruce                    1700 EUB             :     {
                               1701                 : #ifndef WIN32
  516 peter                    1702 UIC           0 :         socklen_t   size = sizeof(port->default_keepalives_interval);
                               1703                 : 
 6462 tgl                      1704               0 :         if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPINTVL,
 6418                          1705               0 :                        (char *) &port->default_keepalives_interval,
                               1706                 :                        &size) < 0)
 6462 bruce                    1707 ECB             :         {
  856 peter                    1708 UIC           0 :             ereport(LOG,
  716 peter                    1709 ECB             :                     (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_KEEPINTVL")));
 2118 tgl                      1710 LBC           0 :             port->default_keepalives_interval = -1; /* don't know */
                               1711                 :         }
                               1712                 : #else
 4658 magnus                   1713 ECB             :         /* We can't get the defaults on Windows, so return "don't know" */
                               1714                 :         port->default_keepalives_interval = -1;
                               1715                 : #endif                          /* WIN32 */
                               1716                 :     }
 6462 bruce                    1717 EUB             : 
 6462 bruce                    1718 UIC           0 :     return port->default_keepalives_interval;
 6462 bruce                    1719 EUB             : #else
                               1720                 :     return 0;
                               1721                 : #endif
                               1722                 : }
                               1723                 : 
                               1724                 : int
 6462 bruce                    1725 GIC        2057 : pq_setkeepalivesinterval(int interval, Port *port)
                               1726                 : {
  418 peter                    1727            2057 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1728 GBC        1857 :         return STATUS_OK;
 6462 bruce                    1729 EUB             : 
                               1730                 : #if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
 6462 bruce                    1731 GBC         200 :     if (interval == port->keepalives_interval)
 6462 bruce                    1732 GIC         200 :         return STATUS_OK;
                               1733                 : 
 4658 magnus                   1734 EUB             : #ifndef WIN32
 6418 tgl                      1735 UIC           0 :     if (port->default_keepalives_interval <= 0)
 6418 tgl                      1736 EUB             :     {
 6462 bruce                    1737 UIC           0 :         if (pq_getkeepalivesinterval(port) < 0)
                               1738                 :         {
 6418 tgl                      1739 UBC           0 :             if (interval == 0)
 2118 tgl                      1740 UIC           0 :                 return STATUS_OK;   /* default is set but unknown */
                               1741                 :             else
 6418                          1742               0 :                 return STATUS_ERROR;
                               1743                 :         }
                               1744                 :     }
                               1745                 : 
 6462 bruce                    1746               0 :     if (interval == 0)
                               1747               0 :         interval = port->default_keepalives_interval;
                               1748                 : 
      tgl                      1749               0 :     if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPINTVL,
                               1750                 :                    (char *) &interval, sizeof(interval)) < 0)
                               1751                 :     {
  856 peter                    1752 UBC           0 :         ereport(LOG,
                               1753                 :                 (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_KEEPINTVL")));
 6462 bruce                    1754 UIC           0 :         return STATUS_ERROR;
                               1755                 :     }
 6462 bruce                    1756 ECB             : 
 6462 bruce                    1757 UIC           0 :     port->keepalives_interval = interval;
                               1758                 : #else                           /* WIN32 */
 4658 magnus                   1759 ECB             :     return pq_setkeepaliveswin32(port, port->keepalives_idle, interval);
                               1760                 : #endif
                               1761                 : #else
 6462 bruce                    1762 EUB             :     if (interval != 0)
                               1763                 :     {
                               1764                 :         ereport(LOG,
  716 peter                    1765                 :                 (errmsg("%s(%s) not supported", "setsockopt", "TCP_KEEPINTVL")));
                               1766                 :         return STATUS_ERROR;
 6418 tgl                      1767                 :     }
                               1768                 : #endif
 6462 bruce                    1769                 : 
 6462 bruce                    1770 UBC           0 :     return STATUS_OK;
                               1771                 : }
                               1772                 : 
 6462 bruce                    1773 EUB             : int
 6462 bruce                    1774 GIC        1088 : pq_getkeepalivescount(Port *port)
 6462 bruce                    1775 EUB             : {
                               1776                 : #ifdef TCP_KEEPCNT
  418 peter                    1777 GIC        1088 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1778            1088 :         return 0;
 6462 bruce                    1779 EUB             : 
 6462 bruce                    1780 UIC           0 :     if (port->keepalives_count != 0)
                               1781               0 :         return port->keepalives_count;
                               1782                 : 
                               1783               0 :     if (port->default_keepalives_count == 0)
                               1784                 :     {
  516 peter                    1785               0 :         socklen_t   size = sizeof(port->default_keepalives_count);
 6418 tgl                      1786 ECB             : 
 6462 tgl                      1787 UIC           0 :         if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPCNT,
 6418 tgl                      1788 LBC           0 :                        (char *) &port->default_keepalives_count,
 6462 bruce                    1789 ECB             :                        &size) < 0)
                               1790                 :         {
  856 peter                    1791 UIC           0 :             ereport(LOG,
  716 peter                    1792 ECB             :                     (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_KEEPCNT")));
 2118 tgl                      1793 LBC           0 :             port->default_keepalives_count = -1; /* don't know */
                               1794                 :         }
 6462 bruce                    1795 EUB             :     }
                               1796                 : 
 6462 bruce                    1797 UBC           0 :     return port->default_keepalives_count;
                               1798                 : #else
 6462 bruce                    1799 EUB             :     return 0;
                               1800                 : #endif
                               1801                 : }
 6418 tgl                      1802                 : 
                               1803                 : int
 6462 bruce                    1804 GIC        2057 : pq_setkeepalivescount(int count, Port *port)
                               1805                 : {
  418 peter                    1806 GBC        2057 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 6462 bruce                    1807            1857 :         return STATUS_OK;
                               1808                 : 
 4775 bruce                    1809 EUB             : #ifdef TCP_KEEPCNT
 6462 bruce                    1810 GIC         200 :     if (count == port->keepalives_count)
                               1811             200 :         return STATUS_OK;
 6462 bruce                    1812 EUB             : 
 6418 tgl                      1813 UIC           0 :     if (port->default_keepalives_count <= 0)
 6418 tgl                      1814 EUB             :     {
 6462 bruce                    1815 UIC           0 :         if (pq_getkeepalivescount(port) < 0)
                               1816                 :         {
 6418 tgl                      1817 UBC           0 :             if (count == 0)
 2118 tgl                      1818 UIC           0 :                 return STATUS_OK;   /* default is set but unknown */
                               1819                 :             else
 6418                          1820               0 :                 return STATUS_ERROR;
                               1821                 :         }
                               1822                 :     }
                               1823                 : 
 6462 bruce                    1824               0 :     if (count == 0)
                               1825               0 :         count = port->default_keepalives_count;
                               1826                 : 
 6462 tgl                      1827 UBC           0 :     if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPCNT,
                               1828                 :                    (char *) &count, sizeof(count)) < 0)
                               1829                 :     {
  856 peter                    1830 UIC           0 :         ereport(LOG,
  716 peter                    1831 ECB             :                 (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_KEEPCNT")));
 6462 bruce                    1832 UIC           0 :         return STATUS_ERROR;
                               1833                 :     }
 6462 bruce                    1834 ECB             : 
 6462 bruce                    1835 LBC           0 :     port->keepalives_count = count;
                               1836                 : #else
 6462 bruce                    1837 EUB             :     if (count != 0)
                               1838                 :     {
                               1839                 :         ereport(LOG,
  716 peter                    1840                 :                 (errmsg("%s(%s) not supported", "setsockopt", "TCP_KEEPCNT")));
                               1841                 :         return STATUS_ERROR;
 6462 bruce                    1842                 :     }
                               1843                 : #endif
                               1844                 : 
 6462 bruce                    1845 UBC           0 :     return STATUS_OK;
                               1846                 : }
                               1847                 : 
 1464 michael                  1848 EUB             : int
 1464 michael                  1849 GIC        1088 : pq_gettcpusertimeout(Port *port)
 1464 michael                  1850 EUB             : {
                               1851                 : #ifdef TCP_USER_TIMEOUT
  418 peter                    1852 GIC        1088 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 1464 michael                  1853            1088 :         return 0;
 1464 michael                  1854 EUB             : 
 1464 michael                  1855 UIC           0 :     if (port->tcp_user_timeout != 0)
                               1856               0 :         return port->tcp_user_timeout;
                               1857                 : 
                               1858               0 :     if (port->default_tcp_user_timeout == 0)
                               1859                 :     {
  516 peter                    1860               0 :         socklen_t   size = sizeof(port->default_tcp_user_timeout);
 1464 michael                  1861 ECB             : 
 1464 michael                  1862 UIC           0 :         if (getsockopt(port->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
 1464 michael                  1863 LBC           0 :                        (char *) &port->default_tcp_user_timeout,
 1464 michael                  1864 ECB             :                        &size) < 0)
                               1865                 :         {
  856 peter                    1866 UIC           0 :             ereport(LOG,
  716 peter                    1867 ECB             :                     (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_USER_TIMEOUT")));
 1464 michael                  1868 LBC           0 :             port->default_tcp_user_timeout = -1; /* don't know */
                               1869                 :         }
 1464 michael                  1870 EUB             :     }
                               1871                 : 
 1464 michael                  1872 UBC           0 :     return port->default_tcp_user_timeout;
                               1873                 : #else
 1464 michael                  1874 EUB             :     return 0;
                               1875                 : #endif
                               1876                 : }
                               1877                 : 
                               1878                 : int
 1464 michael                  1879 GIC        2057 : pq_settcpusertimeout(int timeout, Port *port)
                               1880                 : {
  418 peter                    1881 GBC        2057 :     if (port == NULL || port->laddr.addr.ss_family == AF_UNIX)
 1464 michael                  1882            1857 :         return STATUS_OK;
                               1883                 : 
 1464 michael                  1884 EUB             : #ifdef TCP_USER_TIMEOUT
 1464 michael                  1885 GIC         200 :     if (timeout == port->tcp_user_timeout)
                               1886             200 :         return STATUS_OK;
 1464 michael                  1887 EUB             : 
 1464 michael                  1888 UIC           0 :     if (port->default_tcp_user_timeout <= 0)
 1464 michael                  1889 EUB             :     {
 1464 michael                  1890 UIC           0 :         if (pq_gettcpusertimeout(port) < 0)
                               1891                 :         {
 1464 michael                  1892 UBC           0 :             if (timeout == 0)
 1464 michael                  1893 UIC           0 :                 return STATUS_OK;   /* default is set but unknown */
                               1894                 :             else
                               1895               0 :                 return STATUS_ERROR;
                               1896                 :         }
                               1897                 :     }
                               1898                 : 
                               1899               0 :     if (timeout == 0)
                               1900               0 :         timeout = port->default_tcp_user_timeout;
                               1901                 : 
 1464 michael                  1902 UBC           0 :     if (setsockopt(port->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
                               1903                 :                    (char *) &timeout, sizeof(timeout)) < 0)
                               1904                 :     {
  856 peter                    1905 UIC           0 :         ereport(LOG,
                               1906                 :                 (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_USER_TIMEOUT")));
 1464 michael                  1907               0 :         return STATUS_ERROR;
                               1908                 :     }
 1464 michael                  1909 ECB             : 
 1464 michael                  1910 UIC           0 :     port->tcp_user_timeout = timeout;
                               1911                 : #else
                               1912                 :     if (timeout != 0)
                               1913                 :     {
                               1914                 :         ereport(LOG,
                               1915                 :                 (errmsg("%s(%s) not supported", "setsockopt", "TCP_USER_TIMEOUT")));
                               1916                 :         return STATUS_ERROR;
                               1917                 :     }
                               1918                 : #endif
                               1919                 : 
                               1920               0 :     return STATUS_OK;
                               1921                 : }
  736 tmunro                   1922 ECB             : 
                               1923                 : /*
                               1924                 :  * GUC assign_hook for tcp_keepalives_idle
                               1925                 :  */
                               1926                 : void
  208 tgl                      1927 GNC        1857 : assign_tcp_keepalives_idle(int newval, void *extra)
                               1928                 : {
                               1929                 :     /*
                               1930                 :      * The kernel API provides no way to test a value without setting it; and
                               1931                 :      * once we set it we might fail to unset it.  So there seems little point
                               1932                 :      * in fully implementing the check-then-assign GUC API for these
                               1933                 :      * variables.  Instead we just do the assignment on demand.
                               1934                 :      * pq_setkeepalivesidle reports any problems via ereport(LOG).
                               1935                 :      *
                               1936                 :      * This approach means that the GUC value might have little to do with the
                               1937                 :      * actual kernel value, so we use a show_hook that retrieves the kernel
                               1938                 :      * value rather than trusting GUC's copy.
                               1939                 :      */
                               1940            1857 :     (void) pq_setkeepalivesidle(newval, MyProcPort);
                               1941            1857 : }
                               1942                 : 
                               1943                 : /*
                               1944                 :  * GUC show_hook for tcp_keepalives_idle
                               1945                 :  */
                               1946                 : const char *
                               1947            1088 : show_tcp_keepalives_idle(void)
                               1948                 : {
                               1949                 :     /* See comments in assign_tcp_keepalives_idle */
                               1950                 :     static char nbuf[16];
                               1951                 : 
                               1952            1088 :     snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort));
                               1953            1088 :     return nbuf;
                               1954                 : }
                               1955                 : 
                               1956                 : /*
                               1957                 :  * GUC assign_hook for tcp_keepalives_interval
                               1958                 :  */
                               1959                 : void
                               1960            1857 : assign_tcp_keepalives_interval(int newval, void *extra)
                               1961                 : {
                               1962                 :     /* See comments in assign_tcp_keepalives_idle */
                               1963            1857 :     (void) pq_setkeepalivesinterval(newval, MyProcPort);
                               1964            1857 : }
                               1965                 : 
                               1966                 : /*
                               1967                 :  * GUC show_hook for tcp_keepalives_interval
                               1968                 :  */
                               1969                 : const char *
                               1970            1088 : show_tcp_keepalives_interval(void)
                               1971                 : {
                               1972                 :     /* See comments in assign_tcp_keepalives_idle */
                               1973                 :     static char nbuf[16];
                               1974                 : 
                               1975            1088 :     snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort));
                               1976            1088 :     return nbuf;
                               1977                 : }
                               1978                 : 
                               1979                 : /*
                               1980                 :  * GUC assign_hook for tcp_keepalives_count
                               1981                 :  */
                               1982                 : void
                               1983            1857 : assign_tcp_keepalives_count(int newval, void *extra)
                               1984                 : {
                               1985                 :     /* See comments in assign_tcp_keepalives_idle */
                               1986            1857 :     (void) pq_setkeepalivescount(newval, MyProcPort);
                               1987            1857 : }
                               1988                 : 
                               1989                 : /*
                               1990                 :  * GUC show_hook for tcp_keepalives_count
                               1991                 :  */
                               1992                 : const char *
                               1993            1088 : show_tcp_keepalives_count(void)
                               1994                 : {
                               1995                 :     /* See comments in assign_tcp_keepalives_idle */
                               1996                 :     static char nbuf[16];
                               1997                 : 
                               1998            1088 :     snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort));
                               1999            1088 :     return nbuf;
                               2000                 : }
                               2001                 : 
                               2002                 : /*
                               2003                 :  * GUC assign_hook for tcp_user_timeout
                               2004                 :  */
                               2005                 : void
                               2006            1857 : assign_tcp_user_timeout(int newval, void *extra)
                               2007                 : {
                               2008                 :     /* See comments in assign_tcp_keepalives_idle */
                               2009            1857 :     (void) pq_settcpusertimeout(newval, MyProcPort);
                               2010            1857 : }
                               2011                 : 
                               2012                 : /*
                               2013                 :  * GUC show_hook for tcp_user_timeout
                               2014                 :  */
                               2015                 : const char *
                               2016            1088 : show_tcp_user_timeout(void)
                               2017                 : {
                               2018                 :     /* See comments in assign_tcp_keepalives_idle */
                               2019                 :     static char nbuf[16];
                               2020                 : 
                               2021            1088 :     snprintf(nbuf, sizeof(nbuf), "%d", pq_gettcpusertimeout(MyProcPort));
                               2022            1088 :     return nbuf;
                               2023                 : }
                               2024                 : 
  736 tmunro                   2025 ECB             : /*
                               2026                 :  * Check if the client is still connected.
                               2027                 :  */
                               2028                 : bool
  736 tmunro                   2029 UIC           0 : pq_check_connection(void)
                               2030                 : {
  419 tmunro                   2031 ECB             :     WaitEvent   events[FeBeWaitSetNEvents];
                               2032                 :     int         rc;
                               2033                 : 
                               2034                 :     /*
                               2035                 :      * It's OK to modify the socket event filter without restoring, because
                               2036                 :      * all FeBeWaitSet socket wait sites do the same.
                               2037                 :      */
  419 tmunro                   2038 UIC           0 :     ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, WL_SOCKET_CLOSED, NULL);
                               2039                 : 
                               2040               0 : retry:
                               2041               0 :     rc = WaitEventSetWait(FeBeWaitSet, 0, events, lengthof(events), 0);
                               2042               0 :     for (int i = 0; i < rc; ++i)
                               2043                 :     {
  419 tmunro                   2044 LBC           0 :         if (events[i].events & WL_SOCKET_CLOSED)
  419 tmunro                   2045 UIC           0 :             return false;
                               2046               0 :         if (events[i].events & WL_LATCH_SET)
  419 tmunro                   2047 ECB             :         {
                               2048                 :             /*
                               2049                 :              * A latch event might be preventing other events from being
                               2050                 :              * reported.  Reset it and poll again.  No need to restore it
                               2051                 :              * because no code should expect latches to survive across
                               2052                 :              * CHECK_FOR_INTERRUPTS().
                               2053                 :              */
  332 tgl                      2054 LBC           0 :             ResetLatch(MyLatch);
  332 tgl                      2055 UIC           0 :             goto retry;
                               2056                 :         }
                               2057                 :     }
                               2058                 : 
  736 tmunro                   2059 LBC           0 :     return true;
  736 tmunro                   2060 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a