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:
		@ -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
									
								
							
							
						
						
									
										259
									
								
								mio/bin/t02.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user