some code to implement dns over tcp in dnc

This commit is contained in:
2020-02-21 09:42:10 +00:00
parent c620afe4c9
commit ef50d2458b
8 changed files with 181 additions and 72 deletions

View File

@ -56,6 +56,7 @@ struct mio_svc_dnc_t
struct dnc_sck_xtn_t
{
mio_svc_dnc_t* dnc;
mio_dns_msg_t* reqmsg; /* used when switching to TCP from UDP for truncation */
};
typedef struct dnc_sck_xtn_t dnc_sck_xtn_t;
@ -147,6 +148,118 @@ MIO_DEBUG1 (mio, "releasing dns msg %d\n", (int)mio_ntoh16(mio_dns_msg_to_pkt(ms
mio_dns_free_msg (dnc->mio, msg);
}
/* ----------------------------------------------------------------------- */
static int on_tcp_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen, const mio_skad_t* srcaddr)
{
return 0;
}
static int on_tcp_write (mio_dev_sck_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_skad_t* dstaddr)
{
printf ("ON WRITE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
return 0;
}
static void on_tcp_connect (mio_dev_sck_t* dev)
{
mio_t* mio = dev->mio;
mio_svc_dnc_t* dnc = ((dnc_sck_xtn_t*)mio_dev_sck_getxtn(dev))->dnc;
mio_dns_msg_t* reqmsg = ((dnc_sck_xtn_t*)mio_dev_sck_getxtn(dev))->reqmsg;
dnc_dns_msg_xtn_t* reqmsgxtn = dnc_dns_msg_getxtn(reqmsg);
mio_uint16_t pktlen;
MIO_ASSERT (mio, dev == dnc->tcp_sck);
pktlen = mio_hton16(reqmsg->pktlen);
/* TODO: create writev... which triggered on_write_once */
mio_dev_sck_timedwrite(dev, &pktlen, MIO_SIZEOF(pktlen), &reqmsgxtn->rtmout, reqmsg, MIO_NULL);
if (mio_dev_sck_timedwrite(dev, mio_dns_msg_to_pkt(reqmsg), reqmsg->pktlen, &reqmsgxtn->rtmout, reqmsg, MIO_NULL) <= -1)
{
if (MIO_LIKELY(reqmsgxtn->on_reply))
reqmsgxtn->on_reply (dnc, reqmsg, mio_geterrnum(mio), MIO_NULL, 0);
release_dns_msg (dnc, reqmsg);
}
}
static void on_tcp_disconnect (mio_dev_sck_t* dev)
{
mio_t* mio = dev->mio;
mio_svc_dnc_t* dnc = ((dnc_sck_xtn_t*)mio_dev_sck_getxtn(dev))->dnc;
mio_dns_msg_t* reqmsg = ((dnc_sck_xtn_t*)mio_dev_sck_getxtn(dev))->reqmsg;
dnc_dns_msg_xtn_t* reqmsgxtn = dnc_dns_msg_getxtn(reqmsg);
int status;
/* UNABLE TO CONNECT or CONNECT TIMED OUT */
if (reqmsgxtn->rtries <= 0)
{
status = mio_geterrnum(mio);
}
else
{
status = mio_geterrnum(mio);
}
MIO_DEBUG2 (mio, "TCP UNABLED TO CONNECT .. OR DISCONNECTED ... ---> %d -> %js\n", status, mio_errnum_to_errstr(status));
if (MIO_LIKELY(reqmsgxtn->on_reply))
reqmsgxtn->on_reply (dnc, reqmsg, status, MIO_NULL, 0);
release_dns_msg (dnc, reqmsg);
}
static int switch_reqmsg_transport_to_tcp (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg)
{
mio_t* mio = dnc->mio;
dnc_dns_msg_xtn_t* reqmsgxtn = dnc_dns_msg_getxtn(reqmsg);
dnc_sck_xtn_t* sckxtn;
mio_dev_sck_make_t mkinfo;
mio_dev_sck_connect_t cinfo;
if (!dnc->tcp_sck)
{
MIO_MEMSET (&mkinfo, 0, MIO_SIZEOF(mkinfo));
switch (mio_skad_family(&reqmsgxtn->servaddr))
{
case MIO_AF_INET:
mkinfo.type = MIO_DEV_SCK_TCP4;
break;
case MIO_AF_INET6:
mkinfo.type = MIO_DEV_SCK_TCP6;
break;
default:
mio_seterrnum (mio, MIO_EINTERN);
return -1;
}
mkinfo.on_write = on_tcp_write;
mkinfo.on_read = on_tcp_read;
mkinfo.on_connect = on_tcp_connect;
mkinfo.on_disconnect = on_tcp_disconnect;
dnc->tcp_sck = mio_dev_sck_make(mio, MIO_SIZEOF(*sckxtn), &mkinfo);
}
sckxtn = (dnc_sck_xtn_t*)mio_dev_sck_getxtn(dnc->tcp_sck);
sckxtn->dnc = dnc;
sckxtn->reqmsg = reqmsg;
MIO_MEMSET (&cinfo, 0, MIO_SIZEOF(cinfo));
cinfo.remoteaddr = reqmsgxtn->servaddr;
cinfo.connect_tmout = reqmsgxtn->rtmout; /* TOOD: create a separate connect timeout or treate rtmout as a whole transaction time and calculate the remaining time from the transaction start, and use it */
reqmsgxtn->rtries = 0; /* reset the number of tries back to 0 which means it's never sent over tcp */
return mio_dev_sck_connect(dnc->tcp_sck, &cinfo);
}
/* ----------------------------------------------------------------------- */
static int on_udp_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen, const mio_skad_t* srcaddr)
{
mio_t* mio = dev->mio;
@ -180,10 +293,15 @@ static int on_udp_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen,
if (dev == (mio_dev_sck_t*)reqmsgxtn->dev && pkt->id == reqpkt->id && mio_equal_skads(&reqmsgxtn->servaddr, srcaddr, 0))
{
////////////////////////
pkt->tc = 1;
////////////////////////
if (pkt->tc) /* truncated */
{
/* TODO: add an option for this behavior */
/* TODO: switch to tc ... send the same request over tcp... */
switch_reqmsg_transport_to_tcp (dnc, reqmsg);
return 0;
}
MIO_DEBUG1 (mio, "received dns response...id %d\n", id);
@ -209,6 +327,7 @@ static void on_udp_reply_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob
mio_svc_dnc_t* dnc = ((dnc_sck_xtn_t*)mio_dev_sck_getxtn(dev))->dnc;
MIO_ASSERT (mio, msgxtn->rtmridx == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, dev == dnc->udp_sck);
MIO_DEBUG0 (mio, "*** TIMEOUT ==> unable to receive dns response in time...\n");
if (msgxtn->rtries < msgxtn->rmaxtries)
@ -216,7 +335,7 @@ MIO_DEBUG0 (mio, "*** TIMEOUT ==> unable to receive dns response in time...\n");
mio_ntime_t* tmout;
tmout = MIO_IS_POS_NTIME(&msgxtn->wtmout)? &msgxtn->wtmout: MIO_NULL;
if (mio_dev_sck_timedwrite(dnc->udp_sck, mio_dns_msg_to_pkt(reqmsg), reqmsg->pktlen, tmout, reqmsg, &msgxtn->servaddr) <= -1)
if (mio_dev_sck_timedwrite(dev, mio_dns_msg_to_pkt(reqmsg), reqmsg->pktlen, tmout, reqmsg, &msgxtn->servaddr) <= -1)
{
if (MIO_LIKELY(msgxtn->on_reply))
msgxtn->on_reply (dnc, reqmsg, MIO_ETMOUT, MIO_NULL, 0);

View File

@ -57,6 +57,7 @@ static mio_ooch_t errstr_26[] = {'n', 'o', ' ', 'c', 'a', 'p', 'a', 'b', 'i', 'l
static mio_ooch_t errstr_27[] = {'t', 'i', 'm', 'e', 'd', ' ', 'o', 'u', 't', '\0' };
static mio_ooch_t errstr_28[] = {'u', 'n', 'a', 'b', 'l', 'e', ' ', 't', 'o', ' ', 'm', 'a', 'k', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', '\0' };
static mio_ooch_t errstr_29[] = {'d', 'e', 'v', 'i', 'c', 'e', ' ', 'e', 'r', 'r', 'o', 'r', '\0' };
static mio_ooch_t errstr_30[] = {'d', 'e', 'v', 'i', 'c', 'e', ' ', 'h', 'a', 'n', 'g', '-', 'u', 'p', '\0' };
static mio_ooch_t* errstr[] =
{
errstr_0, errstr_1, errstr_2, errstr_3, errstr_4,
@ -64,7 +65,8 @@ static mio_ooch_t* errstr[] =
errstr_10, errstr_11, errstr_12, errstr_13, errstr_14,
errstr_15, errstr_16, errstr_17, errstr_18, errstr_19,
errstr_20, errstr_21, errstr_22, errstr_23, errstr_24,
errstr_25, errstr_26, errstr_27, errstr_28, errstr_29
errstr_25, errstr_26, errstr_27, errstr_28, errstr_29,
errstr_30
};
/* --------------------------------------------------------------------------

View File

@ -1,8 +1,11 @@
#
# qseawk --striprecspace=on -f generr.awk mio.h
# hawk -f generr.awk mio.h
#
@pragma striprecspc on
BEGIN {
##STRIPRECSPC=1
FS = "[[:space:]]+";
capture = 0;
msgcount = 0;
@ -13,7 +16,7 @@ capture == 1 {
{
capture = 0;
}
else if ($1 ~ /^MIO_E.+,/)
else if ($1 ~ /^MIO_E[[:alnum:]]+,*/)
{
msg = "";
for (i = 3; i < NF; i++)

View File

@ -47,9 +47,6 @@ static int kill_and_free_device (mio_dev_t* dev, int force);
} while (0)
static void on_read_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* job);
static void on_write_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* job);
@ -681,7 +678,6 @@ mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
APPEND_DEVICE_TO_LIST (&mio->actdev, dev);
dev->dev_cap |= MIO_DEV_CAP_ACTIVE;
return dev;
oops_after_make:

View File

@ -1383,16 +1383,19 @@ int mio_skad_ifindex (const mio_skad_t* _skad)
void mio_skad_init_for_ip4 (mio_skad_t* skad, mio_uint16_t port, mio_ip4addr_t* ip4addr)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
struct sockaddr_in* sin = (struct sockaddr_in*)skad;
MIO_MEMSET (sin, 0, MIO_SIZEOF(*sin));
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
if (ip4addr) MIO_MEMCPY (&sin->sin_addr, ip4addr, MIO_IP4ADDR_LEN);
#endif
}
void mio_skad_init_for_ip6 (mio_skad_t* skad, mio_uint16_t port, mio_ip6addr_t* ip6addr, int scope_id)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
struct sockaddr_in6* sin = (struct sockaddr_in6*)skad;
MIO_MEMSET (sin, 0, MIO_SIZEOF(*sin));
@ -1400,6 +1403,7 @@ void mio_skad_init_for_ip6 (mio_skad_t* skad, mio_uint16_t port, mio_ip6addr_t*
sin->sin6_port = htons(port);
sin->sin6_scope_id = scope_id;
if (ip6addr) MIO_MEMCPY (&sin->sin6_addr, ip6addr, MIO_IP6ADDR_LEN);
#endif
}
void mio_skad_init_for_eth (mio_skad_t* skad, int ifindex, mio_ethaddr_t* ethaddr)
@ -1447,11 +1451,13 @@ int mio_equal_skads (const mio_skad_t* addr1, const mio_skad_t* addr2, int stric
switch (f1)
{
#if defined(AF_INET) && (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case AF_INET:
return ((struct sockaddr_in*)addr1)->sin_addr.s_addr == ((struct sockaddr_in*)addr2)->sin_addr.s_addr &&
((struct sockaddr_in*)addr1)->sin_port == ((struct sockaddr_in*)addr2)->sin_port;
#endif
#if defined(AF_INET6)
#if defined(AF_INET6) && (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case AF_INET6:
if (strict)
@ -1468,7 +1474,7 @@ int mio_equal_skads (const mio_skad_t* addr1, const mio_skad_t* addr2, int stric
}
#endif
#if defined(AF_UNIX)
#if defined(AF_UNIX) && (MIO_SIZEOF_STRUCT_SOCKADDR_UN > 0)
case AF_UNIX:
return mio_comp_bcstr(((struct sockaddr_un*)addr1)->sun_path, ((struct sockaddr_un*)addr2)->sun_path) == 0;
#endif