changed mio_dev_sck_connect() to not fire on_connect() callback inside itself upon immediate successful connect.

fixed some issues in dns related code
This commit is contained in:
hyung-hwan 2020-02-25 07:09:20 +00:00
parent 9ef09941c3
commit 71ffd4ce17
7 changed files with 395 additions and 166 deletions

View File

@ -952,7 +952,6 @@ for (i = 0; i < 5; i++)
reply_tmout.sec = 1;
reply_tmout.nsec = 0;
mio_bcstrtoskad (mio, "8.8.8.8:53", &servaddr);
//mio_bcstrtoskad (mio, "[fe80::c7e2:bd6e:1209:ac1b]:1153", &servaddr);
//mio_bcstrtoskad (mio, "[fe80::c7e2:bd6e:1209:ac1b%eno1]:1153", &servaddr);
@ -968,10 +967,14 @@ for (i = 0; i < 5; i++)
{ "code6.abiyo.net", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN },
{ "abiyo.net", MIO_DNS_RRT_MX, MIO_DNS_RRC_IN }
};
mio_ip4ad_t rrdata_a = { { 4, 3, 2, 1 } };
mio_ip6ad_t rrdata_aaaa = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, }};
mio_dns_brr_t rrs[] =
{
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_A, MIO_DNS_RRC_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_A, MIO_DNS_RRC_IN, 86400, MIO_SIZEOF(rrdata_a), &rrdata_a },
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN, 86400, MIO_SIZEOF(rrdata_aaaa), &rrdata_aaaa },
{ MIO_DNS_RR_PART_ANSWER, "miflux.com", MIO_DNS_RRT_NS, MIO_DNS_RRC_IN, 86400, 0, "ns1.miflux.com" },
{ MIO_DNS_RR_PART_ANSWER, "miflux.com", MIO_DNS_RRT_NS, MIO_DNS_RRC_IN, 86400, 0, "ns2.miflux.com" }, //,
//{ MIO_DNS_RR_PART_AUTHORITY, "miflux.com", MIO_DNS_RRT_SOA, MIO_DNS_RRC_IN, 86400, 0, "ns2.miflux.com" }, //,
@ -1029,6 +1032,7 @@ for (i = 0; i < 5; i++)
}
#endif
if (!mio_svc_dnc_resolve(dnc, "a.wild.com", MIO_DNS_RRT_A, 0, on_dnc_resolve, 0))
{
printf ("resolve attempt failure ---> a.wild.com\n");

259
mio/bin/t02.c Normal file
View File

@ -0,0 +1,259 @@
#include <mio.h>
#include <mio-utl.h>
#include <mio-sck.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct mmgr_stat_t
{
mio_oow_t total_count;
};
typedef struct mmgr_stat_t mmgr_stat_t;
static mmgr_stat_t mmgr_stat;
static void* mmgr_alloc (mio_mmgr_t* mmgr, mio_oow_t size)
{
void* x;
if (((mmgr_stat_t*)mmgr->ctx)->total_count > 3000)
{
printf ("CRITICAL ERROR ---> too many heap chunks...\n");
return MIO_NULL;
}
x = malloc (size);
if (x) ((mmgr_stat_t*)mmgr->ctx)->total_count++;
return x;
}
static void* mmgr_realloc (mio_mmgr_t* mmgr, void* ptr, mio_oow_t size)
{
return realloc (ptr, size);
}
static void mmgr_free (mio_mmgr_t* mmgr, void* ptr)
{
((mmgr_stat_t*)mmgr->ctx)->total_count--;
return free (ptr);
}
static mio_mmgr_t mmgr =
{
mmgr_alloc,
mmgr_realloc,
mmgr_free,
&mmgr_stat
};
struct tcp_xtn_t
{
int tally;
};
typedef struct tcp_xtn_t tcp_xtn_t;
static void tcp_sck_on_disconnect (mio_dev_sck_t* tcp)
{
switch (MIO_DEV_SCK_GET_PROGRESS(tcp))
{
case MIO_DEV_SCK_CONNECTING:
MIO_INFO1 (tcp->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
break;
case MIO_DEV_SCK_CONNECTING_SSL:
MIO_INFO1 (tcp->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
break;
case MIO_DEV_SCK_LISTENING:
MIO_INFO1 (tcp->mio, "SHUTTING DOWN THE SERVER SOCKET(%d)...\n", (int)tcp->sck);
break;
case MIO_DEV_SCK_CONNECTED:
MIO_INFO1 (tcp->mio, "OUTGOING CLIENT CONNECTION GOT TORN DOWN(%d).......\n", (int)tcp->sck);
break;
case MIO_DEV_SCK_ACCEPTING_SSL:
MIO_INFO1 (tcp->mio, "INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) ....\n", (int)tcp->sck);
break;
case MIO_DEV_SCK_ACCEPTED:
MIO_INFO1 (tcp->mio, "INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d).......\n", (int)tcp->sck);
break;
default:
MIO_INFO2 (tcp->mio, "SOCKET DEVICE DISCONNECTED (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
break;
}
}
static void tcp_sck_on_connect (mio_dev_sck_t* tcp)
{
mio_bch_t buf1[128], buf2[128];
mio_skadtobcstr (tcp->mio, &tcp->localaddr, buf1, MIO_COUNTOF(buf1), MIO_SKAD_TO_BCSTR_ADDR | MIO_SKAD_TO_BCSTR_PORT);
mio_skadtobcstr (tcp->mio, &tcp->remoteaddr, buf2, MIO_COUNTOF(buf2), MIO_SKAD_TO_BCSTR_ADDR | MIO_SKAD_TO_BCSTR_PORT);
if (tcp->state & MIO_DEV_SCK_CONNECTED)
{
MIO_INFO3 (tcp->mio, "DEVICE connected to a remote server... LOCAL %hs REMOTE %hs SCK: %d\n", buf1, buf2, tcp->sck);
}
else if (tcp->state & MIO_DEV_SCK_ACCEPTED)
{
MIO_INFO3 (tcp->mio, "DEVICE accepted client device... .LOCAL %hs REMOTE %hs SCK: %d\n", buf1, buf2, tcp->sck);
}
if (mio_dev_sck_write(tcp, "hello", 5, MIO_NULL, MIO_NULL) <= -1)
{
mio_dev_sck_halt (tcp);
}
}
static int tcp_sck_on_write (mio_dev_sck_t* tcp, mio_iolen_t wrlen, void* wrctx, const mio_skad_t* dstaddr)
{
tcp_xtn_t* ts;
mio_ntime_t tmout;
if (wrlen <= -1)
{
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_WRITE(%d) >>> SEDING TIMED OUT...........\n", (int)tcp->sck);
mio_dev_sck_halt (tcp);
}
else
{
ts = (tcp_xtn_t*)(tcp + 1);
if (wrlen == 0)
{
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_WRITE(%d) >>> CLOSED WRITING END\n", (int)tcp->sck);
}
else
{
MIO_INFO3 (tcp->mio, "TCP_SCK_ON_WRITE(%d) >>> SENT MESSAGE %d of length %ld\n", (int)tcp->sck, ts->tally, (long int)wrlen);
}
ts->tally++;
// if (ts->tally >= 2) mio_dev_sck_halt (tcp);
MIO_INIT_NTIME (&tmout, 5, 0);
//mio_dev_sck_read (tcp, 1);
MIO_INFO3 (tcp->mio, "TCP_SCK_ON_WRITE(%d) >>> REQUESTING to READ with timeout of %ld.%08ld\n", (int)tcp->sck, (long int)tmout.sec, (long int)tmout.nsec);
mio_dev_sck_timedread (tcp, 1, &tmout);
}
return 0;
}
static int tcp_sck_on_read (mio_dev_sck_t* tcp, const void* buf, mio_iolen_t len, const mio_skad_t* srcaddr)
{
int n;
if (len <= -1)
{
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_READ(%d) STREAM DEVICE: TIMED OUT...\n", (int)tcp->sck);
mio_dev_sck_halt (tcp);
return 0;
}
else if (len <= 0)
{
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_READ(%d) STREAM DEVICE: EOF RECEIVED...\n", (int)tcp->sck);
/* no outstanding request. but EOF */
mio_dev_sck_halt (tcp);
return 0;
}
MIO_INFO2 (tcp->mio, "TCP_SCK_ON_READ(%d) - received %d bytes\n", (int)tcp->sck, (int)len);
{
mio_ntime_t tmout;
static char a ='A';
static char xxx[1000000];
memset (xxx, a++ , MIO_SIZEOF(xxx));
MIO_INFO2 (tcp->mio, "TCP_SCK_ON_READ(%d) >>> REQUESTING to write data of %d bytes\n", (int)tcp->sck, MIO_SIZEOF(xxx));
//return mio_dev_sck_write (tcp, "HELLO", 5, MIO_NULL);
MIO_INIT_NTIME (&tmout, 5, 0);
n = mio_dev_sck_timedwrite(tcp, xxx, MIO_SIZEOF(xxx), &tmout, MIO_NULL, MIO_NULL);
if (n <= -1) return -1;
}
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_READ(%d) - REQUESTING TO STOP READ\n", (int)tcp->sck);
mio_dev_sck_read (tcp, 0);
#if 0
MIO_INFO1 (tcp->mio, "TCP_SCK_ON_READ(%d) - REQUESTING TO CLOSE WRITING END\n", (int)tcp->sck);
/* post the write finisher - close the writing end */
n = mio_dev_sck_write(tcp, MIO_NULL, 0, MIO_NULL, MIO_NULL);
if (n <= -1) return -1;
#endif
return 0;
/* return 1; let the main loop to read more greedily without consulting the multiplexer */
}
int main (int argc, char* argv[])
{
mio_t* mio = MIO_NULL;
mio_dev_sck_t* tcpsvr;
mio_dev_sck_make_t tcp_make;
mio_dev_sck_connect_t tcp_conn;
tcp_xtn_t* ts;
if (argc != 2)
{
fprintf (stderr, "Usage: %s ipaddr:port\n", argv[0]);
return -1;
}
mio = mio_open(&mmgr, 0, MIO_NULL, 512, MIO_NULL);
if (!mio)
{
printf ("Cannot open mio\n");
goto oops;
}
memset (&tcp_conn, 0, MIO_SIZEOF(tcp_conn));
mio_bcstrtoskad(mio, argv[1], &tcp_conn.remoteaddr);
MIO_INIT_NTIME (&tcp_conn.connect_tmout, 5, 0);
tcp_conn.options = 0;
memset (&tcp_make, 0, MIO_SIZEOF(tcp_make));
tcp_make.type = mio_skad_family(&tcp_conn.remoteaddr) == MIO_AF_INET? MIO_DEV_SCK_TCP4: MIO_DEV_SCK_TCP6;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp_make.on_connect = tcp_sck_on_connect;
tcp_make.on_disconnect = tcp_sck_on_disconnect;
tcpsvr = mio_dev_sck_make(mio, MIO_SIZEOF(tcp_xtn_t), &tcp_make);
if (!tcpsvr)
{
printf ("Cannot make a tcp server\n");
goto oops;
}
ts = (tcp_xtn_t*)(tcpsvr + 1);
ts->tally = 0;
if (mio_dev_sck_connect(tcpsvr, &tcp_conn) <= -1)
{
}
mio_loop (mio);
oops:
if (mio) mio_close (mio);
return 0;
return 0;
}

View File

@ -83,29 +83,6 @@ typedef struct dnc_dns_msg_xtn_t dnc_dns_msg_xtn_t;
# define dnc_dns_msg_getxtn(msg) ((dnc_dns_msg_xtn_t*)((mio_uint8_t*)mio_dns_msg_to_pkt(msg) + msg->pktalilen))
#endif
static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, mio_oow_t xtnsize)
{
mio_dns_msg_t* msg;
dnc_dns_msg_xtn_t* msgxtn;
msg = mio_dns_make_msg(dnc->mio, bdns, qr, qr_count, rr, rr_count, edns, MIO_SIZEOF(*msgxtn) + xtnsize);
if (msg)
{
if (bdns->id < 0)
{
mio_dns_pkt_t* pkt = mio_dns_msg_to_pkt(msg);
pkt->id = mio_hton16(dnc->seq);
dnc->seq++;
}
msgxtn = dnc_dns_msg_getxtn(msg);
msgxtn->dev = (mio_dev_t*)dnc->udp_sck;
msgxtn->rtmridx = MIO_TMRIDX_INVALID;
}
return msg;
}
static MIO_INLINE void chain_pending_dns_reqmsg (mio_svc_dnc_t* dnc, mio_dns_msg_t* msg)
{
if (dnc->pending_req)
@ -137,27 +114,39 @@ MIO_DEBUG1 (mio, "releasing dns msg %d\n", (int)mio_ntoh16(mio_dns_msg_to_pkt(ms
unchain_pending_dns_reqmsg (dnc, msg);
}
/* TODO: add it to the free msg list instead of just freeing it. */
if (msgxtn->rtmridx != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (mio, msgxtn->rtmridx);
MIO_ASSERT (mio, msgxtn->rtmridx == MIO_TMRIDX_INVALID);
}
/* TODO: add it to the free msg list instead of just freeing it. */
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)
{
if (MIO_UNLIKELY(dlen <= -1))
{
printf ("ON TCP READ ERROR>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %d\n", dlen);
}
else if (dlen == 0)
{
printf ("ON TCP READ EOF>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %d\n", dlen);
}
else
{
printf ("ON TCP READ DATA>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %d\n", dlen);
}
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");
printf ("ON TCP WRITE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
return 0;
}
@ -169,14 +158,18 @@ static void on_tcp_connect (mio_dev_sck_t* dev)
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_iovec_t iov[2];
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)
/* TODO: Is it better to create 2 byte space when sending UDP and use it here instead of iov? */
iov[0].iov_ptr = &pktlen;
iov[0].iov_len = MIO_SIZEOF(pktlen);
iov[1].iov_ptr = mio_dns_msg_to_pkt(reqmsg);
iov[1].iov_len = reqmsg->pktlen;
if (mio_dev_sck_timedwritev(dev, iov, MIO_COUNTOF(iov), &reqmsgxtn->rtmout, reqmsg, MIO_NULL) <= -1)
{
if (MIO_LIKELY(reqmsgxtn->on_reply))
reqmsgxtn->on_reply (dnc, reqmsg, mio_geterrnum(mio), MIO_NULL, 0);
@ -206,7 +199,6 @@ MIO_DEBUG2 (mio, "TCP UNABLED TO CONNECT .. OR DISCONNECTED ... ---> %d -> %js\n
if (MIO_LIKELY(reqmsgxtn->on_reply))
reqmsgxtn->on_reply (dnc, reqmsg, status, MIO_NULL, 0);
release_dns_msg (dnc, reqmsg);
}
@ -243,6 +235,7 @@ static int switch_reqmsg_transport_to_tcp (mio_svc_dnc_t* dnc, mio_dns_msg_t* re
mkinfo.on_connect = on_tcp_connect;
mkinfo.on_disconnect = on_tcp_disconnect;
dnc->tcp_sck = mio_dev_sck_make(mio, MIO_SIZEOF(*sckxtn), &mkinfo);
if (!dnc->tcp_sck) return -1;
}
sckxtn = (dnc_sck_xtn_t*)mio_dev_sck_getxtn(dnc->tcp_sck);
@ -253,8 +246,19 @@ static int switch_reqmsg_transport_to_tcp (mio_svc_dnc_t* dnc, mio_dns_msg_t* re
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);
if (mio_dev_sck_connect(dnc->tcp_sck, &cinfo) <= -1) return -1; /* the connect request hasn't been honored. */
/* switch the belonging device to the tcp socket since the connect request has been acknowledged. */
reqmsgxtn->dev = (mio_dev_t*)dnc->tcp_sck;
reqmsgxtn->rtries = 0;
if (reqmsgxtn->rtmridx != MIO_TMRIDX_INVALID)
{
/* unschedule a timer job added for udp transport if any */
mio_deltmrjob (mio, reqmsgxtn->rtmridx);
MIO_ASSERT (mio, reqmsgxtn->rtmridx == MIO_TMRIDX_INVALID);
}
return 0;
}
/* ----------------------------------------------------------------------- */
@ -295,12 +299,11 @@ static int on_udp_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen,
////////////////////////
pkt->tc = 1;
////////////////////////
if (pkt->tc) /* truncated */
if (MIO_UNLIKELY(pkt->tc))
{
/* 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;
if (switch_reqmsg_transport_to_tcp(dnc, reqmsg) >= 0) return 0;
/* TODO: add an option to call an error callback with TRUNCATION error code instead of fallback to received UDP truncated message */
}
MIO_DEBUG1 (mio, "received dns response...id %d\n", id);
@ -489,13 +492,14 @@ oops:
void mio_svc_dnc_stop (mio_svc_dnc_t* dnc)
{
mio_t* mio = dnc->mio;
if (dnc->udp_sck) mio_dev_sck_kill (dnc->udp_sck);
MIO_SVC_UNREGISTER (mio, dnc);
if (dnc->tcp_sck) mio_dev_sck_kill (dnc->tcp_sck);
while (dnc->pending_req) release_dns_msg (dnc, dnc->pending_req);
MIO_SVC_UNREGISTER (mio, dnc);
mio_freemem (mio, dnc);
}
mio_dns_msg_t* mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply, mio_oow_t xtnsize)
{
/* send a request or a response */
@ -503,10 +507,19 @@ mio_dns_msg_t* mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mi
dnc_dns_msg_xtn_t* msgxtn;
mio_ntime_t* tmout;
msg = build_dns_msg(dnc, bdns, qr, qr_count, rr, rr_count, edns, MIO_SIZEOF(*msgxtn) + xtnsize);
msg = mio_dns_make_msg(dnc->mio, bdns, qr, qr_count, rr, rr_count, edns, MIO_SIZEOF(*msgxtn) + xtnsize);
if (!msg) return MIO_NULL;
if (bdns->id < 0)
{
mio_dns_pkt_t* pkt = mio_dns_msg_to_pkt(msg);
pkt->id = mio_hton16(dnc->seq);
dnc->seq++;
}
msgxtn = dnc_dns_msg_getxtn(msg);
msgxtn->dev = (mio_dev_t*)dnc->udp_sck;
msgxtn->rtmridx = MIO_TMRIDX_INVALID;
msgxtn->on_reply = on_reply;
msgxtn->wtmout = dnc->send_tmout;
msgxtn->rtmout = dnc->reply_tmout;

View File

@ -285,11 +285,11 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
}
case MIO_DNS_RRT_A:
if (MIO_UNLIKELY(dlen != 4)) goto oops;
if (MIO_UNLIKELY(dlen != MIO_SIZEOF(mio_ip4ad_t))) goto oops;
goto verbatim;
case MIO_DNS_RRT_AAAA:
if (MIO_UNLIKELY(dlen != 16)) goto oops;
if (MIO_UNLIKELY(dlen != MIO_SIZEOF(mio_ip6ad_t))) goto oops;
goto verbatim;
case MIO_DNS_RRT_CNAME:
@ -465,22 +465,19 @@ void mio_dns_free_packet_info (mio_t* mio, mio_dns_pkt_info_t* pi)
/* ----------------------------------------------------------------------- */
static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, void* dptr)
static int encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_uint16_t* dxlen, void* dptr)
{
mio_oow_t xlen;
switch (rr->rrtype)
{
case MIO_DNS_RRT_A:
xlen = rr->dlen;
break;
case MIO_DNS_RRT_AAAA:
xlen = rr->dlen;
break;
if (rr->dlen != MIO_SIZEOF(mio_ip4ad_t)) goto inval;
goto verbatim;
/*
case MIO_DNS_RRT_WKS:
break; */
case MIO_DNS_RRT_AAAA:
if (rr->dlen != MIO_SIZEOF(mio_ip6ad_t)) goto inval;
goto verbatim;
case MIO_DNS_RRT_CNAME:
/*case MIO_DNS_RRT_MB:
@ -496,7 +493,7 @@ static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr,
xlen = to_dn(rr->dptr, dptr);
else
xlen = to_dn_capa(rr->dptr);
if (xlen <= 0)
if (xlen <= 0) goto inval;
break;
#if 0
@ -520,14 +517,21 @@ static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr,
case MIO_DNS_RRT_TXT:
case MIO_DNS_RRT_NULL:
default:
verbatim:
/* TODO: custom transformator? */
if (rr->dlen > 0) MIO_MEMCPY (dptr, rr->dptr, rr->dlen);
if (dptr) MIO_MEMCPY (dptr, rr->dptr, rr->dlen);
xlen = rr->dlen;
break;
}
if (MIO_UNLIKELY(xlen > MIO_TYPE_MAX(mio_uint16_t))) return 0;
return xlen;
if (MIO_UNLIKELY(xlen > MIO_TYPE_MAX(mio_uint16_t))) goto inval;
*dxlen = (mio_uint16_t)xlen;
return 0;
inval:
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, mio_oow_t xtnsize)
@ -545,20 +549,26 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
for (i = 0; i < qr_count; i++)
{
pktlen += to_dn_capa(qr[i].qname) + MIO_SIZEOF(*qrtr);
dnlen = to_dn_capa(qr[i].qname);
if (MIO_UNLIKELY(dnlen <= 0))
{
mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL;
}
pktlen += dnlen + MIO_SIZEOF(*qrtr);
}
for (i = 0; i < rr_count; i++)
{
mio_oow_t rrdata_len;
rrdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], MIO_NULL);
if (MIO_UNLIKELY(rrdata_len <= 0))
mio_uint16_t rrdata_len;
dnlen = to_dn_capa(rr[i].rrname);
if (MIO_UNLIKELY(dnlen <= 0))
{
/* invalid rrdata */
mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL;
}
pktlen += to_dn_capa(rr[i].rrname) + MIO_SIZEOF(*rrtr) + rrdata_len;
if (MIO_UNLIKELY(encode_rrdata_in_dns_msg(mio, &rr[i], &rrdata_len, MIO_NULL) <= -1)) return MIO_NULL;
pktlen += dnlen + MIO_SIZEOF(*rrtr) + rrdata_len;
}
edns_dlen = 0;
@ -572,7 +582,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
for (i = 0; i < edns->beonum; i++)
{
edns_dlen += MIO_SIZEOF(mio_dns_eopt_t) + beopt->dlen;
if (edns_dlen > MIO_TYPE_MAX(mio_uint16_t))
if (MIO_UNLIKELY(edns_dlen > MIO_TYPE_MAX(mio_uint16_t)))
{
mio_seterrbfmt (mio, MIO_EINVAL, "edns options too large");
return MIO_NULL;
@ -584,7 +594,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
}
else
{
if (bhdr->rcode > 0x0F)
if (MIO_UNLIKELY(bhdr->rcode > 0x0F))
{
/* rcode is larger than 4 bits. but edns info is not provided */
mio_seterrbfmt (mio, MIO_EINVAL, "rcode too large without edns - %d", bhdr->rcode);
@ -608,12 +618,8 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
{
/* dnlen includes the ending <zero> */
dnlen = to_dn(qr[i].qname, dn);
if (dnlen <= 0)
{
mio_dns_free_msg (mio, msg);
mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", qr[i].qname);
return MIO_NULL;
}
MIO_ASSERT (mio, dnlen > 0);
qrtr = (mio_dns_qrtr_t*)(dn + dnlen);
qrtr->qtype = mio_hton16(qr[i].qtype);
qrtr->qclass = mio_hton16(qr[i].qclass);
@ -628,23 +634,17 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t
{
if (rr[i].part == rr_sect)
{
mio_oow_t rrdata_len;
mio_uint16_t rrdata_len;
dnlen = to_dn(rr[i].rrname, dn);
if (dnlen <= 0)
{
mio_dns_free_msg (mio, msg);
mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", rr[i].rrname);
return MIO_NULL;
}
MIO_ASSERT (mio, dnlen > 0);
rrtr = (mio_dns_rrtr_t*)(dn + dnlen);
rrtr->rrtype = mio_hton16(rr[i].rrtype);
rrtr->rrclass = mio_hton16(rr[i].rrclass);
rrtr->ttl = mio_hton32(rr[i].ttl);
rrdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], rrtr + 1);
MIO_ASSERT (mio, rrdata_len > 0);
encode_rrdata_in_dns_msg(mio, &rr[i], &rrdata_len, rrtr + 1); /* this must succeed */
rrtr->dlen = mio_hton16(rrdata_len);
dn = (mio_uint8_t*)(rrtr + 1) + rrdata_len;

View File

@ -75,17 +75,17 @@ struct MIO_PACKED mio_ethaddr_t
};
typedef struct mio_ethaddr_t mio_ethaddr_t;
struct MIO_PACKED mio_ip4addr_t
struct MIO_PACKED mio_ip4ad_t
{
mio_uint8_t v[MIO_IP4ADDR_LEN];
};
typedef struct mio_ip4addr_t mio_ip4addr_t;
typedef struct mio_ip4ad_t mio_ip4ad_t;
struct MIO_PACKED mio_ip6addr_t
struct MIO_PACKED mio_ip6ad_t
{
mio_uint8_t v[MIO_IP6ADDR_LEN];
};
typedef struct mio_ip6addr_t mio_ip6addr_t;
typedef struct mio_ip6ad_t mio_ip6ad_t;
#include <mio-upac.h>
#if defined(__cplusplus)
@ -137,13 +137,13 @@ MIO_EXPORT mio_oow_t mio_skadtobcstr (
MIO_EXPORT void mio_skad_init_for_ip4 (
mio_skad_t* skad,
mio_uint16_t port,
mio_ip4addr_t* ip4addr
mio_ip4ad_t* ip4ad
);
MIO_EXPORT void mio_skad_init_for_ip6 (
mio_skad_t* skad,
mio_uint16_t port,
mio_ip6addr_t* ip6addr,
mio_ip6ad_t* ip6ad,
int scope_id
);

View File

@ -986,18 +986,17 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
#endif
/* the socket is already non-blocking */
/*{
int flags = fcntl (rdev->sck, F_GETFL);
fcntl (rdev->sck, F_SETFL, flags & ~O_NONBLOCK);
}*/
/* the socket is already non-blocking */
x = connect(rdev->sck, sa, sl);
/*{
int flags = fcntl (rdev->sck, F_GETFL);
fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
}*/
if (x == -1)
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN)
{
@ -1051,70 +1050,24 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
else
{
/* connected immediately */
/* don't call on_connect() callback even though the connection has been established.
* i don't want on_connect() to be called within the this function. */
if (mio_dev_watch((mio_dev_t*)rdev, MIO_DEV_WATCH_UPDATE, MIO_DEV_EVENT_IN | MIO_DEV_EVENT_OUT) <= -1)
{
/* watcher update failure. it's critical */
mio_stop (mio, MIO_STOPREQ_WATCHER_ERROR);
goto oops_connect;
}
/* as i know it's connected already,
* i don't schedule a connection timeout job */
rdev->remoteaddr = conn->remoteaddr;
sl = MIO_SIZEOF(localaddr);
if (getsockname(rdev->sck, (struct sockaddr*)&localaddr, &sl) == 0) rdev->localaddr = localaddr;
#if defined(USE_SSL)
if (ssl_ctx)
{
int x;
rdev->ssl_ctx = ssl_ctx;
x = connect_ssl(rdev);
if (x <= -1)
{
SSL_CTX_free (rdev->ssl_ctx);
rdev->ssl_ctx = MIO_NULL;
MIO_ASSERT (mio, rdev->ssl == MIO_NULL);
return -1;
}
if (x == 0)
{
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_INIT_NTIME (&rdev->tmout, 0, 0); /* just in case */
/* it's ok to use conn->connect_tmout for ssl-connect as
* the underlying socket connection has been established immediately */
if (MIO_IS_POS_NTIME(&conn->connect_tmout))
{
if (schedule_timer_job_after(rdev, &conn->connect_tmout, ssl_connect_timedout) <= -1)
{
/* no device halting in spite of failure.
* let the caller handle this after having
* checked the return code as it is an IOCTL call. */
SSL_CTX_free (rdev->ssl_ctx);
rdev->ssl_ctx = MIO_NULL;
MIO_ASSERT (mio, rdev->ssl == MIO_NULL);
return -1;
}
else
{
/* update rdev->tmout to the deadline of the connect timeout job */
MIO_ASSERT (mio, rdev->tmrjob_index != MIO_TMRIDX_INVALID);
mio_gettmrjobdeadline (mio, rdev->tmrjob_index, &rdev->tmout);
}
}
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_CONNECTING_SSL);
}
else
{
goto ssl_connected;
}
}
else
{
ssl_connected:
#endif
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_CONNECTED);
if (rdev->on_connect) rdev->on_connect (rdev);
#if defined(USE_SSL)
}
rdev->ssl_ctx = ssl_ctx;
#endif
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_CONNECTING);
return 0;
}
}

