From e2b99ed2a373302f1aea937d5f387c4f2343d243 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 23 Mar 2016 13:54:15 +0000 Subject: [PATCH] added skeleton to support arp --- stio/lib/Makefile.am | 4 +- stio/lib/Makefile.in | 14 +++- stio/lib/main.c | 34 +++++++- stio/lib/stio-arp.c | 181 +++++++++++++++++++++++++++++++++++++++++++ stio/lib/stio-arp.h | 69 +++++++++++++++++ stio/lib/stio-sck.c | 10 ++- stio/lib/stio-sck.h | 3 +- stio/lib/stio-tcp.c | 2 +- stio/lib/stio-tmr.c | 2 +- stio/lib/stio-udp.c | 2 +- 10 files changed, 309 insertions(+), 12 deletions(-) create mode 100644 stio/lib/stio-arp.c create mode 100644 stio/lib/stio-arp.h diff --git a/stio/lib/Makefile.am b/stio/lib/Makefile.am index 2b9713b..9c76f7e 100644 --- a/stio/lib/Makefile.am +++ b/stio/lib/Makefile.am @@ -26,6 +26,7 @@ pkginclude_HEADERS = \ stio-sck.h \ stio-tcp.h \ stio-udp.h \ + stio-arp.h \ stio.h pkglib_LTLIBRARIES = libstio.la @@ -37,7 +38,8 @@ libstio_la_SOURCES = \ stio-tcp.c \ stio-tim.c \ stio-tmr.c \ - stio-udp.c + stio-udp.c \ + stio-arp.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 afcac3e..93c0e65 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-udp.lo libstio_la-stio-arp.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,6 +384,7 @@ pkginclude_HEADERS = \ stio-sck.h \ stio-tcp.h \ stio-udp.h \ + stio-arp.h \ stio.h pkglib_LTLIBRARIES = libstio.la @@ -395,7 +396,8 @@ libstio_la_SOURCES = \ stio-tcp.c \ stio-tim.c \ stio-tmr.c \ - stio-udp.c + stio-udp.c \ + stio-arp.c libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) @@ -552,6 +554,7 @@ 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@ @@ -631,6 +634,13 @@ 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 3d9f40e..5ff8e01 100644 --- a/stio/lib/main.c +++ b/stio/lib/main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ #include #include +/* ========================================================================= */ + struct mmgr_stat_t { stio_size_t total_count; @@ -79,6 +82,8 @@ static stio_mmgr_t mmgr = &mmgr_stat }; +/* ========================================================================= */ + struct tcp_server_t { int tally; @@ -181,9 +186,24 @@ printf ("DISABLING READING..............................\n"); stio_dev_tcp_read (tcp, 0); return 0; -/* return 1; let the main loop to read more greedily without consulint the multiplexer */ +/* return 1; let the main loop to read more greedily without consulting the multiplexer */ } +/* ========================================================================= */ + +static int arp_on_read (stio_dev_arp_t* arp, const void* buf, stio_len_t len, stio_sckadr_t* ) +{ + return 0; +} + +static int arp_on_write (stio_dev_arp_t* arp, stio_len_t wrlen, void* wrctx) +{ + return 0; +} + + +/* ========================================================================= */ + static stio_t* g_stio; static void handle_signal (int sig) @@ -196,12 +216,14 @@ int main () stio_t* stio; stio_dev_udp_t* udp; + stio_dev_arp_t* arp; stio_dev_tcp_t* tcp[2]; struct sockaddr_in sin; struct sigaction sigact; stio_dev_tcp_connect_t tcp_conn; stio_dev_tcp_listen_t tcp_lstn; stio_dev_tcp_make_t tcp_make; + stio_dev_arp_make_t arp_make; tcp_server_t* ts; stio = stio_open (&mmgr, 0, 512, STIO_NULL); @@ -294,6 +316,16 @@ int main () } + memset (&arp_make, 0, STIO_SIZEOF(arp_make)); + arp_make.on_write = arp_on_write; + arp_make.on_read = arp_on_read; + arp = stio_dev_arp_make (stio, 0, &arp_make); + if (!arp) + { + printf ("Cannot make arp\n"); + goto oops; + } + stio_loop (stio); g_stio = STIO_NULL; diff --git a/stio/lib/stio-arp.c b/stio/lib/stio-arp.c new file mode 100644 index 0000000..4424d8a --- /dev/null +++ b/stio/lib/stio-arp.c @@ -0,0 +1,181 @@ +/* + * $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-arp.h" +#include "stio-prv.h" + +#include +#include +#include +#include +#include + +/* ======================================================================== */ + +static int arp_make (stio_dev_t* dev, void* ctx) +{ + stio_dev_arp_t* arp = (stio_dev_arp_t*)dev; + stio_dev_arp_make_t* arg = (stio_dev_arp_make_t*)ctx; + + arp->sck = stio_openasyncsck (dev->stio, PF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); + if (arp->sck == STIO_SCKHND_INVALID) goto oops; + + arp->on_write = arg->on_write; + arp->on_read = arg->on_read; + return 0; + +oops: + if (arp->sck != STIO_SCKHND_INVALID) + { + stio_closeasyncsck (arp->stio, arp->sck); + arp->sck = STIO_SCKHND_INVALID; + } + return -1; +} + +static void arp_kill (stio_dev_t* dev) +{ + stio_dev_arp_t* arp = (stio_dev_arp_t*)dev; + if (arp->sck != STIO_SCKHND_INVALID) + { + stio_closeasyncsck (arp->stio, arp->sck); + arp->sck = STIO_SCKHND_INVALID; + } +} + +static stio_syshnd_t arp_getsyshnd (stio_dev_t* dev) +{ + stio_dev_arp_t* arp = (stio_dev_arp_t*)dev; + return (stio_syshnd_t)arp->sck; +} + +static int arp_read (stio_dev_t* dev, void* buf, stio_len_t* len) +{ + stio_dev_arp_t* arp = (stio_dev_arp_t*)dev; + stio_scklen_t addrlen; + int x; + + struct sockaddr_ll from; + +/* TODO: arp_read need source address ... have to extend the send callback to accept the source address */ +printf ("ARP RECVFROM...\n"); + addrlen = STIO_SIZEOF(from); + x = recvfrom (arp->sck, buf, *len, 0, (struct sockaddr*)&from, &addrlen); + if (x <= -1) + { + if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */ + if (errno == EINTR) return 0; + arp->stio->errnum = stio_syserrtoerrnum(errno); + return -1; + } + + *len = x; + return 1; +} + +static int arp_write (stio_dev_t* dev, const void* data, stio_len_t* len) +{ + stio_dev_arp_t* arp = (stio_dev_arp_t*)arp; + ssize_t x; + +#if 0 +/* TODO: arp_write need target address ... have to extend the send callback to accept the target address */ + x = sendto (arp->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; + arp->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 arp_ioctl (stio_dev_t* dev, int cmd, void* arg) +{ + return 0; +} + +static stio_dev_mth_t arp_mth = +{ + arp_make, + arp_kill, + arp_getsyshnd, + + arp_read, + arp_write, + arp_ioctl, /* ioctl */ +}; + + +/* ======================================================================== */ + +static int arp_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 arp_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 arp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx) +{ + return 0; + +} + +static stio_dev_evcb_t arp_evcb = +{ + arp_ready, + arp_on_read, + arp_on_write +}; + +/* ======================================================================== */ + +stio_dev_arp_t* stio_dev_arp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_arp_make_t* data) +{ + return (stio_dev_arp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_arp_t) + xtnsize, &arp_mth, &arp_evcb, (void*)data); +} diff --git a/stio/lib/stio-arp.h b/stio/lib/stio-arp.h new file mode 100644 index 0000000..b9f2900 --- /dev/null +++ b/stio/lib/stio-arp.h @@ -0,0 +1,69 @@ +/* + * $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_ARP_H_ +#define _STIO_ARP_H_ + +#include +#include + +typedef struct stio_dev_arp_t stio_dev_arp_t; + +typedef int (*stio_dev_arp_on_read_t) (stio_dev_arp_t* dev, const void* data, stio_len_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; +struct stio_dev_arp_make_t +{ + stio_dev_arp_on_write_t on_write; + stio_dev_arp_on_read_t on_read; +}; + +struct stio_dev_arp_t +{ + STIO_DEV_HEADERS; + stio_sckhnd_t sck; + + stio_dev_arp_on_write_t on_write; + stio_dev_arp_on_read_t on_read; +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +STIO_EXPORT stio_dev_arp_t* stio_dev_arp_make ( + stio_t* stio, + stio_size_t xtnsize, + const stio_dev_arp_make_t* data +); + +#ifdef __cplusplus +extern "C" { +#endif + +#endif diff --git a/stio/lib/stio-sck.c b/stio/lib/stio-sck.c index fdf5240..3e44fd7 100644 --- a/stio/lib/stio-sck.c +++ b/stio/lib/stio-sck.c @@ -57,22 +57,22 @@ int stio_makesckasync (stio_t* stio, stio_sckhnd_t sck) return stio_makesyshndasync (stio, (stio_syshnd_t)sck); } -stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type) +stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type, int proto) { stio_sckhnd_t sck; #if defined(_WIN32) - sck = WSASocket (domain, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED /*| WSA_FLAG_NO_HANDLE_INHERIT*/); + sck = WSASocket (domain, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED /*| WSA_FLAG_NO_HANDLE_INHERIT*/); if (sck == STIO_SCKHND_INVALID) { /* stio_seterrnum (dev->stio, STIO_ESYSERR); or translate errno to stio errnum */ return STIO_SCKHND_INVALID; } #else - sck = socket (domain, type, 0); /* NO CLOEXEC or somethign */ + sck = socket (domain, type, proto); if (sck == STIO_SCKHND_INVALID) { - /* stio_seterrnum (dev->stio, STIO_ESYSERR); or translate errno to stio errnum */ + stio->errnum = stio_syserrtoerrnum(errno); return STIO_SCKHND_INVALID; } @@ -81,6 +81,8 @@ stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type) close (sck); return STIO_SCKHND_INVALID; } + + /* TODO: set CLOEXEC if it's defined */ #endif return sck; diff --git a/stio/lib/stio-sck.h b/stio/lib/stio-sck.h index 58318a6..435cc0b 100644 --- a/stio/lib/stio-sck.h +++ b/stio/lib/stio-sck.h @@ -80,7 +80,8 @@ extern "C" { STIO_EXPORT stio_sckhnd_t stio_openasyncsck ( stio_t* stio, int domain, - int type + int type, + int proto ); STIO_EXPORT void stio_closeasyncsck ( diff --git a/stio/lib/stio-tcp.c b/stio/lib/stio-tcp.c index 47967f8..b93f3cb 100644 --- a/stio/lib/stio-tcp.c +++ b/stio/lib/stio-tcp.c @@ -44,7 +44,7 @@ static int tcp_make (stio_dev_t* dev, void* ctx) if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1; - tcp->sck = stio_openasyncsck (dev->stio, family, SOCK_STREAM); + tcp->sck = stio_openasyncsck (dev->stio, family, SOCK_STREAM, 0); if (tcp->sck == STIO_SCKHND_INVALID) goto oops; /* TODO: diff --git a/stio/lib/stio-tmr.c b/stio/lib/stio-tmr.c index e429f60..4a7b142 100644 --- a/stio/lib/stio-tmr.c +++ b/stio/lib/stio-tmr.c @@ -94,7 +94,7 @@ static stio_tmridx_t sift_down (stio_t* stio, stio_tmridx_t index, int notify) { stio_size_t base = stio->tmr.size / 2; - if (index < base) /* at least 1 child is under the 'index' positmrn */ + if (index < base) /* at least 1 child is under the 'index' position */ { stio_tmrjob_t item; #if defined(STIO_USE_TMRJOB_IDXPTR) diff --git a/stio/lib/stio-udp.c b/stio/lib/stio-udp.c index 119417c..fec4836 100644 --- a/stio/lib/stio-udp.c +++ b/stio/lib/stio-udp.c @@ -43,7 +43,7 @@ static int udp_make (stio_dev_t* dev, void* ctx) if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1; - udp->sck = stio_openasyncsck (dev->stio, family, SOCK_DGRAM); + udp->sck = stio_openasyncsck (dev->stio, family, SOCK_DGRAM, 0); if (udp->sck == STIO_SCKHND_INVALID) goto oops; /* some socket options? */