fixed some bugs handling side-channel communication

This commit is contained in:
hyung-hwan 2020-07-26 09:21:05 +00:00
parent 0843ef057d
commit 3684979724
4 changed files with 75 additions and 46 deletions

View File

@ -1181,7 +1181,6 @@ int main (int argc, char* argv[])
goto oops; goto oops;
} }
//mio_dev_sck_sendfile (tcp[2], fd, offset, count); //mio_dev_sck_sendfile (tcp[2], fd, offset, count);
setup_arp_tester(mio); setup_arp_tester(mio);

View File

@ -304,11 +304,12 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, mio_dev_sck_bind_t* sck_bind, mi
break; break;
default: default:
mio_seterrnum (mio, MIO_EINVAL); /*mio_seterrnum (mio, MIO_EINVAL);
goto oops; goto oops;*/
} info.m.type = MIO_DEV_SCK_QX;
break;
MIO_MEMSET (&info, 0, MIO_SIZEOF(info)); }
info.m.on_write = listener_on_write; info.m.on_write = listener_on_write;
info.m.on_read = listener_on_read; info.m.on_read = listener_on_read;
info.m.on_connect = listener_on_connect; info.m.on_connect = listener_on_connect;
@ -324,13 +325,16 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, mio_dev_sck_bind_t* sck_bind, mi
cli->htts = htts; cli->htts = htts;
cli->sck = htts->lsck; cli->sck = htts->lsck;
if (mio_dev_sck_bind(htts->lsck, sck_bind) <= -1) goto oops; if (htts->lsck->type != MIO_DEV_SCK_QX)
{
if (mio_dev_sck_bind(htts->lsck, sck_bind) <= -1) goto oops;
MIO_MEMSET (&info, 0, MIO_SIZEOF(info)); MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
info.l.options = MIO_DEV_SCK_LISTEN_LENIENT; info.l.options = MIO_DEV_SCK_LISTEN_LENIENT;
info.l.backlogs = 255; info.l.backlogs = 4096;
MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1); MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1);
if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops; if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
}
mio_fmttobcstr (htts->mio, htts->server_name_buf, MIO_COUNTOF(htts->server_name_buf), "%s-%d.%d.%d", mio_fmttobcstr (htts->mio, htts->server_name_buf, MIO_COUNTOF(htts->server_name_buf), "%s-%d.%d.%d",
MIO_PACKAGE_NAME, (int)MIO_PACKAGE_VERSION_MAJOR, (int)MIO_PACKAGE_VERSION_MINOR, (int)MIO_PACKAGE_VERSION_PATCH); MIO_PACKAGE_NAME, (int)MIO_PACKAGE_VERSION_MAJOR, (int)MIO_PACKAGE_VERSION_MINOR, (int)MIO_PACKAGE_VERSION_PATCH);

View File

