removed unneeded code
This commit is contained in:
		@ -24,9 +24,6 @@ pkginclude_HEADERS = \
 | 
				
			|||||||
	stio-cmn.h \
 | 
						stio-cmn.h \
 | 
				
			||||||
	stio-pro.h \
 | 
						stio-pro.h \
 | 
				
			||||||
	stio-sck.h \
 | 
						stio-sck.h \
 | 
				
			||||||
	stio-tcp.h \
 | 
					 | 
				
			||||||
	stio-udp.h \
 | 
					 | 
				
			||||||
	stio-arp.h \
 | 
					 | 
				
			||||||
	stio.h
 | 
						stio.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pkglib_LTLIBRARIES = libstio.la
 | 
					pkglib_LTLIBRARIES = libstio.la
 | 
				
			||||||
@ -35,11 +32,8 @@ libstio_la_SOURCES = \
 | 
				
			|||||||
	stio.c \
 | 
						stio.c \
 | 
				
			||||||
	stio-pro.c \
 | 
						stio-pro.c \
 | 
				
			||||||
	stio-sck.c \
 | 
						stio-sck.c \
 | 
				
			||||||
	stio-tcp.c \
 | 
					 | 
				
			||||||
	stio-tim.c \
 | 
						stio-tim.c \
 | 
				
			||||||
	stio-tmr.c \
 | 
						stio-tmr.c
 | 
				
			||||||
	stio-udp.c \
 | 
					 | 
				
			||||||
	stio-arp.c
 | 
					 | 
				
			||||||
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
 | 
					libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
 | 
				
			||||||
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
 | 
					libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
 | 
				
			||||||
libstio_la_LIBADD = $(LIBADD_LIB_COMMON)
 | 
					libstio_la_LIBADD = $(LIBADD_LIB_COMMON)
 | 
				
			||||||
 | 
				
			|||||||
@ -132,7 +132,7 @@ libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
 | 
				
			|||||||
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
 | 
					am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
 | 
				
			||||||
	libstio_la-stio-sck.lo libstio_la-stio-tcp.lo \
 | 
						libstio_la-stio-sck.lo libstio_la-stio-tcp.lo \
 | 
				
			||||||
	libstio_la-stio-tim.lo libstio_la-stio-tmr.lo \
 | 
						libstio_la-stio-tim.lo libstio_la-stio-tmr.lo \
 | 
				
			||||||
	libstio_la-stio-udp.lo libstio_la-stio-arp.lo
 | 
						libstio_la-stio-udp.lo
 | 
				
			||||||
libstio_la_OBJECTS = $(am_libstio_la_OBJECTS)
 | 
					libstio_la_OBJECTS = $(am_libstio_la_OBJECTS)
 | 
				
			||||||
AM_V_lt = $(am__v_lt_@AM_V@)
 | 
					AM_V_lt = $(am__v_lt_@AM_V@)
 | 
				
			||||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 | 
					am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 | 
				
			||||||
@ -384,7 +384,6 @@ pkginclude_HEADERS = \
 | 
				
			|||||||
	stio-sck.h \
 | 
						stio-sck.h \
 | 
				
			||||||
	stio-tcp.h \
 | 
						stio-tcp.h \
 | 
				
			||||||
	stio-udp.h \
 | 
						stio-udp.h \
 | 
				
			||||||
	stio-arp.h \
 | 
					 | 
				
			||||||
	stio.h
 | 
						stio.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pkglib_LTLIBRARIES = libstio.la
 | 
					pkglib_LTLIBRARIES = libstio.la
 | 
				
			||||||
@ -396,8 +395,7 @@ libstio_la_SOURCES = \
 | 
				
			|||||||
	stio-tcp.c \
 | 
						stio-tcp.c \
 | 
				
			||||||
	stio-tim.c \
 | 
						stio-tim.c \
 | 
				
			||||||
	stio-tmr.c \
 | 
						stio-tmr.c \
 | 
				
			||||||
	stio-udp.c \
 | 
						stio-udp.c
 | 
				
			||||||
	stio-arp.c
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
 | 
					libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
 | 
				
			||||||
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
 | 
					libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
 | 
				
			||||||
@ -554,7 +552,6 @@ mostlyclean-compile:
 | 
				
			|||||||
distclean-compile:
 | 
					distclean-compile:
 | 
				
			||||||
	-rm -f *.tab.c
 | 
						-rm -f *.tab.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-arp.Plo@am__quote@
 | 
					 | 
				
			||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-pro.Plo@am__quote@
 | 
					@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-pro.Plo@am__quote@
 | 
				
			||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-sck.Plo@am__quote@
 | 
					@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-sck.Plo@am__quote@
 | 
				
			||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tcp.Plo@am__quote@
 | 
					@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tcp.Plo@am__quote@
 | 
				
			||||||
@ -634,13 +631,6 @@ libstio_la-stio-udp.lo: stio-udp.c
 | 
				
			|||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 | 
					@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 | 
				
			||||||
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-udp.lo `test -f 'stio-udp.c' || echo '$(srcdir)/'`stio-udp.c
 | 
					@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-udp.lo `test -f 'stio-udp.c' || echo '$(srcdir)/'`stio-udp.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libstio_la-stio-arp.lo: stio-arp.c
 | 
					 | 
				
			||||||
@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-arp.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-arp.Tpo -c -o libstio_la-stio-arp.lo `test -f 'stio-arp.c' || echo '$(srcdir)/'`stio-arp.c
 | 
					 | 
				
			||||||
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-arp.Tpo $(DEPDIR)/libstio_la-stio-arp.Plo
 | 
					 | 
				
			||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stio-arp.c' object='libstio_la-stio-arp.lo' libtool=yes @AMDEPBACKSLASH@
 | 
					 | 
				
			||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 | 
					 | 
				
			||||||
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-arp.lo `test -f 'stio-arp.c' || echo '$(srcdir)/'`stio-arp.c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stio-main.o: main.c
 | 
					stio-main.o: main.c
 | 
				
			||||||
@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stio-main.o -MD -MP -MF $(DEPDIR)/stio-main.Tpo -c -o stio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
 | 
					@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stio-main.o -MD -MP -MF $(DEPDIR)/stio-main.Tpo -c -o stio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
 | 
				
			||||||
@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/stio-main.Tpo $(DEPDIR)/stio-main.Po
 | 
					@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/stio-main.Tpo $(DEPDIR)/stio-main.Po
 | 
				
			||||||
 | 
				
			|||||||
@ -26,9 +26,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stio.h>
 | 
					#include <stio.h>
 | 
				
			||||||
 | 
					#include <stio-sck.h>
 | 
				
			||||||
#include <stio-tcp.h>
 | 
					#include <stio-tcp.h>
 | 
				
			||||||
#include <stio-udp.h>
 | 
					 | 
				
			||||||
