diff --git a/stio/lib/Makefile.am b/stio/lib/Makefile.am index 9c76f7e..3b9bc14 100644 --- a/stio/lib/Makefile.am +++ b/stio/lib/Makefile.am @@ -24,9 +24,6 @@ pkginclude_HEADERS = \ stio-cmn.h \ stio-pro.h \ stio-sck.h \ - stio-tcp.h \ - stio-udp.h \ - stio-arp.h \ stio.h pkglib_LTLIBRARIES = libstio.la @@ -35,11 +32,8 @@ libstio_la_SOURCES = \ stio.c \ stio-pro.c \ stio-sck.c \ - stio-tcp.c \ stio-tim.c \ - stio-tmr.c \ - stio-udp.c \ - stio-arp.c + stio-tmr.c libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) libstio_la_LIBADD = $(LIBADD_LIB_COMMON) diff --git a/stio/lib/Makefile.in b/stio/lib/Makefile.in index 93c0e65..afcac3e 100644 --- a/stio/lib/Makefile.in +++ b/stio/lib/Makefile.in @@ -132,7 +132,7 @@ libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) 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-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) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -384,7 +384,6 @@ pkginclude_HEADERS = \ stio-sck.h \ stio-tcp.h \ stio-udp.h \ - stio-arp.h \ stio.h pkglib_LTLIBRARIES = libstio.la @@ -396,8 +395,7 @@ libstio_la_SOURCES = \ stio-tcp.c \ stio-tim.c \ stio-tmr.c \ - stio-udp.c \ - stio-arp.c + stio-udp.c libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) @@ -554,7 +552,6 @@ mostlyclean-compile: distclean-compile: -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-sck.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@ @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 @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 diff --git a/stio/lib/main.c b/stio/lib/main.c index 054ea55..dd20629 100644 --- a/stio/lib/main.c +++ b/stio/lib/main.c @@ -26,9 +26,8 @@ #include +#include #include -#include -#include #include #include @@ -93,7 +92,7 @@ struct 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) { @@ -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); } } -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) @@ -131,7 +130,7 @@ printf ("device accepted client device... .asdfjkasdfkljasdlfkjasdj...\n"); 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; @@ -154,7 +153,7 @@ printf ("ENABLING READING..............................\n"); 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) { @@ -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; 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; } -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; } @@ -229,7 +228,7 @@ int main () stio_t* stio; stio_dev_sck_t* sck; stio_dev_sck_t* tcp[2]; - struct sockaddr_in sin; + struct sigaction sigact; stio_dev_sck_connect_t tcp_conn; stio_dev_sck_listen_t tcp_lstn; @@ -271,8 +270,8 @@ int main () memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); tcp_make.type = STIO_DEV_SCK_TCP4; - tcp_make.on_write = tcp_on_write; - tcp_make.on_read = tcp_on_read; + tcp_make.on_write = tcp_sck_on_write; + tcp_make.on_read = tcp_sck_on_read; tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make); if (!tcp[0]) { @@ -283,17 +282,15 @@ int main () ts = (tcp_server_t*)(tcp[0] + 1); 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)); - 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.on_connect = tcp_on_connect; - tcp_conn.on_disconnect = tcp_on_disconnect; + tcp_conn.on_connect = tcp_sck_on_connect; + tcp_conn.on_disconnect = tcp_sck_on_disconnect; if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1) { printf ("stio_dev_sck_connect() failed....\n"); @@ -301,8 +298,8 @@ int main () } memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); - tcp_make.on_write = tcp_on_write; - tcp_make.on_read = tcp_on_read; + tcp_make.on_write = tcp_sck_on_write; + tcp_make.on_read = tcp_sck_on_read; tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make); if (!tcp[1]) @@ -314,9 +311,7 @@ int main () ts->tally = 0; memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind)); - //memcpy (&tcp_bind.addr, &sin, STIO_SIZEOF(sin)); - ((struct sockaddr_in*)&tcp_bind.addr)->sin_family = AF_INET; - ((struct sockaddr_in*)&tcp_bind.addr)->sin_port = htons(1234); + stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL); if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1) { @@ -324,9 +319,10 @@ int main () goto oops; } + tcp_lstn.backlogs = 100; - tcp_lstn.on_connect = tcp_on_connect; - tcp_lstn.on_disconnect = tcp_on_disconnect; + tcp_lstn.on_connect = tcp_sck_on_connect; + tcp_lstn.on_disconnect = tcp_sck_on_disconnect; if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1) { 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)); sck_make.type = STIO_DEV_SCK_ARP; //sck_make.type = STIO_DEV_SCK_ARP_DGRAM; @@ -346,26 +348,14 @@ int main () goto oops; } -#if 1 -{ - stio_etharp_pkt_t etharp; - struct sockaddr_ll sll; + //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"); - 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)); 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.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); - if (stio_dev_sck_write (sck, ðarp, sizeof(etharp), NULL, &sll) <= -1) - //if (stio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &adr) <= -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) { printf ("CANNOT WRITE ARP...\n"); } diff --git a/stio/lib/stio-arp.c b/stio/lib/stio-arp.c index a32e6da..7a1c4a5 100644 --- a/stio/lib/stio-arp.c +++ b/stio/lib/stio-arp.c @@ -74,7 +74,7 @@ static stio_syshnd_t arp_getsyshnd (stio_dev_t* dev) 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_scklen_t addrlen; @@ -98,7 +98,7 @@ printf ("ARP RECVFROM...\n"); 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; ssize_t x; @@ -154,13 +154,13 @@ static int arp_ready (stio_dev_t* dev, int events) 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); 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; diff --git a/stio/lib/stio-arp.h b/stio/lib/stio-arp.h index 0f16438..61191bb 100644 --- a/stio/lib/stio-arp.h +++ b/stio/lib/stio-arp.h @@ -30,82 +30,9 @@ #include #include -#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 -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 struct stio_dev_arp_make_t stio_dev_arp_make_t; diff --git a/stio/lib/stio-pro.c b/stio/lib/stio-pro.c index 292bcd1..b8cbd5a 100644 --- a/stio/lib/stio-pro.c +++ b/stio/lib/stio-pro.c @@ -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; ssize_t x; @@ -152,7 +152,7 @@ static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len) 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; } @@ -205,7 +205,7 @@ printf ("PRO READY...%p\n", dev); 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; return pro->on_read (pro, data, len); @@ -235,7 +235,7 @@ void stio_dev_pro_kill (stio_dev_pro_t* pro) } #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); } diff --git a/stio/lib/stio-pro.h b/stio/lib/stio-pro.h index f52837c..3a5d107 100644 --- a/stio/lib/stio-pro.h +++ b/stio/lib/stio-pro.h @@ -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 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); struct stio_dev_pro_t @@ -100,7 +100,7 @@ STIO_EXPORT void stio_dev_pro_kill ( STIO_EXPORT int stio_dev_pro_write ( stio_dev_pro_t* pro, const void* data, - stio_len_t len, + stio_iolen_t len, void* wrctx ); diff --git a/stio/lib/stio-sck.c b/stio/lib/stio-sck.c index 7c4f7e8..dca6bda 100644 --- a/stio/lib/stio-sck.c +++ b/stio/lib/stio-sck.c @@ -116,18 +116,19 @@ int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t* 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; STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin)); sin->sin_family = AF_INET; 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; @@ -135,19 +136,23 @@ static void stio_initsckadrforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, st STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin)); sin->sin6_family = AF_INET; 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)); sll->sll_family = AF_PACKET; sll->sll_ifindex = ifindex; - sll->sll_halen = STIO_ETHADR_LEN; - STIO_MEMSET (sll->sll_addr, ethadr, STIO_ETHADR_LEN); + if (ethadr) + { + 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) { @@ -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; } + /* ========================================================================= */ #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_read = arg->on_read; rdev->type = arg->type; - rdev->tmridx_connect = STIO_TMRIDX_INVALID; + return 0; oops: @@ -288,7 +294,7 @@ static stio_syshnd_t dev_sck_getsyshnd (stio_dev_t* dev) 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; 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; } -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_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; 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; } -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; 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 */ } -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; 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; 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; 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; 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); } -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; 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; return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckadr_to_devadr(dev, dstadr, &devadr)); diff --git a/stio/lib/stio-sck.h b/stio/lib/stio-sck.h index 226e579..490e6f6 100644 --- a/stio/lib/stio-sck.h +++ b/stio/lib/stio-sck.h @@ -103,12 +103,12 @@ typedef struct stio_dev_sck_t stio_dev_sck_t; typedef int (*stio_dev_sck_on_read_t) ( stio_dev_sck_t* dev, const void* data, - stio_len_t dlen, + stio_iolen_t dlen, const stio_sckadr_t* srcadr ); typedef int (*stio_dev_sck_on_write_t) ( stio_dev_sck_t* dev, - stio_len_t wrlen, + stio_iolen_t wrlen, void* wrctx, 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; struct stio_dev_sck_bind_t { - int opts; /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */ stio_sckadr_t addr; + /*int opts;*/ /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */ /* TODO: add device name for BIND_TO_DEVICE */ }; @@ -178,6 +178,7 @@ struct stio_dev_sck_accept_t struct stio_dev_sck_t { STIO_DEV_HEADERS; + stio_dev_sck_type_t type; stio_sckhnd_t sck; @@ -231,6 +232,26 @@ STIO_EXPORT int stio_getsckadrinfo ( 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 ( @@ -257,7 +278,7 @@ STIO_EXPORT int stio_dev_sck_listen ( STIO_EXPORT int stio_dev_sck_write ( stio_dev_sck_t* dev, const void* data, - stio_len_t len, + stio_iolen_t len, void* wrctx, const stio_sckadr_t* dstadr ); @@ -265,7 +286,7 @@ STIO_EXPORT int stio_dev_sck_write ( STIO_EXPORT int stio_dev_sck_timedwrite ( stio_dev_sck_t* dev, const void* data, - stio_len_t len, + stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, 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); } -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); } diff --git a/stio/lib/stio-tcp.c b/stio/lib/stio-tcp.c deleted file mode 100644 index a47a8f7..0000000 --- a/stio/lib/stio-tcp.c +++ /dev/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 -#include -#include -#include -#include - -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); -} - diff --git a/stio/lib/stio-tcp.h b/stio/lib/stio-tcp.h deleted file mode 100644 index 3c2eb7c..0000000 --- a/stio/lib/stio-tcp.h +++ /dev/null @@ -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 -#include - -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 diff --git a/stio/lib/stio-udp.c b/stio/lib/stio-udp.c deleted file mode 100644 index f240fa6..0000000 --- a/stio/lib/stio-udp.c +++ /dev/null @@ -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 -#include -#include -#include - - -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 diff --git a/stio/lib/stio-udp.h b/stio/lib/stio-udp.h deleted file mode 100644 index c087806..0000000 --- a/stio/lib/stio-udp.h +++ /dev/null @@ -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 -#include - -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 diff --git a/stio/lib/stio.c b/stio/lib/stio.c index ec92598..74af7b9 100644 --- a/stio/lib/stio.c +++ b/stio/lib/stio.c @@ -177,7 +177,7 @@ printf ("has urgent data...\n"); { stio_wq_t* q; const stio_uint8_t* uptr; - stio_len_t urem, ulen; + stio_iolen_t urem, ulen; int x; q = STIO_WQ_HEAD(&dev->wq); @@ -267,7 +267,7 @@ printf ("has urgent data...\n"); if (dev && stio->revs[i].events & EPOLLIN) { stio_devadr_t srcadr; - stio_len_t len; + stio_iolen_t len; int x; /* 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; } + /* 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 * 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; @@ -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); } -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; - stio_len_t urem, ulen; + stio_iolen_t urem, ulen; stio_wq_t* q; int x; @@ -810,6 +816,7 @@ static int __dev_write (stio_dev_t* dev, const void* data, stio_len_t len, const else { ulen = urem; + x = dev->dev_mth->write (dev, data, &ulen, dstadr); if (x <= -1) return -1; else if (x == 0) goto enqueue_data; @@ -894,12 +901,12 @@ enqueue_data: 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); } -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); } diff --git a/stio/lib/stio.h b/stio/lib/stio.h index 564b040..64706ef 100644 --- a/stio/lib/stio.h +++ b/stio/lib/stio.h @@ -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_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 { @@ -143,10 +143,10 @@ struct stio_dev_mth_t /* 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. * 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); @@ -163,13 +163,13 @@ struct stio_dev_evcb_t /* return -1 on failure, 0 or 1 on success. * 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*/ - 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. * 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 * 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 @@ -177,9 +177,9 @@ struct stio_wq_t stio_wq_t* next; 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_len_t len; /* remaining data length */ + stio_iolen_t len; /* remaining data length */ void* ctx; 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; + + + +/* ========================================================================= */ +/* 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 extern "C" { #endif @@ -366,7 +446,7 @@ STIO_EXPORT int stio_dev_read ( STIO_EXPORT int stio_dev_write ( stio_dev_t* dev, const void* data, - stio_len_t len, + stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr ); @@ -375,7 +455,7 @@ STIO_EXPORT int stio_dev_write ( STIO_EXPORT int stio_dev_timedwrite ( stio_dev_t* dev, const void* data, - stio_len_t len, + stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr