enhanced hio_svc_htts_start() to accept multiple binding addresses.

added hio_skad_init_for_qx()
defined HIO_AF_QX
changed hio-skad to defined HIO_AF_UNIX to a fake value if it's not defined.
fixed skad conversion functions to handle unix addresses  more consistently
This commit is contained in:
hyung-hwan 2021-08-06 03:23:48 +00:00
parent 7710d57968
commit 63cdf7b3bb
9 changed files with 370 additions and 128 deletions

View File

@ -1237,7 +1237,7 @@ for (i = 0; i < 5; i++)
HIO_INFO1 (hio, "UNABLE TO START DNC - %js\n", hio_geterrmsg(hio));
}
htts = hio_svc_htts_start(hio, &htts_bind_info, process_http_request);
htts = hio_svc_htts_start(hio, &htts_bind_info, 1, process_http_request);
if (htts) hio_svc_htts_setservernamewithbcstr (htts, "HIO-HTTP");
else HIO_INFO1 (hio, "UNABLE TO START HTTS - %js\n", hio_geterrmsg(hio));

View File

@ -11,7 +11,6 @@
#include <stdlib.h>
#define MAX_NUM_THRS 256
static int g_reuse_port = 0;
static int g_num_thrs = 2;
static hio_svc_htts_t* g_htts[MAX_NUM_THRS];
static int g_htts_no = 0;
@ -216,7 +215,7 @@ void* thr_func (void* arg)
{
hio_t* hio = HIO_NULL;
hio_svc_htts_t* htts = HIO_NULL;
hio_dev_sck_bind_t htts_bind_info;
hio_dev_sck_bind_t htts_bind_info[2];
int htts_no = -1;
hio = hio_open(HIO_NULL, 0, HIO_NULL, HIO_FEATURE_ALL, 512, HIO_NULL);
@ -229,16 +228,17 @@ void* thr_func (void* arg)
hio_setoption (hio, HIO_LOG_TARGET_BCSTR, "/dev/stderr");
memset (&htts_bind_info, 0, HIO_SIZEOF(htts_bind_info));
if (g_reuse_port)
{
hio_bcstrtoskad (hio, "0.0.0.0:9987", &htts_bind_info.localaddr);
htts_bind_info.options = HIO_DEV_SCK_BIND_REUSEADDR | HIO_DEV_SCK_BIND_REUSEPORT | HIO_DEV_SCK_BIND_IGNERR;
//htts_bind_info.options |= HIO_DEV_SCK_BIND_SSL;
htts_bind_info.ssl_certfile = "localhost.crt";
htts_bind_info.ssl_keyfile = "localhost.key";
}
hio_skad_init_for_qx (&htts_bind_info[0].localaddr);
htts = hio_svc_htts_start(hio, &htts_bind_info, process_http_request);
hio_bcstrtoskad (hio, "0.0.0.0:9988", &htts_bind_info[1].localaddr);
htts_bind_info[1].options = HIO_DEV_SCK_BIND_REUSEADDR | HIO_DEV_SCK_BIND_REUSEPORT | HIO_DEV_SCK_BIND_IGNERR;
#if 0
htts_bind_info[1].options |= HIO_DEV_SCK_BIND_SSL;
htts_bind_info[1].ssl_certfile = "localhost.crt";
htts_bind_info[1].ssl_keyfile = "localhost.key";
#endif
htts = hio_svc_htts_start(hio, &htts_bind_info, HIO_COUNTOF(htts_bind_info), process_http_request);
if (!htts)
{
printf ("Unable to start htts\n");
@ -251,9 +251,7 @@ void* thr_func (void* arg)
g_htts_no = (g_htts_no + 1) % g_num_thrs;
pthread_mutex_unlock (&g_htts_mutex);
printf ("entering the loop for %d\n", htts_no);
hio_loop (hio);
printf ("exiting the loop for %d\n", htts_no);
oops:
pthread_mutex_lock (&g_htts_mutex);
@ -387,7 +385,7 @@ static int try_to_accept (hio_dev_sck_t* sck, hio_dev_sck_qxmsg_t* qxmsg, int in
g_htts_no = (g_htts_no + 1) % g_num_thrs;
pthread_mutex_unlock (&g_htts_mutex);
if (hio_svc_htts_writetosidechan(htts, qxmsg, HIO_SIZEOF(*qxmsg)) <= -1)
if (hio_svc_htts_writetosidechan(htts, 0, qxmsg, HIO_SIZEOF(*qxmsg)) <= -1)
{
hio_bch_t buf[128];
@ -470,6 +468,7 @@ static int add_listener (hio_t* hio, hio_bch_t* addrstr)
hio_dev_sck_t* tcp;
hio_dev_sck_bind_t bi;
hio_dev_sck_listen_t li;
int f;
memset (&bi, 0, HIO_SIZEOF(bi));
if (hio_bcstrtoskad(hio, addrstr, &bi.localaddr) <= -1)
@ -485,7 +484,16 @@ static int add_listener (hio_t* hio, hio_bch_t* addrstr)
#endif
memset (&mi, 0, HIO_SIZEOF(mi));
mi.type = (hio_skad_family(&bi.localaddr) == HIO_AF_INET? HIO_DEV_SCK_TCP4: HIO_DEV_SCK_TCP6);
f = hio_skad_family(&bi.localaddr);
if (f == HIO_AF_INET) mi.type = HIO_DEV_SCK_TCP4;
else if (f == HIO_AF_INET6) mi.type = HIO_DEV_SCK_TCP6;
else if (f == HIO_AF_UNIX) mi.type = HIO_DEV_SCK_UNIX;
else
{
HIO_INFO1 (hio, "unsupported address type - %hs\n", addrstr);
return -1;
}
mi.options = HIO_DEV_SCK_MAKE_LENIENT;
mi.on_write = tcp_sck_on_write;
mi.on_read = tcp_sck_on_read;
@ -496,17 +504,14 @@ static int add_listener (hio_t* hio, hio_bch_t* addrstr)
tcp = hio_dev_sck_make(hio, 0, &mi);
if (!tcp)
{
HIO_INFO1 (hio, "Cannot make tcp - %js\n", hio_geterrmsg(hio));
HIO_INFO2 (hio, "Cannot make tcp for %hs - %js\n", addrstr, hio_geterrmsg(hio));
return -1;
}
if (!g_reuse_port)
if (hio_dev_sck_bind(tcp, &bi) <= -1)
{
if (hio_dev_sck_bind(tcp, &bi) <= -1)
{
HIO_INFO1 (hio, "tcp hio_dev_sck_bind() failed - %js\n", hio_geterrmsg(hio));
return -1;
}
HIO_INFO2 (hio, "tcp hio_dev_sck_bind() failed with %hs - %js\n", addrstr, hio_geterrmsg(hio));
return -1;
}
memset (&li, 0, HIO_SIZEOF(li));
@ -514,9 +519,17 @@ static int add_listener (hio_t* hio, hio_bch_t* addrstr)
HIO_INIT_NTIME (&li.accept_tmout, 5, 1);
if (hio_dev_sck_listen(tcp, &li) <= -1)
{
HIO_INFO1 (hio, "tcp[2] hio_dev_sck_listen() failed - %js\n", hio_geterrmsg(hio));
HIO_INFO2 (hio, "tcp hio_dev_sck_listen() failed on %hs - %js\n", addrstr, hio_geterrmsg(hio));
return -1;
}
else
{
hio_skad_t skad;
hio_bch_t buf[HIO_SKAD_IP_STRLEN + 1];
hio_dev_sck_getsockaddr (tcp, &skad);
hio_skadtobcstr (hio, &skad, buf, HIO_COUNTOF(buf), HIO_SKAD_TO_BCSTR_ADDR | HIO_SKAD_TO_BCSTR_PORT);
HIO_INFO1 (hio, "main listener on %hs\n", buf);
}
return 0;
}
@ -540,12 +553,7 @@ int main (int argc, char* argv[])
// TODO: use getopt() or something similar
for (i = 1; i < argc; )
{
if (strcmp(argv[i], "-r") == 0)
{
g_reuse_port = 1;
i++;
}
else if (strcmp(argv[i], "-t") == 0)
if (strcmp(argv[i], "-t") == 0)
{
i++;
if (i < argc)
@ -602,9 +610,12 @@ int main (int argc, char* argv[])
if (add_listener(hio, "[::]:9987") <= -1 ||
add_listener(hio, "0.0.0.0:9987") <= -1) goto oops;
printf ("entering the main loop\n");
/* add a unix socket listener.
* don't check for an error to continue without it in case it fails. */
unlink ("t06.sck");
add_listener(hio, "@t06.sck");
hio_loop (hio);
printf ("exiting the main loop\n");
xret = 0;

View File

@ -250,7 +250,8 @@ HIO_EXPORT int hio_scan_http_qparam (
HIO_EXPORT hio_svc_htts_t* hio_svc_htts_start (
hio_t* hio,
hio_dev_sck_bind_t* sck_bind,
hio_dev_sck_bind_t* binds,
hio_oow_t nbinds,
hio_svc_htts_proc_req_t proc_req
);
@ -266,6 +267,7 @@ static HIO_INLINE hio_t* hio_svc_htts_gethio(hio_svc_htts_t* svc) { return hio_s
HIO_EXPORT int hio_svc_htts_writetosidechan (
hio_svc_htts_t* htts,
hio_oow_t idx, /* listener index */
const void* dptr,
hio_oow_t dlen
);
@ -275,8 +277,22 @@ HIO_EXPORT int hio_svc_htts_setservernamewithbcstr (
const hio_bch_t* server_name
);
/* return the listening device at the given position.
* not all devices may be up and running */
HIO_EXPORT hio_dev_sck_t* hio_svc_htts_getlistendev (
hio_svc_htts_t* htts,
hio_oow_t idx
);
/* return the total number of listening devices requested to start.
* not all devices may be up and running */
HIO_EXPORT hio_oow_t hio_sv_htts_getnlistendevs (
hio_svc_htts_t* htts
);
HIO_EXPORT int hio_svc_htts_getsockaddr (
hio_svc_htts_t* htts,
hio_oow_t idx, /* listener index */
hio_skad_t* skad
);

View File

@ -262,7 +262,7 @@ typedef void (*hio_dev_sck_on_raw_accept_t) (
enum hio_dev_sck_type_t
{
HIO_DEV_SCK_QX,
HIO_DEV_SCK_UNIX,
HIO_DEV_SCK_TCP4,
HIO_DEV_SCK_TCP6,

View File

@ -52,6 +52,13 @@
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_UN
#endif
#if !defined(HIO_AF_UNIX)
/* this is a fake value */
# define HIO_AF_UNIX (65534)
#endif
/* this is HIO specific. No AF_XXXX definitions must overlap with this */
#define HIO_AF_QX (65530)
struct hio_skad_t
{
hio_uint8_t data[HIO_SIZEOF_SKAD_T];
@ -173,6 +180,10 @@ HIO_EXPORT void hio_skad_init_for_eth (
hio_ethad_t* ethad
);
HIO_EXPORT void hio_skad_init_for_qx (
hio_skad_t* skad
);
HIO_EXPORT int hio_skad_family (
const hio_skad_t* skad
);

View File

@ -38,10 +38,11 @@ struct hio_svc_htts_cli_t
hio_svc_htts_cli_t* cli_prev;
hio_svc_htts_cli_t* cli_next;
/* a listener socket sets htts and sck fields only */
/* a listener socket sets htts, sck, and l_idx fields only */
/* a client sockets uses all the fields in this struct */
hio_svc_htts_t* htts;
hio_dev_sck_t* sck;
hio_oow_t l_idx; /* listening socket: < htts->l.count, client socket: >= htts->l.count */
hio_htrd_t* htrd;
hio_becs_t* sbuf; /* temporary buffer for status line formatting */
@ -62,7 +63,13 @@ struct hio_svc_htts_t
hio_svc_htts_proc_req_t proc_req;
hio_dev_sck_t* lsck;
struct
{
hio_dev_sck_t** sck;
hio_oow_t count;
} l;
/*hio_dev_sck_t* lsck;*/
hio_svc_htts_cli_t cli; /* list head for client list */
hio_tmridx_t idle_tmridx;

View File

@ -48,10 +48,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->sck == cli->htts->lsck); /* the field should still point to the listner socket */
HIO_ASSERT (sck->hio, sck->hio == cli->htts->hio);
cli->sck = sck;
cli->l_idx = HIO_TYPE_MAX(hio_oow_t);
cli->htrd = HIO_NULL;
cli->sbuf = HIO_NULL;
cli->rsrc = HIO_NULL;
@ -138,7 +139,7 @@ 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, sck != cli->htts->lsck);
HIO_ASSERT (hio, cli->rsrc == HIO_NULL); /* if a resource has been set, the resource must take over this handler */
if (len <= -1)
@ -182,7 +183,7 @@ oops:
static int listener_on_write (hio_dev_sck_t* sck, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr)
{
hio_svc_htts_cli_t* cli = hio_dev_sck_getxtn(sck);
HIO_ASSERT (sck->hio, sck != cli->htts->lsck);
//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 */
return 0;
}
@ -214,7 +215,7 @@ static void listener_on_connect (hio_dev_sck_t* sck)
static void listener_on_disconnect (hio_dev_sck_t* sck)
{
hio_t* hio = sck->hio;
hio_svc_htts_cli_t* cli = hio_dev_sck_getxtn(sck);
hio_svc_htts_cli_t* xtn = hio_dev_sck_getxtn(sck);
switch (HIO_DEV_SCK_GET_PROGRESS(sck))
{
@ -241,8 +242,8 @@ static void listener_on_disconnect (hio_dev_sck_t* sck)
/* this progress code indicates that the ssl-level accept failed.
* on_disconnected() with this code is called without corresponding on_connect().
* the cli extension are is not initialized yet */
HIO_ASSERT (hio, sck != cli->sck);
HIO_ASSERT (hio, cli->sck == cli->htts->lsck); /* the field is a copy of the extension are of the listener socket. so it should point to the listner socket */
HIO_ASSERT (hio, sck != xtn->sck);
//HIO_ASSERT (hio, cli->sck == cli->htts->lsck); /* the field is a copy of the extension are of the listener socket. so it should point to the listner socket */
HIO_DEBUG2 (hio, "LISTENER UNABLE TO SSL-ACCEPT CLIENT %p(%d) ....%p\n", sck, (int)sck->hnd);
return;
@ -257,21 +258,21 @@ static void listener_on_disconnect (hio_dev_sck_t* sck)
break;
}
if (sck == cli->htts->lsck)
if (xtn->l_idx < xtn->htts->l.count)
{
/* the listener socket has these fields set to NULL */
HIO_ASSERT (hio, cli->htrd == HIO_NULL);
HIO_ASSERT (hio, cli->sbuf == HIO_NULL);
HIO_ASSERT (hio, xtn->htrd == HIO_NULL);
HIO_ASSERT (hio, xtn->sbuf == HIO_NULL);
HIO_DEBUG2 (hio, "HTTS(%p) - listener socket disconnect %p\n", cli->htts, sck);
cli->htts->lsck = HIO_NULL; /* let the htts service forget about this listening socket */
HIO_DEBUG2 (hio, "HTTS(%p) - listener socket disconnect %p\n", xtn->htts, sck);
xtn->htts->l.sck[xtn->l_idx] = HIO_NULL; /* let the htts service forget about this listening socket */
}
else
{
/* client socket */
HIO_DEBUG2 (hio, "HTTS(%p) - client socket disconnect %p\n", cli->htts, sck);
HIO_ASSERT (hio, cli->sck == sck);
fini_client (cli);
HIO_DEBUG2 (hio, "HTTS(%p) - client socket disconnect %p\n", xtn->htts, sck);
HIO_ASSERT (hio, xtn->sck == sck);
fini_client (xtn);
}
}
@ -315,7 +316,7 @@ static void halt_idle_clients (hio_t* hio, const hio_ntime_t* now, hio_tmrjob_t*
/* ------------------------------------------------------------------------ */
hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* sck_bind, hio_svc_htts_proc_req_t proc_req)
hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* binds, hio_oow_t nbinds, hio_svc_htts_proc_req_t proc_req)
{
hio_svc_htts_t* htts = HIO_NULL;
union
@ -324,68 +325,130 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* sck_bind, hi
hio_dev_sck_listen_t l;
} info;
hio_svc_htts_cli_t* cli;
hio_oow_t i, noks;
if (HIO_UNLIKELY(nbinds <= 0))
{
hio_seterrnum (hio, HIO_EINVAL);
goto oops;
}
htts = (hio_svc_htts_t*)hio_callocmem(hio, HIO_SIZEOF(*htts));
if (HIO_UNLIKELY(!htts)) goto oops;
HIO_DEBUG1 (hio, "HTTS - STARTING SERVICE %p\n", htts);
htts->hio = hio;
htts->svc_stop = hio_svc_htts_stop;
htts->proc_req = proc_req;
htts->idle_tmridx = HIO_TMRIDX_INVALID;
HIO_MEMSET (&info, 0, HIO_SIZEOF(info));
switch (hio_skad_family(&sck_bind->localaddr))
htts->l.sck = (hio_dev_sck_t**)hio_callocmem(hio, HIO_SIZEOF(*htts->l.sck) * nbinds);
if (HIO_UNLIKELY(!htts->l.sck)) goto oops;
htts->l.count = nbinds;
for (i = 0, noks = 0; i < nbinds; i++)
{
case HIO_AF_INET:
info.m.type = HIO_DEV_SCK_TCP4;
break;
case HIO_AF_INET6:
info.m.type = HIO_DEV_SCK_TCP6;
break;
default:
/*hio_seterrnum (hio, HIO_EINVAL);
goto oops;*/
info.m.type = HIO_DEV_SCK_QX;
break;
}
info.m.options = HIO_DEV_SCK_MAKE_LENIENT;
info.m.on_write = listener_on_write;
info.m.on_read = listener_on_read;
info.m.on_connect = listener_on_connect;
info.m.on_disconnect = listener_on_disconnect;
htts->lsck = hio_dev_sck_make(hio, HIO_SIZEOF(*cli), &info.m);
if (HIO_UNLIKELY(!htts->lsck)) goto oops;
/* the name 'cli' for the listening socket is awkward.
* the listening socket will use the htts and sck fields for tracking only.
* each accepted client socket gets the extension size for this size as well.
* most of other fields are used for client management */
cli = (hio_svc_htts_cli_t*)hio_dev_sck_getxtn(htts->lsck);
cli->htts = htts;
cli->sck = htts->lsck;
if (htts->lsck->type != HIO_DEV_SCK_QX)
{
if (hio_dev_sck_bind(htts->lsck, sck_bind) <= -1) goto oops;
hio_dev_sck_t* sck;
HIO_MEMSET (&info, 0, HIO_SIZEOF(info));
info.l.backlogs = 4096; /* TODO: use configuration? */
HIO_INIT_NTIME (&info.l.accept_tmout, 5, 1); /* usedd for ssl accept */
if (hio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
switch (hio_skad_family(&binds[i].localaddr))
{
case HIO_AF_INET:
info.m.type = HIO_DEV_SCK_TCP4;
break;
case HIO_AF_INET6:
info.m.type = HIO_DEV_SCK_TCP6;
break;
#if defined(HIO_AF_UNIX)
case HIO_AF_UNIX:
info.m.type = HIO_DEV_SCK_UNIX;
break;
#endif
case HIO_AF_QX:
info.m.type = HIO_DEV_SCK_QX;
break;
default:
/* ignore this */
continue;
}
info.m.options = HIO_DEV_SCK_MAKE_LENIENT;
info.m.on_write = listener_on_write;
info.m.on_read = listener_on_read;
info.m.on_connect = listener_on_connect;
info.m.on_disconnect = listener_on_disconnect;
sck = hio_dev_sck_make(hio, HIO_SIZEOF(*cli), &info.m);
if (HIO_UNLIKELY(!sck)) continue;
/* the name 'cli' for the listening socket is awkward.
* the listening socket will use the htts, sck, and listening fields for tracking only.
* each accepted client socket gets the extension size for this size as well.
* most of other fields are used for client management. init_client() will set
* the sck field to the client socket and the listening field to 0. */
cli = (hio_svc_htts_cli_t*)hio_dev_sck_getxtn(sck);
cli->htts = htts;
cli->sck = sck;
cli->l_idx = i;
if (sck->type != HIO_DEV_SCK_QX)
{
if (hio_dev_sck_bind(sck, &binds[i]) <= -1)
{
if (HIO_LOG_ENABLED(hio, HIO_LOG_DEBUG))
{
hio_bch_t tmpbuf[HIO_SKAD_IP_STRLEN + 1];
hio_skadtobcstr(hio, &binds[i].localaddr, tmpbuf, HIO_COUNTOF(tmpbuf), HIO_SKAD_TO_BCSTR_ADDR | HIO_SKAD_TO_BCSTR_PORT);
HIO_DEBUG3 (hio, "HTTS(%p) - [%zd] unable to bind to %hs\n", htts, i, tmpbuf);
}
hio_dev_sck_kill (sck);
continue;
}
HIO_MEMSET (&info, 0, HIO_SIZEOF(info));
info.l.backlogs = 4096; /* TODO: use configuration? */
HIO_INIT_NTIME (&info.l.accept_tmout, 5, 1); /* usedd for ssl accept */
if (hio_dev_sck_listen(sck, &info.l) <= -1)
{
if (HIO_LOG_ENABLED(hio, HIO_LOG_DEBUG))
{
hio_bch_t tmpbuf[HIO_SKAD_IP_STRLEN + 1];
hio_skadtobcstr(hio, &binds[i].localaddr, tmpbuf, HIO_COUNTOF(tmpbuf), HIO_SKAD_TO_BCSTR_ADDR | HIO_SKAD_TO_BCSTR_PORT);
HIO_DEBUG3 (hio, "HTTS(%p) - [%zd] unable to bind to %hs\n", htts, i, tmpbuf);
}
hio_dev_sck_kill (sck);
goto oops;
}
}
if (HIO_LOG_ENABLED(hio, HIO_LOG_DEBUG))
{
hio_skad_t tmpad;
hio_bch_t tmpbuf[HIO_SKAD_IP_STRLEN + 1];
hio_dev_sck_getsockaddr(sck, &tmpad);
hio_skadtobcstr(hio, &tmpad, tmpbuf, HIO_COUNTOF(tmpbuf), HIO_SKAD_TO_BCSTR_ADDR | HIO_SKAD_TO_BCSTR_PORT);
HIO_DEBUG3 (hio, "HTTS(%p) - [%zd] listening on %hs\n", htts, i, tmpbuf);
}
htts->l.sck[i] = sck;
noks++;
}
if (noks <= 0) goto oops;
hio_fmttobcstr (htts->hio, htts->server_name_buf, HIO_COUNTOF(htts->server_name_buf), "%s-%d.%d.%d",
HIO_PACKAGE_NAME, (int)HIO_PACKAGE_VERSION_MAJOR, (int)HIO_PACKAGE_VERSION_MINOR, (int)HIO_PACKAGE_VERSION_PATCH);
htts->server_name = htts->server_name_buf;
HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)htts);
HIO_SVC_HTTS_CLIL_INIT (&htts->cli);
HIO_DEBUG3 (hio, "HTTS - STARTED SERVICE %p - LISTENER SOCKET %p(%d)\n", htts, htts->lsck, (int)htts->lsck->hnd);
HIO_DEBUG1 (hio, "HTTS - STARTED SERVICE %p\n", htts);
{
hio_ntime_t t;
@ -403,7 +466,13 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_dev_sck_bind_t* sck_bind, hi
oops:
if (htts)
{
if (htts->lsck) hio_dev_sck_kill (htts->lsck);
if (htts->l.sck)
{
for (i = 0; i < htts->l.count; i++)
hio_dev_sck_kill (htts->l.sck[i]);
hio_freemem (hio, htts->l.sck);
}
hio_freemem (hio, htts);
}
return HIO_NULL;
@ -412,12 +481,17 @@ oops:
void hio_svc_htts_stop (hio_svc_htts_t* htts)
{
hio_t* hio = htts->hio;
hio_oow_t i;
HIO_DEBUG3 (hio, "HTTS - STOPPING SERVICE %p - LISTENER SOCKET %p(%d)\n", htts, htts->lsck, (int)(htts->lsck? htts->lsck->hnd: -1));
HIO_DEBUG1 (hio, "HTTS - STOPPING SERVICE %p\n", htts);
/* htts->lsck may be null if the socket has been destroyed for operational error and
* forgotten in the disconnect callback thereafter */
if (htts->lsck) hio_dev_sck_kill (htts->lsck);
for (i = 0; i < htts->l.count; i++)
{
/* the socket may be null:
* if it has been destroyed for operation errors and forgotten in the disconnect callback thereafter
* if it has never been created successfully */
if (htts->l.sck[i]) hio_dev_sck_kill (htts->l.sck[i]);
}
while (!HIO_SVC_HTTS_CLIL_IS_EMPTY(&htts->cli))
{
@ -430,6 +504,7 @@ void hio_svc_htts_stop (hio_svc_htts_t* htts)
if (htts->idle_tmridx != HIO_TMRIDX_INVALID) hio_deltmrjob (hio, htts->idle_tmridx);
if (htts->l.sck) hio_freemem (hio, htts->l.sck);
hio_freemem (hio, htts);
}
@ -453,10 +528,47 @@ int hio_svc_htts_setservernamewithbcstr (hio_svc_htts_t* htts, const hio_bch_t*
return 0;
}
int hio_svc_htts_getsockaddr (hio_svc_htts_t* htts, hio_skad_t* skad)
hio_dev_sck_t* hio_svc_htts_getlistendev (hio_svc_htts_t* htts, hio_oow_t idx)
{
if (idx >= htts->l.count)
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "index out of range");
return HIO_NULL;
}
if (!htts->l.sck[idx])
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "no listener at the given index");
return HIO_NULL;
}
return htts->l.sck[idx];
}
hio_oow_t hio_svc_htts_getnlistendevs (hio_svc_htts_t* htts)
{
/* return the total number of listening socket devices.
* not all devices may be up and working */
return htts->l.count;
}
int hio_svc_htts_getsockaddr (hio_svc_htts_t* htts, hio_oow_t idx, hio_skad_t* skad)
{
/* return the socket address of the listening socket. */
return hio_dev_sck_getsockaddr(htts->lsck, skad);
if (idx >= htts->l.count)
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "index out of range");
return -1;
}
if (!htts->l.sck[idx])
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "no listener at the given index");
return -1;
}
return hio_dev_sck_getsockaddr(htts->l.sck[idx], skad);
}
/* ----------------------------------------------------------------- */
@ -550,9 +662,21 @@ hio_bch_t* hio_svc_htts_dupmergepaths (hio_svc_htts_t* htts, const hio_bch_t* ba
return xpath;
}
int hio_svc_htts_writetosidechan (hio_svc_htts_t* htts, const void* dptr, hio_oow_t dlen)
int hio_svc_htts_writetosidechan (hio_svc_htts_t* htts, hio_oow_t idx, const void* dptr, hio_oow_t dlen)
{
return hio_dev_sck_writetosidechan(htts->lsck, dptr, dlen);
if (idx >= htts->l.count)
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "index out of range");
return -1;
}
if (!htts->l.sck[idx])
{
hio_seterrbfmt (htts->hio, HIO_EINVAL, "no listener at the given index");
return -1;
}
return hio_dev_sck_writetosidechan(htts->l.sck[idx], dptr, dlen);
}

