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;
}
//mio_dev_sck_sendfile (tcp[2], fd, offset, count);
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;
default:
mio_seterrnum (mio, MIO_EINVAL);
goto oops;
}
/*mio_seterrnum (mio, MIO_EINVAL);
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_read = listener_on_read;
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->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));
info.l.options = MIO_DEV_SCK_LISTEN_LENIENT;
info.l.backlogs = 255;
MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1);
if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
info.l.options = MIO_DEV_SCK_LISTEN_LENIENT;
info.l.backlogs = 4096;
MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1);
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_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) (
mio_dev_sck_t* dev,
mio_syshnd_t syshnd
mio_syshnd_t syshnd,
mio_skad_t* peeradr
);
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));
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)
{
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_connect = arg->on_connect;
rdev->on_disconnect = arg->on_disconnect;
rdev->on_raw_accept = arg->on_raw_accept;
rdev->type = arg->type;
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
return 0;
oops:
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;
}
@ -451,6 +455,7 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
rdev->hnd = *clisckhnd;
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
rdev->side_chan = MIO_SYSHND_INVALID;
if (mio_makesyshndasync(mio, rdev->hnd) <= -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)
{
close (rdev->hnd);
rdev->hnd = MIO_SYSHND_INVALID;
close (rdev->side_chan);
rdev->side_chan = MIO_SYSHND_INVALID;
}
return 0;
}
@ -1001,6 +1006,17 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
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)
{
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_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
* to be created upon accept, you may implement the on_raw_accept() handler.
* the socket handle is delated to the callback. */
rdev->on_raw_accept (rdev, clisck);
rdev->on_raw_accept (rdev, clisck, remoteaddr);
return 0;
}
@ -1486,7 +1502,7 @@ static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t cl
// TODO:
//if (clidev->type == MIO_DEV_SCK_QX) change it to the specified type..
// TODO:
clidev->type = clisck_type;
MIO_ASSERT (mio, clidev->hnd == clisck);
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 */
clidev->on_connect = rdev->on_connect;
clidev->on_disconnect = rdev->on_disconnect;
clidev->on_raw_accept = MIO_NULL; /* don't inherit this */
clidev->on_write = rdev->on_write;
clidev->on_read = rdev->on_read;
@ -1617,7 +1634,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
}
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)
@ -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_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");
return -1;
}
mio_dev_sck_qxmsg_t* qxmsg;
qxmsg = (mio_dev_sck_qxmsg_t*)data;
if (qxmsg->cmd == MIO_DEV_SCK_QXMSG_NEWCONN)
{
if (make_accepted_client_connection(rdev, qxmsg->syshnd, &qxmsg->remoteaddr) <= -1)
if (dlen != MIO_SIZEOF(*qxmsg))
{
close (qxmsg->syshnd);
mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx packet size");
return -1;
}
}
else
{
mio_seterrbfmt (mio, MIO_EINVAL, "wrong qx command code");
return -1;
qxmsg = (mio_dev_sck_qxmsg_t*)data;
if (qxmsg->cmd == MIO_DEV_SCK_QXMSG_NEWCONN)
{
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)
{
/*mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;*/
/* this should not be called */
return 0;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
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 =
@ -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)
{
if (dev->side_chan == MIO_SYSHND_INVALID)
{
mio_seterrnum (dev->mio, MIO_ENOCAPA);
return -1;
}
write (dev->side_chan, dptr, dlen);
if (write(dev->side_chan, dptr, dlen) <= -1) return -1; /* this doesn't set the error information. if you may check errno, though */
return 0;
}