adding some code to handle multicast

This commit is contained in:
hyung-hwan 2021-08-17 07:00:22 +00:00
parent 11579e8802
commit 914a0c3905
13 changed files with 195 additions and 95 deletions

View File

@ -369,7 +369,7 @@ static int arp_sck_on_read (hio_dev_sck_t* dev, const void* data, hio_iolen_t dl
eap = (hio_etharp_pkt_t*)data; eap = (hio_etharp_pkt_t*)data;
printf ("ARP ON IFINDEX %d OPCODE: %d", hio_skad_ifindex(srcaddr), ntohs(eap->arphdr.opcode)); printf ("ARP ON IFINDEX %d OPCODE: %d", hio_skad_get_ifindex(srcaddr), ntohs(eap->arphdr.opcode));
printf (" SHA: %02X:%02X:%02X:%02X:%02X:%02X", eap->arppld.sha[0], eap->arppld.sha[1], eap->arppld.sha[2], eap->arppld.sha[3], eap->arppld.sha[4], eap->arppld.sha[5]); printf (" SHA: %02X:%02X:%02X:%02X:%02X:%02X", eap->arppld.sha[0], eap->arppld.sha[1], eap->arppld.sha[2], eap->arppld.sha[3], eap->arppld.sha[4], eap->arppld.sha[5]);
printf (" SPA: %d.%d.%d.%d", eap->arppld.spa[0], eap->arppld.spa[1], eap->arppld.spa[2], eap->arppld.spa[3]); printf (" SPA: %d.%d.%d.%d", eap->arppld.spa[0], eap->arppld.spa[1], eap->arppld.spa[2], eap->arppld.spa[3]);

View File

@ -228,7 +228,7 @@ int main (int argc, char* argv[])
tcp_conn.options = 0; tcp_conn.options = 0;
memset (&tcp_make, 0, HIO_SIZEOF(tcp_make)); memset (&tcp_make, 0, HIO_SIZEOF(tcp_make));
tcp_make.type = hio_skad_family(&tcp_conn.remoteaddr) == HIO_AF_INET? HIO_DEV_SCK_TCP4: HIO_DEV_SCK_TCP6; tcp_make.type = hio_skad_get_family(&tcp_conn.remoteaddr) == HIO_AF_INET? HIO_DEV_SCK_TCP4: HIO_DEV_SCK_TCP6;
tcp_make.on_write = tcp_sck_on_write; tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read; tcp_make.on_read = tcp_sck_on_read;
tcp_make.on_connect = tcp_sck_on_connect; tcp_make.on_connect = tcp_sck_on_connect;

View File

@ -465,9 +465,9 @@ static int tcp_sck_on_read (hio_dev_sck_t* sck, const void* buf, hio_iolen_t len
{ {
/* won't be invoked /* won't be invoked
* invokde if sctp_sp */ * invokde if sctp_sp */
#if 0
hio_iovec_t iov; 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 */ /* 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)); printf ("[%.*s] chan %d\n", (int)len, buf, hio_skad_chan(srcaddr));
iov.iov_ptr = buf; iov.iov_ptr = buf;
@ -502,7 +502,7 @@ static int add_listener (hio_t* hio, hio_bch_t* addrstr)
#endif #endif
memset (&mi, 0, HIO_SIZEOF(mi)); memset (&mi, 0, HIO_SIZEOF(mi));
f = hio_skad_family(&bi.localaddr); f = hio_skad_get_family(&bi.localaddr);
if (f == HIO_AF_INET) mi.type = g_dev_type4; if (f == HIO_AF_INET) mi.type = g_dev_type4;
else if (f == HIO_AF_INET6) mi.type = g_dev_type6; else if (f == HIO_AF_INET6) mi.type = g_dev_type6;
else if (f == HIO_AF_UNIX) mi.type = HIO_DEV_SCK_UNIX; else if (f == HIO_AF_UNIX) mi.type = HIO_DEV_SCK_UNIX;
@ -645,6 +645,12 @@ int main (int argc, char* argv[])
unlink ("t06.sck"); unlink ("t06.sck");
add_listener(hio, "@t06.sck"); add_listener(hio, "@t06.sck");
{
hio_skad_t skad;
hio_bcstrtoskad(hio, "[::]:3547", &skad);
hio_svc_dhcs_start (hio, &skad, 1);
}
hio_loop (hio); hio_loop (hio);
xret = 0; xret = 0;

24
hio/configure vendored
View File

@ -17581,9 +17581,13 @@ else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in_x))" "ac_cv_sizeof_struct_sockaddr_in_x" " 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 <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
struct sockaddr_extra_t
{
unsigned short chan;
}
struct sockaddr_in_x { struct sockaddr_in_x {
struct sockaddr_in a; struct sockaddr_in a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
"; then : "; then :
@ -17622,9 +17626,13 @@ else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_in6_x))" "ac_cv_sizeof_struct_sockaddr_in6_x" " 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 <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in6_x { struct sockaddr_in6_x {
struct sockaddr_in6 a; struct sockaddr_in6 a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
"; then : "; then :
@ -18025,9 +18033,13 @@ else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in_x { struct sockaddr_in_x {
struct sockaddr_in a; struct sockaddr_in a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
"; then : "; then :
@ -18067,9 +18079,13 @@ else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in6_x { struct sockaddr_in6_x {
struct sockaddr_in6 a; struct sockaddr_in6 a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
"; then : "; then :

View File

@ -469,17 +469,25 @@ then
AC_CHECK_SIZEOF(struct sockaddr_in_x,,[ AC_CHECK_SIZEOF(struct sockaddr_in_x,,[
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
struct sockaddr_extra_t
{
unsigned short chan;
}
struct sockaddr_in_x { struct sockaddr_in_x {
struct sockaddr_in a; struct sockaddr_in a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
]) ])
AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[ AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in6_x { struct sockaddr_in6_x {
struct sockaddr_in6 a; struct sockaddr_in6 a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
]) ])
@ -539,18 +547,26 @@ else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in_x { struct sockaddr_in_x {
struct sockaddr_in a; struct sockaddr_in a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
]) ])
AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[ AC_CHECK_SIZEOF(struct sockaddr_in6_x,,[
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
struct sockaddr_extra_t
{
unsigned short chan;
};
struct sockaddr_in6_x { struct sockaddr_in6_x {
struct sockaddr_in6 a; struct sockaddr_in6 a;
unsigned short chan; struct sockaddr_extra_t u;
}; };
]) ])

View File

@ -59,16 +59,16 @@ static hio_dev_sck_t* open_socket (hio_t* hio, hio_svc_dhcs_cfg_t* cfg)
hio_dev_sck_t* sck = HIO_NULL; hio_dev_sck_t* sck = HIO_NULL;
int f; int f;
f = hio_skad_family(&cfg->bind_addr); f = hio_skad_get_family(&cfg->bind_addr);
if (f != HIO_AF_INET || f != HIO_AF_INET6) if (f != HIO_AF_INET && f != HIO_AF_INET6)
{ {
hio_seterrbfmt (hio, HIO_EINVAL, "invalid bind address family"); hio_seterrbfmt (hio, HIO_EINVAL, "invalid bind address family");
goto oops; goto oops;
} }
HIO_MEMSET (&m, 0, HIO_SIZEOF(m)); HIO_MEMSET (&m, 0, HIO_SIZEOF(m));
m.type = HIO_DEV_SCK_UDP6; m.type = (f == HIO_AF_INET? HIO_DEV_SCK_UDP4: HIO_DEV_SCK_UDP6);
m.options = HIO_DEV_SCK_BIND_REUSEADDR | HIO_DEV_SCK_BIND_REUSEPORT | HIO_DEV_SCK_BIND_IGNERR; //m.options = HIO_DEV_SCK_MAKE_LENIENT;
//m.on_write = //m.on_write =
//m.on_read = ... //m.on_read = ...
//m.on_connect = ... //m.on_connect = ...
@ -76,11 +76,29 @@ static hio_dev_sck_t* open_socket (hio_t* hio, hio_svc_dhcs_cfg_t* cfg)
sck = hio_dev_sck_make(hio, 0, &m); sck = hio_dev_sck_make(hio, 0, &m);
if (HIO_UNLIKELY(!sck)) goto oops; if (HIO_UNLIKELY(!sck)) goto oops;
/*
#if defined(IPV6_RECVPKTINFO)
hio_dev_sck_setsockopt (dhcs->sck, IPPROTO_IPV6, IPV6_RECVPKTINFO, &v);
#elif defined(IPV6_PKTINFO)
hio_dev_sck_setsockopt (dhcs->sck, IPPROTO_IPV6, IPV6_PKTINFO, &v);
#else
//# error no ipv6 pktinfo
#endif
*/
#if 0 {
if (hio_dev_sck_joingroup(sck, mcast_addr, ifindex) <= -1) goto oops; /* TODO: accept hio_dev_sck_bind_t instead of hio_skad_t? */
#endif hio_dev_sck_bind_t b;
HIO_MEMSET (&b, 0, HIO_SIZEOF(b));
b.localaddr = cfg->bind_addr;
if (hio_dev_sck_bind(sck, &b) <= -1) goto oops;
}
{
hio_skad_t mcast_addr;
hio_bcstrtoskad(hio, "[ff02::1:2]:0", &mcast_addr);
if (hio_dev_sck_joinmcastgroup(sck, &mcast_addr, 2) <= -1) goto oops;
}
return sck; return sck;
@ -98,34 +116,23 @@ hio_svc_dhcs_t* hio_svc_dhcs_start (hio_t* hio, const hio_skad_t* local_binds, h
hio_dev_sck_listen_t l; hio_dev_sck_listen_t l;
} info; } info;
hio_oow_t i; hio_oow_t i;
hio_dev_sck_t* sck;
dhcs = (hio_svc_dhcs_t*)hio_callocmem(hio, HIO_SIZEOF(*dhcs)); dhcs = (hio_svc_dhcs_t*)hio_callocmem(hio, HIO_SIZEOF(*dhcs));
if (HIO_UNLIKELY(!dhcs)) goto oops; if (HIO_UNLIKELY(!dhcs)) goto oops;
dhcs->hio = hio; dhcs->hio = hio;
for (i = 0; i < local_nbinds; i++) for (i = 0; i < local_nbinds; i++)
{ {
HIO_MEMSET (&info, 0, HIO_SIZEOF(info)); hio_svc_dhcs_cfg_t cfg;
info.m.type = HIO_DEV_SCK_UDP6;
info.m.options = HIO_DEV_SCK_BIND_REUSEADDR | HIO_DEV_SCK_BIND_REUSEPORT | HIO_DEV_SCK_BIND_IGNERR;
//info.m.on_write =
//info.m.on_read = ...
//info.m.on_connect = ...
//info.m.on_disconnect = ...
dhcs->sck = hio_dev_sck_make(hio, 0, &info.m);
if (HIO_UNLIKELY(!dhcs->sck)) goto oops;
#if defined(IPV6_RECVPKTINFO) HIO_MEMSET (&cfg, 0, HIO_SIZEOF(cfg));
hio_dev_sck_setsockopt (dhcs->sck, IPPROTO_IPV6, IPV6_RECVPKTINFO, &v); cfg.bind_addr = local_binds[i];
#elif defined(IPV6_PKTINFO)
hio_dev_sck_setsockopt (dhcs->sck, IPPROTO_IPV6, IPV6_PKTINFO, &v);
#else
//# error no ipv6 pktinfo
#endif
hio_dev_sck_bind(dhcs->sck, &local_binds[i]); sck = open_socket(hio, &cfg);
if (HIO_UNLIKELY(!sck)) goto oops;
/* TODO: remember this in dhcs... */
} }
HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)dhcs); HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)dhcs);
@ -134,7 +141,12 @@ hio_svc_dhcs_t* hio_svc_dhcs_start (hio_t* hio, const hio_skad_t* local_binds, h
oops: oops:
if (dhcs) if (dhcs)
{ {
if (dhcs->sck) hio_dev_sck_kill (dhcs->sck); if (sck) hio_dev_sck_kill (sck);
/*TODO:
for (i = 0; i < local_nbinds; i++)
{
if (dhcs->sck[i]) hio_dev_sck_kill(dhcs->sck[i])
}*/
hio_freemem (hio, dhcs); hio_freemem (hio, dhcs);
} }
return HIO_NULL; return HIO_NULL;

View File

@ -471,7 +471,7 @@ static int switch_reqmsg_transport_to_tcp (hio_svc_dnc_t* dnc, hio_dns_msg_t* re
if (!dnc->tcp_sck) if (!dnc->tcp_sck)
{ {
HIO_MEMSET (&mkinfo, 0, HIO_SIZEOF(mkinfo)); HIO_MEMSET (&mkinfo, 0, HIO_SIZEOF(mkinfo));
switch (hio_skad_family(&reqmsgxtn->servaddr)) switch (hio_skad_get_family(&reqmsgxtn->servaddr))
{ {
case HIO_AF_INET: case HIO_AF_INET:
mkinfo.type = HIO_DEV_SCK_TCP4; mkinfo.type = HIO_DEV_SCK_TCP4;
@ -736,7 +736,7 @@ hio_svc_dnc_t* hio_svc_dnc_start (hio_t* hio, const hio_skad_t* serv_addr, const
dnc->max_tries = max_tries; dnc->max_tries = max_tries;
HIO_MEMSET (&mkinfo, 0, HIO_SIZEOF(mkinfo)); HIO_MEMSET (&mkinfo, 0, HIO_SIZEOF(mkinfo));
switch (hio_skad_family(serv_addr)) switch (hio_skad_get_family(serv_addr))
{ {
case HIO_AF_INET: case HIO_AF_INET:
mkinfo.type = HIO_DEV_SCK_UDP4; mkinfo.type = HIO_DEV_SCK_UDP4;

View File

@ -26,7 +26,7 @@
#define _HIO_DHCP_H_ #define _HIO_DHCP_H_
#include <hio.h> #include <hio.h>
#include <hio-skad.h> #include <hio-sck.h>
#define HIO_DHCP6_SERVER_PORT (547) #define HIO_DHCP6_SERVER_PORT (547)
#define HIO_DHCP6_CLIENT_PORT (546) #define HIO_DHCP6_CLIENT_PORT (546)
@ -97,7 +97,6 @@ typedef struct hio_dhcp6_pktinf_t hio_dhcp6_pktinf_t;
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
typedef struct hio_svc_dhcs_t hio_svc_dhcs_t; typedef struct hio_svc_dhcs_t hio_svc_dhcs_t;
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
@ -110,20 +109,10 @@ HIO_EXPORT hio_svc_dhcs_t* hio_svc_dhcs_start (
hio_t* hio, hio_t* hio,
const hio_skad_t* local_binds, const hio_skad_t* local_binds,
hio_oow_t local_nbinds hio_oow_t local_nbinds
#if 0
,
const hio_skad_t* serv_addr, /* required */
const hio_skad_t* bind_addr, /* optional. can be HIO_NULL */
const hio_ntime_t* send_tmout, /* required */
const hio_ntime_t* reply_tmout, /* required */
hio_oow_t max_tries /* required */
#endif
); );
HIO_EXPORT void hio_svc_dhcs_stop ( HIO_EXPORT void hio_svc_dhcs_stop (
hio_svc_dhcs_t* dhcs hio_svc_dhcs_t* dhcs
); );
#if defined(HIO_HAVE_INLINE) #if defined(HIO_HAVE_INLINE)

View File

@ -580,7 +580,6 @@ HIO_EXPORT int hio_dev_sck_getsockopt (
hio_scklen_t* optlen hio_scklen_t* optlen
); );
HIO_EXPORT int hio_dev_sck_getsockaddr ( HIO_EXPORT int hio_dev_sck_getsockaddr (
hio_dev_sck_t* dev, hio_dev_sck_t* dev,
hio_skad_t* skad hio_skad_t* skad
@ -591,6 +590,18 @@ HIO_EXPORT int hio_dev_sck_getpeeraddr (
hio_skad_t* skad hio_skad_t* skad
); );
HIO_EXPORT int hio_dev_sck_joinmcastgroup (
hio_dev_sck_t* dev,
const hio_skad_t* mcast_skad,
int ifindex
);
HIO_EXPORT int hio_dev_sck_leavemcastgroup (
hio_dev_sck_t* dev,
const hio_skad_t* mcast_skad,
int ifindex
);
HIO_EXPORT int hio_dev_sck_shutdown ( HIO_EXPORT int hio_dev_sck_shutdown (
hio_dev_sck_t* dev, hio_dev_sck_t* dev,
int how /* bitwise-ORed of hio_dev_sck_shutdown_how_t enumerators */ int how /* bitwise-ORed of hio_dev_sck_shutdown_how_t enumerators */

View File

@ -194,23 +194,25 @@ HIO_EXPORT void hio_skad_init_for_qx (
hio_skad_t* skad hio_skad_t* skad
); );
HIO_EXPORT int hio_skad_family ( HIO_EXPORT int hio_skad_get_family (
const hio_skad_t* skad const hio_skad_t* skad
); );
HIO_EXPORT int hio_skad_size ( HIO_EXPORT int hio_skad_get_size (
const hio_skad_t* skad const hio_skad_t* skad
); );
HIO_EXPORT int hio_skad_port ( HIO_EXPORT int hio_skad_get_port (
const hio_skad_t* skad const hio_skad_t* skad
); );
HIO_EXPORT int hio_skad_ifindex ( /* for link-level addresses */
HIO_EXPORT int hio_skad_get_ifindex (
const hio_skad_t* skad const hio_skad_t* skad
); );
HIO_EXPORT int hio_skad_scope_id ( /* for ipv6 */
HIO_EXPORT int hio_skad_get_scope_id (
const hio_skad_t* skad const hio_skad_t* skad
); );
@ -219,7 +221,8 @@ HIO_EXPORT void hio_skad_set_scope_id (
int scope_id int scope_id
); );
HIO_EXPORT hio_uint16_t hio_skad_chan ( /* for sctp */
HIO_EXPORT hio_uint16_t hio_skad_get_chan (
const hio_skad_t* skad const hio_skad_t* skad
); );
@ -228,6 +231,12 @@ HIO_EXPORT void hio_skad_set_chan (
hio_uint16_t chan hio_uint16_t chan
); );
HIO_EXPORT hio_oow_t hio_skad_get_ipad_bytes (
hio_skad_t* skad,
void* buf,
hio_oow_t len
);
HIO_EXPORT void hio_clear_skad ( HIO_EXPORT void hio_clear_skad (
hio_skad_t* skad hio_skad_t* skad
); );

View File

@ -366,7 +366,7 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* binds, hio_o
hio_dev_sck_t* sck; hio_dev_sck_t* sck;
HIO_MEMSET (&info, 0, HIO_SIZEOF(info)); HIO_MEMSET (&info, 0, HIO_SIZEOF(info));
switch (hio_skad_family(&binds[i].localaddr)) switch (hio_skad_get_family(&binds[i].localaddr))
{ {
case HIO_AF_INET: case HIO_AF_INET:
info.m.type = HIO_DEV_SCK_TCP4; info.m.type = HIO_DEV_SCK_TCP4;
@ -388,7 +388,7 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* binds, hio_o
default: default:
/* ignore this */ /* ignore this */
HIO_DEBUG3 (hio, "HTTS(%p) - [%zu] unsupported bind address type %d\n", htts, i, (int)hio_skad_family(&binds[i].localaddr)); HIO_DEBUG3 (hio, "HTTS(%p) - [%zu] unsupported bind address type %d\n", htts, i, (int)hio_skad_get_family(&binds[i].localaddr));
continue; continue;
} }
info.m.options = HIO_DEV_SCK_MAKE_LENIENT; info.m.options = HIO_DEV_SCK_MAKE_LENIENT;

View File

@ -205,7 +205,7 @@ static hio_devaddr_t* skad_to_devaddr (hio_dev_sck_t* dev, const hio_skad_t* sck
if (sckaddr) if (sckaddr)
{ {
devaddr->ptr = (void*)sckaddr; devaddr->ptr = (void*)sckaddr;
devaddr->len = hio_skad_size(sckaddr); devaddr->len = hio_skad_get_size(sckaddr);
return devaddr; return devaddr;
} }
@ -1014,7 +1014,7 @@ static int dev_sck_write_sctp_sp (hio_dev_t* dev, const void* data, hio_iolen_t*
&iov, 1, dstaddr->ptr, dstaddr->len, &iov, 1, dstaddr->ptr, dstaddr->len,
0, /* ppid - opaque */ 0, /* ppid - opaque */
0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */ 0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */
hio_skad_chan(dstaddr->ptr), /* stream number */ hio_skad_get_chan(dstaddr->ptr), /* stream number */
0, /* ttl */ 0, /* ttl */
0 /* context*/); 0 /* context*/);
if (x <= -1) if (x <= -1)
@ -1039,7 +1039,7 @@ static int dev_sck_writev_sctp_sp (hio_dev_t* dev, const hio_iovec_t* iov, hio_i
iov, *iovcnt, dstaddr->ptr, dstaddr->len, iov, *iovcnt, dstaddr->ptr, dstaddr->len,
0, /* ppid - opaque */ 0, /* ppid - opaque */
0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */ 0, /* flags (e.g. SCTP_UNORDERED, SCTP_EOF, SCT_ABORT, ...) */
hio_skad_chan(dstaddr->ptr), /* stream number */ hio_skad_get_chan(dstaddr->ptr), /* stream number */
0, /* ttl */ 0, /* ttl */
0 /* context*/); 0 /* context*/);
if (x <= -1) if (x <= -1)
@ -1239,7 +1239,7 @@ static int dev_sck_ioctl (hio_dev_t* dev, int cmd, void* arg)
return -1; return -1;
} }
if (hio_skad_family(&bnd->localaddr) == HIO_AF_INET6) /* getsockopt(rdev->hnd, SO_DOMAIN, ...) may return the domain but it's kernel specific as well */ if (hio_skad_get_family(&bnd->localaddr) == HIO_AF_INET6) /* getsockopt(rdev->hnd, SO_DOMAIN, ...) may return the domain but it's kernel specific as well */
{ {
/* TODO: should i make it into bnd->options? HIO_DEV_SCK_BIND_IPV6ONLY? applicable to ipv6 though. */ /* TODO: should i make it into bnd->options? HIO_DEV_SCK_BIND_IPV6ONLY? applicable to ipv6 though. */
int v = 1; int v = 1;
@ -1375,7 +1375,7 @@ static int dev_sck_ioctl (hio_dev_t* dev, int cmd, void* arg)
#endif #endif
} }
x = bind(rdev->hnd, (struct sockaddr*)&bnd->localaddr, hio_skad_size(&bnd->localaddr)); x = bind(rdev->hnd, (struct sockaddr*)&bnd->localaddr, hio_skad_get_size(&bnd->localaddr));
if (x <= -1) if (x <= -1)
{ {
hio_seterrwithsyserr (hio, 0, errno); hio_seterrwithsyserr (hio, 0, errno);
@ -1859,7 +1859,7 @@ static int make_accepted_client_connection (hio_dev_sck_t* rdev, hio_syshnd_t cl
{ {
clidev->state |= HIO_DEV_SCK_INTERCEPTED; clidev->state |= HIO_DEV_SCK_INTERCEPTED;
} }
else if (hio_skad_port(&clidev->localaddr) != hio_skad_port(&rdev->localaddr)) else if (hio_skad_get_port(&clidev->localaddr) != hio_skad_get_port(&rdev->localaddr))
{ {
/* When TPROXY is used, getsockname() and SO_ORIGNAL_DST return /* When TPROXY is used, getsockname() and SO_ORIGNAL_DST return
* the same addresses. however, the port number may be different * the same addresses. however, the port number may be different
@ -2508,21 +2508,22 @@ int hio_dev_sck_getpeeraddr (hio_dev_sck_t* dev, hio_skad_t* skad)
return 0; return 0;
} }
int hio_dev_sck_joinmcastgroup (hio_dev_sck_t* dev, const hio_skad_t* mcast_skad, int ifindex) static int update_mcast_group (hio_dev_sck_t* dev, int join, const hio_skad_t* mcast_skad, int ifindex)
{ {
int f; int f;
f = hio_skad_family(mcast_skad); f = hio_skad_get_family(mcast_skad);
switch (f) switch (f)
{ {
case HIO_AF_INET: case HIO_AF_INET:
{ {
/* TODO: if ip_mreqn doesn't exist, get the ip address of the index and set to imr_address */
struct ip_mreqn mreq; struct ip_mreqn mreq;
HIO_MEMSET (&mreq, 0, HIO_SIZEOF(mreq)); HIO_MEMSET (&mreq, 0, HIO_SIZEOF(mreq));
//mreq.imr_multiaddr hio_skad_get_ipad_bytes (mcast_skad, &mreq.imr_multiaddr, HIO_SIZEOF(mreq.imr_multiaddr));
mreq.imr_ifindex = ifindex; mreq.imr_ifindex = ifindex;
/*mreq.imr_address = */ /*mreq.imr_address = */
if (hio_dev_sck_setsockopt(dev, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, HIO_SIZEOF(mreq)) <= -1) return -1; if (hio_dev_sck_setsockopt(dev, IPPROTO_IP, (join? IP_ADD_MEMBERSHIP: IP_DROP_MEMBERSHIP), &mreq, HIO_SIZEOF(mreq)) <= -1) return -1;
return 0; return 0;
} }
@ -2530,9 +2531,9 @@ int hio_dev_sck_joinmcastgroup (hio_dev_sck_t* dev, const hio_skad_t* mcast_skad
{ {
struct ipv6_mreq mreq; struct ipv6_mreq mreq;
HIO_MEMSET (&mreq, 0, HIO_SIZEOF(mreq)); HIO_MEMSET (&mreq, 0, HIO_SIZEOF(mreq));
mreq.ipv6mr_interface = ifindex; /* TODO: can reuse the scope id? */ hio_skad_get_ipad_bytes (mcast_skad, &mreq.ipv6mr_multiaddr, HIO_SIZEOF(mreq.ipv6mr_multiaddr));
//mreq.ipv6mr_multiaddr = hio_skad_ip6ad(); mreq.ipv6mr_interface = ifindex;
if (hio_dev_sck_setsockopt(dev, IPPROTO_IP, IPV6_JOIN_GROUP, &mreq, HIO_SIZEOF(mreq)) <= -1) return -1; if (hio_dev_sck_setsockopt(dev, IPPROTO_IPV6, (join? IPV6_JOIN_GROUP: IPV6_LEAVE_GROUP), &mreq, HIO_SIZEOF(mreq)) <= -1) return -1;
return 0; return 0;
} }
} }
@ -2542,6 +2543,16 @@ int hio_dev_sck_joinmcastgroup (hio_dev_sck_t* dev, const hio_skad_t* mcast_skad
return -1; return -1;
} }
int hio_dev_sck_joinmcastgroup (hio_dev_sck_t* dev, const hio_skad_t* mcast_skad, int ifindex)
{
return update_mcast_group(dev, 1, mcast_skad, ifindex);
}
int hio_dev_sck_leavemcastgroup (hio_dev_sck_t* dev, const hio_skad_t* mcast_skad, int ifindex)
{
return update_mcast_group(dev, 0, mcast_skad, ifindex);
}
/* ========================================================================= */ /* ========================================================================= */
int hio_dev_sck_shutdown (hio_dev_sck_t* dev, int how) int hio_dev_sck_shutdown (hio_dev_sck_t* dev, int how)

View File

@ -42,6 +42,12 @@
# include <net/if_dl.h> # include <net/if_dl.h>
#endif #endif
struct sockaddr_extra_t
{
hio_uint16_t chan;
};
typedef struct sockaddr_extra_t sockaddr_extra_t;
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
/* dirty hack to secure more space at the end of the actual socket address. /* dirty hack to secure more space at the end of the actual socket address.
* the extra fiels must be transparent to unaware parties. * the extra fiels must be transparent to unaware parties.
@ -50,12 +56,12 @@
* *
* extra fields: * extra fields:
* chan - used as a stream number for SCTP PACKETSEQ sockets. * chan - used as a stream number for SCTP PACKETSEQ sockets.
* use hio_skad_chan() and hio_skad_setchan() for safe access. * use hio_skad_get_chan() and hio_skad_set_chan() for safe access.
*/ */
struct sockaddr_in_x struct sockaddr_in_x
{ {
struct sockaddr_in a; struct sockaddr_in a;
hio_uint16_t chan; sockaddr_extra_t x;
}; };
#endif #endif
@ -63,7 +69,7 @@ struct sockaddr_in_x
struct sockaddr_in6_x struct sockaddr_in6_x
{ {
struct sockaddr_in6 a; struct sockaddr_in6 a;
hio_uint16_t chan; sockaddr_extra_t x;
}; };
#endif #endif
@ -1002,7 +1008,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
/* unsupported types will result in an empty string */ /* unsupported types will result in an empty string */
switch (hio_skad_family(_skad)) switch (hio_skad_get_family(_skad))
{ {
case HIO_AF_INET: case HIO_AF_INET:
if (flags & HIO_SKAD_TO_UCSTR_ADDR) if (flags & HIO_SKAD_TO_UCSTR_ADDR)
@ -1263,7 +1269,7 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf,
/* unsupported types will result in an empty string */ /* unsupported types will result in an empty string */
switch (hio_skad_family(_skad)) switch (hio_skad_get_family(_skad))
{ {
case HIO_AF_INET: case HIO_AF_INET:
if (flags & HIO_SKAD_TO_BCSTR_ADDR) if (flags & HIO_SKAD_TO_BCSTR_ADDR)
@ -1382,17 +1388,17 @@ done:
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int hio_skad_family (const hio_skad_t* _skad) int hio_skad_get_family (const hio_skad_t* _skad)
{ {
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
/*HIO_STATIC_ASSERT (HIO_SIZEOF(*_skad) >= HIO_SIZEOF(*skad));*/ /*HIO_STATIC_ASSERT (HIO_SIZEOF(*_skad) >= HIO_SIZEOF(*skad));*/
return skad->sa.sa_family; return skad->sa.sa_family;
} }
int hio_skad_size (const hio_skad_t* _skad) int hio_skad_get_size (const hio_skad_t* _skad)
{ {
/* this excludes the size of the 'chan' field. /* this excludes the size of additiona fields(e.g. chan)
* the field is not part of the core socket address */ * the fields are not part of the core socket address */
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
/*HIO_STATIC_ASSERT (HIO_SIZEOF(*_skad) >= HIO_SIZEOF(*skad));*/ /*HIO_STATIC_ASSERT (HIO_SIZEOF(*_skad) >= HIO_SIZEOF(*skad));*/
@ -1419,7 +1425,7 @@ int hio_skad_size (const hio_skad_t* _skad)
return 0; return 0;
} }
int hio_skad_port (const hio_skad_t* _skad) int hio_skad_get_port (const hio_skad_t* _skad)
{ {
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
@ -1435,7 +1441,7 @@ int hio_skad_port (const hio_skad_t* _skad)
return 0; return 0;
} }
int hio_skad_ifindex (const hio_skad_t* _skad) int hio_skad_get_ifindex (const hio_skad_t* _skad)
{ {
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
@ -1449,7 +1455,7 @@ int hio_skad_ifindex (const hio_skad_t* _skad)
return 0; return 0;
} }
int hio_skad_scope_id (const hio_skad_t* _skad) int hio_skad_get_scope_id (const hio_skad_t* _skad)
{ {
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
@ -1469,17 +1475,17 @@ void hio_skad_set_scope_id (hio_skad_t* _skad, int scope_id)
#endif #endif
} }
hio_uint16_t hio_skad_chan (const hio_skad_t* _skad) hio_uint16_t hio_skad_get_chan (const hio_skad_t* _skad)
{ {
const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad; const hio_skad_alt_t* skad = (const hio_skad_alt_t*)_skad;
switch (skad->sa.sa_family) switch (skad->sa.sa_family)
{ {
#if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) #if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case AF_INET: return skad->in4.chan; case AF_INET: return skad->in4.x.chan;
#endif #endif
#if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) #if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case AF_INET6: return skad->in6.chan; case AF_INET6: return skad->in6.x.chan;
#endif #endif
} }
return 0; return 0;
@ -1492,14 +1498,38 @@ void hio_skad_set_chan (hio_skad_t* _skad, hio_uint16_t chan)
switch (skad->sa.sa_family) switch (skad->sa.sa_family)
{ {
#if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) #if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case AF_INET: skad->in4.chan = chan; break; case AF_INET: skad->in4.x.chan = chan; break;
#endif #endif
#if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) #if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case AF_INET6: skad->in6.chan = chan; break; case AF_INET6: skad->in6.x.chan = chan; break;
#endif #endif
} }
} }
hio_oow_t hio_skad_get_ipad_bytes (hio_skad_t* _skad, void* buf, hio_oow_t len)
{
hio_skad_alt_t* skad = (hio_skad_alt_t*)_skad;
hio_oow_t outlen = 0;
switch (skad->sa.sa_family)
{
#if defined(AF_INET) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case AF_INET:
outlen = len < HIO_SIZEOF(skad->in4.a.sin_addr)? len: HIO_SIZEOF(skad->in4.a.sin_addr);
HIO_MEMCPY (buf, &skad->in4.a.sin_addr, outlen);
break;
#endif
#if defined(AF_INET6) && (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case AF_INET6:
outlen = len < HIO_SIZEOF(skad->in6.a.sin6_addr)? len: HIO_SIZEOF(skad->in6.a.sin6_addr);
HIO_MEMCPY (buf, &skad->in6.a.sin6_addr, outlen);
break;
#endif
}
return outlen;
}
void hio_skad_init_for_ip4 (hio_skad_t* skad, hio_uint16_t port, hio_ip4ad_t* ip4ad) void hio_skad_init_for_ip4 (hio_skad_t* skad, hio_uint16_t port, hio_ip4ad_t* ip4ad)
{ {
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) #if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
@ -1603,8 +1633,8 @@ int hio_equal_skads (const hio_skad_t* addr1, const hio_skad_t* addr2, int stric
{ {
int f1; int f1;
if ((f1 = hio_skad_family(addr1)) != hio_skad_family(addr2) || if ((f1 = hio_skad_get_family(addr1)) != hio_skad_get_family(addr2) ||
hio_skad_size(addr1) != hio_skad_size(addr2)) return 0; hio_skad_get_size(addr1) != hio_skad_get_size(addr2)) return 0;
switch (f1) switch (f1)
{ {
@ -1637,7 +1667,7 @@ int hio_equal_skads (const hio_skad_t* addr1, const hio_skad_t* addr2, int stric
#endif #endif
default: default:
return HIO_MEMCMP(addr1, addr2, hio_skad_size(addr1)) == 0; return HIO_MEMCMP(addr1, addr2, hio_skad_get_size(addr1)) == 0;
} }
} }