From e5fbf1967f387625f8181b8258d3be56e80dba58 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 25 Mar 2018 02:53:03 +0000 Subject: [PATCH] added hcl_get_sockaddr_info() --- lib/hcl-utl.h | 10 ++++++++++ lib/main-c.c | 49 +++++++++++++++++++++++++++++-------------------- lib/utl.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/lib/hcl-utl.h b/lib/hcl-utl.h index 5f10a1d..85eec67 100644 --- a/lib/hcl-utl.h +++ b/lib/hcl-utl.h @@ -636,6 +636,16 @@ HCL_EXPORT int hcl_bcharstosckaddr ( # define hcl_oochars_to_sckaddr hcl_bchars_to_sckaddr #endif +/** + * The hcl_get_sckaddr_info() function returns the socket family. + * if \a scklen is not #HCL_NULL, it also sets the actual address length + * in the memory pointed to by it. + */ +HCL_EXPORT int hcl_get_sckaddr_info ( + const hcl_sckaddr_t* sckaddr, + hcl_scklen_t* scklen +); + #if defined(__cplusplus) } #endif diff --git a/lib/main-c.c b/lib/main-c.c index cce9044..b51fd44 100644 --- a/lib/main-c.c +++ b/lib/main-c.c @@ -510,7 +510,7 @@ static int feed_data (hcl_client_t* client, const void* ptr, hcl_oow_t len) /* ========================================================================= */ -static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script, int shut_wr_after_req) +static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script, int reuse_addr, int shut_wr_after_req) { hcl_sckaddr_t sckaddr; hcl_scklen_t scklen; @@ -542,23 +542,26 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* goto oops; } - if (sckfam == AF_INET) + if (reuse_addr) { - struct sockaddr_in anyaddr; - int opt = 1; - setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); - memset (&anyaddr, 0, HCL_SIZEOF(anyaddr)); - anyaddr.sin_family = sckfam; - bind(sck, (struct sockaddr *)&anyaddr, scklen); - } - else if (sckfam == AF_INET6) - { - struct sockaddr_in6 anyaddr; - int opt = 1; - setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); - memset (&anyaddr, 0, HCL_SIZEOF(anyaddr)); - anyaddr.sin6_family = sckfam; - bind(sck, (struct sockaddr *)&anyaddr, scklen); + if (sckfam == AF_INET) + { + struct sockaddr_in anyaddr; + int opt = 1; + setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); + memset (&anyaddr, 0, HCL_SIZEOF(anyaddr)); + anyaddr.sin_family = sckfam; + bind(sck, (struct sockaddr *)&anyaddr, scklen); + } + else if (sckfam == AF_INET6) + { + struct sockaddr_in6 anyaddr; + int opt = 1; + setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); + memset (&anyaddr, 0, HCL_SIZEOF(anyaddr)); + anyaddr.sin6_family = sckfam; + bind(sck, (struct sockaddr *)&anyaddr, scklen); + } } if (connect(sck, (struct sockaddr*)&sckaddr, scklen) <= -1) @@ -678,6 +681,7 @@ int main (int argc, char* argv[]) static hcl_bopt_lng_t lopt[] = { { ":log", 'l' }, + { "reuseaddr", '\0' }, { "shutwr", '\0' }, { HCL_NULL, '\0' } }; @@ -692,6 +696,7 @@ int main (int argc, char* argv[]) hcl_client_prim_t client_prim; int n; const char* logopt = HCL_NULL; + int reuse_addr = 0; int shut_wr_after_req = 0; setlocale (LC_ALL, ""); @@ -699,7 +704,7 @@ int main (int argc, char* argv[]) if (argc < 2) { print_usage: - fprintf (stderr, "Usage: %s [-l/--log log-options] [--shutwr] bind-address:port script-to-run\n", argv[0]); + fprintf (stderr, "Usage: %s [-l/--log log-options] [--reuseaddr] [--shutwr] bind-address:port script-to-run\n", argv[0]); return -1; } @@ -712,7 +717,11 @@ int main (int argc, char* argv[]) break; case '\0': - if (hcl_compbcstr(opt.lngopt, "shutwr") == 0) + if (hcl_compbcstr(opt.lngopt, "reuseaddr") == 0) + { + reuse_addr = 1; + } + else if (hcl_compbcstr(opt.lngopt, "shutwr") == 0) { shut_wr_after_req = 1; } @@ -770,7 +779,7 @@ int main (int argc, char* argv[]) set_signal (SIGINT, handle_sigint); set_signal_to_ignore (SIGPIPE); - n = handle_request (client, argv[opt.ind], argv[opt.ind + 1], shut_wr_after_req); + n = handle_request (client, argv[opt.ind], argv[opt.ind + 1], reuse_addr, shut_wr_after_req); set_signal_to_default (SIGINT); set_signal_to_default (SIGPIPE); diff --git a/lib/utl.c b/lib/utl.c index 93527d3..bb2ddca 100644 --- a/lib/utl.c +++ b/lib/utl.c @@ -1115,7 +1115,10 @@ hcl_uint128_t hcl_hton128 (hcl_uint128_t x) union sockaddr_t { + struct sockaddr sa; +#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN > 0) struct sockaddr_in in4; +#endif #if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) struct sockaddr_in6 in6; #endif @@ -1147,3 +1150,31 @@ typedef union sockaddr_t sockaddr_t; #define str_to_ipv6 uchars_to_ipv6 #define str_to_sockaddr hcl_ucharstosckaddr #include "sa-utl.h" + + +int hcl_get_sckaddr_info (const hcl_sckaddr_t* sckaddr, hcl_scklen_t* scklen) +{ + sockaddr_t* sa = (sockaddr_t*)sckaddr; + if (scklen) + { + switch (sa->sa.sa_family) + { + #if (HCL_SIZEOF_STRUCT_SOCKADDR_IN > 0) + case AF_INET: + *scklen = HCL_SIZEOF(sa->in4); + break; + #endif + + #if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + case AF_INET6: + *scklen = HCL_SIZEOF(sa->in6); + break; + #endif + + default: + *scklen = 0; /* unknown */ + break; + } + } + return sa->sa.sa_family; +}