From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dk4sock23.ctr | 172 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 support/dktools/dk4sock23.ctr (limited to 'support/dktools/dk4sock23.ctr') diff --git a/support/dktools/dk4sock23.ctr b/support/dktools/dk4sock23.ctr new file mode 100644 index 0000000000..8e711a175a --- /dev/null +++ b/support/dktools/dk4sock23.ctr @@ -0,0 +1,172 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + +%% module + + +#include "dk4sock.h" +#include "dk4mem.h" + + + +$!trace-include + + + +dk4_socket_set_t * +dk4socket_set_server_directly( + unsigned short portno, + int backlog, + int local, + dk4_er_t *erp +) +{ +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + struct sockaddr_in6 soin6; +#endif + struct sockaddr_in soin4; + dk4_socket_set_t *back = NULL; + size_t max; + int res; +#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR)) + int opt; +#endif + + if (0 < portno) { + max = 1; +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + max++; +#endif + back = dk4socket_set_new(max, erp); + if (NULL != back) { + /* IPv4 address + */ + DK4_MEMRES(&soin4, sizeof(soin4)); + soin4.sin_family = AF_INET; + soin4.sin_port = dk4socket_htons(portno); + if (0 != local) { + soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_LOOPBACK); + } else { + soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); + } + (back->pSockets)[back->szUsed] = dk4socket_open( + AF_INET, SOCK_STREAM, 0, erp + ); + if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) { +#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT) + dk4socket_set_one_bytes(&opt, sizeof(opt)); + res = setsockopt( + (back->pSockets)[back->szUsed], SOL_SOCKET, + SO_REUSEPORT, (void *)(&opt), sizeof(opt) + ); + if (0 != res) { $? "! failed to reuse port number" + } +#else +#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR) + $? ". SO_REUSEADDR" + dk4socket_set_one_bytes(&opt, sizeof(opt)); + res = setsockopt( + (back->pSockets)[back->szUsed], SOL_SOCKET, + SO_REUSEADDR, (void *)(&opt), sizeof(opt) + ); + if (0 != res) { $? "! failed to reuse address" + } +#else + $? ". neither SO_REUSEPORT nor SO_REUSEADDR" +#endif +#endif + + res = dk4socket_bind( + (back->pSockets)[back->szUsed], + (struct sockaddr *)(&soin4), + sizeof(soin4), + erp + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + res = dk4socket_listen( + (back->pSockets)[back->szUsed], + backlog, + erp + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + back->szUsed += 1; + } else { + (void)dk4socket_close((back->pSockets)[back->szUsed], NULL); + (back->pSockets)[back->szUsed] = INVALID_SOCKET; + } + } else { + (void)dk4socket_close((back->pSockets)[back->szUsed], NULL); + (back->pSockets)[back->szUsed] = INVALID_SOCKET; + } + } + /* IPv6 address if available + */ +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + DK4_MEMRES(&soin6, sizeof(soin6)); + soin6.sin6_family = AF_INET6; + if (0 != local) { soin6.sin6_addr.s6_addr[15] = 0x01; } + soin6.sin6_port = dk4socket_htons(portno); + (back->pSockets)[back->szUsed] = dk4socket_open( + AF_INET6, SOCK_STREAM, 0, erp + ); + if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) { +#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT) + dk4socket_set_one_bytes(&opt, sizeof(opt)); + res = setsockopt( + (back->pSockets)[back->szUsed], SOL_SOCKET, + SO_REUSEPORT, (void *)(&opt), sizeof(opt) + ); + if (0 != res) { $? "! failed to reuse port number" + } +#else +#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR) + $? ". SO_REUSEADDR" + dk4socket_set_one_bytes(&opt, sizeof(opt)); + res = setsockopt( + (back->pSockets)[back->szUsed], SOL_SOCKET, + SO_REUSEADDR, (void *)(&opt), sizeof(opt) + ); + if (0 != res) { $? "! failed to reuse address" + } +#else + $? ". neither SO_REUSEPORT nor SO_REUSEADDR" +#endif +#endif + res = dk4socket_bind( + (back->pSockets)[back->szUsed], + (struct sockaddr *)(&soin6), + sizeof(soin6), + erp + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + res = dk4socket_listen( + (back->pSockets)[back->szUsed], + backlog, + erp + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { + back->szUsed += 1; + } else { + (void)dk4socket_close((back->pSockets)[back->szUsed], NULL); + (back->pSockets)[back->szUsed] = INVALID_SOCKET; + } + } else { + (void)dk4socket_close((back->pSockets)[back->szUsed], NULL); + (back->pSockets)[back->szUsed] = INVALID_SOCKET; + } + } +#endif + if (0 == back->szUsed) { + dk4socket_set_delete(back, NULL); + back = NULL; + } + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + -- cgit v1.2.3