View File

@ -224,13 +224,18 @@ struct sck_type_map_t
int extra_dev_cap;
};
#define __AF_QX 999999
#define __AF_BPF 999998
static struct sck_type_map_t sck_type_map[] =
{
/* HIO_DEV_SCK_QX */
{ __AF_QX, 0, 0, 0 },
{ HIO_AF_QX, 0, 0, 0 },
#if defined(AF_UNIX)
{ AF_UNIX, SOCK_STREAM, 0, HIO_DEV_CAP_STREAM },
#else
{ -1, 0, 0, 0 },
#endif
/* HIO_DEV_SCK_TCP4 */
{ AF_INET, SOCK_STREAM, 0, HIO_DEV_CAP_STREAM },
@ -278,7 +283,6 @@ static struct sck_type_map_t sck_type_map[] =
{ -1, 0, 0, 0 },
#endif
/* HIO_DEV_SCK_BPF - arp */
{ __AF_BPF, 0, 0, 0 } /* not implemented yet */
};
@ -397,7 +401,7 @@ static int dev_sck_make (hio_dev_t* dev, void* ctx)
goto oops;
}
if (HIO_UNLIKELY(sck_type_map[arg->type].domain == __AF_QX))
if (HIO_UNLIKELY(sck_type_map[arg->type].domain == HIO_AF_QX))
{
hnd = open_async_qx(hio, &side_chan);
if (hnd == HIO_SYSHND_INVALID) goto oops;
@ -2200,7 +2204,11 @@ int hio_dev_sck_getsockopt (hio_dev_sck_t* dev, int level, int optname, void* op
int hio_dev_sck_getsockaddr (hio_dev_sck_t* dev, hio_skad_t* skad)
{
hio_scklen_t addrlen = HIO_SIZEOF(*skad);
if (getsockname(dev->hnd, (struct sockaddr*)skad, &addrlen) <= -1)
if (dev->type == HIO_DEV_SCK_QX)
{
hio_skad_init_for_qx (skad);
}
else if (getsockname(dev->hnd, (struct sockaddr*)skad, &addrlen) <= -1)
{
hio_seterrwithsyserr (dev->hio, 0, errno);
return -1;
@ -2211,7 +2219,11 @@ int hio_dev_sck_getsockaddr (hio_dev_sck_t* dev, hio_skad_t* skad)
int hio_dev_sck_getpeeraddr (hio_dev_sck_t* dev, hio_skad_t* skad)
{
hio_scklen_t addrlen = HIO_SIZEOF(*skad);
if (getpeername(dev->hnd, (struct sockaddr*)skad, &addrlen) <= -1)
if (dev->type == HIO_DEV_SCK_QX)
{
hio_skad_init_for_qx (skad);
}
else if (getpeername(dev->hnd, (struct sockaddr*)skad, &addrlen) <= -1)
{
hio_seterrwithsyserr (dev->hio, 0, errno);
return -1;

View File

@ -382,17 +382,30 @@ int hio_ucharstoskad (hio_t* hio, const hio_uch_t* str, hio_oow_t len, hio_skad_
/* use HIO_SIZEOF(*_skad) instead of HIO_SIZEOF(*skad) in case they are different */
HIO_MEMSET (skad, 0, HIO_SIZEOF(*_skad));
#if defined(AF_UNIX)
if (*p == '/' && len >= 2)
if (p[0] == '<' && p[1] == 'q' && p[2] == 'x' && p[3] == '>' && p[4] == '\0')
{
hio_oow_t dstlen;
/* this is HIO specific. the rest isn't important */
skad->sa.sa_family = HIO_AF_QX;
return 0;
}
if (*p == '@')
{
#if defined(AF_UNIX) && (HIO_SIZEOF_STRUCT_SOCKADDR_UN > 0)
/* @aaa, @/tmp/aaa ... */
hio_oow_t srclen, dstlen;
dstlen = HIO_COUNTOF(skad->un.sun_path) - 1;
if (hio_convutobchars(hio, p, &len, skad->un.sun_path, &dstlen) <= -1) return -1;
srclen = len - 1;
if (hio_convutobchars(hio, p + 1, &srclen, skad->un.sun_path, &dstlen) <= -1) return -1;
skad->un.sun_path[dstlen] = '\0';
skad->un.sun_family = AF_UNIX;
return 0;
}
#else
hio_seterrbfmt (hio, HIO_ENOIMPL, "unix address not supported");
return -1;
#endif
}
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (*p == '[')
@ -596,14 +609,25 @@ int hio_bcharstoskad (hio_t* hio, const hio_bch_t* str, hio_oow_t len, hio_skad_
/* use HIO_SIZEOF(*_skad) instead of HIO_SIZEOF(*skad) in case they are different */
HIO_MEMSET (skad, 0, HIO_SIZEOF(*_skad));
#if defined(AF_UNIX)
if (*p == '/' && len >= 2)
if (p[0] == '<' && p[1] == 'q' && p[2] == 'x' && p[3] == '>' && p[4] == '\0')
{
hio_copy_bcstr (skad->un.sun_path, HIO_COUNTOF(skad->un.sun_path), str);
skad->un.sun_family = AF_UNIX;
/* this is HIO specific. the rest isn't important */
skad->sa.sa_family = HIO_AF_QX;
return 0;
}
if (*p == '@')
{
#if defined(AF_UNIX) && (HIO_SIZEOF_STRUCT_SOCKADDR_UN > 0)
/* @aaa, @/tmp/aaa ... */
hio_copy_bchars_to_bcstr (skad->un.sun_path, HIO_COUNTOF(skad->un.sun_path), str + 1, len - 1);
skad->un.sun_family = HIO_AF_UNIX;
return 0;
#else
hio_seterrbfmt (hio, HIO_ENOIMPL, "unix address not supported");
return -1;
#endif
}
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (*p == '[')
@ -959,17 +983,17 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
switch (hio_skad_family(_skad))
{
case HIO_AF_INET:
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
xlen += ip4ad_to_ucstr(&skad->in4.sin_addr, buf, len);
}
if (flags & HIO_SKAD_TO_BCSTR_PORT)
if (flags & HIO_SKAD_TO_UCSTR_PORT)
{
if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in4.sin_port != 0)
if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in4.sin_port != 0)
{
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = ':';
@ -982,11 +1006,11 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
break;
case HIO_AF_INET6:
if (flags & HIO_SKAD_TO_BCSTR_PORT)
if (flags & HIO_SKAD_TO_UCSTR_PORT)
{
if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0)
if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.sin6_port != 0)
{
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = '[';
@ -994,7 +1018,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
}
}
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
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);
@ -1017,11 +1041,11 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
}
}
if (flags & HIO_SKAD_TO_BCSTR_PORT)
if (flags & HIO_SKAD_TO_UCSTR_PORT)
{
if (!(flags & HIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0)
if (!(flags & HIO_SKAD_TO_UCSTR_ADDR) || skad->in6.sin6_port != 0)
{
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = ']';
@ -1038,7 +1062,7 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
break;
case HIO_AF_UNIX:
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = '@';
@ -1053,6 +1077,21 @@ hio_oow_t hio_skadtoucstr (hio_t* hio, const hio_skad_t* _skad, hio_uch_t* buf,
}
}
break;
case HIO_AF_QX:
if (flags & HIO_SKAD_TO_UCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = '<';
if (xlen + 1 >= len) goto done;
buf[xlen++] = 'q';
if (xlen + 1 >= len) goto done;
buf[xlen++] = 'x';
if (xlen + 1 >= len) goto done;
buf[xlen++] = '>';
}
break;
}
@ -1294,6 +1333,21 @@ hio_oow_t hio_skadtobcstr (hio_t* hio, const hio_skad_t* _skad, hio_bch_t* buf,
xlen += hio_copy_bcstr(&buf[xlen], len - xlen, skad->un.sun_path);
}
break;
case HIO_AF_QX:
if (flags & HIO_SKAD_TO_BCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
buf[xlen++] = '<';
if (xlen + 1 >= len) goto done;
buf[xlen++] = 'q';
if (xlen + 1 >= len) goto done;
buf[xlen++] = 'x';
if (xlen + 1 >= len) goto done;
buf[xlen++] = '>';
}
break;
}
@ -1454,6 +1508,13 @@ void hio_skad_init_for_eth (hio_skad_t* skad, int ifindex, hio_ethad_t* ethad)
#endif
}
void hio_skad_init_for_qx (hio_skad_t* _skad)
{
hio_skad_alt_t* skad = (hio_skad_alt_t*)_skad;
HIO_MEMSET (skad, 0, HIO_SIZEOF(*_skad));
skad->sa.sa_family = HIO_AF_QX;
}
void hio_clear_skad (hio_skad_t* _skad)
{
hio_skad_alt_t* skad = (hio_skad_alt_t*)_skad;