From a0bd10822acca12c0b279842e4fdae042f8c354d Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 9 Aug 2021 08:24:21 +0000 Subject: [PATCH] tweaked the hio_skad_t structure to hold extra information required for sctp seqpacket sockets sctp seqpacket socket support is not completed yet --- hio/bin/t06.c | 23 +++- hio/configure | 181 +++++++++++++++++++++++++++++- hio/configure.ac | 41 ++++++- hio/lib/hio-cfg.h.in | 12 ++ hio/lib/hio-sck.h | 2 +- hio/lib/hio-skad.h | 26 ++++- hio/lib/hio.h | 12 +- hio/lib/http-svr.c | 27 ++++- hio/lib/sck.c | 258 ++++++++++++++++++++++++++++++------------- hio/lib/skad.c | 210 ++++++++++++++++++++++++----------- hio/lib/utl.c | 52 --------- 11 files changed, 628 insertions(+), 216 deletions(-) diff --git a/hio/bin/t06.c b/hio/bin/t06.c index 24f9bc0..5054233 100644 --- a/hio/bin/t06.c +++ b/hio/bin/t06.c @@ -452,15 +452,29 @@ static void tcp_sck_on_raw_accept (hio_dev_sck_t* sck, hio_syshnd_t syshnd, hio_ try_to_accept (sck, &qxmsg, 0); } -static int tcp_sck_on_write (hio_dev_sck_t* tcp, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr) +static int tcp_sck_on_write (hio_dev_sck_t* sck, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr) { - /* won't be invoked */ + /* won't be invoked if tcp. + * invokde if sctp_sp */ +//printf ("wrote back chan %d\n", hio_skad_chan(dstaddr)); return 0; } -static int tcp_sck_on_read (hio_dev_sck_t* tcp, const void* buf, hio_iolen_t len, const hio_skad_t* srcaddr) +static int tcp_sck_on_read (hio_dev_sck_t* sck, const void* buf, hio_iolen_t len, const hio_skad_t* srcaddr) { - /* won't be invoked */ + /* won't be invoked + * invokde if sctp_sp */ + hio_iovec_t iov; + +#if 0 +/* the code here is invoked on a seqpacket socket. .. this part not ready. will rewrite if the core support is done */ +printf ("[%.*s] chan %d\n", (int)len, buf, hio_skad_chan(srcaddr)); +iov.iov_ptr = buf; +iov.iov_len = len; +hio_skad_set_scope_id (srcaddr, 3); +hio_dev_sck_writev (sck, &iov, 1, HIO_NULL, srcaddr); +#endif + return 0; } @@ -652,7 +666,6 @@ oops: pthread_join (t[i], HIO_NULL); } - if (hio) hio_close (hio); return xret; } diff --git a/hio/configure b/hio/configure index 929af2c..cbf1d0c 100755 --- a/hio/configure +++ b/hio/configure @@ -17569,6 +17569,89 @@ cat >>confdefs.h <<_ACEOF _ACEOF + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_in_x" >&5 +$as_echo_n "checking size of struct sockaddr_in_x... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_in_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in_x))" "ac_cv_sizeof_struct_sockaddr_in_x" " + #include + #include + struct sockaddr_in_x { + struct sockaddr_in a; + unsigned short chan; + }; + +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_in_x" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_in_x) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_in_x=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_in_x" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_in_x" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_IN_X $ac_cv_sizeof_struct_sockaddr_in_x +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_in6_x" >&5 +$as_echo_n "checking size of struct sockaddr_in6_x... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_in6_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in6_x))" "ac_cv_sizeof_struct_sockaddr_in6_x" " + #include + #include + struct sockaddr_in6_x { + struct sockaddr_in6 a; + unsigned short chan; + }; + +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_in6_x" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_in6_x) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_in6_x=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_in6_x" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_in6_x" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_IN6_X $ac_cv_sizeof_struct_sockaddr_in6_x +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -17929,6 +18012,91 @@ cat >>confdefs.h <<_ACEOF _ACEOF + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_in_x" >&5 +$as_echo_n "checking size of struct sockaddr_in_x... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_in_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in_x))" "ac_cv_sizeof_struct_sockaddr_in_x" " + #include + #include + #include + struct sockaddr_in_x { + struct sockaddr_in a; + unsigned short chan; + }; + +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_in_x" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_in_x) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_in_x=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_in_x" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_in_x" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_IN_X $ac_cv_sizeof_struct_sockaddr_in_x +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_in6_x" >&5 +$as_echo_n "checking size of struct sockaddr_in6_x... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_in6_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in6_x))" "ac_cv_sizeof_struct_sockaddr_in6_x" " + #include + #include + #include + struct sockaddr_in6_x { + struct sockaddr_in6 a; + unsigned short chan; + }; + +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_in6_x" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_in6_x) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_in6_x=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_in6_x" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_in6_x" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_IN6_X $ac_cv_sizeof_struct_sockaddr_in6_x +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -18041,7 +18209,6 @@ _ACEOF - # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -18542,6 +18709,18 @@ cat >>confdefs.h <<_ACEOF _ACEOF + +cat >>confdefs.h <<_ACEOF +#define HIO_SIZEOF_STRUCT_SOCKADDR_IN_X ${ac_cv_sizeof_struct_sockaddr_in_x} +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HIO_SIZEOF_STRUCT_SOCKADDR_IN6_X ${ac_cv_sizeof_struct_sockaddr_in6_x} +_ACEOF + + + cat >>confdefs.h <<_ACEOF #define HIO_SIZEOF_STRUCT_SOCKADDR_UN ${ac_cv_sizeof_struct_sockaddr_un} _ACEOF diff --git a/hio/configure.ac b/hio/configure.ac index 7b7f121..04590df 100644 --- a/hio/configure.ac +++ b/hio/configure.ac @@ -466,6 +466,23 @@ then AC_CHECK_SIZEOF(struct sockaddr_in6,,[ #include #include ]) + AC_CHECK_SIZEOF(struct sockaddr_in_x,,[ + #include + #include + struct sockaddr_in_x { + struct sockaddr_in a; + unsigned short chan; + }; + ]) + AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[ + #include + #include + struct sockaddr_in6_x { + struct sockaddr_in6 a; + unsigned short chan; + }; + ]) + AC_CHECK_SIZEOF(struct sockaddr_un,,[ #include #include ]) @@ -518,6 +535,25 @@ else #include #include #include ]) + AC_CHECK_SIZEOF(struct sockaddr_in_x,,[ + #include + #include + #include + struct sockaddr_in_x { + struct sockaddr_in a; + unsigned short chan; + }; + ]) + AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[ + #include + #include + #include + struct sockaddr_in6_x { + struct sockaddr_in6 a; + unsigned short chan; + }; + ]) + AC_CHECK_SIZEOF(struct sockaddr_un,,[ #include #include @@ -531,7 +567,6 @@ else #include #include ]) - AC_CHECK_SIZEOF(socklen_t,, [ #include #include ]) @@ -696,6 +731,10 @@ AC_DEFINE_UNQUOTED(HIO_AF_UNIX, (${ax_cv_numvalof_AF_UNIX}), [AF_UNIX]) AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_IN, ${ac_cv_sizeof_struct_sockaddr_in}, [sizeof(struct sockaddr_in)]) AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_IN6, ${ac_cv_sizeof_struct_sockaddr_in6}, [sizeof(struct sockaddr_in6)]) + +AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_IN_X, ${ac_cv_sizeof_struct_sockaddr_in_x}, [sizeof(struct sockaddr_in_x)]) +AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_IN6_X, ${ac_cv_sizeof_struct_sockaddr_in6_x}, [sizeof(struct sockaddr_in6_x)]) + AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_UN, ${ac_cv_sizeof_struct_sockaddr_un}, [sizeof(struct sockaddr_un)]) AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_LL, ${ac_cv_sizeof_struct_sockaddr_ll}, [sizeof(struct sockaddr_ll)]) AC_DEFINE_UNQUOTED(HIO_SIZEOF_STRUCT_SOCKADDR_DL, ${ac_cv_sizeof_struct_sockaddr_dl}, [sizeof(struct sockaddr_dl)]) diff --git a/hio/lib/hio-cfg.h.in b/hio/lib/hio-cfg.h.in index 67e353d..1cb983e 100644 --- a/hio/lib/hio-cfg.h.in +++ b/hio/lib/hio-cfg.h.in @@ -648,6 +648,12 @@ /* sizeof(struct sockaddr_in6) */ #undef HIO_SIZEOF_STRUCT_SOCKADDR_IN6 +/* sizeof(struct sockaddr_in6_x) */ +#undef HIO_SIZEOF_STRUCT_SOCKADDR_IN6_X + +/* sizeof(struct sockaddr_in_x) */ +#undef HIO_SIZEOF_STRUCT_SOCKADDR_IN_X + /* sizeof(struct sockaddr_ll) */ #undef HIO_SIZEOF_STRUCT_SOCKADDR_LL @@ -790,6 +796,12 @@ /* The size of `struct sockaddr_in6', as computed by sizeof. */ #undef SIZEOF_STRUCT_SOCKADDR_IN6 +/* The size of `struct sockaddr_in6_x', as computed by sizeof. */ +#undef SIZEOF_STRUCT_SOCKADDR_IN6_X + +/* The size of `struct sockaddr_in_x', as computed by sizeof. */ +#undef SIZEOF_STRUCT_SOCKADDR_IN_X + /* The size of `struct sockaddr_ll', as computed by sizeof. */ #undef SIZEOF_STRUCT_SOCKADDR_LL diff --git a/hio/lib/hio-sck.h b/hio/lib/hio-sck.h index 4e6e4f0..5ef07bf 100644 --- a/hio/lib/hio-sck.h +++ b/hio/lib/hio-sck.h @@ -379,7 +379,7 @@ struct hio_dev_sck_t int state; - /* remote peer address for a stateful stream socket. valid if one of the + /* remote peer address for a stream socket. valid if one of the * followings is set in state: * HIO_DEV_TCP_ACCEPTING_SSL * HIO_DEV_TCP_ACCEPTED diff --git a/hio/lib/hio-skad.h b/hio/lib/hio-skad.h index 1a16211..adc68e8 100644 --- a/hio/lib/hio-skad.h +++ b/hio/lib/hio-skad.h @@ -31,13 +31,13 @@ #include #define HIO_SIZEOF_SKAD_T 1 -#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > HIO_SIZEOF_SKAD_T) +#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN_X > HIO_SIZEOF_SKAD_T) # undef HIO_SIZEOF_SKAD_T -# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN +# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN_X #endif -#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > HIO_SIZEOF_SKAD_T) +#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6_X > HIO_SIZEOF_SKAD_T) # undef HIO_SIZEOF_SKAD_T -# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN6 +# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN6_X #endif #if (HIO_SIZEOF_STRUCT_SOCKADDR_LL > HIO_SIZEOF_SKAD_T) # undef HIO_SIZEOF_SKAD_T @@ -200,6 +200,24 @@ HIO_EXPORT int hio_skad_ifindex ( const hio_skad_t* skad ); +HIO_EXPORT int hio_skad_scope_id ( + const hio_skad_t* skad +); + +HIO_EXPORT void hio_skad_set_scope_id ( + hio_skad_t* skad, + int scope_id +); + +HIO_EXPORT hio_uint16_t hio_skad_chan ( + const hio_skad_t* skad +); + +HIO_EXPORT void hio_skad_set_chan ( + hio_skad_t* skad, + hio_uint16_t chan +); + HIO_EXPORT void hio_clear_skad ( hio_skad_t* skad ); diff --git a/hio/lib/hio.h b/hio/lib/hio.h index 3063811..e9a395d 100644 --- a/hio/lib/hio.h +++ b/hio/lib/hio.h @@ -995,12 +995,12 @@ HIO_EXPORT int hio_dev_sendfile ( ); HIO_EXPORT int hio_dev_timedwrite ( - hio_dev_t* dev, - const void* data, - hio_iolen_t len, - const hio_ntime_t* tmout, - void* wrctx, - const hio_devaddr_t* dstaddr + hio_dev_t* dev, + const void* data, + hio_iolen_t len, + const hio_ntime_t* tmout, + void* wrctx, + const hio_devaddr_t* dstaddr ); diff --git a/hio/lib/http-svr.c b/hio/lib/http-svr.c index 4074e74..f5a33ac 100644 --- a/hio/lib/http-svr.c +++ b/hio/lib/http-svr.c @@ -27,6 +27,8 @@ #include "http-prv.h" #include +#define INVALID_LIDX HIO_TYPE_MAX(hio_oow_t) + /* ------------------------------------------------------------------------ */ static int client_htrd_peek_request (hio_htrd_t* htrd, hio_htre_t* req) { @@ -48,11 +50,11 @@ static int init_client (hio_svc_htts_cli_t* cli, hio_dev_sck_t* sck) /* the htts field must be filled with the same field in the listening socket upon accept() */ HIO_ASSERT (sck->hio, cli->htts != HIO_NULL); - //HIO_ASSERT (sck->hio, cli->sck == cli->htts->lsck); /* the field should still point to the listner socket */ + HIO_ASSERT (sck->hio, cli->l_idx < cli->htts->l.count); /* at this point, it's still the listener's index as it's cloned */ HIO_ASSERT (sck->hio, sck->hio == cli->htts->hio); cli->sck = sck; - cli->l_idx = HIO_TYPE_MAX(hio_oow_t); + cli->l_idx = INVALID_LIDX; /* not a listening socket anymore */ cli->htrd = HIO_NULL; cli->sbuf = HIO_NULL; cli->rsrc = HIO_NULL; @@ -139,8 +141,12 @@ static int listener_on_read (hio_dev_sck_t* sck, const void* buf, hio_iolen_t le hio_oow_t rem; int x; - //HIO_ASSERT (hio, sck != cli->htts->lsck); - HIO_ASSERT (hio, cli->rsrc == HIO_NULL); /* if a resource has been set, the resource must take over this handler */ + HIO_ASSERT (hio, cli->l_idx == INVALID_LIDX); + + /* if a resource has been set(cli->rsrc not NULL), the resource must take over + * this handler. this handler is never called unless the the overriding handler + * call this. */ + HIO_ASSERT (hio, cli->rsrc == HIO_NULL); if (len <= -1) { @@ -182,9 +188,18 @@ oops: static int listener_on_write (hio_dev_sck_t* sck, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr) { + /* don't get deluded by the name. it's set on both the listener and the client. + * it is not supposed to be triggered on the listener, however */ hio_svc_htts_cli_t* cli = hio_dev_sck_getxtn(sck); - //HIO_ASSERT (sck->hio, sck != cli->htts->lsck); - HIO_ASSERT (sck->hio, cli->rsrc == HIO_NULL); /* if a resource has been set, the resource must take over this handler */ + HIO_ASSERT (sck->hio, cli->l_idx == INVALID_LIDX); + + /* if a resource has been set(cli->rsrc not NULL), the resource must take over + * this handler. this handler is never called unless the the overriding handler + * call this. */ + HIO_ASSERT (sck->hio, cli->rsrc == HIO_NULL); + + /* anyways, nothing to do upon write completion */ + return 0; } diff --git a/hio/lib/sck.c b/hio/lib/sck.c index 31f96e5..76819e2 100644 --- a/hio/lib/sck.c +++ b/hio/lib/sck.c @@ -24,7 +24,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include #include "hio-prv.h" @@ -95,7 +94,6 @@ static hio_syshnd_t open_async_socket (hio_t* hio, int domain, int type, int proto) { hio_syshnd_t sck = HIO_SYSHND_INVALID; - int flags; #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) type |= SOCK_NONBLOCK | SOCK_CLOEXEC; @@ -179,8 +177,10 @@ done: static hio_syshnd_t open_async_bpf (hio_t* hio) { hio_syshnd_t fd = HIO_SYSHND_INVALID; +#if 0 int tmp; unsigned int bufsize; +#endif fd = open("/dev/bpf", O_RDWR); if (fd == HIO_SYSHND_INVALID) goto oops; @@ -265,10 +265,12 @@ static struct sck_type_map_t sck_type_map[] = { AF_INET6, SOCK_STREAM, IPPROTO_SCTP, 1, 1, HIO_DEV_CAP_STREAM }, /* HIO_DEV_SCK_SCTP4_SP - not implemented */ - { AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 1, 1, 0 }, + /*{ AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 1, 1, 0 },*/ + { -1, 0, 0, 0, 0, 0 }, /* HIO_DEV_SCK_SCTP6_SP - not implemented */ - { AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 1, 1, 0 }, + /*{ AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 1, 1, 0 },*/ + { -1, 0, 0, 0, 0, 0 }, #else { -1, 0, 0, 0, 0, 0 }, { -1, 0, 0, 0, 0, 0 }, @@ -363,39 +365,12 @@ static void ssl_connect_timedout (hio_t* hio, const hio_ntime_t* now, hio_tmrjob static HIO_INLINE int schedule_timer_job_at (hio_dev_sck_t* dev, const hio_ntime_t* fire_at, hio_tmrjob_handler_t handler) { -#if 1 return hio_schedtmrjobat(dev->hio, fire_at, handler, &dev->tmrjob_index, dev); -#else - hio_tmrjob_t tmrjob; - - HIO_MEMSET (&tmrjob, 0, HIO_SIZEOF(tmrjob)); - tmrjob.ctx = dev; - tmrjob.when = *fire_at; - - tmrjob.handler = handler; - tmrjob.idxptr = &dev->tmrjob_index; - - HIO_ASSERT (dev->hio, dev->tmrjob_index == HIO_TMRIDX_INVALID); - dev->tmrjob_index = hio_instmrjob(dev->hio, &tmrjob); - return dev->tmrjob_index == HIO_TMRIDX_INVALID? -1: 0; -#endif } static HIO_INLINE int schedule_timer_job_after (hio_dev_sck_t* dev, const hio_ntime_t* fire_after, hio_tmrjob_handler_t handler) { -#if 1 return hio_schedtmrjobafter(dev->hio, fire_after, handler, &dev->tmrjob_index, dev); -#else - hio_t* hio = dev->hio; - hio_ntime_t fire_at; - - HIO_ASSERT (hio, HIO_IS_POS_NTIME(fire_after)); - - hio_gettime (hio, &fire_at); - HIO_ADD_NTIME (&fire_at, &fire_at, fire_after); - - return schedule_timer_job_at(dev, &fire_at, handler); -#endif } /* ======================================================================== */ @@ -519,6 +494,7 @@ static int dev_sck_kill (hio_dev_t* dev, int force) hio_t* hio = dev->hio; hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; +#if 0 if (IS_STREAM(rdev)) { /*if (HIO_DEV_SCK_GET_PROGRESS(rdev)) @@ -528,20 +504,22 @@ static int dev_sck_kill (hio_dev_t* dev, int force) * it is the same if connect or accept has not been called. */ if (rdev->on_disconnect) rdev->on_disconnect (rdev); /*}*/ - - if (rdev->tmrjob_index != HIO_TMRIDX_INVALID) - { - hio_deltmrjob (hio, rdev->tmrjob_index); - HIO_ASSERT (hio, rdev->tmrjob_index == HIO_TMRIDX_INVALID); - } } else { - HIO_ASSERT (hio, (rdev->state & HIO_DEV_SCK_ALL_PROGRESS_BITS) == 0); - HIO_ASSERT (hio, rdev->tmrjob_index == HIO_TMRIDX_INVALID); + /* non-stream, but lisenable or connectable can have the progress bits on */ + /*HIO_ASSERT (hio, (rdev->state & HIO_DEV_SCK_ALL_PROGRESS_BITS) == 0);*/ if (rdev->on_disconnect) rdev->on_disconnect (rdev); } +#else + if (rdev->on_disconnect) rdev->on_disconnect (rdev); +#endif + if (rdev->tmrjob_index != HIO_TMRIDX_INVALID) + { + hio_deltmrjob (hio, rdev->tmrjob_index); + HIO_ASSERT (hio, rdev->tmrjob_index == HIO_TMRIDX_INVALID); + } #if defined(USE_SSL) if (rdev->ssl) @@ -651,15 +629,90 @@ static int dev_sck_read_stateless (hio_dev_t* dev, void* buf, hio_iolen_t* len, static int dev_sck_read_bpf (hio_dev_t* dev, void* buf, hio_iolen_t* len, hio_devaddr_t* srcaddr) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrwithsyserr (hio, 0, HIO_ENOIMPL); return -1; } #if defined(IPPROTO_SCTP) +static int recvmsg_sctp( + int s, void* ptr, hio_oow_t len, struct sockaddr* srcaddr, hio_scklen_t* srcaddrlen, + struct sctp_sndrcvinfo* sinfo, int* msg_flags) +{ + int n; + struct iovec iov; + struct msghdr msg; + struct cmsghdr* cmsg; + hio_uint8_t cmsg_buf[CMSG_SPACE(HIO_SIZEOF(*sinfo))]; + + iov.iov_base = ptr; + iov.iov_len = len; + + HIO_MEMSET (&msg, 0, HIO_SIZEOF(msg)); + msg.msg_name = srcaddr; + msg.msg_namelen = *srcaddrlen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsg_buf; + msg.msg_controllen = HIO_SIZEOF(cmsg_buf); + + n = recvmsg(s, &msg, 0); + if (n <= -1) return n; + + *srcaddrlen = msg.msg_namelen; + if (msg_flags) *msg_flags = msg.msg_flags; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg ; cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) + { + HIO_MEMCPY(sinfo, CMSG_DATA(cmsg), HIO_SIZEOF(*sinfo)); + break; + } + } + + return n; +} + +static int sendmsg_sctp( + int s, const hio_iovec_t* iov, hio_oow_t iovcnt, struct sockaddr* dstaddr, hio_scklen_t dstaddrlen, + hio_uint32_t ppid, hio_uint32_t flags, hio_uint16_t stream_no, hio_uint32_t ttl, hio_uint32_t context) +{ + struct sctp_sndrcvinfo* sinfo; + struct msghdr msg; + struct cmsghdr* cmsg; + hio_uint8_t cmsg_buf[CMSG_SPACE(HIO_SIZEOF(*sinfo))]; + + msg.msg_name = dstaddr; + msg.msg_namelen = dstaddrlen; + msg.msg_iov = (struct iovec*)iov; + msg.msg_iovlen = iovcnt; + + msg.msg_control = cmsg_buf; + msg.msg_controllen = HIO_SIZEOF(cmsg_buf); + msg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(HIO_SIZEOF(*sinfo)); + + msg.msg_controllen = cmsg->cmsg_len; + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + HIO_MEMSET (sinfo, 0, HIO_SIZEOF(*sinfo)); + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_flags = flags; + sinfo->sinfo_stream = stream_no; + sinfo->sinfo_timetolive = ttl; + sinfo->sinfo_context = context; + + return sendmsg(s, &msg, 0); +} + static int dev_sck_read_sctp_sp (hio_dev_t* dev, void* buf, hio_iolen_t* len, hio_devaddr_t* srcaddr) { +/* NOTE: sctp support is far away from complete */ hio_t* hio = dev->hio; hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; hio_scklen_t srcaddrlen; @@ -668,21 +721,9 @@ static int dev_sck_read_sctp_sp (hio_dev_t* dev, void* buf, hio_iolen_t* len, hi struct sctp_sndrcvinfo sri; srcaddrlen = HIO_SIZEOF(rdev->remoteaddr); -/* -struct sctp_sndrcvinfo { - __u16 sinfo_stream; - __u16 sinfo_ssn; - __u16 sinfo_flags; - __u32 sinfo_ppid; - __u32 sinfo_context; - __u32 sinfo_timetolive; - __u32 sinfo_tsn; - __u32 sinfo_cumtsn; - sctp_assoc_t sinfo_assoc_id; -}; -*/ + /* msg_flags -> flags such as MSG_NOTIFICATION or MSG_EOR */ - x = sctp_recvmsg(rdev->hnd, buf, *len, (struct sockaddr*)&rdev->remoteaddr, &srcaddrlen, &sri, &msg_flags); + x = recvmsg_sctp(rdev->hnd, buf, *len, (struct sockaddr*)&rdev->remoteaddr, &srcaddrlen, &sri, &msg_flags); if (x <= -1) { int eno = errno; @@ -695,11 +736,16 @@ struct sctp_sndrcvinfo { return -1; } +/* +if (msg_flags & MSG_EOR) end of message?? +else push to buffer??? +*/ + hio_skad_set_chan (&rdev->remoteaddr, sri.sinfo_stream); +/* TODO: how to store sri.sinfo_ppid or sri.sinfo_context? */ srcaddr->ptr = &rdev->remoteaddr; srcaddr->len = srcaddrlen; *len = x; - //*sid = sri.sinfo_stream; /* stream number */ return 1; } #endif @@ -938,7 +984,7 @@ static int dev_sck_writev_stateless (hio_dev_t* dev, const hio_iovec_t* iov, hio static int dev_sck_write_bpf (hio_dev_t* dev, const void* data, hio_iolen_t* len, const hio_devaddr_t* dstaddr) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrwithsyserr (hio, 0, HIO_ENOIMPL); return -1; } @@ -946,24 +992,28 @@ static int dev_sck_write_bpf (hio_dev_t* dev, const void* data, hio_iolen_t* len static int dev_sck_writev_bpf (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t* iovcnt, const hio_devaddr_t* dstaddr) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrwithsyserr (hio, 0, HIO_ENOIMPL); return -1; } /* ------------------------------------------------------------------------------ */ -#if defined(IPPROTO_SCTPXX) +#if defined(IPPROTO_SCTP) static int dev_sck_write_sctp_sp (hio_dev_t* dev, const void* data, hio_iolen_t* len, const hio_devaddr_t* dstaddr) { +/* NOTE: sctp support is far away from complete */ hio_t* hio = dev->hio; hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; ssize_t x; + hio_iovec_t iov; - x = sctp_sendmsg(rdev->hnd, - data, *len, dstaddr->ptr, dstaddr->len, - sir->info_ppid, /* ppid - opaque */ - 0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */, - sid, /* stream number */ + iov.iov_ptr = (void*)data; + iov.iov_len = *len; + x = sendmsg_sctp(rdev->hnd, + &iov, 1, dstaddr->ptr, dstaddr->len, + 0, /* ppid - opaque */ + 0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */ + hio_skad_chan(dstaddr->ptr), /* stream number */ 0, /* ttl */ 0 /* context*/); if (x <= -1) @@ -980,11 +1030,27 @@ static int dev_sck_write_sctp_sp (hio_dev_t* dev, const void* data, hio_iolen_t* static int dev_sck_writev_sctp_sp (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t* iovcnt, const hio_devaddr_t* dstaddr) { - /* TODO: use sctp_sendv? */ hio_t* hio = dev->hio; hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; - hio_seterrwithsyserr (hio, 0, HIO_ENOIMPL); - return -1; + ssize_t x; + + x = sendmsg_sctp(rdev->hnd, + iov, *iovcnt, dstaddr->ptr, dstaddr->len, + 0, /* ppid - opaque */ + 0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */ + hio_skad_chan(dstaddr->ptr), /* stream number */ + 0, /* ttl */ + 0 /* context*/); + if (x <= -1) + { + if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */ + if (errno == EINTR) return 0; + hio_seterrwithsyserr (hio, 0, errno); + return -1; + } + + *iovcnt = x; + return 1; } #endif @@ -1346,7 +1412,7 @@ static int dev_sck_ioctl (hio_dev_t* dev, int cmd, void* arg) if (!sck_type_map[rdev->type].connectable) { - hio_seterrbfmt (hio, HIO_EPERM, "disallowed to connect stateless device"); + hio_seterrbfmt (hio, HIO_EPERM, "unconnectable socket device"); return -1; } @@ -1487,7 +1553,7 @@ fcntl (rdev->hnd, F_SETFL, flags | O_NONBLOCK); if (!sck_type_map[rdev->type].listenable) { - hio_seterrbfmt (hio, HIO_EPERM, "disallowed to listen on stateless device"); + hio_seterrbfmt (hio, HIO_EPERM, "unlistenable socket device"); return -1; } @@ -1506,8 +1572,8 @@ fcntl (rdev->hnd, F_SETFL, flags | O_NONBLOCK); /* TODO: need to keep the old watch flags before STOP and * use the flags witn START */ - if (hio_dev_watch(rdev, HIO_DEV_WATCH_STOP, 0) <= -1 || - hio_dev_watch(rdev, HIO_DEV_WATCH_START, 0) <= -1) + if (hio_dev_watch((hio_dev_t*)rdev, HIO_DEV_WATCH_STOP, 0) <= -1 || + hio_dev_watch((hio_dev_t*)rdev, HIO_DEV_WATCH_START, 0) <= -1) { hio_stop (hio, HIO_STOPREQ_WATCHER_ERROR); return -1; @@ -1555,6 +1621,21 @@ static hio_dev_mth_t dev_mth_sck_stream = dev_sck_sendfile_stream, }; +static hio_dev_mth_t dev_mth_sck_sctp_sp = +{ + dev_sck_make, + dev_sck_kill, + HIO_NULL, + dev_sck_getsyshnd, + HIO_NULL, + dev_sck_ioctl, /* ioctl */ + + dev_sck_read_sctp_sp, + dev_sck_write_sctp_sp, + dev_sck_writev_sctp_sp, + HIO_NULL, /* sendfile */ +}; + static hio_dev_mth_t dev_mth_clisck_stateless = { dev_sck_make_client, @@ -1585,6 +1666,21 @@ static hio_dev_mth_t dev_mth_clisck_stream = dev_sck_sendfile_stream }; +static hio_dev_mth_t dev_mth_clisck_sctp_sp = +{ + dev_sck_make_client, + dev_sck_kill, + dev_sck_fail_before_make_client, + dev_sck_getsyshnd, + HIO_NULL, + dev_sck_ioctl, + + dev_sck_read_sctp_sp, + dev_sck_write_sctp_sp, + dev_sck_writev_sctp_sp, + HIO_NULL, +}; + static hio_dev_mth_t dev_mth_sck_bpf = { dev_sck_make, @@ -1720,7 +1816,8 @@ static int make_accepted_client_connection (hio_dev_sck_t* rdev, hio_syshnd_t cl * choose the client socket method base on the master socket * device capability. currently, stream or non-stream is supported. */ - dev_mth = (sck_type_map[clisck_type].extra_dev_cap & HIO_DEV_CAP_STREAM)? &dev_mth_clisck_stream: &dev_mth_clisck_stateless; + dev_mth = (sck_type_map[clisck_type].extra_dev_cap & HIO_DEV_CAP_STREAM)? &dev_mth_clisck_stream: + (sck_type_map[clisck_type].proto == IPPROTO_SCTP)? &dev_mth_clisck_sctp_sp: &dev_mth_clisck_stateless; clidev = (hio_dev_sck_t*)hio_dev_make(hio, rdev->dev_size, dev_mth, rdev->dev_evcb, &clisck); if (HIO_UNLIKELY(!clidev)) { @@ -2133,6 +2230,13 @@ static hio_dev_evcb_t dev_sck_event_callbacks_stateless = dev_evcb_sck_on_read_stateless, dev_evcb_sck_on_write_stateless }; + +static hio_dev_evcb_t dev_sck_event_callbacks_sctp_sp = +{ + dev_evcb_sck_ready_stateless, + dev_evcb_sck_on_read_stateless, + dev_evcb_sck_on_write_stateless +}; /* ========================================================================= */ static int dev_evcb_sck_ready_qx (hio_dev_t* dev, int events) @@ -2233,7 +2337,7 @@ static hio_dev_evcb_t dev_sck_event_callbacks_qx = static int dev_evcb_sck_ready_bpf (hio_dev_t* dev, int events) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrnum (hio, HIO_ENOIMPL); return -1; } @@ -2241,7 +2345,7 @@ static int dev_evcb_sck_ready_bpf (hio_dev_t* dev, int events) static int dev_evcb_sck_on_read_bpf (hio_dev_t* dev, const void* data, hio_iolen_t dlen, const hio_devaddr_t* srcaddr) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrnum (hio, HIO_ENOIMPL); return -1; } @@ -2249,7 +2353,7 @@ static int dev_evcb_sck_on_read_bpf (hio_dev_t* dev, const void* data, hio_iolen static int dev_evcb_sck_on_write_bpf (hio_dev_t* dev, hio_iolen_t wrlen, void* wrctx, const hio_devaddr_t* dstaddr) { hio_t* hio = dev->hio; - hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + /*hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev;*/ hio_seterrnum (hio, HIO_ENOIMPL); return -1; } @@ -2291,6 +2395,12 @@ hio_dev_sck_t* hio_dev_sck_make (hio_t* hio, hio_oow_t xtnsize, const hio_dev_sc hio, HIO_SIZEOF(hio_dev_sck_t) + xtnsize, &dev_mth_sck_stream, &dev_sck_event_callbacks_stream, (void*)info); } + else if (sck_type_map[info->type].proto == IPPROTO_SCTP) + { + rdev = (hio_dev_sck_t*)hio_dev_make( + hio, HIO_SIZEOF(hio_dev_sck_t) + xtnsize, + &dev_mth_sck_sctp_sp, &dev_sck_event_callbacks_sctp_sp, (void*)info); + } else { rdev = (hio_dev_sck_t*)hio_dev_make( diff --git a/hio/lib/skad.c b/hio/lib/skad.c index 45a9c35..2690f83 100644 --- a/hio/lib/skad.c +++ b/hio/lib/skad.c @@ -45,14 +45,39 @@ # include #endif +#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) +/* dirty hack to secure more space at the end of the actual socket address. + * the extra fiels must be transparent to unaware parties. + * if you add/delete extra fields or change the size of existing fields, + * you must update the corresponding checks in configure.ac. + * + * extra fields: + * chan - used as a stream number for SCTP PACKETSEQ sockets. + * use hio_skad_chan() and hio_skad_setchan() for safe access. + */ +struct sockaddr_in_x +{ + struct sockaddr_in a; + hio_uint16_t chan; +}; +#endif + +#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) +struct sockaddr_in6_x +{ + struct sockaddr_in6 a; + hio_uint16_t chan; +}; +#endif + union hio_skad_alt_t { struct sockaddr sa; #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) - struct sockaddr_in in4; + struct sockaddr_in_x in4; #endif #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - struct sockaddr_in6 in6; + struct sockaddr_in6_x in6; #endif #if (HIO_SIZEOF_STRUCT_SOCKADDR_LL > 0) struct sockaddr_ll ll; @@ -434,16 +459,16 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ if (*p >= '0' && *p <= '9') { /* numeric scope id */ - skad->in6.sin6_scope_id = 0; + skad->in6.a.sin6_scope_id = 0; do { - x = skad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < skad->in6.sin6_scope_id) + x = skad->in6.a.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.a.sin6_scope_id) { hio_seterrbfmt (hio, HIO_EINVAL, "scope id too large"); return -1; /* overflow */ } - skad->in6.sin6_scope_id = x; + skad->in6.a.sin6_scope_id = x; p++; } while (p < end && *p >= '0' && *p <= '9'); @@ -455,15 +480,15 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ unsigned int index; do p++; while (p < end && *p != ']'); if (hio_ucharstoifindex(hio, stmp, p - stmp, &index) <= -1) return -1; - skad->in6.sin6_scope_id = index; + skad->in6.a.sin6_scope_id = index; } if (p >= end || *p != ']') goto no_rbrack; } p++; /* skip ] */ - if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; - skad->in6.sin6_family = AF_INET6; + if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.a.sin6_addr) <= -1) goto unrecog; + skad->in6.a.sin6_family = AF_INET6; } else { @@ -473,7 +498,7 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ while (p < end && *p != ':') p++; tmp.len = p - tmp.ptr; - if (uchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1) + if (uchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.a.sin_addr) <= -1) { #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) /* check if it is an IPv6 address not enclosed in []. @@ -487,7 +512,7 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ while (p < end && *p != '%') p++; tmp.len = p - tmp.ptr; - if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; + if (uchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.a.sin6_addr) <= -1) goto unrecog; if (p < end && *p == '%') { @@ -506,16 +531,16 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ if (*p >= '0' && *p <= '9') { /* numeric scope id */ - skad->in6.sin6_scope_id = 0; + skad->in6.a.sin6_scope_id = 0; do { - x = skad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < skad->in6.sin6_scope_id) + x = skad->in6.a.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.a.sin6_scope_id) { hio_seterrbfmt (hio, HIO_EINVAL, "scope id too large"); return -1; /* overflow */ } - skad->in6.sin6_scope_id = x; + skad->in6.a.sin6_scope_id = x; p++; } while (p < end && *p >= '0' && *p <= '9'); @@ -527,20 +552,20 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ unsigned int index; do p++; while (p < end); if (hio_ucharstoifindex(hio, stmp, p - stmp, &index) <= -1) return -1; - skad->in6.sin6_scope_id = index; + skad->in6.a.sin6_scope_id = index; } } if (p < end) goto unrecog; /* some gargage after the end? */ - skad->in6.sin6_family = AF_INET6; + skad->in6.a.sin6_family = AF_INET6; return 0; #else goto unrecog; #endif } - skad->in4.sin_family = AF_INET; + skad->in4.a.sin_family = AF_INET; #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) } #endif @@ -568,12 +593,12 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_ } #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - if (skad->in4.sin_family == AF_INET) - skad->in4.sin_port = hio_hton16(port); + if (skad->in4.a.sin_family == AF_INET) + skad->in4.a.sin_port = hio_hton16(port); else - skad->in6.sin6_port = hio_hton16(port); + skad->in6.a.sin6_port = hio_hton16(port); #else - skad->in4.sin_port = hio_hton16(port); + skad->in4.a.sin_port = hio_hton16(port); #endif } @@ -656,16 +681,16 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ if (*p >= '0' && *p <= '9') { /* numeric scope id */ - skad->in6.sin6_scope_id = 0; + skad->in6.a.sin6_scope_id = 0; do { - x = skad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < skad->in6.sin6_scope_id) + x = skad->in6.a.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.a.sin6_scope_id) { hio_seterrbfmt (hio, HIO_EINVAL, "scope id too large"); return -1; /* overflow */ } - skad->in6.sin6_scope_id = x; + skad->in6.a.sin6_scope_id = x; p++; } while (p < end && *p >= '0' && *p <= '9'); @@ -677,15 +702,15 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ unsigned int index; do p++; while (p < end && *p != ']'); if (hio_bcharstoifindex(hio, stmp, p - stmp, &index) <= -1) return -1; - skad->in6.sin6_scope_id = index; + skad->in6.a.sin6_scope_id = index; } if (p >= end || *p != ']') goto no_rbrack; } p++; /* skip ] */ - if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; - skad->in6.sin6_family = AF_INET6; + if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.a.sin6_addr) <= -1) goto unrecog; + skad->in6.a.sin6_family = AF_INET6; } else { @@ -695,7 +720,7 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ while (p < end && *p != ':') p++; tmp.len = p - tmp.ptr; - if (bchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1) + if (bchars_to_ipv4(tmp.ptr, tmp.len, &skad->in4.a.sin_addr) <= -1) { #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) /* check if it is an IPv6 address not enclosed in []. @@ -710,7 +735,7 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ while (p < end && *p != '%') p++; tmp.len = p - tmp.ptr; - if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; + if (bchars_to_ipv6(tmp.ptr, tmp.len, &skad->in6.a.sin6_addr) <= -1) goto unrecog; if (p < end && *p == '%') { @@ -729,16 +754,16 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ if (*p >= '0' && *p <= '9') { /* numeric scope id */ - skad->in6.sin6_scope_id = 0; + skad->in6.a.sin6_scope_id = 0; do { - x = skad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < skad->in6.sin6_scope_id) + x = skad->in6.a.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.a.sin6_scope_id) { hio_seterrbfmt (hio, HIO_EINVAL, "scope id too large"); return -1; /* overflow */ } - skad->in6.sin6_scope_id = x; + skad->in6.a.sin6_scope_id = x; p++; } while (p < end && *p >= '0' && *p <= '9'); @@ -750,20 +775,20 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ unsigned int index; do p++; while (p < end); if (hio_bcharstoifindex(hio, stmp, p - stmp, &index) <= -1) return -1; - skad->in6.sin6_scope_id = index; + skad->in6.a.sin6_scope_id = index; } } if (p < end) goto unrecog; /* some gargage after the end? */ - skad->in6.sin6_family = AF_INET6; + skad->in6.a.sin6_family = AF_INET6; return 0; #else goto unrecog; #endif } - skad->in4.sin_family = AF_INET; + skad->in4.a.sin_family = AF_INET; #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) } #endif @@ -791,12 +816,12 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_ } #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - if (skad->in4.sin_family == AF_INET) - skad->in4.sin_port = hio_hton16(port); + if (skad->in4.a.sin_family == AF_INET) + skad->in4.a.sin_port = hio_hton16(port); else - skad->in6.sin6_port = hio_hton16(port); + skad->in6.a.sin6_port = hio_hton16(port); #else - skad->in4.sin_port = hio_hton16(port); + skad->in4.a.sin_port = hio_hton16(port); #endif } @@ -986,12 +1011,12 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, if (flags & HIO_SKAD_TO_UCSTR_ADDR) { if (xlen + 1 >= len) goto done; - xlen += ip4ad_to_ucstr(&skad->in4.sin_addr, buf, len); + xlen += ip4ad_to_ucstr(&skad->in4.a.sin_addr, buf, len); } if (flags & HIO_SKAD_TO_UCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in4.sin_port != 0) + if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in4.a.sin_port != 0) { if (flags & HIO_SKAD_TO_UCSTR_ADDR) { @@ -1000,7 +1025,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, } if (xlen + 1 >= len) goto done; - xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in4.sin_port), 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in4.a.sin_port), 10, 0, '\0', HIO_NULL); } } break; @@ -1008,7 +1033,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, case HIO_AF_INET6: if (flags & HIO_SKAD_TO_UCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.sin6_port != 0) + if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.a.sin6_port != 0) { if (flags & HIO_SKAD_TO_UCSTR_ADDR) { @@ -1021,9 +1046,9 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, if (flags & HIO_SKAD_TO_UCSTR_ADDR) { if (xlen + 1 >= len) goto done; - xlen += ip6ad_to_ucstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen); + xlen += ip6ad_to_ucstr(&skad->in6.a.sin6_addr, &buf[xlen], len - xlen); - if (skad->in6.sin6_scope_id != 0) + if (skad->in6.a.sin6_scope_id != 0) { int tmp; @@ -1032,10 +1057,10 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, if (xlen + 1 >= len) goto done; - tmp = hio_ifindextoucstr(hio, skad->in6.sin6_scope_id, &buf[xlen], len - xlen); + tmp = hio_ifindextoucstr(hio, skad->in6.a.sin6_scope_id, &buf[xlen], len - xlen); if (tmp <= -1) { - xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, skad->in6.sin6_scope_id, 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, skad->in6.a.sin6_scope_id, 10, 0, '\0', HIO_NULL); } else xlen += tmp; } @@ -1043,7 +1068,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, if (flags & HIO_SKAD_TO_UCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.sin6_port != 0) + if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.a.sin6_port != 0) { if (flags & HIO_SKAD_TO_UCSTR_ADDR) { @@ -1055,7 +1080,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf, } if (xlen + 1 >= len) goto done; - xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in6.sin6_port), 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in6.a.sin6_port), 10, 0, '\0', HIO_NULL); } } @@ -1247,12 +1272,12 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, if (flags & HIO_SKAD_TO_BCSTR_ADDR) { if (xlen + 1 >= len) goto done; - xlen += ip4ad_to_bcstr(&skad->in4.sin_addr, buf, len); + xlen += ip4ad_to_bcstr(&skad->in4.a.sin_addr, buf, len); } if (flags & HIO_SKAD_TO_BCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in4.sin_port != 0) + if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in4.a.sin_port != 0) { if (flags & HIO_SKAD_TO_BCSTR_ADDR) { @@ -1261,7 +1286,7 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, } if (xlen + 1 >= len) goto done; - xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in4.sin_port), 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in4.a.sin_port), 10, 0, '\0', HIO_NULL); } } break; @@ -1269,7 +1294,7 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, case HIO_AF_INET6: if (flags & HIO_SKAD_TO_BCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.a.sin6_port != 0) { if (flags & HIO_SKAD_TO_BCSTR_ADDR) { @@ -1283,9 +1308,9 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, { if (xlen + 1 >= len) goto done; - xlen += ip6ad_to_bcstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen); + xlen += ip6ad_to_bcstr(&skad->in6.a.sin6_addr, &buf[xlen], len - xlen); - if (skad->in6.sin6_scope_id != 0) + if (skad->in6.a.sin6_scope_id != 0) { int tmp; @@ -1294,10 +1319,10 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, if (xlen + 1 >= len) goto done; - tmp = hio_ifindextobcstr(hio, skad->in6.sin6_scope_id, &buf[xlen], len - xlen); + tmp = hio_ifindextobcstr(hio, skad->in6.a.sin6_scope_id, &buf[xlen], len - xlen); if (tmp <= -1) { - xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, skad->in6.sin6_scope_id, 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, skad->in6.a.sin6_scope_id, 10, 0, '\0', HIO_NULL); } else xlen += tmp; } @@ -1305,7 +1330,7 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, if (flags & HIO_SKAD_TO_BCSTR_PORT) { - if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.a.sin6_port != 0) { if (flags & HIO_SKAD_TO_BCSTR_ADDR) { @@ -1317,7 +1342,7 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf, } if (xlen + 1 >= len) goto done; - xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in6.sin6_port), 10, 0, '\0', HIO_NULL); + xlen += hio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, hio_ntoh16(skad->in6.a.sin6_port), 10, 0, '\0', HIO_NULL); } } @@ -1369,6 +1394,9 @@ int hio_skad_family (const hio_skad_t* _skad) int hio_skad_size (const hio_skad_t* _skad) { + /* this excludes the size of the 'chan' field. + * the field is not part of the core socket address */ + const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; /*HIO_STATIC_ASSERT (HIO_SIZEOF(*_skad) >= HIO_SIZEOF(*skad));*/ @@ -1401,10 +1429,10 @@ int hio_skad_port (const hio_skad_t* _skad) switch (skad->sa.sa_family) { #if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) - case AF_INET: return hio_ntoh16(((struct sockaddr_in*)skad)->sin_port); + case AF_INET: return hio_ntoh16(skad->in4.a.sin_port); #endif #if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - case AF_INET6: return hio_ntoh16(((struct sockaddr_in6*)skad)->sin6_port); + case AF_INET6: return hio_ntoh16(skad->in6.a.sin6_port); #endif } return 0; @@ -1415,15 +1443,65 @@ int hio_skad_ifindex (const hio_skad_t* _skad) const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; #if defined(AF_PACKET) && (HIO_SIZEOF_STRUCT_SOCKADDR_LL > 0) - if (skad->sa.sa_family == AF_PACKET) return ((struct sockaddr_ll*)skad)->sll_ifindex; + if (skad->sa.sa_family == AF_PACKET) return skad->ll.sll_ifindex; #elif defined(AF_LINK) && (HIO_SIZEOF_STRUCT_SOCKADDR_DL > 0) - if (skad->sa.sa_family == AF_LINK) return ((struct sockaddr_dl*)skad)->sdl_index; + if (skad->sa.sa_family == AF_LINK) return skad->dl.sdl_index; #endif return 0; } +int hio_skad_scope_id (const hio_skad_t* _skad) +{ + const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; + +#if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + if (skad->sa.sa_family == AF_INET6) return skad->in6.a.sin6_scope_id; +#endif + + return 0; +} + +void hio_skad_set_scope_id (hio_skad_t* _skad, int scope_id) +{ + hio_skad_alt_t* skad = (hio_skad_alt_t*)_skad; + +#if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + if (skad->sa.sa_family == AF_INET6) skad->in6.a.sin6_scope_id = scope_id; +#endif +} + +hio_uint16_t hio_skad_chan (const hio_skad_t* _skad) +{ + const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; + + switch (skad->sa.sa_family) + { + #if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) + case AF_INET: return skad->in4.chan; + #endif + #if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + case AF_INET6: return skad->in6.chan; + #endif + } + return 0; +} + +void hio_skad_set_chan (hio_skad_t* _skad, hio_uint16_t chan) +{ + hio_skad_alt_t* skad = (hio_skad_alt_t*)_skad; + + switch (skad->sa.sa_family) + { + #if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) + case AF_INET: skad->in4.chan = chan; break; + #endif + #if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + case AF_INET6: skad->in6.chan = chan; break; + #endif + } +} void hio_skad_init_for_ip4 (hio_skad_t* skad, hio_uint16_t port, hio_ip4ad_t* ip4ad) { diff --git a/hio/lib/utl.c b/hio/lib/utl.c index 54db6fc..d6310fb 100644 --- a/hio/lib/utl.c +++ b/hio/lib/utl.c @@ -29,58 +29,6 @@ /* ========================================================================= */ -int hio_comp_ucstr_limited (const hio_uch_t* str1, const hio_uch_t* str2, hio_oow_t maxlen, int ignorecase) -{ - if (maxlen == 0) return 0; - - if (ignorecase) - { - while (hio_to_uch_lower(*str1) == hio_to_uch_lower(*str2)) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((hio_uchu_t)hio_to_uch_lower(*str1) > (hio_uchu_t)hio_to_uch_lower(*str2))? 1: -1; - } - else - { - while (*str1 == *str2) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((hio_uchu_t)*str1 > (hio_uchu_t)*str2)? 1: -1; - } -} - -int hio_comp_bcstr_limited (const hio_bch_t* str1, const hio_bch_t* str2, hio_oow_t maxlen, int ignorecase) -{ - if (maxlen == 0) return 0; - - if (ignorecase) - { - while (hio_to_uch_lower(*str1) == hio_to_uch_lower(*str2)) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((hio_bchu_t)hio_to_uch_lower(*str1) > (hio_bchu_t)hio_to_uch_lower(*str2))? 1: -1; - } - else - { - while (*str1 == *str2) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((hio_bchu_t)*str1 > (hio_bchu_t)*str2)? 1: -1; - } -} - int hio_comp_ucstr_bcstr (const hio_uch_t* str1, const hio_bch_t* str2, int ignorecase) { if (ignorecase)