tweaked the hio_skad_t structure to hold extra information required for sctp seqpacket sockets

sctp seqpacket socket support is not completed yet
This commit is contained in:
hyung-hwan 2021-08-09 08:24:21 +00:00
parent 2e91e08ec2
commit a0bd10822a
11 changed files with 628 additions and 216 deletions

View File

@ -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;
}

181
hio/configure vendored
View File

@ -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 <winsock2.h>
#include <ws2tcpip.h>
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 <winsock2.h>
#include <ws2tcpip.h>
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
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

View File

@ -466,6 +466,23 @@ then
AC_CHECK_SIZEOF(struct sockaddr_in6,,[
#include <winsock2.h>
#include <ws2tcpip.h>])
AC_CHECK_SIZEOF(struct sockaddr_in_x,,[
#include <winsock2.h>
#include <ws2tcpip.h>
struct sockaddr_in_x {
struct sockaddr_in a;
unsigned short chan;
};
])
AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[
#include <winsock2.h>
#include <ws2tcpip.h>
struct sockaddr_in6_x {
struct sockaddr_in6 a;
unsigned short chan;
};
])
AC_CHECK_SIZEOF(struct sockaddr_un,,[
#include <winsock2.h>
#include <ws2tcpip.h>])
@ -518,6 +535,25 @@ else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>])
AC_CHECK_SIZEOF(struct sockaddr_in_x,,[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
struct sockaddr_in_x {
struct sockaddr_in a;
unsigned short chan;
};
])
AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
struct sockaddr_in6_x {
struct sockaddr_in6 a;
unsigned short chan;
};
])
AC_CHECK_SIZEOF(struct sockaddr_un,,[
#include <sys/types.h>
#include <sys/socket.h>
@ -531,7 +567,6 @@ else
#include <sys/socket.h>
#include <net/if_dl.h>])
AC_CHECK_SIZEOF(socklen_t,, [
#include <sys/types.h>
#include <sys/socket.h>])
@ -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)])

View File

@ -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

View File

@ -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

View File

@ -31,13 +31,13 @@
#include <hio-utl.h>
#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
);

View File

@ -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
);

View File

@ -27,6 +27,8 @@
#include "http-prv.h"
#include <hio-path.h>
#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;
}

View File

@ -24,7 +24,6 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <hio-sck.h>
#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(

View File

@ -45,14 +45,39 @@
# include <net/if_dl.h>
#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)
{

View File

@ -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)