@ -255,7 +255,8 @@ typedef void (*mio_dev_sck_on_connect_t) (
typedef void (*mio_dev_sck_on_raw_accept_t) ( typedef void (*mio_dev_sck_on_raw_accept_t) (
mio_dev_sck_t* dev, mio_dev_sck_t* dev,
mio_syshnd_t syshnd mio_syshnd_t syshnd,
mio_skad_t* peeradr
); );
enum mio_dev_sck_type_t enum mio_dev_sck_type_t

View File

@ -383,6 +383,10 @@ static int dev_sck_make (mio_dev_t* dev, void* ctx)
MIO_ASSERT (mio, arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map)); MIO_ASSERT (mio, arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map));
rdev->hnd = MIO_SYSHND_INVALID;
rdev->side_chan = MIO_SYSHND_INVALID;
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
if (sck_type_map[arg->type].domain <= -1) if (sck_type_map[arg->type].domain <= -1)
{ {
mio_seterrnum (mio, MIO_ENOIMPL); /* TODO: better error info? */ mio_seterrnum (mio, MIO_ENOIMPL); /* TODO: better error info? */
@ -426,14 +430,14 @@ static int dev_sck_make (mio_dev_t* dev, void* ctx)
rdev->on_read = arg->on_read; rdev->on_read = arg->on_read;
rdev->on_connect = arg->on_connect; rdev->on_connect = arg->on_connect;
rdev->on_disconnect = arg->on_disconnect; rdev->on_disconnect = arg->on_disconnect;
rdev->on_raw_accept = arg->on_raw_accept;
rdev->type = arg->type; rdev->type = arg->type;
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
return 0; return 0;
oops: oops:
if (hnd != MIO_SYSHND_INVALID) close_async_socket (mio, hnd); if (hnd != MIO_SYSHND_INVALID) close_async_socket (mio, hnd);
if (side_chan != MIO_SYSHND_INVALID) close (rdev->side_chan); if (side_chan != MIO_SYSHND_INVALID) close (side_chan);
return -1; return -1;
} }
@ -451,6 +455,7 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
rdev->hnd = *clisckhnd; rdev->hnd = *clisckhnd;
rdev->tmrjob_index = MIO_TMRIDX_INVALID; rdev->tmrjob_index = MIO_TMRIDX_INVALID;
rdev->side_chan = MIO_SYSHND_INVALID;
if (mio_makesyshndasync(mio, rdev->hnd) <= -1 || if (mio_makesyshndasync(mio, rdev->hnd) <= -1 ||
mio_makesyshndcloexec(mio, rdev->hnd) <= -1) return -1; mio_makesyshndcloexec(mio, rdev->hnd) <= -1) return -1;
@ -508,8 +513,8 @@ static int dev_sck_kill (mio_dev_t* dev, int force)
if (rdev->side_chan != MIO_SYSHND_INVALID) if (rdev->side_chan != MIO_SYSHND_INVALID)
{ {
close (rdev->hnd); close (rdev->side_chan);
rdev->hnd = MIO_SYSHND_INVALID; rdev->side_chan = MIO_SYSHND_INVALID;
} }
return 0; return 0;
} }
@ -1001,6 +1006,17 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
return -1; return -1;
} }
if (mio_skad_family(&bnd->localaddr) == MIO_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? MIO_DEV_SCK_BIND_IPV6ONLY? applicable to ipv6 though. */
int v = 1;
if (setsockopt(rdev->hnd, IPPROTO_IPV6, IPV6_V6ONLY, &v, MIO_SIZEOF(v)) == -1)
{
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set IPV6_V6ONLY");
return -1;
}
}
if (bnd->options & MIO_DEV_SCK_BIND_BROADCAST) if (bnd->options & MIO_DEV_SCK_BIND_BROADCAST)
{ {
int v = 1; int v = 1;
@ -1457,7 +1473,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
} }
} }
static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t clisck, mio_skad_t* remoteaddr) static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t clisck, mio_skad_t* remoteaddr, mio_dev_sck_type_t clisck_type)
{ {
mio_t* mio = rdev->mio; mio_t* mio = rdev->mio;
mio_dev_sck_t* clidev; mio_dev_sck_t* clidev;
@ -1468,7 +1484,7 @@ static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t cl
/* this is a special optional callback. If you don't want a client socket device /* this is a special optional callback. If you don't want a client socket device
* to be created upon accept, you may implement the on_raw_accept() handler. * to be created upon accept, you may implement the on_raw_accept() handler.
* the socket handle is delated to the callback. */ * the socket handle is delated to the callback. */
rdev->on_raw_accept (rdev, clisck); rdev->on_raw_accept (rdev, clisck, remoteaddr);
return 0; return 0;
} }
@ -1486,7 +1502,7 @@ static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t cl
// TODO: // TODO:
//if (clidev->type == MIO_DEV_SCK_QX) change it to the specified type.. //if (clidev->type == MIO_DEV_SCK_QX) change it to the specified type..
// TODO: // TODO:
clidev->type = clisck_type;
MIO_ASSERT (mio, clidev->hnd == clisck); MIO_ASSERT (mio, clidev->hnd == clisck);
clidev->dev_cap |= MIO_DEV_CAP_IN | MIO_DEV_CAP_OUT | MIO_DEV_CAP_STREAM; clidev->dev_cap |= MIO_DEV_CAP_IN | MIO_DEV_CAP_OUT | MIO_DEV_CAP_STREAM;
@ -1536,6 +1552,7 @@ static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t cl
* you can still change them inside the on_connect handler */ * you can still change them inside the on_connect handler */
clidev->on_connect = rdev->on_connect; clidev->on_connect = rdev->on_connect;
clidev->on_disconnect = rdev->on_disconnect; clidev->on_disconnect = rdev->on_disconnect;
clidev->on_raw_accept = MIO_NULL; /* don't inherit this */
clidev->on_write = rdev->on_write; clidev->on_write = rdev->on_write;
clidev->on_read = rdev->on_read; clidev->on_read = rdev->on_read;
@ -1617,7 +1634,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
} }
accept_done: accept_done:
return make_accepted_client_connection (rdev, clisck, &remoteaddr); return make_accepted_client_connection (rdev, clisck, &remoteaddr, rdev->type);
} }
static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events) static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
@ -1918,37 +1935,51 @@ static int dev_evcb_sck_on_read_qx (mio_dev_t* dev, const void* data, mio_iolen_
{ {
mio_t* mio = dev->mio; mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev; mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_dev_sck_qxmsg_t* qxmsg;
if (dlen != MIO_SIZEOF(*qxmsg)) if (rdev->type == MIO_DEV_SCK_QX)
{ {
mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx packet size"); mio_dev_sck_qxmsg_t* qxmsg;
return -1;
}
qxmsg = (mio_dev_sck_qxmsg_t*)data; if (dlen != MIO_SIZEOF(*qxmsg))
if (qxmsg->cmd == MIO_DEV_SCK_QXMSG_NEWCONN)
{
if (make_accepted_client_connection(rdev, qxmsg->syshnd, &qxmsg->remoteaddr) <= -1)
{ {
close (qxmsg->syshnd); mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx packet size");
return -1; return -1;
} }
}
else qxmsg = (mio_dev_sck_qxmsg_t*)data;
{ if (qxmsg->cmd == MIO_DEV_SCK_QXMSG_NEWCONN)
mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx command code"); {
return -1; if (make_accepted_client_connection(rdev, qxmsg->syshnd, &qxmsg->remoteaddr, qxmsg->scktype) <= -1)
{
close (qxmsg->syshnd);
return -1;
}
}
else
{
mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx command code");
return -1;
}
return 0;
} }
return 0;
/* this is not for a qx socket */
return rdev->on_read(rdev, data, dlen, MIO_NULL);
} }
static int dev_evcb_sck_on_write_qx (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr) static int dev_evcb_sck_on_write_qx (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr)
{ {
/*mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;*/ mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
/* this should not be called */
return 0; if (rdev->type == MIO_DEV_SCK_QX)
{
/* this should not be called */
return 0;
}
return rdev->on_write(rdev, wrlen, wrctx, MIO_NULL);
} }
static mio_dev_evcb_t dev_sck_event_callbacks_qx = static mio_dev_evcb_t dev_sck_event_callbacks_qx =
@ -2077,13 +2108,7 @@ int mio_dev_sck_sendfileok (mio_dev_sck_t* dev)
int mio_dev_sck_writetosidechan (mio_dev_sck_t* dev, const void* dptr, mio_oow_t dlen) int mio_dev_sck_writetosidechan (mio_dev_sck_t* dev, const void* dptr, mio_oow_t dlen)
{ {
if (dev->side_chan == MIO_SYSHND_INVALID) if (write(dev->side_chan, dptr, dlen) <= -1) return -1; /* this doesn't set the error information. if you may check errno, though */
{
mio_seterrnum (dev->mio, MIO_ENOCAPA);
return -1;
}
write (dev->side_chan, dptr, dlen);
return 0; return 0;
} }