#include <stio-arp.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
@ -93,7 +92,7 @@ struct tcp_server_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
typedef struct tcp_server_t tcp_server_t;
 | 
					typedef struct tcp_server_t tcp_server_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_on_disconnect (stio_dev_sck_t* tcp)
 | 
					static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (tcp->state & STIO_DEV_TCP_CONNECTING)
 | 
						if (tcp->state & STIO_DEV_TCP_CONNECTING)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -116,7 +115,7 @@ static void tcp_on_disconnect (stio_dev_sck_t* tcp)
 | 
				
			|||||||
		printf ("TCP DISCONNECTED - THIS MUST NOT HAPPEN (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
 | 
							printf ("TCP DISCONNECTED - THIS MUST NOT HAPPEN (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static int tcp_on_connect (stio_dev_sck_t* tcp)
 | 
					static int tcp_sck_on_connect (stio_dev_sck_t* tcp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tcp->state & STIO_DEV_TCP_CONNECTED)
 | 
						if (tcp->state & STIO_DEV_TCP_CONNECTED)
 | 
				
			||||||
@ -131,7 +130,7 @@ printf ("device accepted client device... .asdfjkasdfkljasdlfkjasdj...\n");
 | 
				
			|||||||
	return stio_dev_sck_write  (tcp, "hello", 5, STIO_NULL, STIO_NULL);
 | 
						return stio_dev_sck_write  (tcp, "hello", 5, STIO_NULL, STIO_NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tcp_on_write (stio_dev_sck_t* tcp, stio_len_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
 | 
					static int tcp_sck_on_write (stio_dev_sck_t* tcp, stio_iolen_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tcp_server_t* ts;
 | 
						tcp_server_t* ts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -154,7 +153,7 @@ printf ("ENABLING READING..............................\n");
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tcp_on_read (stio_dev_sck_t* tcp, const void* buf, stio_len_t len, const stio_sckadr_t* srcadr)
 | 
					static int tcp_sck_on_read (stio_dev_sck_t* tcp, const void* buf, stio_iolen_t len, const stio_sckadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (len <= 0)
 | 
						if (len <= 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -191,7 +190,7 @@ printf ("DISABLING READING..............................\n");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, const stio_sckadr_t* srcadr)
 | 
					static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_etharp_pkt_t* eap;
 | 
						stio_etharp_pkt_t* eap;
 | 
				
			||||||
	struct sockaddr_ll* sll = (struct sockaddr_ll*)srcadr; 
 | 
						struct sockaddr_ll* sll = (struct sockaddr_ll*)srcadr; 
 | 
				
			||||||
@ -208,7 +207,7 @@ static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_len_t dl
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_len_t wrlen, void* wrctx)
 | 
					static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -229,7 +228,7 @@ int main ()
 | 
				
			|||||||
	stio_t* stio;
 | 
						stio_t* stio;
 | 
				
			||||||
	stio_dev_sck_t* sck;
 | 
						stio_dev_sck_t* sck;
 | 
				
			||||||
	stio_dev_sck_t* tcp[2];
 | 
						stio_dev_sck_t* tcp[2];
 | 
				
			||||||
	struct sockaddr_in sin;
 | 
					
 | 
				
			||||||
	struct sigaction sigact;
 | 
						struct sigaction sigact;
 | 
				
			||||||
	stio_dev_sck_connect_t tcp_conn;
 | 
						stio_dev_sck_connect_t tcp_conn;
 | 
				
			||||||
	stio_dev_sck_listen_t tcp_lstn;
 | 
						stio_dev_sck_listen_t tcp_lstn;
 | 
				
			||||||
@ -271,8 +270,8 @@ int main ()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
 | 
						memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
 | 
				
			||||||
	tcp_make.type = STIO_DEV_SCK_TCP4;
 | 
						tcp_make.type = STIO_DEV_SCK_TCP4;
 | 
				
			||||||
	tcp_make.on_write = tcp_on_write;
 | 
						tcp_make.on_write = tcp_sck_on_write;
 | 
				
			||||||
	tcp_make.on_read = tcp_on_read;
 | 
						tcp_make.on_read = tcp_sck_on_read;
 | 
				
			||||||
	tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
 | 
						tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
 | 
				
			||||||
	if (!tcp[0])
 | 
						if (!tcp[0])
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -283,17 +282,15 @@ int main ()
 | 
				
			|||||||
	ts = (tcp_server_t*)(tcp[0] + 1);
 | 
						ts = (tcp_server_t*)(tcp[0] + 1);
 | 
				
			||||||
	ts->tally = 0;
 | 
						ts->tally = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&sin, 0, STIO_SIZEOF(sin));
 | 
					 | 
				
			||||||
	sin.sin_family = AF_INET;
 | 
					 | 
				
			||||||
	sin.sin_port = htons(9999);
 | 
					 | 
				
			||||||
	inet_pton (sin.sin_family, "192.168.1.119", &sin.sin_addr);
 | 
					 | 
				
			||||||
	//inet_pton (sin.sin_family, "127.0.0.1", &sin.sin_addr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
 | 
						memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
 | 
				
			||||||
	memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin));
 | 
					{
 | 
				
			||||||
 | 
						in_addr_t ia = inet_addr("192.168.1.119");
 | 
				
			||||||
 | 
						stio_sckadr_initforip4 (&tcp_conn.addr, 9999, (stio_ip4adr_t*)&ia);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
	tcp_conn.tmout.sec = 5;
 | 
						tcp_conn.tmout.sec = 5;
 | 
				
			||||||
	tcp_conn.on_connect = tcp_on_connect;
 | 
						tcp_conn.on_connect = tcp_sck_on_connect;
 | 
				
			||||||
	tcp_conn.on_disconnect = tcp_on_disconnect;
 | 
						tcp_conn.on_disconnect = tcp_sck_on_disconnect;
 | 
				
			||||||
	if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
 | 
						if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		printf ("stio_dev_sck_connect() failed....\n");
 | 
							printf ("stio_dev_sck_connect() failed....\n");
 | 
				
			||||||
@ -301,8 +298,8 @@ int main ()
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
 | 
						memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
 | 
				
			||||||
	tcp_make.on_write = tcp_on_write;
 | 
						tcp_make.on_write = tcp_sck_on_write;
 | 
				
			||||||
	tcp_make.on_read = tcp_on_read;
 | 
						tcp_make.on_read = tcp_sck_on_read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
 | 
						tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
 | 
				
			||||||
	if (!tcp[1])
 | 
						if (!tcp[1])
 | 
				
			||||||
@ -314,9 +311,7 @@ int main ()
 | 
				
			|||||||
	ts->tally = 0;
 | 
						ts->tally = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
 | 
						memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
 | 
				
			||||||
	//memcpy (&tcp_bind.addr, &sin, STIO_SIZEOF(sin));
 | 
						stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL);
 | 
				
			||||||
	((struct sockaddr_in*)&tcp_bind.addr)->sin_family = AF_INET;
 | 
					 | 
				
			||||||
	((struct sockaddr_in*)&tcp_bind.addr)->sin_port = htons(1234);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
 | 
						if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -324,9 +319,10 @@ int main ()
 | 
				
			|||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcp_lstn.backlogs = 100;
 | 
						tcp_lstn.backlogs = 100;
 | 
				
			||||||
	tcp_lstn.on_connect = tcp_on_connect;
 | 
						tcp_lstn.on_connect = tcp_sck_on_connect;
 | 
				
			||||||
	tcp_lstn.on_disconnect = tcp_on_disconnect;
 | 
						tcp_lstn.on_disconnect = tcp_sck_on_disconnect;
 | 
				
			||||||
	if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
 | 
						if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		printf ("stio_dev_sck_listen() failed....\n");
 | 
							printf ("stio_dev_sck_listen() failed....\n");
 | 
				
			||||||
@ -334,6 +330,12 @@ int main ()
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stio_sckadr_t ethdst;
 | 
				
			||||||
 | 
						stio_etharp_pkt_t etharp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&sck_make, 0, STIO_SIZEOF(sck_make));
 | 
						memset (&sck_make, 0, STIO_SIZEOF(sck_make));
 | 
				
			||||||
	sck_make.type = STIO_DEV_SCK_ARP;
 | 
						sck_make.type = STIO_DEV_SCK_ARP;
 | 
				
			||||||
	//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
 | 
						//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
 | 
				
			||||||
@ -346,26 +348,14 @@ int main ()
 | 
				
			|||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 1
 | 
						//stio_sckadr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethadr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
 | 
				
			||||||
{
 | 
						stio_sckadr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethadr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
 | 
				
			||||||
	stio_etharp_pkt_t etharp;
 | 
					 | 
				
			||||||
	struct sockaddr_ll sll;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&sll, 0, sizeof(sll));
 | 
					 | 
				
			||||||
	sll.sll_family = AF_PACKET;
 | 
					 | 
				
			||||||
//	sll.sll_protocol = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
 | 
					 | 
				
			||||||
//	sll.sll_hatype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
 | 
					 | 
				
			||||||
	sll.sll_halen = STIO_ETHADR_LEN;
 | 
					 | 
				
			||||||
	memcpy (sll.sll_addr, "\xFF\xFF\xFF\xFF\xFF\xFF", sll.sll_halen);
 | 
					 | 
				
			||||||
	sll.sll_ifindex = if_nametoindex ("enp0s25.3");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* if unicast ... */
 | 
					 | 
				
			||||||
	//sll.sll_pkttype = PACKET_OTHERHOST;
 | 
					 | 
				
			||||||
//	sll.sll_pkttype = PACKET_BROADCAST;
 | 
					 | 
				
			||||||
	memset (ðarp, 0, sizeof(etharp));
 | 
						memset (ðarp, 0, sizeof(etharp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
 | 
						memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
 | 
				
			||||||
	memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADR_LEN);
 | 
						//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADR_LEN);
 | 
				
			||||||
 | 
						memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADR_LEN);
 | 
				
			||||||
	etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
 | 
						etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
 | 
						etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
 | 
				
			||||||
@ -376,8 +366,8 @@ int main ()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
 | 
						memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stio_dev_sck_write (sck, ðarp, sizeof(etharp), NULL, &sll) <= -1)
 | 
						if (stio_dev_sck_write (sck, ðarp, sizeof(etharp), NULL, ðdst) <= -1)
 | 
				
			||||||
	//if (stio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &adr) <= -1)
 | 
						//if (stio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, ðadr) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		printf ("CANNOT WRITE ARP...\n");
 | 
							printf ("CANNOT WRITE ARP...\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ static stio_syshnd_t arp_getsyshnd (stio_dev_t* dev)
 | 
				
			|||||||
	return (stio_syshnd_t)arp->sck;
 | 
						return (stio_syshnd_t)arp->sck;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_read (stio_dev_t* dev, void* buf, stio_len_t* len)
 | 
					static int arp_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_arp_t* arp = (stio_dev_arp_t*)dev;
 | 
						stio_dev_arp_t* arp = (stio_dev_arp_t*)dev;
 | 
				
			||||||
	stio_scklen_t addrlen;
 | 
						stio_scklen_t addrlen;
 | 
				
			||||||
@ -98,7 +98,7 @@ printf ("ARP RECVFROM...\n");
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_write (stio_dev_t* dev, const void* data, stio_len_t* len)
 | 
					static int arp_write (stio_dev_t* dev, const void* data, stio_iolen_t* len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_arp_t* arp = (stio_dev_arp_t*)arp;
 | 
						stio_dev_arp_t* arp = (stio_dev_arp_t*)arp;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -154,13 +154,13 @@ static int arp_ready (stio_dev_t* dev, int events)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
 | 
					static int arp_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
printf ("dATA received %d bytes\n", (int)len);
 | 
					printf ("dATA received %d bytes\n", (int)len);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
 | 
					static int arp_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -30,82 +30,9 @@
 | 
				
			|||||||
#include <stio.h>
 | 
					#include <stio.h>
 | 
				
			||||||
#include <stio-sck.h>
 | 
					#include <stio-sck.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STIO_ETHHDR_PROTO_IP4 0x0800
 | 
					 | 
				
			||||||
#define STIO_ETHHDR_PROTO_ARP 0x0806
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define STIO_ARPHDR_OPCODE_REQUEST 1
 | 
					 | 
				
			||||||
#define STIO_ARPHDR_OPCODE_REPLY   2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define STIO_ARPHDR_HTYPE_ETH 0x0001
 | 
					 | 
				
			||||||
#define STIO_ARPHDR_PTYPE_IP4 0x0800
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define STIO_ETHADR_LEN 6
 | 
					 | 
				
			||||||
#define STIO_IP4ADR_LEN 4
 | 
					 | 
				
			||||||
#define STIO_IP6ADR_LEN 16 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma pack(push)
 | 
					 | 
				
			||||||
#pragma pack(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_ethadr_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint8_t v[STIO_ETHADR_LEN]; 
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_ethadr_t stio_ethadr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_ip4adr_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint8_t v[STIO_IP4ADR_LEN];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_ip4adr_t stio_ip4adr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_ip6adr_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint8_t v[STIO_IP6ADR_LEN]; 
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_ip6adr_t stio_ip6adr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_ethhdr_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint8_t  dest[STIO_ETHADR_LEN];
 | 
					 | 
				
			||||||
	stio_uint8_t  source[STIO_ETHADR_LEN];
 | 
					 | 
				
			||||||
	stio_uint16_t proto;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_ethhdr_t stio_ethhdr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_arphdr_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint16_t htype;   /* hardware type (ethernet: 0x0001) */
 | 
					 | 
				
			||||||
	stio_uint16_t ptype;   /* protocol type (ipv4: 0x0800) */
 | 
					 | 
				
			||||||
	stio_uint8_t  hlen;    /* hardware address length (ethernet: 6) */
 | 
					 | 
				
			||||||
	stio_uint8_t  plen;    /* protocol address length (ipv4 :4) */
 | 
					 | 
				
			||||||
	stio_uint16_t opcode;  /* operation code */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_arphdr_t stio_arphdr_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* arp payload for ipv4 over ethernet */
 | 
					 | 
				
			||||||
struct stio_etharp_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_uint8_t sha[STIO_ETHADR_LEN];   /* source hardware address */
 | 
					 | 
				
			||||||
	stio_uint8_t spa[STIO_IP4ADR_LEN];   /* source protocol address */
 | 
					 | 
				
			||||||
	stio_uint8_t tha[STIO_ETHADR_LEN];   /* target hardware address */
 | 
					 | 
				
			||||||
	stio_uint8_t tpa[STIO_IP4ADR_LEN];   /* target protocol address */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_etharp_t stio_etharp_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_etharp_pkt_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_ethhdr_t ethhdr;
 | 
					 | 
				
			||||||
	stio_arphdr_t arphdr;
 | 
					 | 
				
			||||||
	stio_etharp_t arppld;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma pack(pop)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
typedef int (*stio_dev_arp_on_read_t) (stio_dev_arp_t* dev, stio_pkt_arp_t* pkt, stio_len_t len);
 | 
					typedef int (*stio_dev_arp_on_read_t) (stio_dev_arp_t* dev, stio_pkt_arp_t* pkt, stio_iolen_t len);
 | 
				
			||||||
typedef int (*stio_dev_arp_on_write_t) (stio_dev_arp_t* dev, void* wrctx);
 | 
					typedef int (*stio_dev_arp_on_write_t) (stio_dev_arp_t* dev, void* wrctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct stio_dev_arp_make_t stio_dev_arp_make_t;
 | 
					typedef struct stio_dev_arp_make_t stio_dev_arp_make_t;
 | 
				
			||||||
 | 
				
			|||||||
@ -134,7 +134,7 @@ static void pro_kill (stio_dev_t* dev)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len)
 | 
					static int pro_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -152,7 +152,7 @@ static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_write (stio_dev_t* dev, const void* data, stio_len_t* len)
 | 
					static int pro_write (stio_dev_t* dev, const void* data, stio_iolen_t* len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -205,7 +205,7 @@ printf ("PRO READY...%p\n", dev);
 | 
				
			|||||||
	return 1; /* the device is ok. carry on reading or writing */
 | 
						return 1; /* the device is ok. carry on reading or writing */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_on_read (stio_dev_t* dev, const void* data, stio_len_t len, const stio_devadr_t* srcadr)
 | 
					static int pro_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
	return pro->on_read (pro, data, len);
 | 
						return pro->on_read (pro, data, len);
 | 
				
			||||||
@ -235,7 +235,7 @@ void stio_dev_pro_kill (stio_dev_pro_t* pro)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
int stio_dev_pro_write (stio_dev_pro_t* pro, const void* data, stio_len_t len, void* wrctx)
 | 
					int stio_dev_pro_write (stio_dev_pro_t* pro, const void* data, stio_iolen_t len, void* wrctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)pro, data, len, wrctx);
 | 
						return stio_dev_write ((stio_dev_t*)pro, data, len, wrctx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -40,7 +40,7 @@ typedef enum stio_dev_pro_type_t stio_dev_pro_type_t;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct stio_dev_pro_t stio_dev_pro_t;
 | 
					typedef struct stio_dev_pro_t stio_dev_pro_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_len_t len);
 | 
					typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_iolen_t len);
 | 
				
			||||||
typedef int (*stio_dev_pro_on_write_t) (stio_dev_pro_t* dev, void* wrctx);
 | 
					typedef int (*stio_dev_pro_on_write_t) (stio_dev_pro_t* dev, void* wrctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct stio_dev_pro_t
 | 
					struct stio_dev_pro_t
 | 
				
			||||||
@ -100,7 +100,7 @@ STIO_EXPORT void stio_dev_pro_kill (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_pro_write (
 | 
					STIO_EXPORT int stio_dev_pro_write (
 | 
				
			||||||
	stio_dev_pro_t*  pro,
 | 
						stio_dev_pro_t*  pro,
 | 
				
			||||||
	const void*      data,
 | 
						const void*      data,
 | 
				
			||||||
	stio_len_t       len,
 | 
						stio_iolen_t       len,
 | 
				
			||||||
	void*            wrctx
 | 
						void*            wrctx
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -116,18 +116,19 @@ int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t*
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					/* ========================================================================= */
 | 
				
			||||||
static void stio_initsckadrforip4 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip4adr_t* ip4adr)
 | 
					
 | 
				
			||||||
 | 
					void stio_sckadr_initforip4 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip4adr_t* ip4adr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_in* sin = (struct sockaddr_in*)sckadr;
 | 
						struct sockaddr_in* sin = (struct sockaddr_in*)sckadr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
 | 
						STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
 | 
				
			||||||
	sin->sin_family = AF_INET;
 | 
						sin->sin_family = AF_INET;
 | 
				
			||||||
	sin->sin_port = htons(port);
 | 
						sin->sin_port = htons(port);
 | 
				
			||||||
	STIO_MEMSET (&sin->sin_addr, ip4adr, STIO_IP4ADR_LEN);
 | 
						if (ip4adr) STIO_MEMCPY (&sin->sin_addr, ip4adr, STIO_IP4ADR_LEN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void stio_initsckadrforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip6adr_t* ip6adr)
 | 
					void stio_sckadr_initforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip6adr_t* ip6adr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_in6* sin = (struct sockaddr_in6*)sckadr;
 | 
						struct sockaddr_in6* sin = (struct sockaddr_in6*)sckadr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -135,19 +136,23 @@ static void stio_initsckadrforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, st
 | 
				
			|||||||
	STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
 | 
						STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
 | 
				
			||||||
	sin->sin6_family = AF_INET;
 | 
						sin->sin6_family = AF_INET;
 | 
				
			||||||
	sin->sin6_port = htons(port);
 | 
						sin->sin6_port = htons(port);
 | 
				
			||||||
	STIO_MEMSET (&sin->sin_addr, ip6adr, STIO_IP6ADR_LEN);
 | 
						if (ip6adr) STIO_MEMCPY (&sin->sin6_addr, ip6adr, STIO_IP6ADR_LEN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stio void stio_intisckadrforeth (stio_sckadr_t* sckadr, int ifindex, stio_ethadr_t* ethadr)
 | 
					void stio_sckadr_initforeth (stio_sckadr_t* sckadr, int ifindex, stio_ethadr_t* ethadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_ll* sll = (struct sockaddr_in*)sckadr;
 | 
						struct sockaddr_ll* sll = (struct sockaddr_ll*)sckadr;
 | 
				
			||||||
	STIO_MEMSET (sll, 0, STIO_SIZEOF(*sll));
 | 
						STIO_MEMSET (sll, 0, STIO_SIZEOF(*sll));
 | 
				
			||||||
	sll->sll_family = AF_PACKET;
 | 
						sll->sll_family = AF_PACKET;
 | 
				
			||||||
	sll->sll_ifindex = ifindex;
 | 
						sll->sll_ifindex = ifindex;
 | 
				
			||||||
	sll->sll_halen = STIO_ETHADR_LEN;
 | 
						if (ethadr)
 | 
				
			||||||
	STIO_MEMSET (sll->sll_addr, ethadr, STIO_ETHADR_LEN);
 | 
						{
 | 
				
			||||||
 | 
							sll->sll_halen = STIO_ETHADR_LEN;
 | 
				
			||||||
 | 
							STIO_MEMCPY (sll->sll_addr, ethadr, STIO_ETHADR_LEN);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_devadr_t* sckadr_to_devadr (stio_dev_sck_t* dev, const stio_sckadr_t* sckadr, stio_devadr_t* devadr)
 | 
					static stio_devadr_t* sckadr_to_devadr (stio_dev_sck_t* dev, const stio_sckadr_t* sckadr, stio_devadr_t* devadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -168,6 +173,7 @@ static STIO_INLINE stio_sckadr_t* devadr_to_sckadr (stio_dev_sck_t* dev, const s
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	return (stio_sckadr_t*)devadr->ptr;
 | 
						return (stio_sckadr_t*)devadr->ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IS_STATEFUL(sck) ((sck)->dev_capa & STIO_DEV_CAPA_STREAM)
 | 
					#define IS_STATEFUL(sck) ((sck)->dev_capa & STIO_DEV_CAPA_STREAM)
 | 
				
			||||||
@ -228,8 +234,8 @@ static int dev_sck_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
	rdev->on_write = arg->on_write;
 | 
						rdev->on_write = arg->on_write;
 | 
				
			||||||
	rdev->on_read = arg->on_read;
 | 
						rdev->on_read = arg->on_read;
 | 
				
			||||||
	rdev->type = arg->type;
 | 
						rdev->type = arg->type;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	rdev->tmridx_connect = STIO_TMRIDX_INVALID;
 | 
						rdev->tmridx_connect = STIO_TMRIDX_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oops:
 | 
					oops:
 | 
				
			||||||
@ -288,7 +294,7 @@ static stio_syshnd_t dev_sck_getsyshnd (stio_dev_t* dev)
 | 
				
			|||||||
	return (stio_syshnd_t)rdev->sck;
 | 
						return (stio_syshnd_t)rdev->sck;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* srcadr)
 | 
					static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* tcp = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* tcp = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -306,7 +312,7 @@ static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_len_t* len, s
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* srcadr)
 | 
					static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	stio_scklen_t srcadrlen;
 | 
						stio_scklen_t srcadrlen;
 | 
				
			||||||
@ -330,7 +336,7 @@ static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_len_t* len,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr)
 | 
					static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -366,7 +372,7 @@ static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_len_t
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr)
 | 
					static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -741,25 +747,25 @@ static int dev_evcb_sck_ready_stateless (stio_dev_t* dev, int events)
 | 
				
			|||||||
	return 1; /* the device is ok. carry on reading or writing */
 | 
						return 1; /* the device is ok. carry on reading or writing */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_evcb_sck_on_read_stateful (stio_dev_t* dev, const void* data, stio_len_t dlen, const stio_devadr_t* srcadr)
 | 
					static int dev_evcb_sck_on_read_stateful (stio_dev_t* dev, const void* data, stio_iolen_t dlen, const stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	return rdev->on_read (rdev, data, dlen, STIO_NULL);
 | 
						return rdev->on_read (rdev, data, dlen, STIO_NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_evcb_sck_on_write_stateful (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
 | 
					static int dev_evcb_sck_on_write_stateful (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	return rdev->on_write (rdev, wrlen, wrctx, STIO_NULL);
 | 
						return rdev->on_write (rdev, wrlen, wrctx, STIO_NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_evcb_sck_on_read_stateless (stio_dev_t* dev, const void* data, stio_len_t dlen, const stio_devadr_t* srcadr)
 | 
					static int dev_evcb_sck_on_read_stateless (stio_dev_t* dev, const void* data, stio_iolen_t dlen, const stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	return rdev->on_read (rdev, data, dlen, srcadr->ptr);
 | 
						return rdev->on_read (rdev, data, dlen, srcadr->ptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
 | 
					static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
						stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
 | 
				
			||||||
	return rdev->on_write (rdev, wrlen, wrctx, dstadr->ptr);
 | 
						return rdev->on_write (rdev, wrlen, wrctx, dstadr->ptr);
 | 
				
			||||||
@ -818,13 +824,13 @@ int stio_dev_sck_listen (stio_dev_sck_t* dev, stio_dev_sck_listen_t* info)
 | 
				
			|||||||
	return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_SCK_LISTEN, info);
 | 
						return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_SCK_LISTEN, info);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stio_dev_sck_write (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, void* wrctx, const stio_sckadr_t* dstadr)
 | 
					int stio_dev_sck_write (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, void* wrctx, const stio_sckadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_devadr_t devadr;
 | 
						stio_devadr_t devadr;
 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)dev, data, dlen, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
 | 
						return stio_dev_write ((stio_dev_t*)dev, data, dlen, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stio_dev_sck_timedwrite (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, const stio_ntime_t* tmout, void* wrctx, const stio_sckadr_t* dstadr)
 | 
					int stio_dev_sck_timedwrite (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_ntime_t* tmout, void* wrctx, const stio_sckadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_devadr_t devadr;
 | 
						stio_devadr_t devadr;
 | 
				
			||||||
	return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
 | 
						return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
 | 
				
			||||||
 | 
				
			|||||||
@ -103,12 +103,12 @@ typedef struct stio_dev_sck_t stio_dev_sck_t;
 | 
				
			|||||||
typedef int (*stio_dev_sck_on_read_t) (
 | 
					typedef int (*stio_dev_sck_on_read_t) (
 | 
				
			||||||
	stio_dev_sck_t*      dev,
 | 
						stio_dev_sck_t*      dev,
 | 
				
			||||||
	const void*          data,
 | 
						const void*          data,
 | 
				
			||||||
	stio_len_t           dlen,
 | 
						stio_iolen_t           dlen,
 | 
				
			||||||
	const stio_sckadr_t* srcadr
 | 
						const stio_sckadr_t* srcadr
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
typedef int (*stio_dev_sck_on_write_t) (
 | 
					typedef int (*stio_dev_sck_on_write_t) (
 | 
				
			||||||
	stio_dev_sck_t*      dev,
 | 
						stio_dev_sck_t*      dev,
 | 
				
			||||||
	stio_len_t           wrlen,
 | 
						stio_iolen_t           wrlen,
 | 
				
			||||||
	void*                wrctx,
 | 
						void*                wrctx,
 | 
				
			||||||
	const stio_sckadr_t* dstadr
 | 
						const stio_sckadr_t* dstadr
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
@ -145,8 +145,8 @@ struct stio_dev_sck_make_t
 | 
				
			|||||||
typedef struct stio_dev_sck_bind_t stio_dev_sck_bind_t;
 | 
					typedef struct stio_dev_sck_bind_t stio_dev_sck_bind_t;
 | 
				
			||||||
struct stio_dev_sck_bind_t
 | 
					struct stio_dev_sck_bind_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int opts; /* TODO: REUSEADDR , TRANSPARENT, etc  or someting?? */
 | 
					 | 
				
			||||||
	stio_sckadr_t addr;
 | 
						stio_sckadr_t addr;
 | 
				
			||||||
 | 
						/*int opts;*/ /* TODO: REUSEADDR , TRANSPARENT, etc  or someting?? */
 | 
				
			||||||
	/* TODO: add device name for BIND_TO_DEVICE */
 | 
						/* TODO: add device name for BIND_TO_DEVICE */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -178,6 +178,7 @@ struct stio_dev_sck_accept_t
 | 
				
			|||||||
struct stio_dev_sck_t
 | 
					struct stio_dev_sck_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	STIO_DEV_HEADERS;
 | 
						STIO_DEV_HEADERS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stio_dev_sck_type_t type;
 | 
						stio_dev_sck_type_t type;
 | 
				
			||||||
	stio_sckhnd_t sck;
 | 
						stio_sckhnd_t sck;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -231,6 +232,26 @@ STIO_EXPORT int stio_getsckadrinfo (
 | 
				
			|||||||
	stio_sckfam_t*       family
 | 
						stio_sckfam_t*       family
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stio_sckadr_initforip4 (
 | 
				
			||||||
 | 
						stio_sckadr_t* sckadr,
 | 
				
			||||||
 | 
						stio_uint16_t  port,
 | 
				
			||||||
 | 
						stio_ip4adr_t* ip4adr
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stio_sckadr_initforip6 (
 | 
				
			||||||
 | 
						stio_sckadr_t* sckadr,
 | 
				
			||||||
 | 
						stio_uint16_t  port,
 | 
				
			||||||
 | 
						stio_ip6adr_t* ip6adr
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stio_sckadr_initforeth (
 | 
				
			||||||
 | 
						stio_sckadr_t* sckadr,
 | 
				
			||||||
 | 
						int            ifindex,
 | 
				
			||||||
 | 
						stio_ethadr_t* ethadr
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STIO_EXPORT stio_dev_sck_t* stio_dev_sck_make (
 | 
					STIO_EXPORT stio_dev_sck_t* stio_dev_sck_make (
 | 
				
			||||||
@ -257,7 +278,7 @@ STIO_EXPORT int stio_dev_sck_listen (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_sck_write (
 | 
					STIO_EXPORT int stio_dev_sck_write (
 | 
				
			||||||
	stio_dev_sck_t*       dev,
 | 
						stio_dev_sck_t*       dev,
 | 
				
			||||||
	const void*           data,
 | 
						const void*           data,
 | 
				
			||||||
	stio_len_t            len,
 | 
						stio_iolen_t            len,
 | 
				
			||||||
	void*                 wrctx,
 | 
						void*                 wrctx,
 | 
				
			||||||
	const stio_sckadr_t*  dstadr
 | 
						const stio_sckadr_t*  dstadr
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
@ -265,7 +286,7 @@ STIO_EXPORT int stio_dev_sck_write (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_sck_timedwrite (
 | 
					STIO_EXPORT int stio_dev_sck_timedwrite (
 | 
				
			||||||
	stio_dev_sck_t*       dev,
 | 
						stio_dev_sck_t*       dev,
 | 
				
			||||||
	const void*           data,
 | 
						const void*           data,
 | 
				
			||||||
	stio_len_t            len,
 | 
						stio_iolen_t            len,
 | 
				
			||||||
	const stio_ntime_t*   tmout,
 | 
						const stio_ntime_t*   tmout,
 | 
				
			||||||
	void*                 wrctx,
 | 
						void*                 wrctx,
 | 
				
			||||||
	const stio_sckadr_t*  dstadr
 | 
						const stio_sckadr_t*  dstadr
 | 
				
			||||||
@ -285,12 +306,12 @@ static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
static STIO_INLINE int stio_dev_sck_write (stio_dev_sck_t* sck, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
					static STIO_INLINE int stio_dev_sck_write (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)sck, data, len, wrctx, STIO_NULL);
 | 
						return stio_dev_write ((stio_dev_t*)sck, data, len, wrctx, STIO_NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static STIO_INLINE int stio_dev_sck_timedwrite (stio_dev_sck_t* sck, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx)
 | 
					static STIO_INLINE int stio_dev_sck_timedwrite (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return stio_dev_timedwrite ((stio_dev_t*)sck, data, len, tmout, wrctx, STIO_NULL);
 | 
						return stio_dev_timedwrite ((stio_dev_t*)sck, data, len, tmout, wrctx, STIO_NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,537 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * $Id$
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
    Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
    modification, are permitted provided that the following conditions
 | 
					 | 
				
			||||||
    are met:
 | 
					 | 
				
			||||||
    1. Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
    2. Redistributions in binary form must reproduce the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer in the
 | 
					 | 
				
			||||||
       documentation and/or other materials provided with the distribution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
					 | 
				
			||||||
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
 | 
					 | 
				
			||||||
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
					 | 
				
			||||||
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
					 | 
				
			||||||
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
					 | 
				
			||||||
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
					 | 
				
			||||||
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
					 | 
				
			||||||
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					 | 
				
			||||||
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
					 | 
				
			||||||
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "stio-tcp.h"
 | 
					 | 
				
			||||||
#include "stio-prv.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_make (stio_dev_t* dev, void* ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	stio_dev_tcp_make_t* arg = (stio_dev_tcp_make_t*)ctx;
 | 
					 | 
				
			||||||
	stio_scklen_t len;
 | 
					 | 
				
			||||||
	stio_sckfam_t family;
 | 
					 | 
				
			||||||
	int iv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tcp->sck = stio_openasyncsck (dev->stio, family, SOCK_STREAM, 0);
 | 
					 | 
				
			||||||
	if (tcp->sck == STIO_SCKHND_INVALID) goto oops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO:
 | 
					 | 
				
			||||||
	setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...);
 | 
					 | 
				
			||||||
	 TRANSPARENT, ETC. 
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
	iv = 1;
 | 
					 | 
				
			||||||
	if (setsockopt (tcp->sck, SOL_SOCKET, SO_REUSEADDR, &iv, STIO_SIZEOF(iv)) == -1 ||
 | 
					 | 
				
			||||||
	    bind (tcp->sck, (struct sockaddr*)&arg->addr, len) == -1) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tcp->dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_OUT_QUEUED | STIO_DEV_CAPA_STREAM;
 | 
					 | 
				
			||||||
	tcp->on_write = arg->on_write;
 | 
					 | 
				
			||||||
	tcp->on_read = arg->on_read; 
 | 
					 | 
				
			||||||
	tcp->tmridx_connect = STIO_TMRIDX_INVALID;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
oops:
 | 
					 | 
				
			||||||
	if (tcp->sck != STIO_SCKHND_INVALID)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		stio_closeasyncsck (tcp->stio, tcp->sck);
 | 
					 | 
				
			||||||
		tcp->sck = STIO_SCKHND_INVALID;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_make_accepted (stio_dev_t* dev, void* ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tcp->sck = *sck;
 | 
					 | 
				
			||||||
	if (stio_makesckasync (dev->stio, tcp->sck) <= -1) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void tcp_kill (stio_dev_t* dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (tcp->state & (STIO_DEV_TCP_ACCEPTED | STIO_DEV_TCP_CONNECTED | STIO_DEV_TCP_CONNECTING | STIO_DEV_TCP_LISTENING))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (tcp->on_disconnect) tcp->on_disconnect (tcp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (tcp->tmridx_connect != STIO_TMRIDX_INVALID)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		stio_deltmrjob (dev->stio, tcp->tmridx_connect);
 | 
					 | 
				
			||||||
		STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (tcp->sck != STIO_SCKHND_INVALID) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		stio_closeasyncsck (tcp->stio, tcp->sck);
 | 
					 | 
				
			||||||
		tcp->sck = STIO_SCKHND_INVALID;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_syshnd_t tcp_getsyshnd (stio_dev_t* dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	return (stio_syshnd_t)tcp->sck;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_read (stio_dev_t* dev, void* buf, stio_len_t* len, void* src_addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	ssize_t x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	x = recv (tcp->sck, buf, *len, 0);
 | 
					 | 
				
			||||||
	if (x == -1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;  /* no data available */
 | 
					 | 
				
			||||||
		if (errno == EINTR) return 0;
 | 
					 | 
				
			||||||
		tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*len = x;
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_write (stio_dev_t* dev, const void* data, stio_len_t* len, const void* dest_addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	ssize_t x;
 | 
					 | 
				
			||||||
	int flags = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (*len <= 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/* it's a writing finish indicator. close the writing end of
 | 
					 | 
				
			||||||
		 * the socket, probably leaving it in the half-closed state */
 | 
					 | 
				
			||||||
		if (shutdown (tcp->sck, SHUT_WR) == -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* TODO: flags MSG_DONTROUTE, MSG_DONTWAIT, MSG_MORE, MSG_OOB, MSG_NOSIGNAL */
 | 
					 | 
				
			||||||
#if defined(MSG_NOSIGNAL)
 | 
					 | 
				
			||||||
	flags |= MSG_NOSIGNAL;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	x = sendto (tcp->sck, data, *len, flags, STIO_NULL, 0);
 | 
					 | 
				
			||||||
	if (x == -1) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;  /* no data can be written */
 | 
					 | 
				
			||||||
		if (errno == EINTR) return 0;
 | 
					 | 
				
			||||||
		tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*len = x;
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void tmr_connect_handle (stio_t* stio, const stio_ntime_t* now, stio_tmrjob_t* job)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (tcp->state & STIO_DEV_TCP_CONNECTING)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/* the state check for STIO_DEV_TCP_CONNECTING is actually redundant
 | 
					 | 
				
			||||||
		 * as it must not be fired  after it gets connected. the timer job 
 | 
					 | 
				
			||||||
		 * doesn't need to be deleted when it gets connected for this check 
 | 
					 | 
				
			||||||
		 * here. this libarary, however, deletes the job when it gets 
 | 
					 | 
				
			||||||
		 * connected. */
 | 
					 | 
				
			||||||
		stio_dev_tcp_halt (tcp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (cmd)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		case STIO_DEV_TCP_BIND:
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			stio_dev_tcp_bind_t* bnd = (stio_dev_tcp_bind_t*)arg;
 | 
					 | 
				
			||||||
			struct sockaddr* sa = (struct sockaddr*)&bnd->addr;
 | 
					 | 
				
			||||||
			stio_scklen_t sl;
 | 
					 | 
				
			||||||
			stio_sckfam_t fam;
 | 
					 | 
				
			||||||
			int x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (stio_getsckadrinfo (dev->stio, &bnd->addr, &sl, &fam) <= -1) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#if defined(_WIN32)
 | 
					 | 
				
			||||||
			/* TODO */
 | 
					 | 
				
			||||||
		#else
 | 
					 | 
				
			||||||
			/* the socket is already non-blocking */
 | 
					 | 
				
			||||||
			x = bind (tcp->sck, sa, sl);
 | 
					 | 
				
			||||||
			if (x == -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case STIO_DEV_TCP_CONNECT:
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			stio_dev_tcp_connect_t* conn = (stio_dev_tcp_connect_t*)arg;
 | 
					 | 
				
			||||||
			struct sockaddr* sa = (struct sockaddr*)&conn->addr;
 | 
					 | 
				
			||||||
			stio_scklen_t sl;
 | 
					 | 
				
			||||||
			int x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (sa->sa_family == AF_INET) sl = STIO_SIZEOF(struct sockaddr_in);
 | 
					 | 
				
			||||||
			else if (sa->sa_family == AF_INET6) sl = STIO_SIZEOF(struct sockaddr_in6);
 | 
					 | 
				
			||||||
			else 
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				dev->stio->errnum = STIO_EINVAL;
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#if defined(_WIN32)
 | 
					 | 
				
			||||||
			/* TODO */
 | 
					 | 
				
			||||||
		#else
 | 
					 | 
				
			||||||
			/* the socket is already non-blocking */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			x = connect (tcp->sck, sa, sl);
 | 
					 | 
				
			||||||
			if (x == -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (errno == EINPROGRESS || errno == EWOULDBLOCK)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_UPDATE, STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT) >= 0)
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						stio_tmrjob_t tmrjob;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						if (!stio_isnegtime(&conn->tmout))
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							STIO_MEMSET (&tmrjob, 0, STIO_SIZEOF(tmrjob));
 | 
					 | 
				
			||||||
							tmrjob.ctx = tcp;
 | 
					 | 
				
			||||||
							stio_gettime (&tmrjob.when);
 | 
					 | 
				
			||||||
							stio_addtime (&tmrjob.when, &conn->tmout, &tmrjob.when);
 | 
					 | 
				
			||||||
							tmrjob.handler = tmr_connect_handle;
 | 
					 | 
				
			||||||
							tmrjob.idxptr = &tcp->tmridx_connect;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
 | 
					 | 
				
			||||||
							tcp->tmridx_connect = stio_instmrjob (tcp->stio, &tmrjob);
 | 
					 | 
				
			||||||
							if (tcp->tmridx_connect == STIO_TMRIDX_INVALID)
 | 
					 | 
				
			||||||
							{
 | 
					 | 
				
			||||||
								stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_UPDATE, STIO_DEV_EVENT_IN);
 | 
					 | 
				
			||||||
								/* event manipulation failure can't be handled properly. so ignore it. 
 | 
					 | 
				
			||||||
								 * anyway, it's already in a failure condition */
 | 
					 | 
				
			||||||
								return -1;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						tcp->state |= STIO_DEV_TCP_CONNECTING;
 | 
					 | 
				
			||||||
						tcp->peeradr = conn->addr;
 | 
					 | 
				
			||||||
						tcp->on_connect = conn->on_connect;
 | 
					 | 
				
			||||||
						tcp->on_disconnect = conn->on_disconnect;
 | 
					 | 
				
			||||||
						return 0;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* connected immediately */
 | 
					 | 
				
			||||||
			tcp->state |= STIO_DEV_TCP_CONNECTED;
 | 
					 | 
				
			||||||
			tcp->peeradr = conn->addr;
 | 
					 | 
				
			||||||
			tcp->on_connect = conn->on_connect;
 | 
					 | 
				
			||||||
			tcp->on_disconnect = conn->on_disconnect;
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case STIO_DEV_TCP_LISTEN:
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			stio_dev_tcp_listen_t* lstn = (stio_dev_tcp_listen_t*)arg;
 | 
					 | 
				
			||||||
			int x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#if defined(_WIN32)
 | 
					 | 
				
			||||||
			/* TODO */
 | 
					 | 
				
			||||||
		#else
 | 
					 | 
				
			||||||
			x = listen (tcp->sck, lstn->backlogs);
 | 
					 | 
				
			||||||
			if (x == -1) 
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			tcp->state |= STIO_DEV_TCP_LISTENING;
 | 
					 | 
				
			||||||
			tcp->on_connect = lstn->on_connect;
 | 
					 | 
				
			||||||
			tcp->on_disconnect = lstn->on_disconnect;
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_dev_mth_t tcp_mth = 
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tcp_make,
 | 
					 | 
				
			||||||
	tcp_kill,
 | 
					 | 
				
			||||||
	tcp_getsyshnd,
 | 
					 | 
				
			||||||
	tcp_read,
 | 
					 | 
				
			||||||
	tcp_write,
 | 
					 | 
				
			||||||
	tcp_ioctl, 
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* accepted tcp socket */
 | 
					 | 
				
			||||||
static stio_dev_mth_t tcp_acc_mth =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tcp_make_accepted,
 | 
					 | 
				
			||||||
	tcp_kill,
 | 
					 | 
				
			||||||
	tcp_getsyshnd,
 | 
					 | 
				
			||||||
	tcp_read,
 | 
					 | 
				
			||||||
	tcp_write,
 | 
					 | 
				
			||||||
	tcp_ioctl
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ------------------------------------------------------------------------ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_ready (stio_dev_t* dev, int events)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
printf ("TCP READY...%p\n", dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_ERR)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		int errcode;
 | 
					 | 
				
			||||||
		stio_scklen_t len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		len = STIO_SIZEOF(errcode);
 | 
					 | 
				
			||||||
		if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* the error number is set to the socket error code.
 | 
					 | 
				
			||||||
			 * errno resulting from getsockopt() doesn't reflect the actual
 | 
					 | 
				
			||||||
			 * socket error. so errno is not used to set the error number.
 | 
					 | 
				
			||||||
			 * instead, the generic device error STIO_EDEVERRR is used */
 | 
					 | 
				
			||||||
			tcp->stio->errnum = STIO_EDEVERR;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			tcp->stio->errnum = stio_syserrtoerrnum (errcode);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (tcp->state & STIO_DEV_TCP_CONNECTING)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (events & STIO_DEV_EVENT_HUP)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* device hang-up */
 | 
					 | 
				
			||||||
			tcp->stio->errnum = STIO_EDEVHUP;
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* invalid event masks. generic device error */
 | 
					 | 
				
			||||||
			tcp->stio->errnum = STIO_EDEVERR;
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (events & STIO_DEV_EVENT_OUT)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			int errcode;
 | 
					 | 
				
			||||||
			stio_scklen_t len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			STIO_ASSERT (!(tcp->state & STIO_DEV_TCP_CONNECTED));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			len = STIO_SIZEOF(errcode);
 | 
					 | 
				
			||||||
			if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if (errcode == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				tcp->state &= ~STIO_DEV_TCP_CONNECTING;
 | 
					 | 
				
			||||||
				tcp->state |= STIO_DEV_TCP_CONNECTED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_RENEW, 0) <= -1) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (tcp->tmridx_connect != STIO_TMRIDX_INVALID)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					stio_deltmrjob (tcp->stio, tcp->tmridx_connect);
 | 
					 | 
				
			||||||
					STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (tcp->on_connect (tcp) <= -1) 
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n");
 | 
					 | 
				
			||||||
					return -1;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				/* still in progress */
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errcode);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0; /* success but don't invoke on_read() */ 
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (tcp->state & STIO_DEV_TCP_LISTENING)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (events & STIO_DEV_EVENT_HUP)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* device hang-up */
 | 
					 | 
				
			||||||
			tcp->stio->errnum = STIO_EDEVHUP;
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_OUT))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			tcp->stio->errnum = STIO_EDEVERR;
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (events & STIO_DEV_EVENT_IN)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			stio_sckhnd_t clisck;
 | 
					 | 
				
			||||||
			stio_sckadr_t peer;
 | 
					 | 
				
			||||||
			stio_scklen_t addrlen;
 | 
					 | 
				
			||||||
			stio_dev_tcp_t* clitcp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* this is a server(lisening) socket */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			addrlen = STIO_SIZEOF(peer);
 | 
					 | 
				
			||||||
			clisck = accept (tcp->sck, (struct sockaddr*)&peer, &addrlen);
 | 
					 | 
				
			||||||
			if (clisck == STIO_SCKHND_INVALID)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;
 | 
					 | 
				
			||||||
				if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				tcp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* use tcp->dev_size when instantiating a client tcp device
 | 
					 | 
				
			||||||
			 * instead of STIO_SIZEOF(stio_dev_tcp_t). therefore, the 
 | 
					 | 
				
			||||||
			 * extension area as big as that of the master tcp device
 | 
					 | 
				
			||||||
			 * is created in the client tcp device */
 | 
					 | 
				
			||||||
			clitcp = (stio_dev_tcp_t*)stio_makedev (tcp->stio, tcp->dev_size, &tcp_acc_mth, tcp->dev_evcb, &clisck); 
 | 
					 | 
				
			||||||
			if (!clitcp) 
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				close (clisck);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			clitcp->dev_capa |= STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_STREAM;
 | 
					 | 
				
			||||||
			clitcp->state |= STIO_DEV_TCP_ACCEPTED;
 | 
					 | 
				
			||||||
			clitcp->peeradr = peer;
 | 
					 | 
				
			||||||
			/*clitcp->parent = tcp;*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* inherit some event handlers from the parent.
 | 
					 | 
				
			||||||
			 * you can still change them inside the on_connect handler */
 | 
					 | 
				
			||||||
			clitcp->on_connect = tcp->on_connect;
 | 
					 | 
				
			||||||
			clitcp->on_disconnect = tcp->on_disconnect; 
 | 
					 | 
				
			||||||
			clitcp->on_write = tcp->on_write;
 | 
					 | 
				
			||||||
			clitcp->on_read = tcp->on_read;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			clitcp->tmridx_connect = STIO_TMRIDX_INVALID;
 | 
					 | 
				
			||||||
			if (clitcp->on_connect (clitcp) <= -1) stio_dev_tcp_halt (clitcp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return 0; /* success but don't invoke on_read() */ 
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (events & STIO_DEV_EVENT_HUP)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT)) 
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* probably half-open? */
 | 
					 | 
				
			||||||
			return 1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		tcp->stio->errnum = STIO_EDEVHUP;
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 1; /* the device is ok. carry on reading or writing */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	return tcp->on_read (tcp, data, len);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int tcp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
 | 
					 | 
				
			||||||
	return tcp->on_write (tcp, wrlen, wrctx);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_dev_evcb_t tcp_evcb =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tcp_ready,
 | 
					 | 
				
			||||||
	tcp_on_read,
 | 
					 | 
				
			||||||
	tcp_on_write
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stio_dev_tcp_t* stio_dev_tcp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_tcp_make_t* data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (stio_dev_tcp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_tcp_t) + xtnsize, &tcp_mth, &tcp_evcb, (void*)data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int stio_dev_tcp_bind (stio_dev_tcp_t* tcp, stio_dev_tcp_bind_t* bind)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_BIND, bind);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int stio_dev_tcp_connect (stio_dev_tcp_t* tcp, stio_dev_tcp_connect_t* conn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_CONNECT, conn);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int stio_dev_tcp_listen (stio_dev_tcp_t* tcp, stio_dev_tcp_listen_t* lstn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_LISTEN, lstn);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,186 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * $Id$
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
    Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
    modification, are permitted provided that the following conditions
 | 
					 | 
				
			||||||
    are met:
 | 
					 | 
				
			||||||
    1. Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
    2. Redistributions in binary form must reproduce the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer in the
 | 
					 | 
				
			||||||
       documentation and/or other materials provided with the distribution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
					 | 
				
			||||||
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
 | 
					 | 
				
			||||||
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
					 | 
				
			||||||
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
					 | 
				
			||||||
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
					 | 
				
			||||||
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
					 | 
				
			||||||
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
					 | 
				
			||||||
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					 | 
				
			||||||
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
					 | 
				
			||||||
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef _STIO_TCP_H_
 | 
					 | 
				
			||||||
#define _STIO_TCP_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stio.h>
 | 
					 | 
				
			||||||
#include <stio-sck.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum stio_dev_tcp_ioctl_cmd_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_BIND, 
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_CONNECT,
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_LISTEN
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef enum stio_dev_tcp_ioctl_cmd_t stio_dev_tcp_ioctl_cmd_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum stio_dev_tcp_state_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_CONNECTING = (1 << 0),
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_CONNECTED  = (1 << 1),
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_LISTENING  = (1 << 2),
 | 
					 | 
				
			||||||
	STIO_DEV_TCP_ACCEPTED   = (1 << 3)
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef enum stio_dev_tcp_state_t stio_dev_tcp_state_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_t stio_dev_tcp_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int (*stio_dev_tcp_on_connect_t) (stio_dev_tcp_t* dev);
 | 
					 | 
				
			||||||
typedef void (*stio_dev_tcp_on_disconnect_t) (stio_dev_tcp_t* dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int (*stio_dev_tcp_on_read_t) (stio_dev_tcp_t* dev, const void* data, stio_len_t len);
 | 
					 | 
				
			||||||
typedef int (*stio_dev_tcp_on_write_t) (stio_dev_tcp_t* dev, stio_len_t wrlen, void* wrctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_dev_tcp_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	STIO_DEV_HEADERS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stio_sckhnd_t sck;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* bitwised-ORed of #stio_dev_tcp_state_t enumerators */
 | 
					 | 
				
			||||||
	int state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* peer address - valid if one of the followings is set:
 | 
					 | 
				
			||||||
	 *  STIO_DEV_TCP_ACCEPTED
 | 
					 | 
				
			||||||
	 *  STIO_DEV_TCP_CONNECTED
 | 
					 | 
				
			||||||
	 *  STIO_DEV_TCP_CONNECTING */
 | 
					 | 
				
			||||||
	stio_sckadr_t peeradr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** return 0 on succes, -1 on failure/
 | 
					 | 
				
			||||||
	 *  called on a new tcp device for an accepted client or
 | 
					 | 
				
			||||||
	 *         on a tcp device conntected to a remote server */
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_connect_t on_connect;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_disconnect_t on_disconnect;
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_read_t on_read;
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_write_t on_write;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stio_tmridx_t tmridx_connect;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_make_t stio_dev_tcp_make_t;
 | 
					 | 
				
			||||||
struct stio_dev_tcp_make_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* TODO: options: REUSEADDR for binding?? */
 | 
					 | 
				
			||||||
	stio_sckadr_t addr; /* binding address. */
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_write_t on_write;
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_read_t on_read;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_bind_t stio_dev_tcp_bind_t;
 | 
					 | 
				
			||||||
struct stio_dev_tcp_bind_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int opts; /* TODO: REUSEADDR , TRANSPARENT, etc  or someting?? */
 | 
					 | 
				
			||||||
	stio_sckadr_t addr;
 | 
					 | 
				
			||||||
	/* TODO: add device name for BIND_TO_DEVICE */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_connect_t stio_dev_tcp_connect_t;
 | 
					 | 
				
			||||||
struct stio_dev_tcp_connect_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_sckadr_t addr;
 | 
					 | 
				
			||||||
	stio_ntime_t tmout; /* connect timeout */
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_connect_t on_connect;
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_disconnect_t on_disconnect;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t;
 | 
					 | 
				
			||||||
struct stio_dev_tcp_listen_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int backlogs;
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
 | 
					 | 
				
			||||||
	stio_dev_tcp_on_disconnect_t on_disconnect; /* should on_discconneted be part of on_accept_t??? */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_tcp_accept_t stio_dev_tcp_accept_t;
 | 
					 | 
				
			||||||
struct stio_dev_tcp_accept_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_syshnd_t   sck;
 | 
					 | 
				
			||||||
/* TODO: add timeout */
 | 
					 | 
				
			||||||
	stio_sckadr_t   peeradr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STIO_EXPORT  stio_dev_tcp_t* stio_dev_tcp_make (
 | 
					 | 
				
			||||||
	stio_t*                    stio,
 | 
					 | 
				
			||||||
	stio_size_t                xtnsize,
 | 
					 | 
				
			||||||
	const stio_dev_tcp_make_t* data
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STIO_EXPORT int stio_dev_tcp_bind (
 | 
					 | 
				
			||||||
	stio_dev_tcp_t*         tcp,
 | 
					 | 
				
			||||||
	stio_dev_tcp_bind_t*    bind
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STIO_EXPORT int stio_dev_tcp_connect (
 | 
					 | 
				
			||||||
	stio_dev_tcp_t*         tcp,
 | 
					 | 
				
			||||||
	stio_dev_tcp_connect_t* conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STIO_EXPORT int stio_dev_tcp_listen (
 | 
					 | 
				
			||||||
	stio_dev_tcp_t*         tcp,
 | 
					 | 
				
			||||||
	stio_dev_tcp_listen_t*  lstn
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(STIO_HAVE_INLINE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_tcp_read (stio_dev_tcp_t* tcp, int enabled)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_read ((stio_dev_t*)tcp, enabled);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_tcp_write (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, void* wrctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)tcp, data, len, wrctx, STIO_NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_tcp_timedwrite (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_timedwrite ((stio_dev_t*)tcp, data, len, tmout, wrctx, STIO_NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE void stio_dev_tcp_halt (stio_dev_tcp_t* tcp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_halt ((stio_dev_t*)tcp);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define stio_dev_tcp_read(tcp,enabled) stio_dev_read((stio_dev_t*)tcp, enabled)
 | 
					 | 
				
			||||||
#define stio_dev_tcp_write(tcp,data,len,wrctx) stio_dev_write((stio_dev_t*)tcp, data, len, wrctx, STIO_NULL)
 | 
					 | 
				
			||||||
#define stio_dev_tcp_timedwrite(tcp,data,len,tmout,wrctx) stio_dev_timedwrite((stio_dev_t*)tcp, data, len, tmout, wrctx, STIO_NULL)
 | 
					 | 
				
			||||||
#define stio_dev_tcp_halt(tcp) stio_dev_halt((stio_dev_t*)tcp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@ -1,189 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * $Id$
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
    Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
    modification, are permitted provided that the following conditions
 | 
					 | 
				
			||||||
    are met:
 | 
					 | 
				
			||||||
    1. Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
    2. Redistributions in binary form must reproduce the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer in the
 | 
					 | 
				
			||||||
       documentation and/or other materials provided with the distribution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
					 | 
				
			||||||
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
 | 
					 | 
				
			||||||
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
					 | 
				
			||||||
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
					 | 
				
			||||||
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
					 | 
				
			||||||
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
					 | 
				
			||||||
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
					 | 
				
			||||||
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					 | 
				
			||||||
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
					 | 
				
			||||||
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
#include "stio-udp.h"
 | 
					 | 
				
			||||||
#include "stio-prv.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_make (stio_dev_t* dev, void* ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
 | 
					 | 
				
			||||||
	stio_dev_udp_make_t* arg = (stio_dev_udp_make_t*)ctx;
 | 
					 | 
				
			||||||
	stio_scklen_t len;
 | 
					 | 
				
			||||||
	stio_sckfam_t family;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	udp->sck = stio_openasyncsck (dev->stio, family, SOCK_DGRAM, 0);
 | 
					 | 
				
			||||||
	if (udp->sck == STIO_SCKHND_INVALID) goto oops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* some socket options? */
 | 
					 | 
				
			||||||
	if (bind (udp->sck, (struct sockaddr*)&arg->addr, len) == -1) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		udp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	udp->on_write = arg->on_write;
 | 
					 | 
				
			||||||
	udp->on_read = arg->on_read;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
oops:
 | 
					 | 
				
			||||||
	if (udp->sck != STIO_SCKHND_INVALID)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		stio_closeasyncsck (udp->stio, udp->sck);
 | 
					 | 
				
			||||||
		udp->sck = STIO_SCKHND_INVALID;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void udp_kill (stio_dev_t* dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
 | 
					 | 
				
			||||||
	if (udp->sck != STIO_SCKHND_INVALID) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		stio_closeasyncsck (udp->stio, udp->sck);
 | 
					 | 
				
			||||||
		udp->sck = STIO_SCKHND_INVALID;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_syshnd_t udp_getsyshnd (stio_dev_t* dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
 | 
					 | 
				
			||||||
	return (stio_syshnd_t)udp->sck;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_read (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* adr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
 | 
					 | 
				
			||||||
	stio_scklen_t addrlen;
 | 
					 | 
				
			||||||
	int x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: udp_read need source address ... have to extend the send callback to accept the source address */
 | 
					 | 
				
			||||||
printf ("UDP RECVFROM...\n");
 | 
					 | 
				
			||||||
	addrlen = STIO_SIZEOF(udp->peeradr);
 | 
					 | 
				
			||||||
	x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peeradr, &addrlen);
 | 
					 | 
				
			||||||
	if (x <= -1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;  /* no data available */
 | 
					 | 
				
			||||||
		if (errno == EINTR) return 0;
 | 
					 | 
				
			||||||
		udp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*len = x;
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_write (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* adr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_udp_t* udp = (stio_dev_udp_t*)udp;
 | 
					 | 
				
			||||||
	ssize_t x;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
/* TODO: udp_write need target address ... have to extend the send callback to accept the target address */
 | 
					 | 
				
			||||||
	x = sendto (udp->sck, data, *len, skad, stio_getskadlen(skad));
 | 
					 | 
				
			||||||
	if (x <= -1) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;  /* no data can be written */
 | 
					 | 
				
			||||||
		if (errno == EINTR) return 0;
 | 
					 | 
				
			||||||
		udp->stio->errnum = stio_syserrtoerrnum(errno);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* for UDP, if the data chunk can't be written at one go, it's actually a failure */
 | 
					 | 
				
			||||||
	if (x != *len) return -1; /* TODO: can i hava an indicator for this in stio? */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*len = x;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_ioctl (stio_dev_t* dev, int cmd, void* arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ------------------------------------------------------------------------ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_dev_mth_t udp_mth = 
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	udp_make,
 | 
					 | 
				
			||||||
	udp_kill,
 | 
					 | 
				
			||||||
	udp_getsyshnd,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	udp_read,
 | 
					 | 
				
			||||||
	udp_write,
 | 
					 | 
				
			||||||
	udp_ioctl,     /* ioctl */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_ready (stio_dev_t* dev, int events)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
/* TODO: ... */
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_ERR) printf ("UDP READY ERROR.....\n");
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_HUP) printf ("UDP READY HANGUP.....\n");
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_PRI) printf ("UDP READY PRI.....\n");
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_IN) printf ("UDP READY IN.....\n");
 | 
					 | 
				
			||||||
	if (events & STIO_DEV_EVENT_OUT) printf ("UDP READY OUT.....\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
printf ("dATA received %d bytes\n", (int)len);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int udp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stio_dev_evcb_t udp_evcb =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	udp_ready,
 | 
					 | 
				
			||||||
	udp_on_read,
 | 
					 | 
				
			||||||
	udp_on_write
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stio_dev_udp_t* stio_dev_udp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_udp_make_t* data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (stio_dev_udp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_udp_t) + xtnsize, &udp_mth, &udp_evcb, (void*)data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@ -1,103 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * $Id$
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
    Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Redistribution and use in source and binary forms, with or without
 | 
					 | 
				
			||||||
    modification, are permitted provided that the following conditions
 | 
					 | 
				
			||||||
    are met:
 | 
					 | 
				
			||||||
    1. Redistributions of source code must retain the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer.
 | 
					 | 
				
			||||||
    2. Redistributions in binary form must reproduce the above copyright
 | 
					 | 
				
			||||||
       notice, this list of conditions and the following disclaimer in the
 | 
					 | 
				
			||||||
       documentation and/or other materials provided with the distribution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
					 | 
				
			||||||
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
 | 
					 | 
				
			||||||
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
					 | 
				
			||||||
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
					 | 
				
			||||||
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
					 | 
				
			||||||
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
					 | 
				
			||||||
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
					 | 
				
			||||||
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					 | 
				
			||||||
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
					 | 
				
			||||||
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef _STIO_UDP_H_
 | 
					 | 
				
			||||||
#define _STIO_UDP_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stio.h>
 | 
					 | 
				
			||||||
#include <stio-sck.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_udp_t stio_dev_udp_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int (*stio_dev_udp_on_read_t) (stio_dev_udp_t* dev, const void* data, stio_len_t len);
 | 
					 | 
				
			||||||
typedef int (*stio_dev_udp_on_write_t) (stio_dev_udp_t* dev, void* wrctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct stio_dev_udp_make_t stio_dev_udp_make_t;
 | 
					 | 
				
			||||||
struct stio_dev_udp_make_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* TODO: options: REUSEADDR for binding?? */
 | 
					 | 
				
			||||||
	stio_sckadr_t addr; /* binding address. */
 | 
					 | 
				
			||||||
	stio_dev_udp_on_write_t on_write;
 | 
					 | 
				
			||||||
	stio_dev_udp_on_read_t on_read;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct stio_dev_udp_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	STIO_DEV_HEADERS;
 | 
					 | 
				
			||||||
	stio_sckhnd_t sck;
 | 
					 | 
				
			||||||
	stio_sckadr_t peer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stio_dev_udp_on_write_t on_write;
 | 
					 | 
				
			||||||
	stio_dev_udp_on_read_t on_read;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STIO_EXPORT stio_dev_udp_t* stio_dev_udp_make (
 | 
					 | 
				
			||||||
	stio_t*                    stio,
 | 
					 | 
				
			||||||
	stio_size_t                xtnsize,
 | 
					 | 
				
			||||||
	const stio_dev_udp_make_t* data
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(STIO_HAVE_INLINE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_udp_read (stio_dev_udp_t* udp, int enabled)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_read ((stio_dev_t*)udp, enabled);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_udp_write (stio_dev_udp_t* udp, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)udp, data, len, wrctx, dstadr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_udp_timedwrite (stio_dev_udp_t* udp, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_timedwrite ((stio_dev_t*)udp, data, len, tmout, wrctx, dstadr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE void stio_dev_udp_halt (stio_dev_udp_t* udp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_halt ((stio_dev_t*)udp);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define stio_dev_udp_read(udp,enabled) stio_dev_read((stio_dev_t*)udp, enabled)
 | 
					 | 
				
			||||||
#define stio_dev_udp_write(udp,data,len,wrctx,dstadr) stio_dev_write((stio_dev_t*)udp, data, len, wrctx, dstadr)
 | 
					 | 
				
			||||||
#define stio_dev_udp_timedwrite(udp,data,len,tmout,wrctx,dstadr) stio_dev_timedwrite((stio_dev_t*)udp, data, len, tmout, wrctx, dstadr)
 | 
					 | 
				
			||||||
#define stio_dev_udp_halt(udp) stio_dev_halt((stio_dev_t*)udp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@ -177,7 +177,7 @@ printf ("has urgent data...\n");
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			stio_wq_t* q;
 | 
								stio_wq_t* q;
 | 
				
			||||||
			const stio_uint8_t* uptr;
 | 
								const stio_uint8_t* uptr;
 | 
				
			||||||
			stio_len_t urem, ulen;
 | 
								stio_iolen_t urem, ulen;
 | 
				
			||||||
			int x;
 | 
								int x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			q = STIO_WQ_HEAD(&dev->wq);
 | 
								q = STIO_WQ_HEAD(&dev->wq);
 | 
				
			||||||
@ -267,7 +267,7 @@ printf ("has urgent data...\n");
 | 
				
			|||||||
	if (dev && stio->revs[i].events & EPOLLIN)
 | 
						if (dev && stio->revs[i].events & EPOLLIN)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		stio_devadr_t srcadr;
 | 
							stio_devadr_t srcadr;
 | 
				
			||||||
		stio_len_t len;
 | 
							stio_iolen_t len;
 | 
				
			||||||
		int x;
 | 
							int x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* the devices are all non-blocking. read as much as possible
 | 
							/* the devices are all non-blocking. read as much as possible
 | 
				
			||||||
@ -516,6 +516,12 @@ stio_dev_t* stio_makedev (stio_t* stio, stio_size_t dev_size, stio_dev_mth_t* de
 | 
				
			|||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* the make callback must not change these fields */
 | 
				
			||||||
 | 
						STIO_ASSERT (dev->dev_mth == dev_mth);
 | 
				
			||||||
 | 
						STIO_ASSERT (dev->dev_evcb == dev_evcb);
 | 
				
			||||||
 | 
						STIO_ASSERT (dev->dev_prev == STIO_NULL);
 | 
				
			||||||
 | 
						STIO_ASSERT (dev->dev_next == STIO_NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set some internal capability bits according to the capabilities 
 | 
						/* set some internal capability bits according to the capabilities 
 | 
				
			||||||
	 * removed by the device making callback for convenience sake. */
 | 
						 * removed by the device making callback for convenience sake. */
 | 
				
			||||||
	if (!(dev->dev_capa & STIO_DEV_CAPA_IN)) dev->dev_capa |= STIO_DEV_CAPA_IN_CLOSED;
 | 
						if (!(dev->dev_capa & STIO_DEV_CAPA_IN)) dev->dev_capa |= STIO_DEV_CAPA_IN_CLOSED;
 | 
				
			||||||
@ -750,10 +756,10 @@ static void on_write_timeout (stio_t* stio, const stio_ntime_t* now, stio_tmrjob
 | 
				
			|||||||
	if (x <= -1) stio_dev_halt (dev);
 | 
						if (x <= -1) stio_dev_halt (dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __dev_write (stio_dev_t* dev, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
 | 
					static int __dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const stio_uint8_t* uptr;
 | 
						const stio_uint8_t* uptr;
 | 
				
			||||||
	stio_len_t urem, ulen;
 | 
						stio_iolen_t urem, ulen;
 | 
				
			||||||
	stio_wq_t* q;
 | 
						stio_wq_t* q;
 | 
				
			||||||
	int x;
 | 
						int x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -810,6 +816,7 @@ static int __dev_write (stio_dev_t* dev, const void* data, stio_len_t len, const
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ulen = urem;
 | 
							ulen = urem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		x = dev->dev_mth->write (dev, data, &ulen, dstadr);
 | 
							x = dev->dev_mth->write (dev, data, &ulen, dstadr);
 | 
				
			||||||
		if (x <= -1) return -1;
 | 
							if (x <= -1) return -1;
 | 
				
			||||||
		else if (x == 0) goto enqueue_data;
 | 
							else if (x == 0) goto enqueue_data;
 | 
				
			||||||
@ -894,12 +901,12 @@ enqueue_data:
 | 
				
			|||||||
	return 0; /* request pused to a write queue. */
 | 
						return 0; /* request pused to a write queue. */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stio_dev_write (stio_dev_t* dev, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
					int stio_dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __dev_write (dev, data, len, STIO_NULL, wrctx, dstadr);
 | 
						return __dev_write (dev, data, len, STIO_NULL, wrctx, dstadr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stio_dev_timedwrite (stio_dev_t* dev, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
 | 
					int stio_dev_timedwrite (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __dev_write (dev, data, len, tmout, wrctx, dstadr);
 | 
						return __dev_write (dev, data, len, tmout, wrctx, dstadr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ typedef struct stio_dev_mth_t stio_dev_mth_t;
 | 
				
			|||||||
typedef struct stio_dev_evcb_t stio_dev_evcb_t;
 | 
					typedef struct stio_dev_evcb_t stio_dev_evcb_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct stio_wq_t stio_wq_t;
 | 
					typedef struct stio_wq_t stio_wq_t;
 | 
				
			||||||
typedef stio_intptr_t stio_len_t; /* NOTE: this is a signed type */
 | 
					typedef stio_intptr_t stio_iolen_t; /* NOTE: this is a signed type */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum stio_errnum_t
 | 
					enum stio_errnum_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -143,10 +143,10 @@ struct stio_dev_mth_t
 | 
				
			|||||||
	/* return -1 on failure, 0 if no data is availble, 1 otherwise.
 | 
						/* return -1 on failure, 0 if no data is availble, 1 otherwise.
 | 
				
			||||||
	 * when returning 1, *len must be sent to the length of data read.
 | 
						 * when returning 1, *len must be sent to the length of data read.
 | 
				
			||||||
	 * if *len is set to 0, it's treated as EOF. */
 | 
						 * if *len is set to 0, it's treated as EOF. */
 | 
				
			||||||
	int           (*read)         (stio_dev_t* dev, void* data, stio_len_t* len, stio_devadr_t* srcadr);
 | 
						int           (*read)         (stio_dev_t* dev, void* data, stio_iolen_t* len, stio_devadr_t* srcadr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ------------------------------------------------------------------ */
 | 
						/* ------------------------------------------------------------------ */
 | 
				
			||||||
	int           (*write)        (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr);
 | 
						int           (*write)        (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ------------------------------------------------------------------ */
 | 
						/* ------------------------------------------------------------------ */
 | 
				
			||||||
	int           (*ioctl)        (stio_dev_t* dev, int cmd, void* arg);
 | 
						int           (*ioctl)        (stio_dev_t* dev, int cmd, void* arg);
 | 
				
			||||||
@ -163,13 +163,13 @@ struct stio_dev_evcb_t
 | 
				
			|||||||
	/* return -1 on failure, 0 or 1 on success.
 | 
						/* return -1 on failure, 0 or 1 on success.
 | 
				
			||||||
	 * when 0 is returned, the main loop stops the attempt to read more data.
 | 
						 * when 0 is returned, the main loop stops the attempt to read more data.
 | 
				
			||||||
	 * when 1 is returned, the main loop attempts to read more data without*/
 | 
						 * when 1 is returned, the main loop attempts to read more data without*/
 | 
				
			||||||
	int           (*on_read)      (stio_dev_t* dev, const void* data, stio_len_t len, const stio_devadr_t* srcadr);
 | 
						int           (*on_read)      (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* return -1 on failure, 0 on success. 
 | 
						/* return -1 on failure, 0 on success. 
 | 
				
			||||||
	 * wrlen is the length of data written. it is the length of the originally
 | 
						 * wrlen is the length of data written. it is the length of the originally
 | 
				
			||||||
	 * posted writing request for a stream device. For a non stream device, it
 | 
						 * posted writing request for a stream device. For a non stream device, it
 | 
				
			||||||
	 * may be shorter than the originally posted length. */
 | 
						 * may be shorter than the originally posted length. */
 | 
				
			||||||
	int           (*on_write)      (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr);
 | 
						int           (*on_write)      (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct stio_wq_t
 | 
					struct stio_wq_t
 | 
				
			||||||
@ -177,9 +177,9 @@ struct stio_wq_t
 | 
				
			|||||||
	stio_wq_t*     next;
 | 
						stio_wq_t*     next;
 | 
				
			||||||
	stio_wq_t*     prev;
 | 
						stio_wq_t*     prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stio_len_t     olen; /* original data length */
 | 
						stio_iolen_t     olen; /* original data length */
 | 
				
			||||||
	stio_uint8_t*  ptr;  /* pointer to data */
 | 
						stio_uint8_t*  ptr;  /* pointer to data */
 | 
				
			||||||
	stio_len_t     len;  /* remaining data length */
 | 
						stio_iolen_t     len;  /* remaining data length */
 | 
				
			||||||
	void*          ctx;
 | 
						void*          ctx;
 | 
				
			||||||
	stio_dev_t*    dev; /* back-pointer to the device */
 | 
						stio_dev_t*    dev; /* back-pointer to the device */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -286,6 +286,86 @@ enum stio_dev_event_t
 | 
				
			|||||||
typedef enum stio_dev_event_t stio_dev_event_t;
 | 
					typedef enum stio_dev_event_t stio_dev_event_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					/* TOOD: move these to a separte file */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STIO_ETHHDR_PROTO_IP4 0x0800
 | 
				
			||||||
 | 
					#define STIO_ETHHDR_PROTO_ARP 0x0806
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STIO_ARPHDR_OPCODE_REQUEST 1
 | 
				
			||||||
 | 
					#define STIO_ARPHDR_OPCODE_REPLY   2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STIO_ARPHDR_HTYPE_ETH 0x0001
 | 
				
			||||||
 | 
					#define STIO_ARPHDR_PTYPE_IP4 0x0800
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STIO_ETHADR_LEN 6
 | 
				
			||||||
 | 
					#define STIO_IP4ADR_LEN 4
 | 
				
			||||||
 | 
					#define STIO_IP6ADR_LEN 16 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma pack(push)
 | 
				
			||||||
 | 
					#pragma pack(1)
 | 
				
			||||||
 | 
					struct stio_ethadr_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint8_t v[STIO_ETHADR_LEN]; 
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_ethadr_t stio_ethadr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stio_ip4adr_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint8_t v[STIO_IP4ADR_LEN];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_ip4adr_t stio_ip4adr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stio_ip6adr_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint8_t v[STIO_IP6ADR_LEN]; 
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_ip6adr_t stio_ip6adr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stio_ethhdr_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint8_t  dest[STIO_ETHADR_LEN];
 | 
				
			||||||
 | 
						stio_uint8_t  source[STIO_ETHADR_LEN];
 | 
				
			||||||
 | 
						stio_uint16_t proto;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_ethhdr_t stio_ethhdr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stio_arphdr_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint16_t htype;   /* hardware type (ethernet: 0x0001) */
 | 
				
			||||||
 | 
						stio_uint16_t ptype;   /* protocol type (ipv4: 0x0800) */
 | 
				
			||||||
 | 
						stio_uint8_t  hlen;    /* hardware address length (ethernet: 6) */
 | 
				
			||||||
 | 
						stio_uint8_t  plen;    /* protocol address length (ipv4 :4) */
 | 
				
			||||||
 | 
						stio_uint16_t opcode;  /* operation code */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_arphdr_t stio_arphdr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* arp payload for ipv4 over ethernet */
 | 
				
			||||||
 | 
					struct stio_etharp_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_uint8_t sha[STIO_ETHADR_LEN];   /* source hardware address */
 | 
				
			||||||
 | 
						stio_uint8_t spa[STIO_IP4ADR_LEN];   /* source protocol address */
 | 
				
			||||||
 | 
						stio_uint8_t tha[STIO_ETHADR_LEN];   /* target hardware address */
 | 
				
			||||||
 | 
						stio_uint8_t tpa[STIO_IP4ADR_LEN];   /* target protocol address */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_etharp_t stio_etharp_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stio_etharp_pkt_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_ethhdr_t ethhdr;
 | 
				
			||||||
 | 
						stio_arphdr_t arphdr;
 | 
				
			||||||
 | 
						stio_etharp_t arppld;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
 | 
				
			||||||
 | 
					#pragma pack(pop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -366,7 +446,7 @@ STIO_EXPORT int stio_dev_read (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_write (
 | 
					STIO_EXPORT int stio_dev_write (
 | 
				
			||||||
	stio_dev_t*         dev,
 | 
						stio_dev_t*         dev,
 | 
				
			||||||
	const void*         data,
 | 
						const void*         data,
 | 
				
			||||||
	stio_len_t          len,
 | 
						stio_iolen_t          len,
 | 
				
			||||||
	void*               wrctx,
 | 
						void*               wrctx,
 | 
				
			||||||
	const stio_devadr_t*   dstadr
 | 
						const stio_devadr_t*   dstadr
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
@ -375,7 +455,7 @@ STIO_EXPORT int stio_dev_write (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_timedwrite (
 | 
					STIO_EXPORT int stio_dev_timedwrite (
 | 
				
			||||||
	stio_dev_t*         dev,
 | 
						stio_dev_t*         dev,
 | 
				
			||||||
	const void*         data,
 | 
						const void*         data,
 | 
				
			||||||
	stio_len_t          len,
 | 
						stio_iolen_t          len,
 | 
				
			||||||
	const stio_ntime_t* tmout,
 | 
						const stio_ntime_t* tmout,
 | 
				
			||||||
	void*               wrctx,
 | 
						void*               wrctx,
 | 
				
			||||||
	const stio_devadr_t*   dstadr
 | 
						const stio_devadr_t*   dstadr
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user