LCOV - differential code coverage report
Current view: top level - src/common - ip.c (source / functions) Coverage Total Hit UBC CBC
Current: 7a15cff1f11193467898da1c1fabf06fd2caee04 vs 84a3778c79c2d28b4dc281d03ef2ab019b16483b Lines: 76.0 % 75 57 18 57
Current Date: 2025-12-15 18:36:29 -0500 Functions: 100.0 % 5 5 5
Baseline: lcov-20251216-010103-baseline Branches: 60.0 % 60 36 24 36
Baseline Date: 2025-12-15 13:30:48 -0800 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(360..) days: 76.0 % 75 57 18 57
Function coverage date bins:
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(360..) days: 60.0 % 60 36 24 36

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * ip.c
                                  4                 :                :  *    IPv6-aware network access.
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/common/ip.c
                                 12                 :                :  *
                                 13                 :                :  * This file and the IPV6 implementation were initially provided by
                                 14                 :                :  * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
                                 15                 :                :  * http://www.lbsd.net.
                                 16                 :                :  *
                                 17                 :                :  *-------------------------------------------------------------------------
                                 18                 :                :  */
                                 19                 :                : 
                                 20                 :                : #ifndef FRONTEND
                                 21                 :                : #include "postgres.h"
                                 22                 :                : #else
                                 23                 :                : #include "postgres_fe.h"
                                 24                 :                : #endif
                                 25                 :                : 
                                 26                 :                : #include <unistd.h>
                                 27                 :                : #include <sys/stat.h>
                                 28                 :                : #include <sys/socket.h>
                                 29                 :                : #include <netdb.h>
                                 30                 :                : #include <netinet/in.h>
                                 31                 :                : #include <netinet/tcp.h>
                                 32                 :                : #include <arpa/inet.h>
                                 33                 :                : #include <sys/file.h>
                                 34                 :                : 
                                 35                 :                : #include "common/ip.h"
                                 36                 :                : 
                                 37                 :                : 
                                 38                 :                : 
                                 39                 :                : static int  getaddrinfo_unix(const char *path,
                                 40                 :                :                              const struct addrinfo *hintsp,
                                 41                 :                :                              struct addrinfo **result);
                                 42                 :                : 
                                 43                 :                : static int  getnameinfo_unix(const struct sockaddr_un *sa, int salen,
                                 44                 :                :                              char *node, int nodelen,
                                 45                 :                :                              char *service, int servicelen,
                                 46                 :                :                              int flags);
                                 47                 :                : 
                                 48                 :                : 
                                 49                 :                : /*
                                 50                 :                :  *  pg_getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets
                                 51                 :                :  *
                                 52                 :                :  * The API of this routine differs from the standard getaddrinfo() definition
                                 53                 :                :  * in that it requires a valid hintp, a null pointer is not allowed.
                                 54                 :                :  */
                                 55                 :                : int
 3392 heikki.linnakangas@i       56                 :CBC       18172 : pg_getaddrinfo_all(const char *hostname, const char *servname,
                                 57                 :                :                    const struct addrinfo *hintp, struct addrinfo **result)
                                 58                 :                : {
                                 59                 :                :     int         rc;
                                 60                 :                : 
                                 61                 :                :     /* not all versions of getaddrinfo() zero *result on failure */
                                 62                 :          18172 :     *result = NULL;
                                 63                 :                : 
                                 64         [ +  + ]:          18172 :     if (hintp->ai_family == AF_UNIX)
                                 65                 :          14007 :         return getaddrinfo_unix(servname, hintp, result);
                                 66                 :                : 
                                 67                 :                :     /* NULL has special meaning to getaddrinfo(). */
                                 68   [ +  -  +  - ]:           4165 :     rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
                                 69                 :                :                      servname, hintp, result);
                                 70                 :                : 
                                 71                 :           4165 :     return rc;
                                 72                 :                : }
                                 73                 :                : 
                                 74                 :                : 
                                 75                 :                : /*
                                 76                 :                :  *  pg_freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix
                                 77                 :                :  *
                                 78                 :                :  * Note: the ai_family field of the original hint structure must be passed
                                 79                 :                :  * so that we can tell whether the addrinfo struct was built by the system's
                                 80                 :                :  * getaddrinfo() routine or our own getaddrinfo_unix() routine.  Some versions
                                 81                 :                :  * of getaddrinfo() might be willing to return AF_UNIX addresses, so it's
                                 82                 :                :  * not safe to look at ai_family in the addrinfo itself.
                                 83                 :                :  */
                                 84                 :                : void
 3100 tgl@sss.pgh.pa.us          85                 :          18172 : pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
                                 86                 :                : {
 3392 heikki.linnakangas@i       87         [ +  + ]:          18172 :     if (hint_ai_family == AF_UNIX)
                                 88                 :                :     {
                                 89                 :                :         /* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */
                                 90         [ +  + ]:          28014 :         while (ai != NULL)
                                 91                 :                :         {
                                 92                 :          14007 :             struct addrinfo *p = ai;
                                 93                 :                : 
                                 94                 :          14007 :             ai = ai->ai_next;
                                 95                 :          14007 :             free(p->ai_addr);
                                 96                 :          14007 :             free(p);
                                 97                 :                :         }
                                 98                 :                :     }
                                 99                 :                :     else
                                100                 :                :     {
                                101                 :                :         /* struct was built by getaddrinfo() */
                                102         [ +  - ]:           4165 :         if (ai != NULL)
                                103                 :           4165 :             freeaddrinfo(ai);
                                104                 :                :     }
                                105                 :          18172 : }
                                106                 :                : 
                                107                 :                : 
                                108                 :                : /*
                                109                 :                :  *  pg_getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets
                                110                 :                :  *
                                111                 :                :  * The API of this routine differs from the standard getnameinfo() definition
                                112                 :                :  * in two ways: first, the addr parameter is declared as sockaddr_storage
                                113                 :                :  * rather than struct sockaddr, and second, the node and service fields are
                                114                 :                :  * guaranteed to be filled with something even on failure return.
                                115                 :                :  */
                                116                 :                : int
 3100 tgl@sss.pgh.pa.us         117                 :          26549 : pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
                                118                 :                :                    char *node, int nodelen,
                                119                 :                :                    char *service, int servicelen,
                                120                 :                :                    int flags)
                                121                 :                : {
                                122                 :                :     int         rc;
                                123                 :                : 
 3392 heikki.linnakangas@i      124   [ +  -  +  + ]:          26549 :     if (addr && addr->ss_family == AF_UNIX)
                                125                 :          25853 :         rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
                                126                 :                :                               node, nodelen,
                                127                 :                :                               service, servicelen,
                                128                 :                :                               flags);
                                129                 :                :     else
                                130                 :            696 :         rc = getnameinfo((const struct sockaddr *) addr, salen,
                                131                 :                :                          node, nodelen,
                                132                 :                :                          service, servicelen,
                                133                 :                :                          flags);
                                134                 :                : 
                                135         [ -  + ]:          26549 :     if (rc != 0)
                                136                 :                :     {
 3392 heikki.linnakangas@i      137         [ #  # ]:UBC           0 :         if (node)
                                138                 :              0 :             strlcpy(node, "???", nodelen);
                                139         [ #  # ]:              0 :         if (service)
                                140                 :              0 :             strlcpy(service, "???", servicelen);
                                141                 :                :     }
                                142                 :                : 
 3392 heikki.linnakangas@i      143                 :CBC       26549 :     return rc;
                                144                 :                : }
                                145                 :                : 
                                146                 :                : 
                                147                 :                : /* -------
                                148                 :                :  *  getaddrinfo_unix - get unix socket info using IPv6-compatible API
                                149                 :                :  *
                                150                 :                :  *  Bugs: only one addrinfo is set even though hintsp is NULL or
                                151                 :                :  *        ai_socktype is 0
                                152                 :                :  *        AI_CANONNAME is not supported.
                                153                 :                :  * -------
                                154                 :                :  */
                                155                 :                : static int
 3100 tgl@sss.pgh.pa.us         156                 :          14007 : getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
                                157                 :                :                  struct addrinfo **result)
                                158                 :                : {
 1249 peter@eisentraut.org      159                 :          14007 :     struct addrinfo hints = {0};
                                160                 :                :     struct addrinfo *aip;
                                161                 :                :     struct sockaddr_un *unp;
                                162                 :                : 
 3392 heikki.linnakangas@i      163                 :          14007 :     *result = NULL;
                                164                 :                : 
                                165         [ -  + ]:          14007 :     if (strlen(path) >= sizeof(unp->sun_path))
 3392 heikki.linnakangas@i      166                 :UBC           0 :         return EAI_FAIL;
                                167                 :                : 
 3392 heikki.linnakangas@i      168         [ -  + ]:CBC       14007 :     if (hintsp == NULL)
                                169                 :                :     {
 3392 heikki.linnakangas@i      170                 :UBC           0 :         hints.ai_family = AF_UNIX;
                                171                 :              0 :         hints.ai_socktype = SOCK_STREAM;
                                172                 :                :     }
                                173                 :                :     else
 3392 heikki.linnakangas@i      174                 :CBC       14007 :         memcpy(&hints, hintsp, sizeof(hints));
                                175                 :                : 
                                176         [ -  + ]:          14007 :     if (hints.ai_socktype == 0)
 3392 heikki.linnakangas@i      177                 :UBC           0 :         hints.ai_socktype = SOCK_STREAM;
                                178                 :                : 
 3392 heikki.linnakangas@i      179         [ -  + ]:CBC       14007 :     if (hints.ai_family != AF_UNIX)
                                180                 :                :     {
                                181                 :                :         /* shouldn't have been called */
 3392 heikki.linnakangas@i      182                 :UBC           0 :         return EAI_FAIL;
                                183                 :                :     }
                                184                 :                : 
 3392 heikki.linnakangas@i      185                 :CBC       14007 :     aip = calloc(1, sizeof(struct addrinfo));
                                186         [ -  + ]:          14007 :     if (aip == NULL)
 3392 heikki.linnakangas@i      187                 :UBC           0 :         return EAI_MEMORY;
                                188                 :                : 
 3392 heikki.linnakangas@i      189                 :CBC       14007 :     unp = calloc(1, sizeof(struct sockaddr_un));
                                190         [ -  + ]:          14007 :     if (unp == NULL)
                                191                 :                :     {
 3392 heikki.linnakangas@i      192                 :UBC           0 :         free(aip);
                                193                 :              0 :         return EAI_MEMORY;
                                194                 :                :     }
                                195                 :                : 
 3392 heikki.linnakangas@i      196                 :CBC       14007 :     aip->ai_family = AF_UNIX;
                                197                 :          14007 :     aip->ai_socktype = hints.ai_socktype;
                                198                 :          14007 :     aip->ai_protocol = hints.ai_protocol;
                                199                 :          14007 :     aip->ai_next = NULL;
                                200                 :          14007 :     aip->ai_canonname = NULL;
                                201                 :          14007 :     *result = aip;
                                202                 :                : 
                                203                 :          14007 :     unp->sun_family = AF_UNIX;
                                204                 :          14007 :     aip->ai_addr = (struct sockaddr *) unp;
                                205                 :          14007 :     aip->ai_addrlen = sizeof(struct sockaddr_un);
                                206                 :                : 
                                207                 :          14007 :     strcpy(unp->sun_path, path);
                                208                 :                : 
                                209                 :                :     /*
                                210                 :                :      * If the supplied path starts with @, replace that with a zero byte for
                                211                 :                :      * the internal representation.  In that mode, the entire sun_path is the
                                212                 :                :      * address, including trailing zero bytes.  But we set the address length
                                213                 :                :      * to only include the length of the original string.  That way the
                                214                 :                :      * trailing zero bytes won't show up in any network or socket lists of the
                                215                 :                :      * operating system.  This is just a convention, also followed by other
                                216                 :                :      * packages.
                                217                 :                :      */
 1847 peter@eisentraut.org      218         [ -  + ]:          14007 :     if (path[0] == '@')
                                219                 :                :     {
 1847 peter@eisentraut.org      220                 :UBC           0 :         unp->sun_path[0] = '\0';
                                221                 :              0 :         aip->ai_addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(path);
                                222                 :                :     }
                                223                 :                : 
 3392 heikki.linnakangas@i      224                 :CBC       14007 :     return 0;
                                225                 :                : }
                                226                 :                : 
                                227                 :                : /*
                                228                 :                :  * Convert an address to a hostname.
                                229                 :                :  */
                                230                 :                : static int
 3100 tgl@sss.pgh.pa.us         231                 :          25853 : getnameinfo_unix(const struct sockaddr_un *sa, int salen,
                                232                 :                :                  char *node, int nodelen,
                                233                 :                :                  char *service, int servicelen,
                                234                 :                :                  int flags)
                                235                 :                : {
                                236                 :                :     int         ret;
                                237                 :                : 
                                238                 :                :     /* Invalid arguments. */
 3392 heikki.linnakangas@i      239   [ +  -  +  -  :          25853 :     if (sa == NULL || sa->sun_family != AF_UNIX ||
                                              +  + ]
                                240         [ -  + ]:          13208 :         (node == NULL && service == NULL))
 3392 heikki.linnakangas@i      241                 :UBC           0 :         return EAI_FAIL;
                                242                 :                : 
 3392 heikki.linnakangas@i      243         [ +  + ]:CBC       25853 :     if (node)
                                244                 :                :     {
                                245                 :          12645 :         ret = snprintf(node, nodelen, "%s", "[local]");
 2680 tgl@sss.pgh.pa.us         246   [ +  -  -  + ]:          12645 :         if (ret < 0 || ret >= nodelen)
 3392 heikki.linnakangas@i      247                 :UBC           0 :             return EAI_MEMORY;
                                248                 :                :     }
                                249                 :                : 
 3392 heikki.linnakangas@i      250         [ +  + ]:CBC       25853 :     if (service)
                                251                 :                :     {
                                252                 :                :         /*
                                253                 :                :          * Check whether it looks like an abstract socket, but it could also
                                254                 :                :          * just be an empty string.
                                255                 :                :          */
 1847 peter@eisentraut.org      256   [ +  +  -  + ]:          25846 :         if (sa->sun_path[0] == '\0' && sa->sun_path[1] != '\0')
 1847 peter@eisentraut.org      257                 :UBC           0 :             ret = snprintf(service, servicelen, "@%s", sa->sun_path + 1);
                                258                 :                :         else
 1847 peter@eisentraut.org      259                 :CBC       25846 :             ret = snprintf(service, servicelen, "%s", sa->sun_path);
 2680 tgl@sss.pgh.pa.us         260   [ +  -  -  + ]:          25846 :         if (ret < 0 || ret >= servicelen)
 3392 heikki.linnakangas@i      261                 :UBC           0 :             return EAI_MEMORY;
                                262                 :                :     }
                                263                 :                : 
 3392 heikki.linnakangas@i      264                 :CBC       25853 :     return 0;
                                265                 :                : }
        

Generated by: LCOV version 2.4-beta