commit 75716fd6ed1a99a0e601b2820363b17d7c0333a7 from: Thomas Adam date: Sat Aug 27 17:51:57 2022 UTC portable: sockets: handle sa_len/ss_len portably In the sockaddr_storage struct, there can be a ss_len field. This is seen on some BSDs, but not Linux. Since this isn't POSIX-specific, there's no guarantee it will be available on all systems. commit - 0b75e088e5e7799559ddc81934e9d06c29f10c5b commit + 75716fd6ed1a99a0e601b2820363b17d7c0333a7 blob - c7430a2ac5b8b9bbade860a42ce3959bcf0449a0 blob + 554ab266ff55ce404d9d1fe773286dbbadbfeb51 --- configure.ac +++ configure.ac @@ -83,6 +83,35 @@ AC_TYPE_UINT8_T # Check for ifgroupreq which is only available on BSD. AC_CHECK_TYPES([struct ifgroupreq]) +# Check for sockaddr_storage. On some systems, ss_len is filled out, although +# this is not mandated by POSIX, and hence systems such as linux, don't have +# it. +AC_CHECK_TYPES([struct sockaddr_storage], [], [], [ +#include +#include +]) + +# Same thing as sockaddr_storage above, only now check if the member exists in +# the struct as well. +AC_CHECK_MEMBERS([struct sockaddr_storage.ss_len], , , + [ #include + #include + #include ] +) + +AC_CHECK_MEMBERS([struct sockaddr.sa_len], , , + [ #include + #include + #include ] +) + +# Both checks above will result in: +# +# HAVE_STRUCT_SOCKADDR_AS_LEN +# SS_LEN +# +# Either being defined or not. + # Look for library needed for flock. AC_SEARCH_LIBS(flock, bsd) blob - c59d9dd4fdcf5133bae8ce3411896c675c37f956 blob + f007a7588d8c6facc9de0df884df46e60482a84d --- gotwebd/sockets.c +++ gotwebd/sockets.c @@ -524,7 +524,7 @@ sockets_create_socket(struct address *a, in_port_t por return -1; } - if (bind(fd, (struct sockaddr *)&a->ss, a->ss.ss_len) == -1) { + if (bind(fd, (struct sockaddr *)&a->ss, SS_LEN(&a->ss)) == -1) { close(fd); log_info("%s: can't bind to port %d", __func__, ntohs(port)); blob - 9b586119d4d22d75fd6373a77e85867d2cc3ab1c blob + 8d52a920333aebf6b2466dcbb50e15c4bae98549 --- include/got_compat.h +++ include/got_compat.h @@ -200,8 +200,36 @@ void uuid_to_string(uuid_t *, char **, uint32_t *); #define SHA1Init SHA1_Init #define SHA1Update SHA1_Update #define SHA1Final SHA1_Final +#endif + +/* + * The following SA_LEN/SS_LEN dance comes from various source, notably + * OpenSMTP by way of OpenNTPD and OpenBGPD (thanks everyone!). got-portable + * has tweaked a lot of the following macros to suit the needs of + * got-portable. + */ + +/* From OpenNTPD portable */ +#if !defined(SA_LEN) +# if defined(HAVE_STRUCT_SOCKADDR_SA_LEN) +# define SA_LEN(x) ((x)->sa_len) +# else +# define SA_LEN(x) ((x)->sa_family == AF_INET6 ? \ + sizeof(struct sockaddr_in6) : \ + sizeof(struct sockaddr_in)) +# endif + #endif +/* From OpenBGPD portable */ +#if !defined(SS_LEN) +# if defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN) +# define SS_LEN(x) ((x)->ss_len) +# else +# define SS_LEN(x) SA_LEN((struct sockaddr *)(x)) +# endif +#endif + #ifndef HAVE_ASPRINTF /* asprintf.c */ int asprintf(char **, const char *, ...);