View File

@ -790,7 +790,7 @@ int mio_bcharstoskad (mio_t* mio, const mio_bch_t* str, mio_oow_t len, mio_skad_
unrecog:
mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address");
return -1;
no_rbrack:
mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket");
return -1;
@ -827,7 +827,7 @@ no_rbrack:
/* ---------------------------------------------------------- */
static mio_oow_t ip4addr_to_ucstr (const struct in_addr* ipad, mio_uch_t* buf, mio_oow_t size)
static mio_oow_t ip4ad_to_ucstr (const struct in_addr* ipad, mio_uch_t* buf, mio_oow_t size)
{
mio_uint8_t b;
mio_uch_t* p, * end;
@ -859,7 +859,7 @@ static mio_oow_t ip4addr_to_ucstr (const struct in_addr* ipad, mio_uch_t* buf, m
}
static mio_oow_t ip6addr_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mio_oow_t size)
static mio_oow_t ip6ad_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mio_oow_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
@ -942,7 +942,7 @@ static mio_oow_t ip6addr_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf,
{
struct in_addr ip4ad;
MIO_MEMCPY (&ip4ad.s_addr, ipad->s6_addr + 12, MIO_SIZEOF(ip4ad.s_addr));
tp += ip4addr_to_ucstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp));
tp += ip4ad_to_ucstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp));
break;
}
@ -972,7 +972,7 @@ mio_oow_t mio_skadtoucstr (mio_t* mio, const mio_skad_t* _skad, mio_uch_t* buf,
if (flags & MIO_SKAD_TO_BCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
xlen += ip4addr_to_ucstr(&skad->in4.sin_addr, buf, len);
xlen += ip4ad_to_ucstr(&skad->in4.sin_addr, buf, len);
}
if (flags & MIO_SKAD_TO_BCSTR_PORT)
@ -1007,7 +1007,7 @@ mio_oow_t mio_skadtoucstr (mio_t* mio, const mio_skad_t* _skad, mio_uch_t* buf,
if (flags & MIO_SKAD_TO_BCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
xlen += ip6addr_to_ucstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen);
xlen += ip6ad_to_ucstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen);
if (skad->in6.sin6_scope_id != 0)
{
@ -1073,7 +1073,7 @@ done:
/* ---------------------------------------------------------- */
static mio_oow_t ip4addr_to_bcstr (const struct in_addr* ipad, mio_bch_t* buf, mio_oow_t size)
static mio_oow_t ip4ad_to_bcstr (const struct in_addr* ipad, mio_bch_t* buf, mio_oow_t size)
{
mio_uint8_t b;
mio_bch_t* p, * end;
@ -1105,7 +1105,7 @@ static mio_oow_t ip4addr_to_bcstr (const struct in_addr* ipad, mio_bch_t* buf, m
}
static mio_oow_t ip6addr_to_bcstr (const struct in6_addr* ipad, mio_bch_t* buf, mio_oow_t size)
static mio_oow_t ip6ad_to_bcstr (const struct in6_addr* ipad, mio_bch_t* buf, mio_oow_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
@ -1188,7 +1188,7 @@ static mio_oow_t ip6addr_to_bcstr (const struct in6_addr* ipad, mio_bch_t* buf,
{
struct in_addr ip4ad;
MIO_MEMCPY (&ip4ad.s_addr, ipad->s6_addr + 12, MIO_SIZEOF(ip4ad.s_addr));
tp += ip4addr_to_bcstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp));
tp += ip4ad_to_bcstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp));
break;
}
@ -1218,7 +1218,7 @@ mio_oow_t mio_skadtobcstr (mio_t* mio, const mio_skad_t* _skad, mio_bch_t* buf,
if (flags & MIO_SKAD_TO_BCSTR_ADDR)
{
if (xlen + 1 >= len) goto done;
xlen += ip4addr_to_bcstr(&skad->in4.sin_addr, buf, len);
xlen += ip4ad_to_bcstr(&skad->in4.sin_addr, buf, len);
}
if (flags & MIO_SKAD_TO_BCSTR_PORT)
@ -1254,7 +1254,7 @@ mio_oow_t mio_skadtobcstr (mio_t* mio, const mio_skad_t* _skad, mio_bch_t* buf,
{
if (xlen + 1 >= len) goto done;
xlen += ip6addr_to_bcstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen);
xlen += ip6ad_to_bcstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen);
if (skad->in6.sin6_scope_id != 0)
{
@ -1381,7 +1381,7 @@ 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)
void mio_skad_init_for_ip4 (mio_skad_t* skad, mio_uint16_t port, mio_ip4ad_t* ip4ad)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
struct sockaddr_in* sin = (struct sockaddr_in*)skad;
@ -1389,11 +1389,11 @@ void mio_skad_init_for_ip4 (mio_skad_t* skad, mio_uint16_t port, mio_ip4addr_t*
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);
if (ip4ad) MIO_MEMCPY (&sin->sin_addr, ip4ad, 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)
void mio_skad_init_for_ip6 (mio_skad_t* skad, mio_uint16_t port, mio_ip6ad_t* ip6ad, int scope_id)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
struct sockaddr_in6* sin = (struct sockaddr_in6*)skad;
@ -1402,7 +1402,7 @@ void mio_skad_init_for_ip6 (mio_skad_t* skad, mio_uint16_t port, mio_ip6addr_t*
sin->sin6_family = AF_INET;
sin->sin6_port = htons(port);
sin->sin6_scope_id = scope_id;
if (ip6addr) MIO_MEMCPY (&sin->sin6_addr, ip6addr, MIO_IP6ADDR_LEN);
if (ip6ad) MIO_MEMCPY (&sin->sin6_addr, ip6ad, MIO_IP6ADDR_LEN);
#endif
}