added SSL to the listening socket
This commit is contained in:
parent
3ca7bcd549
commit
ec4bd54e53
@ -33,7 +33,8 @@ libstio_la_SOURCES = \
|
||||
stio-pro.c \
|
||||
stio-sck.c \
|
||||
stio-tim.c \
|
||||
stio-tmr.c
|
||||
stio-tmr.c \
|
||||
stio-utl.c
|
||||
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
|
||||
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
|
||||
libstio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
|
||||
|
@ -105,7 +105,7 @@ am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
|
||||
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
|
||||
libstio_la-stio-sck.lo libstio_la-stio-tim.lo \
|
||||
libstio_la-stio-tmr.lo
|
||||
libstio_la-stio-tmr.lo libstio_la-stio-utl.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@)
|
||||
@ -338,7 +338,8 @@ libstio_la_SOURCES = \
|
||||
stio-pro.c \
|
||||
stio-sck.c \
|
||||
stio-tim.c \
|
||||
stio-tmr.c
|
||||
stio-tmr.c \
|
||||
stio-utl.c
|
||||
|
||||
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
|
||||
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
|
||||
@ -491,6 +492,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-sck.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tim.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tmr.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-utl.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stio-main.Po@am__quote@
|
||||
|
||||
@ -550,6 +552,13 @@ libstio_la-stio-tmr.lo: stio-tmr.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-tmr.lo `test -f 'stio-tmr.c' || echo '$(srcdir)/'`stio-tmr.c
|
||||
|
||||
libstio_la-stio-utl.lo: stio-utl.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-utl.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-utl.Tpo -c -o libstio_la-stio-utl.lo `test -f 'stio-utl.c' || echo '$(srcdir)/'`stio-utl.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-utl.Tpo $(DEPDIR)/libstio_la-stio-utl.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-utl.c' object='libstio_la-stio-utl.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-utl.lo `test -f 'stio-utl.c' || echo '$(srcdir)/'`stio-utl.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
|
||||
|
@ -145,19 +145,34 @@ static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
|
||||
static int tcp_sck_on_connect (stio_dev_sck_t* tcp)
|
||||
{
|
||||
|
||||
stio_sckfam_t fam;
|
||||
stio_scklen_t len;
|
||||
stio_mchar_t buf1[128], buf2[128];
|
||||
|
||||
memset (buf1, 0, STIO_SIZEOF(buf1));
|
||||
memset (buf2, 0, STIO_SIZEOF(buf2));
|
||||
|
||||
stio_getsckaddrinfo (tcp->stio, &tcp->localaddr, &len, &fam);
|
||||
inet_ntop (fam, tcp->localaddr.data, buf1, STIO_COUNTOF(buf1));
|
||||
|
||||
stio_getsckaddrinfo (tcp->stio, &tcp->remoteaddr, &len, &fam);
|
||||
inet_ntop (fam, tcp->remoteaddr.data, buf2, STIO_COUNTOF(buf2));
|
||||
|
||||
if (tcp->state & STIO_DEV_SCK_CONNECTED)
|
||||
{
|
||||
printf ("device connected to a remote server... .asdfjkasdfkljasdlfkjasdj...\n");
|
||||
|
||||
printf ("device connected to a remote server... LOCAL %s:%d REMOTE %s:%d.", buf1, stio_getsckaddrport(&tcp->localaddr), buf2, stio_getsckaddrport(&tcp->remoteaddr));
|
||||
|
||||
}
|
||||
else if (tcp->state & STIO_DEV_SCK_ACCEPTED)
|
||||
{
|
||||
printf ("device accepted client device... .asdfjkasdfkljasdlfkjasdj...\n");
|
||||
printf ("device accepted client device... .LOCAL %s:%d REMOTE %s:%d\n", buf1, stio_getsckaddrport(&tcp->localaddr), buf2, stio_getsckaddrport(&tcp->remoteaddr));
|
||||
}
|
||||
|
||||
return stio_dev_sck_write (tcp, "hello", 5, STIO_NULL, STIO_NULL);
|
||||
}
|
||||
|
||||
static int tcp_sck_on_write (stio_dev_sck_t* tcp, stio_iolen_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_sckaddr_t* dstaddr)
|
||||
{
|
||||
tcp_server_t* ts;
|
||||
|
||||
@ -180,7 +195,7 @@ printf ("ENABLING READING..............................\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_sck_on_read (stio_dev_sck_t* tcp, const void* buf, stio_iolen_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_sckaddr_t* srcaddr)
|
||||
{
|
||||
if (len <= 0)
|
||||
{
|
||||
@ -217,10 +232,10 @@ printf ("DISABLING READING..............................\n");
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_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_sckaddr_t* srcaddr)
|
||||
{
|
||||
stio_etharp_pkt_t* eap;
|
||||
struct sockaddr_ll* sll = (struct sockaddr_ll*)srcadr;
|
||||
struct sockaddr_ll* sll = (struct sockaddr_ll*)srcaddr;
|
||||
|
||||
if (dlen < STIO_SIZEOF(*eap)) return 0; /* drop */
|
||||
|
||||
@ -234,7 +249,7 @@ static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
|
||||
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckaddr_t* dstaddr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -344,7 +359,7 @@ int main ()
|
||||
memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
|
||||
{
|
||||
in_addr_t ia = inet_addr("192.168.1.119");
|
||||
stio_sckadr_initforip4 (&tcp_conn.addr, 9999, (stio_ip4adr_t*)&ia);
|
||||
stio_sckaddr_initforip4 (&tcp_conn.remoteaddr, 9999, (stio_ip4addr_t*)&ia);
|
||||
}
|
||||
tcp_conn.tmout.sec = 5;
|
||||
tcp_conn.on_connect = tcp_sck_on_connect;
|
||||
@ -372,7 +387,7 @@ int main ()
|
||||
ts->tally = 0;
|
||||
|
||||
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
|
||||
stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL);
|
||||
stio_sckaddr_initforip4 (&tcp_bind.localaddr, 1234, STIO_NULL);
|
||||
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR;
|
||||
|
||||
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
|
||||
@ -408,32 +423,31 @@ int main ()
|
||||
ts->tally = 0;
|
||||
|
||||
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
|
||||
stio_sckadr_initforip4 (&tcp_bind.addr, 1235, STIO_NULL);
|
||||
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR | STIO_DEV_SCK_BIND_SECURE;
|
||||
tcp_bind.certfile = STIO_MT("stio.certfile");
|
||||
tcp_bind.keyfile = STIO_MT("stio.keyfile");
|
||||
stio_sckaddr_initforip4 (&tcp_bind.localaddr, 1235, STIO_NULL);
|
||||
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR | /*STIO_DEV_SCK_BIND_REUSEPORT |*/ STIO_DEV_SCK_BIND_SSL;
|
||||
tcp_bind.certfile = STIO_MT("localhost.crt");
|
||||
tcp_bind.keyfile = STIO_MT("localhost.key");
|
||||
|
||||
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
|
||||
if (stio_dev_sck_bind (tcp[2],&tcp_bind) <= -1)
|
||||
{
|
||||
printf ("stio_dev_sck_bind() failed....\n");
|
||||
goto oops;
|
||||
}
|
||||
|
||||
|
||||
tcp_lstn.backlogs = 100;
|
||||
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)
|
||||
if (stio_dev_sck_listen (tcp[2], &tcp_lstn) <= -1)
|
||||
{
|
||||
printf ("stio_dev_sck_listen() failed....\n");
|
||||
goto oops;
|
||||
}
|
||||
|
||||
|
||||
//stio_dev_sck_sendfile (tcp[2], fd, offset, count);
|
||||
#if 1
|
||||
{
|
||||
|
||||
stio_sckadr_t ethdst;
|
||||
stio_sckaddr_t ethdst;
|
||||
stio_etharp_pkt_t etharp;
|
||||
|
||||
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
|
||||
@ -448,26 +462,26 @@ int main ()
|
||||
goto oops;
|
||||
}
|
||||
|
||||
//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_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
|
||||
stio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
|
||||
|
||||
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, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADR_LEN);
|
||||
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
||||
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADDR_LEN);
|
||||
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADDR_LEN);
|
||||
etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
|
||||
|
||||
etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
|
||||
etharp.arphdr.ptype = STIO_CONST_HTON16(STIO_ARPHDR_PTYPE_IP4);
|
||||
etharp.arphdr.hlen = STIO_ETHADR_LEN;
|
||||
etharp.arphdr.plen = STIO_IP4ADR_LEN;
|
||||
etharp.arphdr.hlen = STIO_ETHADDR_LEN;
|
||||
etharp.arphdr.plen = STIO_IP4ADDR_LEN;
|
||||
etharp.arphdr.opcode = STIO_CONST_HTON16(STIO_ARPHDR_OPCODE_REQUEST);
|
||||
|
||||
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
|
||||
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
||||
|
||||
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, ðaddr) <= -1)
|
||||
{
|
||||
printf ("CANNOT WRITE ARP...\n");
|
||||
}
|
||||
|
@ -1,192 +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-arp.h"
|
||||
#include "stio-prv.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if 0
|
||||
/* ======================================================================== */
|
||||
|
||||
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_iolen_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_iolen_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_iolen_t len)
|
||||
{
|
||||
printf ("dATA received %d bytes\n", (int)len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arp_on_write (stio_dev_t* dev, stio_iolen_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);
|
||||
}
|
||||
|
||||
int stio_dev_arp_write (stio_dev_arp_t* dev, const stio_pkt_arp_t* arp, void* wrctx)
|
||||
{
|
||||
return stio_dev_write ((stio_dev_t*)dev, arp, STIO_SIZEOF(*arp), wrctx);
|
||||
}
|
||||
|
||||
int stio_dev_arp_timedwrite (stio_dev_arp_t* dev, const stio_pkt_arp_t* arp, const stio_ntime_t* tmout, void* wrctx)
|
||||
{
|
||||
return stio_dev_write ((stio_dev_t*)dev, arp, STIO_SIZEOF(*arp), wrctx);
|
||||
}
|
||||
#endif
|
@ -1,84 +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_ARP_H_
|
||||
#define _STIO_ARP_H_
|
||||
|
||||
#include <stio.h>
|
||||
#include <stio-sck.h>
|
||||
|
||||
|
||||
#if 0
|
||||
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;
|
||||
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;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
STIO_EXPORT stio_dev_arp_t* stio_dev_arp_make (
|
||||
stio_t* stio,
|
||||
stio_size_t xtnsize,
|
||||
const stio_dev_arp_make_t* data
|
||||
);
|
||||
|
||||
STIO_EXPORT int stio_dev_arp_write (
|
||||
stio_dev_arp_t* dev,
|
||||
const stio_pkt_arp_t* arp,
|
||||
void* wrctx
|
||||
);
|
||||
|
||||
STIO_EXPORT int stio_dev_arp_timedwrite (
|
||||
stio_dev_arp_t* dev,
|
||||
const stio_pkt_arp_t* arp,
|
||||
const stio_ntime_t* tmout,
|
||||
void* wrctx
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif
|
@ -540,7 +540,7 @@ static int dev_pro_kill_slave (stio_dev_t* dev, int force)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dev_pro_read_slave (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
|
||||
static int dev_pro_read_slave (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devaddr_t* srcaddr)
|
||||
{
|
||||
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
|
||||
ssize_t x;
|
||||
@ -548,7 +548,7 @@ static int dev_pro_read_slave (stio_dev_t* dev, void* buf, stio_iolen_t* len, st
|
||||
x = read (pro->pfd, buf, *len);
|
||||
if (x <= -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
||||
if (errno == EINTR) return 0;
|
||||
pro->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
@ -558,7 +558,7 @@ static int dev_pro_read_slave (stio_dev_t* dev, void* buf, stio_iolen_t* len, st
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_pro_write_slave (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
|
||||
static int dev_pro_write_slave (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devaddr_t* dstaddr)
|
||||
{
|
||||
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
|
||||
ssize_t x;
|
||||
@ -566,7 +566,7 @@ static int dev_pro_write_slave (stio_dev_t* dev, const void* data, stio_iolen_t*
|
||||
x = write (pro->pfd, data, *len);
|
||||
if (x <= -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||
if (errno == EINTR) return 0;
|
||||
pro->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
@ -662,14 +662,14 @@ static int pro_ready (stio_dev_t* dev, int events)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pro_on_read (stio_dev_t* dev, const void* data, stio_iolen_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_devaddr_t* srcaddr)
|
||||
{
|
||||
/* virtual device. no I/O */
|
||||
dev->stio->errnum = STIO_EINTERN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pro_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
|
||||
static int pro_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr)
|
||||
{
|
||||
/* virtual device. no I/O */
|
||||
dev->stio->errnum = STIO_EINTERN;
|
||||
@ -711,19 +711,19 @@ static int pro_ready_slave (stio_dev_t* dev, int events)
|
||||
}
|
||||
|
||||
|
||||
static int pro_on_read_slave_out (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr)
|
||||
static int pro_on_read_slave_out (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr)
|
||||
{
|
||||
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
|
||||
return pro->master->on_read (pro->master, data, len, STIO_DEV_PRO_OUT);
|
||||
}
|
||||
|
||||
static int pro_on_read_slave_err (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr)
|
||||
static int pro_on_read_slave_err (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr)
|
||||
{
|
||||
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
|
||||
return pro->master->on_read (pro->master, data, len, STIO_DEV_PRO_ERR);
|
||||
}
|
||||
|
||||
static int pro_on_write_slave (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
|
||||
static int pro_on_write_slave (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr)
|
||||
{
|
||||
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
|
||||
return pro->master->on_write (pro->master, wrlen, wrctx);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define STIO_MEMSET(dst,byte,count) memset(dst,byte,count)
|
||||
#define STIO_MEMCPY(dst,src,count) memcpy(dst,src,count)
|
||||
#define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count)
|
||||
#define STIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
|
||||
#define STIO_ASSERT assert
|
||||
|
||||
|
||||
|
@ -37,6 +37,22 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netpacket/packet.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <limits.h>
|
||||
# if defined(HAVE_LINUX_NETFILTER_IPV4_H)
|
||||
# include <linux/netfilter_ipv4.h> /* SO_ORIGINAL_DST */
|
||||
# endif
|
||||
# if !defined(SO_ORIGINAL_DST)
|
||||
# define SO_ORIGINAL_DST 80
|
||||
# endif
|
||||
# if !defined(IP_TRANSPARENT)
|
||||
# define IP_TRANSPARENT 19
|
||||
# endif
|
||||
# if !defined(SO_REUSEPORT)
|
||||
# define SO_REUSEPORT 15
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
|
||||
# include <openssl/ssl.h>
|
||||
# if defined(HAVE_OPENSSL_ERR_H)
|
||||
@ -48,11 +64,6 @@
|
||||
# define USE_SSL
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSL)
|
||||
# define HANDLE_TO_SSL(x) ((SSL*)(x))
|
||||
# define SSL_TO_HANDLE(x) ((qse_httpd_hnd_t)(x))
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
void stio_closeasyncsck (stio_t* stio, stio_sckhnd_t sck)
|
||||
{
|
||||
@ -117,7 +128,7 @@ stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type, int proto)
|
||||
return sck;
|
||||
}
|
||||
|
||||
int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t* len, stio_sckfam_t* family)
|
||||
int stio_getsckaddrinfo (stio_t* stio, const stio_sckaddr_t* addr, stio_scklen_t* len, stio_sckfam_t* family)
|
||||
{
|
||||
struct sockaddr* saddr = (struct sockaddr*)addr;
|
||||
|
||||
@ -135,70 +146,99 @@ int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t*
|
||||
|
||||
case AF_PACKET:
|
||||
if (len) *len = STIO_SIZEOF(struct sockaddr_ll);
|
||||
if (family) *family = AF_INET6;
|
||||
if (family) *family = AF_PACKET;
|
||||
return 0;
|
||||
|
||||
/* TODO: more address type */
|
||||
}
|
||||
|
||||
stio->errnum = STIO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
stio_uint16_t stio_getsckaddrport (const stio_sckaddr_t* addr)
|
||||
{
|
||||
struct sockaddr* saddr = (struct sockaddr*)addr;
|
||||
|
||||
switch (saddr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return stio_ntoh16(((struct sockaddr_in*)addr)->sin_port);
|
||||
|
||||
case AF_INET6:
|
||||
return stio_ntoh16(((struct sockaddr_in6*)addr)->sin6_port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int stio_equalsckaddrs (stio_t* stio, const stio_sckaddr_t* addr1, const stio_sckaddr_t* addr2)
|
||||
{
|
||||
stio_sckfam_t fam1, fam2;
|
||||
stio_scklen_t len1, len2;
|
||||
|
||||
stio_getsckaddrinfo (stio, addr1, &len1, &fam1);
|
||||
stio_getsckaddrinfo (stio, addr2, &len2, &fam2);
|
||||
return fam1 == fam2 && len1 == len2 && STIO_MEMCMP (addr1, addr2, len1) == 0;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
void stio_sckadr_initforip4 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip4adr_t* ip4adr)
|
||||
void stio_sckaddr_initforip4 (stio_sckaddr_t* sckaddr, stio_uint16_t port, stio_ip4addr_t* ip4addr)
|
||||
{
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sckadr;
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sckaddr;
|
||||
|
||||
STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(port);
|
||||
if (ip4adr) STIO_MEMCPY (&sin->sin_addr, ip4adr, STIO_IP4ADR_LEN);
|
||||
if (ip4addr) STIO_MEMCPY (&sin->sin_addr, ip4addr, STIO_IP4ADDR_LEN);
|
||||
}
|
||||
|
||||
void stio_sckadr_initforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip6adr_t* ip6adr)
|
||||
void stio_sckaddr_initforip6 (stio_sckaddr_t* sckaddr, stio_uint16_t port, stio_ip6addr_t* ip6addr)
|
||||
{
|
||||
struct sockaddr_in6* sin = (struct sockaddr_in6*)sckadr;
|
||||
struct sockaddr_in6* sin = (struct sockaddr_in6*)sckaddr;
|
||||
|
||||
/* TODO: include sin6_scope_id */
|
||||
STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
|
||||
sin->sin6_family = AF_INET;
|
||||
sin->sin6_port = htons(port);
|
||||
if (ip6adr) STIO_MEMCPY (&sin->sin6_addr, ip6adr, STIO_IP6ADR_LEN);
|
||||
if (ip6addr) STIO_MEMCPY (&sin->sin6_addr, ip6addr, STIO_IP6ADDR_LEN);
|
||||
}
|
||||
|
||||
void stio_sckadr_initforeth (stio_sckadr_t* sckadr, int ifindex, stio_ethadr_t* ethadr)
|
||||
void stio_sckaddr_initforeth (stio_sckaddr_t* sckaddr, int ifindex, stio_ethaddr_t* ethaddr)
|
||||
{
|
||||
struct sockaddr_ll* sll = (struct sockaddr_ll*)sckadr;
|
||||
struct sockaddr_ll* sll = (struct sockaddr_ll*)sckaddr;
|
||||
STIO_MEMSET (sll, 0, STIO_SIZEOF(*sll));
|
||||
sll->sll_family = AF_PACKET;
|
||||
sll->sll_ifindex = ifindex;
|
||||
if (ethadr)
|
||||
if (ethaddr)
|
||||
{
|
||||
sll->sll_halen = STIO_ETHADR_LEN;
|
||||
STIO_MEMCPY (sll->sll_addr, ethadr, STIO_ETHADR_LEN);
|
||||
sll->sll_halen = STIO_ETHADDR_LEN;
|
||||
STIO_MEMCPY (sll->sll_addr, ethaddr, STIO_ETHADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static stio_devadr_t* sckadr_to_devadr (stio_dev_sck_t* dev, const stio_sckadr_t* sckadr, stio_devadr_t* devadr)
|
||||
static stio_devaddr_t* sckaddr_to_devaddr (stio_dev_sck_t* dev, const stio_sckaddr_t* sckaddr, stio_devaddr_t* devaddr)
|
||||
{
|
||||
if (sckadr)
|
||||
if (sckaddr)
|
||||
{
|
||||
stio_scklen_t len;
|
||||
|
||||
stio_getsckadrinfo (dev->stio, sckadr, &len, STIO_NULL);
|
||||
devadr->ptr = (void*)sckadr;
|
||||
devadr->len = len;
|
||||
return devadr;
|
||||
stio_getsckaddrinfo (dev->stio, sckaddr, &len, STIO_NULL);
|
||||
devaddr->ptr = (void*)sckaddr;
|
||||
devaddr->len = len;
|
||||
return devaddr;
|
||||
}
|
||||
|
||||
return STIO_NULL;
|
||||
}
|
||||
|
||||
static STIO_INLINE stio_sckadr_t* devadr_to_sckadr (stio_dev_sck_t* dev, const stio_devadr_t* devadr, stio_sckadr_t* sckadr)
|
||||
static STIO_INLINE stio_sckaddr_t* devaddr_to_sckaddr (stio_dev_sck_t* dev, const stio_devaddr_t* devaddr, stio_sckaddr_t* sckaddr)
|
||||
{
|
||||
return (stio_sckadr_t*)devadr->ptr;
|
||||
return (stio_sckaddr_t*)devaddr->ptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -279,8 +319,22 @@ static int dev_sck_make_client (stio_dev_t* dev, void* ctx)
|
||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||
stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
|
||||
|
||||
/* nothing special is done here except setting the socket handle.
|
||||
* most of the initialization is done by the listening socket device
|
||||
* after a client socket has been created. */
|
||||
|
||||
rdev->sck = *sck;
|
||||
if (stio_makesckasync (rdev->stio, rdev->sck) <= -1) return -1;
|
||||
#if defined(FD_CLOEXEC)
|
||||
{
|
||||
int flags = fcntl (rdev->sck, F_GETFD, 0);
|
||||
if (fcntl (rdev->sck, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -308,20 +362,26 @@ static int dev_sck_kill (stio_dev_t* dev, int force)
|
||||
STIO_ASSERT (rdev->tmridx_connect == STIO_TMRIDX_INVALID);
|
||||
}
|
||||
|
||||
#if defined(USE_SSL)
|
||||
if (rdev->ssl)
|
||||
{
|
||||
SSL_shutdown ((SSL*)rdev->ssl); /* is this needed? */
|
||||
SSL_free ((SSL*)rdev->ssl);
|
||||
rdev->ssl = STIO_NULL;
|
||||
}
|
||||
if (!(rdev->state & (STIO_DEV_SCK_ACCEPTED | STIO_DEV_SCK_ACCEPTING_SSL)) && rdev->sslctx)
|
||||
{
|
||||
SSL_CTX_free ((SSL_CTX*)rdev->sslctx);
|
||||
rdev->sslctx = STIO_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rdev->sck != STIO_SCKHND_INVALID)
|
||||
{
|
||||
stio_closeasyncsck (rdev->stio, rdev->sck);
|
||||
rdev->sck = STIO_SCKHND_INVALID;
|
||||
}
|
||||
|
||||
#if defined(USE_SSL)
|
||||
if (rdev->secure_ctx)
|
||||
{
|
||||
SSL_CTX_free ((SSL_CTX*)rdev->secure_ctx);
|
||||
rdev->secure_ctx = STIO_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -331,93 +391,153 @@ 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_iolen_t* len, stio_devadr_t* srcadr)
|
||||
{
|
||||
stio_dev_sck_t* tcp = (stio_dev_sck_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 dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
|
||||
static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devaddr_t* srcaddr)
|
||||
{
|
||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||
stio_scklen_t srcadrlen;
|
||||
ssize_t x;
|
||||
|
||||
srcadrlen = STIO_SIZEOF(rdev->peeradr);
|
||||
x = recvfrom (rdev->sck, buf, *len, 0, (struct sockaddr*)&rdev->peeradr, &srcadrlen);
|
||||
if (x <= -1)
|
||||
#if defined(USE_SSL)
|
||||
if (rdev->ssl)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */
|
||||
if (errno == EINTR) return 0;
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
int x;
|
||||
|
||||
srcadr->ptr = &rdev->peeradr;
|
||||
srcadr->len = srcadrlen;
|
||||
|
||||
*len = x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
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 (rdev->sck, SHUT_WR) == -1)
|
||||
x = SSL_read ((SSL*)rdev->ssl, buf, *len);
|
||||
if (x <= -1)
|
||||
{
|
||||
int err = SSL_get_error ((SSL*)rdev->ssl, x);
|
||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*len = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
ssize_t x;
|
||||
|
||||
x = recv (rdev->sck, buf, *len, 0);
|
||||
if (x == -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
||||
if (errno == EINTR) return 0;
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
*len = x;
|
||||
#if defined(USE_SSL)
|
||||
}
|
||||
|
||||
/* TODO: flags MSG_DONTROUTE, MSG_DONTWAIT, MSG_MORE, MSG_OOB, MSG_NOSIGNAL */
|
||||
#if defined(MSG_NOSIGNAL)
|
||||
flags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
x = send (rdev->sck, data, *len, flags);
|
||||
if (x == -1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devaddr_t* srcaddr)
|
||||
{
|
||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||
stio_scklen_t srcaddrlen;
|
||||
ssize_t x;
|
||||
|
||||
srcaddrlen = STIO_SIZEOF(rdev->remoteaddr);
|
||||
x = recvfrom (rdev->sck, buf, *len, 0, (struct sockaddr*)&rdev->remoteaddr, &srcaddrlen);
|
||||
if (x <= -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
||||
if (errno == EINTR) return 0;
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
srcaddr->ptr = &rdev->remoteaddr;
|
||||
srcaddr->len = srcaddrlen;
|
||||
|
||||
*len = x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_iolen_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_devaddr_t* dstaddr)
|
||||
{
|
||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||
|
||||
|
||||
#if defined(USE_SSL)
|
||||
if (rdev->ssl)
|
||||
{
|
||||
int x;
|
||||
|
||||
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 (SSL_shutdown ((SSL*)rdev->ssl) == -1)
|
||||
{
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
x = SSL_write ((SSL*)rdev->ssl, data, *len);
|
||||
if (x <= -1)
|
||||
{
|
||||
int err = SSL_get_error ((SSL*)rdev->ssl, x);
|
||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*len = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
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 (rdev->sck, SHUT_WR) == -1)
|
||||
{
|
||||
rdev->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 = send (rdev->sck, data, *len, flags);
|
||||
if (x == -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||
if (errno == EINTR) return 0;
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*len = x;
|
||||
#if defined(USE_SSL)
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devaddr_t* dstaddr)
|
||||
{
|
||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||
ssize_t x;
|
||||
|
||||
x = sendto (rdev->sck, data, *len, 0, dstadr->ptr, dstadr->len);
|
||||
x = sendto (rdev->sck, data, *len, 0, dstaddr->ptr, dstaddr->len);
|
||||
if (x <= -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||
if (errno == EINTR) return 0;
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
@ -436,12 +556,12 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
|
||||
case STIO_DEV_SCK_BIND:
|
||||
{
|
||||
stio_dev_sck_bind_t* bnd = (stio_dev_sck_bind_t*)arg;
|
||||
struct sockaddr* sa = (struct sockaddr*)&bnd->addr;
|
||||
struct sockaddr* sa = (struct sockaddr*)&bnd->localaddr;
|
||||
stio_scklen_t sl;
|
||||
stio_sckfam_t fam;
|
||||
int x;
|
||||
#if defined(USE_SSL)
|
||||
SSL_CTX* ssl = STIO_NULL;
|
||||
SSL_CTX* ssl_ctx = STIO_NULL;
|
||||
#endif
|
||||
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_BROADCAST)
|
||||
@ -456,65 +576,109 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
|
||||
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_REUSEADDR)
|
||||
{
|
||||
#if defined(SO_REUSEADDR)
|
||||
int v = 1;
|
||||
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEADDR, &v, STIO_SIZEOF(v)) == -1)
|
||||
{
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_SECURE)
|
||||
{
|
||||
#if defined(USE_SSL)
|
||||
SSL_CTX* ssl;
|
||||
|
||||
ssl = SSL_CTX_new (SSLv23_server_method());
|
||||
if (!ssl)
|
||||
{
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate_file (ssl, bnd->certfile, SSL_FILETYPE_PEM) == 0 ||
|
||||
SSL_CTX_use_PrivateKey_file (ssl, bnd->keyfile, SSL_FILETYPE_PEM) == 0 ||
|
||||
SSL_CTX_check_private_key (ssl) == 0)
|
||||
{
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
SSL_CTX_free (ssl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_CTX_set_read_ahead (ssl, 0);
|
||||
#else
|
||||
#else
|
||||
rdev->stio->errnum = STIO_ENOIMPL;
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stio_getsckadrinfo (dev->stio, &bnd->addr, &sl, &fam) <= -1) return -1;
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_REUSEPORT)
|
||||
{
|
||||
#if defined(SO_REUSEPORT)
|
||||
int v = 1;
|
||||
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEPORT, &v, STIO_SIZEOF(v)) == -1)
|
||||
{
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
rdev->stio->errnum = STIO_ENOIMPL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_TRANSPARENT)
|
||||
{
|
||||
#if defined(IP_TRANSPARENT)
|
||||
int v = 1;
|
||||
if (setsockopt (rdev->sck, SOL_IP, IP_TRANSPARENT, &v, STIO_SIZEOF(v)) == -1)
|
||||
{
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
rdev->stio->errnum = STIO_ENOIMPL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bnd->options & STIO_DEV_SCK_BIND_SSL)
|
||||
{
|
||||
#if defined(USE_SSL)
|
||||
if (!bnd->certfile || !bnd->keyfile)
|
||||
{
|
||||
rdev->stio->errnum = STIO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssl_ctx = SSL_CTX_new (SSLv23_server_method());
|
||||
if (!ssl_ctx)
|
||||
{
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate_file (ssl_ctx, bnd->certfile, SSL_FILETYPE_PEM) == 0 ||
|
||||
SSL_CTX_use_PrivateKey_file (ssl_ctx, bnd->keyfile, SSL_FILETYPE_PEM) == 0 ||
|
||||
SSL_CTX_check_private_key (ssl_ctx) == 0 /*||
|
||||
SSL_CTX_use_certificate_chain_file (ssl_ctx, bnd->chainfile) == 0*/)
|
||||
{
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
SSL_CTX_free (ssl_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_CTX_set_read_ahead (ssl_ctx, 0);
|
||||
#else
|
||||
rdev->stio->errnum = STIO_ENOIMPL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stio_getsckaddrinfo (dev->stio, &bnd->localaddr, &sl, &fam) <= -1) return -1;
|
||||
|
||||
x = bind (rdev->sck, sa, sl);
|
||||
if (x == -1)
|
||||
{
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
#if defined(USE_SSL)
|
||||
if (ssl) SSL_CTX_free (ssl);
|
||||
#endif
|
||||
#if defined(USE_SSL)
|
||||
if (ssl_ctx) SSL_CTX_free (ssl_ctx);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
rdev->localaddr = bnd->localaddr;
|
||||
|
||||
#if defined(USE_SSL)
|
||||
rdev->secure_ctx = ssl;
|
||||
rdev->sslctx = ssl_ctx;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case STIO_DEV_SCK_CONNECT:
|
||||
{
|
||||
stio_dev_sck_connect_t* conn = (stio_dev_sck_connect_t*)arg;
|
||||
struct sockaddr* sa = (struct sockaddr*)&conn->addr;
|
||||
struct sockaddr* sa = (struct sockaddr*)&conn->remoteaddr;
|
||||
stio_scklen_t sl;
|
||||
stio_sckaddr_t localaddr;
|
||||
int x;
|
||||
|
||||
if (!IS_STATEFUL(rdev))
|
||||
@ -535,7 +699,7 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
|
||||
x = connect (rdev->sck, sa, sl);
|
||||
if (x == -1)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK)
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
{
|
||||
if (stio_dev_watch ((stio_dev_t*)rdev, STIO_DEV_WATCH_UPDATE, STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT) >= 0)
|
||||
{
|
||||
@ -562,7 +726,7 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
|
||||
}
|
||||
|
||||
rdev->state |= STIO_DEV_SCK_CONNECTING;
|
||||
rdev->peeradr = conn->addr;
|
||||
rdev->remoteaddr = conn->remoteaddr;
|
||||
rdev->on_connect = conn->on_connect;
|
||||
rdev->on_disconnect = conn->on_disconnect;
|
||||
return 0;
|
||||
@ -575,9 +739,12 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
|
||||
|
||||
/* connected immediately */
|
||||
rdev->state |= STIO_DEV_SCK_CONNECTED;
|
||||
rdev->peeradr = conn->addr;
|
||||
rdev->remoteaddr = conn->remoteaddr;
|
||||
rdev->on_connect = conn->on_connect;
|
||||
rdev->on_disconnect = conn->on_disconnect;
|
||||
|
||||
sl = STIO_SIZEOF(localaddr);
|
||||
if (getsockname (rdev->sck, (struct sockaddr*)&localaddr, &sl) == 0) rdev->localaddr = localaddr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -700,6 +867,9 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
|
||||
}
|
||||
else if (errcode == 0)
|
||||
{
|
||||
stio_sckaddr_t localaddr;
|
||||
stio_scklen_t addrlen;
|
||||
|
||||
rdev->state &= ~STIO_DEV_SCK_CONNECTING;
|
||||
rdev->state |= STIO_DEV_SCK_CONNECTED;
|
||||
|
||||
@ -711,6 +881,9 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
|
||||
STIO_ASSERT (rdev->tmridx_connect == STIO_TMRIDX_INVALID);
|
||||
}
|
||||
|
||||
addrlen = STIO_SIZEOF(localaddr);
|
||||
if (getsockname (rdev->sck, (struct sockaddr*)&localaddr, &addrlen) == 0) rdev->localaddr = localaddr;
|
||||
|
||||
if (rdev->on_connect (rdev) <= -1) return -1;
|
||||
}
|
||||
else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK)
|
||||
@ -742,17 +915,17 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
|
||||
else if (events & STIO_DEV_EVENT_IN)
|
||||
{
|
||||
stio_sckhnd_t clisck;
|
||||
stio_sckadr_t peer;
|
||||
stio_sckaddr_t remoteaddr;
|
||||
stio_scklen_t addrlen;
|
||||
stio_dev_sck_t* clidev;
|
||||
|
||||
/* this is a server(lisening) socket */
|
||||
|
||||
addrlen = STIO_SIZEOF(peer);
|
||||
clisck = accept (rdev->sck, (struct sockaddr*)&peer, &addrlen);
|
||||
addrlen = STIO_SIZEOF(remoteaddr);
|
||||
clisck = accept (rdev->sck, (struct sockaddr*)&remoteaddr, &addrlen);
|
||||
if (clisck == STIO_SCKHND_INVALID)
|
||||
{
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;
|
||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0;
|
||||
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
|
||||
|
||||
rdev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
@ -770,10 +943,55 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
|
||||
return -1;
|
||||
}
|
||||
|
||||
clidev->dev_capa |= STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_STREAM;
|
||||
clidev->state |= STIO_DEV_SCK_ACCEPTED;
|
||||
clidev->peeradr = peer;
|
||||
STIO_ASSERT (clidev->sck == clisck);
|
||||
|
||||
clidev->dev_capa |= STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_STREAM | STIO_DEV_CAPA_OUT_QUEUED;
|
||||
if (rdev->sslctx)
|
||||
clidev->state |= STIO_DEV_SCK_ACCEPTING_SSL;
|
||||
else
|
||||
clidev->state |= STIO_DEV_SCK_ACCEPTED;
|
||||
/*clidev->parent = sck;*/
|
||||
clidev->remoteaddr = remoteaddr;
|
||||
|
||||
addrlen = STIO_SIZEOF(clidev->localaddr);
|
||||
if (getsockname(clisck, (struct sockaddr*)&clidev->localaddr, &addrlen) == -1) clidev->localaddr = rdev->localaddr;
|
||||
|
||||
#if defined(SO_ORIGINAL_DST)
|
||||
/* if REDIRECT is used, SO_ORIGINAL_DST returns the original
|
||||
* destination address. When REDIRECT is not used, it returnes
|
||||
* the address of the local socket. In this case, it should
|
||||
* be same as the result of getsockname(). */
|
||||
addrlen = STIO_SIZEOF(clidev->orgdstaddr);
|
||||
if (getsockopt (clisck, SOL_IP, SO_ORIGINAL_DST, &clidev->orgdstaddr, &addrlen) == -1) clidev->orgdstaddr = rdev->localaddr;
|
||||
#else
|
||||
clidev->orgdstaddr = rdev->localaddr;
|
||||
#endif
|
||||
|
||||
if (!stio_equalsckaddrs (rdev->stio, &clidev->orgdstaddr, &clidev->localaddr))
|
||||
{
|
||||
clidev->state |= STIO_DEV_SCK_INTERCEPTED;
|
||||
}
|
||||
else if (stio_getsckaddrport (&clidev->localaddr) != stio_getsckaddrport(&rdev->localaddr))
|
||||
{
|
||||
/* When TPROXY is used, getsockname() and SO_ORIGNAL_DST return
|
||||
* the same addresses. however, the port number may be different
|
||||
* as a typical TPROXY rule is set to change the port number.
|
||||
* However, this check is fragile if the server port number is
|
||||
* set to 0.
|
||||
*
|
||||
* Take note that the above assumption gets wrong if the TPROXY
|
||||
* rule doesn't change the port number. so it won't be able
|
||||
* to handle such a TPROXYed packet without port transformation. */
|
||||
clidev->state |= STIO_DEV_SCK_INTERCEPTED;
|
||||
}
|
||||
#if 0
|
||||
else if ((clidev->initial_ifindex = resolve_ifindex (fd, clidev->localaddr)) <= -1)
|
||||
{
|
||||
/* the local_address is not one of a local address.
|
||||
* it's probably proxied. */
|
||||
clidev->state |= STIO_DEV_SCK_INTERCEPTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* inherit some event handlers from the parent.
|
||||
* you can still change them inside the on_connect handler */
|
||||
@ -782,12 +1000,87 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
|
||||
clidev->on_write = rdev->on_write;
|
||||
clidev->on_read = rdev->on_read;
|
||||
|
||||
clidev->tmridx_connect = STIO_TMRIDX_INVALID;
|
||||
if (clidev->on_connect(clidev) <= -1) stio_dev_sck_halt (clidev);
|
||||
if (clidev->state & STIO_DEV_SCK_ACCEPTED)
|
||||
{
|
||||
STIO_ASSERT (!(clidev->state & STIO_DEV_SCK_ACCEPTING_SSL));
|
||||
clidev->tmridx_connect = STIO_TMRIDX_INVALID;
|
||||
if (clidev->on_connect(clidev) <= -1) stio_dev_sck_halt (clidev);
|
||||
}
|
||||
else
|
||||
{
|
||||
STIO_ASSERT (clidev->state & STIO_DEV_SCK_ACCEPTING_SSL);
|
||||
/* actual SSL acceptance must be completed in the client device */
|
||||
|
||||
/* let the client device know the SSL context to use */
|
||||
clidev->sslctx = rdev->sslctx;
|
||||
|
||||
/* TODO: secure accept timeout handling */
|
||||
/* clidev->tmridx_connect??? */
|
||||
clidev->tmridx_connect = STIO_TMRIDX_INVALID;
|
||||
printf ("TO DO SSL ...............................\n");
|
||||
}
|
||||
|
||||
return 0; /* success but don't invoke on_read() */
|
||||
}
|
||||
}
|
||||
else if (rdev->state & STIO_DEV_SCK_ACCEPTING_SSL)
|
||||
{
|
||||
#if defined(USE_SSL)
|
||||
int ret;
|
||||
|
||||
printf ("SSL IN ACCPEING>.. %p.......................\n", rdev);
|
||||
/* client socket has been accepted. SSL accpetance is needed here */
|
||||
if (!rdev->ssl)
|
||||
{
|
||||
SSL* ssl;
|
||||
|
||||
printf ("SSL CREATED.....................\n");
|
||||
ssl = SSL_new (rdev->sslctx);
|
||||
if (!ssl)
|
||||
{
|
||||
printf ("SSL ERROR 1>..................... %s\n", ERR_reason_error_string(ERR_get_error()));
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SSL_set_fd (ssl, rdev->sck) == 0)
|
||||
{
|
||||
printf ("SSL ERROR 2>..................... %s\n", ERR_reason_error_string(ERR_get_error()));
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
SSL_set_read_ahead (ssl, 0);
|
||||
|
||||
rdev->ssl = ssl;
|
||||
}
|
||||
|
||||
ret = SSL_accept ((SSL*)rdev->ssl);
|
||||
if (ret <= 0)
|
||||
{
|
||||
int err = SSL_get_error (rdev->ssl, ret);
|
||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
/* handshaking isn't complete */
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf ("SSL ERROR 3>..................... %s\n", ERR_reason_error_string(err));
|
||||
rdev->stio->errnum = STIO_ESYSERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf ("SSL ACCEPTED.....................\n");
|
||||
rdev->state &= ~STIO_DEV_SCK_ACCEPTING_SSL;
|
||||
rdev->state |= STIO_DEV_SCK_ACCEPTED;
|
||||
if (rdev->on_connect(rdev) <= -1) stio_dev_sck_halt (rdev);
|
||||
|
||||
return 0; /* no reading or writing yet */
|
||||
|
||||
#else
|
||||
rdev->stio->errnum = STIO_EINTERN;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (events & STIO_DEV_EVENT_HUP)
|
||||
{
|
||||
if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT))
|
||||
@ -836,28 +1129,28 @@ 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_iolen_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_devaddr_t* srcaddr)
|
||||
{
|
||||
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_iolen_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_devaddr_t* dstaddr)
|
||||
{
|
||||
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_iolen_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_devaddr_t* srcaddr)
|
||||
{
|
||||
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, srcaddr->ptr);
|
||||
}
|
||||
|
||||
static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_iolen_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_devaddr_t* dstaddr)
|
||||
{
|
||||
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, dstaddr->ptr);
|
||||
}
|
||||
|
||||
static stio_dev_evcb_t dev_sck_event_callbacks_stateful =
|
||||
@ -917,14 +1210,14 @@ 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_iolen_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_sckaddr_t* dstaddr)
|
||||
{
|
||||
stio_devadr_t devadr;
|
||||
return stio_dev_write ((stio_dev_t*)dev, data, dlen, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
|
||||
stio_devaddr_t devaddr;
|
||||
return stio_dev_write ((stio_dev_t*)dev, data, dlen, wrctx, sckaddr_to_devaddr(dev, dstaddr, &devaddr));
|
||||
}
|
||||
|
||||
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)
|
||||
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_sckaddr_t* dstaddr)
|
||||
{
|
||||
stio_devadr_t devadr;
|
||||
return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
|
||||
stio_devaddr_t devaddr;
|
||||
return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckaddr_to_devaddr(dev, dstaddr, &devaddr));
|
||||
}
|
||||
|
@ -29,13 +29,14 @@
|
||||
|
||||
#include <stio.h>
|
||||
|
||||
struct stio_sckadr_t
|
||||
typedef int stio_sckfam_t;
|
||||
|
||||
struct stio_sckaddr_t
|
||||
{
|
||||
int family;
|
||||
stio_sckfam_t family;
|
||||
stio_uint8_t data[128]; /* TODO: use the actual sockaddr size */
|
||||
};
|
||||
|
||||
typedef struct stio_sckadr_t stio_sckadr_t;
|
||||
typedef struct stio_sckaddr_t stio_sckaddr_t;
|
||||
|
||||
#if (STIO_SIZEOF_SOCKLEN_T == STIO_SIZEOF_INT)
|
||||
#if defined(STIO_SOCKLEN_T_IS_SIGNED)
|
||||
@ -70,8 +71,6 @@ typedef struct stio_sckadr_t stio_sckadr_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef int stio_sckfam_t;
|
||||
|
||||
|
||||
#define STIO_SCK_ETH_PROTO_IP4 0x0800
|
||||
#define STIO_SCK_ETH_PROTO_ARP 0x0806
|
||||
@ -91,26 +90,28 @@ typedef enum stio_dev_sck_ioctl_cmd_t stio_dev_sck_ioctl_cmd_t;
|
||||
|
||||
enum stio_dev_sck_state_t
|
||||
{
|
||||
STIO_DEV_SCK_CONNECTING = (1 << 0),
|
||||
STIO_DEV_SCK_CONNECTED = (1 << 1),
|
||||
STIO_DEV_SCK_LISTENING = (1 << 2),
|
||||
STIO_DEV_SCK_ACCEPTED = (1 << 3)
|
||||
STIO_DEV_SCK_CONNECTING = (1 << 0),
|
||||
STIO_DEV_SCK_CONNECTED = (1 << 1),
|
||||
STIO_DEV_SCK_LISTENING = (1 << 2),
|
||||
STIO_DEV_SCK_ACCEPTING_SSL = (1 << 3),
|
||||
STIO_DEV_SCK_ACCEPTED = (1 << 4),
|
||||
STIO_DEV_SCK_INTERCEPTED = (1 << 5)
|
||||
};
|
||||
typedef enum stio_dev_sck_state_t stio_dev_sck_state_t;
|
||||
|
||||
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_iolen_t dlen,
|
||||
const stio_sckadr_t* srcadr
|
||||
stio_dev_sck_t* dev,
|
||||
const void* data,
|
||||
stio_iolen_t dlen,
|
||||
const stio_sckaddr_t* srcaddr
|
||||
);
|
||||
typedef int (*stio_dev_sck_on_write_t) (
|
||||
stio_dev_sck_t* dev,
|
||||
stio_iolen_t wrlen,
|
||||
void* wrctx,
|
||||
const stio_sckadr_t* dstadr
|
||||
stio_dev_sck_t* dev,
|
||||
stio_iolen_t wrlen,
|
||||
void* wrctx,
|
||||
const stio_sckaddr_t* dstaddr
|
||||
);
|
||||
|
||||
typedef int (*stio_dev_sck_on_connect_t) (stio_dev_sck_t* dev);
|
||||
@ -144,11 +145,15 @@ struct stio_dev_sck_make_t
|
||||
|
||||
enum stio_dev_sck_bind_option_t
|
||||
{
|
||||
STIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
|
||||
STIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
|
||||
/* TODO: more options --- TRANSPARENT...SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
|
||||
STIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
|
||||
STIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
|
||||
STIO_DEV_SCK_BIND_REUSEPORT = (1 << 2),
|
||||
STIO_DEV_SCK_BIND_TRANSPARENT = (1 << 3),
|
||||
|
||||
STIO_DEV_SCK_BIND_SECURE = (1 << 15)
|
||||
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
|
||||
/* BINDTODEVICE??? */
|
||||
|
||||
STIO_DEV_SCK_BIND_SSL = (1 << 15)
|
||||
};
|
||||
typedef enum stio_dev_sck_bind_option_t stio_dev_sck_bind_option_t;
|
||||
|
||||
@ -156,7 +161,7 @@ typedef struct stio_dev_sck_bind_t stio_dev_sck_bind_t;
|
||||
struct stio_dev_sck_bind_t
|
||||
{
|
||||
int options;
|
||||
stio_sckadr_t addr;
|
||||
stio_sckaddr_t localaddr;
|
||||
/* TODO: add device name for BIND_TO_DEVICE */
|
||||
|
||||
const stio_mchar_t* certfile;
|
||||
@ -166,7 +171,7 @@ struct stio_dev_sck_bind_t
|
||||
typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t;
|
||||
struct stio_dev_sck_connect_t
|
||||
{
|
||||
stio_sckadr_t addr;
|
||||
stio_sckaddr_t remoteaddr;
|
||||
stio_ntime_t tmout; /* connect timeout */
|
||||
stio_dev_sck_on_connect_t on_connect;
|
||||
stio_dev_sck_on_disconnect_t on_disconnect;
|
||||
@ -185,7 +190,7 @@ struct stio_dev_sck_accept_t
|
||||
{
|
||||
stio_syshnd_t sck;
|
||||
/* TODO: add timeout */
|
||||
stio_sckadr_t peeradr;
|
||||
stio_sckaddr_t remoteaddr;
|
||||
};
|
||||
|
||||
struct stio_dev_sck_t
|
||||
@ -194,15 +199,18 @@ struct stio_dev_sck_t
|
||||
|
||||
stio_dev_sck_type_t type;
|
||||
stio_sckhnd_t sck;
|
||||
void* secure_ctx;
|
||||
|
||||
void* sslctx;
|
||||
void* ssl;
|
||||
|
||||
stio_dev_sck_on_write_t on_write;
|
||||
stio_dev_sck_on_read_t on_read;
|
||||
|
||||
int state;
|
||||
/** 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 */
|
||||
|
||||
/* 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_sck_on_connect_t on_connect;
|
||||
stio_dev_sck_on_disconnect_t on_disconnect;
|
||||
stio_tmridx_t tmridx_connect;
|
||||
@ -215,7 +223,10 @@ struct stio_dev_sck_t
|
||||
*
|
||||
* also used as a placeholder to store source address for
|
||||
* a stateless socket */
|
||||
stio_sckadr_t peeradr;
|
||||
stio_sckaddr_t remoteaddr;
|
||||
|
||||
stio_sckaddr_t localaddr;
|
||||
stio_sckaddr_t orgdstaddr;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -239,30 +250,38 @@ STIO_EXPORT int stio_makesckasync (
|
||||
stio_sckhnd_t sck
|
||||
);
|
||||
|
||||
STIO_EXPORT int stio_getsckadrinfo (
|
||||
STIO_EXPORT int stio_getsckaddrinfo (
|
||||
stio_t* stio,
|
||||
const stio_sckadr_t* addr,
|
||||
const stio_sckaddr_t* addr,
|
||||
stio_scklen_t* len,
|
||||
stio_sckfam_t* family
|
||||
);
|
||||
|
||||
|
||||
void stio_sckadr_initforip4 (
|
||||
stio_sckadr_t* sckadr,
|
||||
stio_uint16_t port,
|
||||
stio_ip4adr_t* ip4adr
|
||||
/*
|
||||
* The stio_getsckaddrport() function returns the port number of a socket
|
||||
* address in the host byte order. If the address doesn't support the port
|
||||
* number, it returns 0.
|
||||
*/
|
||||
STIO_EXPORT stio_uint16_t stio_getsckaddrport (
|
||||
const stio_sckaddr_t* addr
|
||||
);
|
||||
|
||||
void stio_sckadr_initforip6 (
|
||||
stio_sckadr_t* sckadr,
|
||||
STIO_EXPORT void stio_sckaddr_initforip4 (
|
||||
stio_sckaddr_t* sckaddr,
|
||||
stio_uint16_t port,
|
||||
stio_ip6adr_t* ip6adr
|
||||
stio_ip4addr_t* ip4addr
|
||||
);
|
||||
|
||||
void stio_sckadr_initforeth (
|
||||
stio_sckadr_t* sckadr,
|
||||
STIO_EXPORT void stio_sckaddr_initforip6 (
|
||||
stio_sckaddr_t* sckaddr,
|
||||
stio_uint16_t port,
|
||||
stio_ip6addr_t* ip6addr
|
||||
);
|
||||
|
||||
STIO_EXPORT void stio_sckaddr_initforeth (
|
||||
stio_sckaddr_t* sckaddr,
|
||||
int ifindex,
|
||||
stio_ethadr_t* ethadr
|
||||
stio_ethaddr_t* ethaddr
|
||||
);
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -293,7 +312,7 @@ STIO_EXPORT int stio_dev_sck_write (
|
||||
const void* data,
|
||||
stio_iolen_t len,
|
||||
void* wrctx,
|
||||
const stio_sckadr_t* dstadr
|
||||
const stio_sckaddr_t* dstaddr
|
||||
);
|
||||
|
||||
STIO_EXPORT int stio_dev_sck_timedwrite (
|
||||
@ -302,7 +321,7 @@ STIO_EXPORT int stio_dev_sck_timedwrite (
|
||||
stio_iolen_t len,
|
||||
const stio_ntime_t* tmout,
|
||||
void* wrctx,
|
||||
const stio_sckadr_t* dstadr
|
||||
const stio_sckaddr_t* dstaddr
|
||||
);
|
||||
|
||||
#if defined(STIO_HAVE_INLINE)
|
||||
|
524
stio/lib/stio-utl.c
Normal file
524
stio/lib/stio-utl.c
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
* $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-prv.h"
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if defined(STIO_HAVE_UINT16_T)
|
||||
|
||||
stio_uint16_t stio_ntoh16 (stio_uint16_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint16_t)(
|
||||
((stio_uint16_t)c[0] << 8) |
|
||||
((stio_uint16_t)c[1] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
stio_uint16_t stio_hton16 (stio_uint16_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint16_t)(
|
||||
((stio_uint16_t)c[0] << 8) |
|
||||
((stio_uint16_t)c[1] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if defined(STIO_HAVE_UINT32_T)
|
||||
|
||||
stio_uint32_t stio_ntoh32 (stio_uint32_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint32_t)(
|
||||
((stio_uint32_t)c[0] << 24) |
|
||||
((stio_uint32_t)c[1] << 16) |
|
||||
((stio_uint32_t)c[2] << 8) |
|
||||
((stio_uint32_t)c[3] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
stio_uint32_t stio_hton32 (stio_uint32_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint32_t)(
|
||||
((stio_uint32_t)c[0] << 24) |
|
||||
((stio_uint32_t)c[1] << 16) |
|
||||
((stio_uint32_t)c[2] << 8) |
|
||||
((stio_uint32_t)c[3] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if defined(STIO_HAVE_UINT64_T)
|
||||
|
||||
stio_uint64_t stio_ntoh64 (stio_uint64_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint64_t)(
|
||||
((stio_uint64_t)c[0] << 56) |
|
||||
((stio_uint64_t)c[1] << 48) |
|
||||
((stio_uint64_t)c[2] << 40) |
|
||||
((stio_uint64_t)c[3] << 32) |
|
||||
((stio_uint64_t)c[4] << 24) |
|
||||
((stio_uint64_t)c[5] << 16) |
|
||||
((stio_uint64_t)c[6] << 8) |
|
||||
((stio_uint64_t)c[7] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
stio_uint64_t stio_hton64 (stio_uint64_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint64_t)(
|
||||
((stio_uint64_t)c[0] << 56) |
|
||||
((stio_uint64_t)c[1] << 48) |
|
||||
((stio_uint64_t)c[2] << 40) |
|
||||
((stio_uint64_t)c[3] << 32) |
|
||||
((stio_uint64_t)c[4] << 24) |
|
||||
((stio_uint64_t)c[5] << 16) |
|
||||
((stio_uint64_t)c[6] << 8) |
|
||||
((stio_uint64_t)c[7] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if defined(STIO_HAVE_UINT128_T)
|
||||
|
||||
stio_uint128_t stio_ntoh128 (stio_uint128_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint128_t)(
|
||||
((stio_uint128_t)c[0] << 120) |
|
||||
((stio_uint128_t)c[1] << 112) |
|
||||
((stio_uint128_t)c[2] << 104) |
|
||||
((stio_uint128_t)c[3] << 96) |
|
||||
((stio_uint128_t)c[4] << 88) |
|
||||
((stio_uint128_t)c[5] << 80) |
|
||||
((stio_uint128_t)c[6] << 72) |
|
||||
((stio_uint128_t)c[7] << 64) |
|
||||
((stio_uint128_t)c[8] << 56) |
|
||||
((stio_uint128_t)c[9] << 48) |
|
||||
((stio_uint128_t)c[10] << 40) |
|
||||
((stio_uint128_t)c[11] << 32) |
|
||||
((stio_uint128_t)c[12] << 24) |
|
||||
((stio_uint128_t)c[13] << 16) |
|
||||
((stio_uint128_t)c[14] << 8) |
|
||||
((stio_uint128_t)c[15] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
stio_uint128_t stio_hton128 (stio_uint128_t x)
|
||||
{
|
||||
#if defined(STIO_ENDIAN_BIG)
|
||||
return x;
|
||||
#elif defined(STIO_ENDIAN_LITTLE)
|
||||
stio_uint8_t* c = (stio_uint8_t*)&x;
|
||||
return (stio_uint128_t)(
|
||||
((stio_uint128_t)c[0] << 120) |
|
||||
((stio_uint128_t)c[1] << 112) |
|
||||
((stio_uint128_t)c[2] << 104) |
|
||||
((stio_uint128_t)c[3] << 96) |
|
||||
((stio_uint128_t)c[4] << 88) |
|
||||
((stio_uint128_t)c[5] << 80) |
|
||||
((stio_uint128_t)c[6] << 72) |
|
||||
((stio_uint128_t)c[7] << 64) |
|
||||
((stio_uint128_t)c[8] << 56) |
|
||||
((stio_uint128_t)c[9] << 48) |
|
||||
((stio_uint128_t)c[10] << 40) |
|
||||
((stio_uint128_t)c[11] << 32) |
|
||||
((stio_uint128_t)c[12] << 24) |
|
||||
((stio_uint128_t)c[13] << 16) |
|
||||
((stio_uint128_t)c[14] << 8) |
|
||||
((stio_uint128_t)c[15] << 0));
|
||||
#else
|
||||
# error Unknown endian
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#define IS_MSPACE(x) ((x) == STIO_MT(' ') || (x) == STIO_MT('\t') || (x) == STIO_MT('\n') || (x) == STIO_MT('\r'))
|
||||
|
||||
stio_mchar_t* stio_mbsdup (stio_t* stio, const stio_mchar_t* src)
|
||||
{
|
||||
stio_mchar_t* dst;
|
||||
stio_size_t len;
|
||||
|
||||
dst = (stio_mchar_t*)src;
|
||||
while (*dst != STIO_MT('\0')) dst++;
|
||||
len = dst - src;
|
||||
|
||||
dst = STIO_MMGR_ALLOC (stio->mmgr, (len + 1) * STIO_SIZEOF(*src));
|
||||
if (!dst)
|
||||
{
|
||||
stio->errnum = STIO_ENOMEM;
|
||||
return STIO_NULL;
|
||||
}
|
||||
|
||||
STIO_MEMCPY (dst, src, (len + 1) * STIO_SIZEOF(*src));
|
||||
return dst;
|
||||
}
|
||||
|
||||
stio_size_t stio_mbscpy (stio_mchar_t* buf, const stio_mchar_t* str)
|
||||
{
|
||||
stio_mchar_t* org = buf;
|
||||
while ((*buf++ = *str++) != STIO_MT('\0'));
|
||||
return buf - org - 1;
|
||||
}
|
||||
|
||||
int stio_mbsspltrn (
|
||||
stio_mchar_t* s, const stio_mchar_t* delim,
|
||||
stio_mchar_t lquote, stio_mchar_t rquote,
|
||||
stio_mchar_t escape, const stio_mchar_t* trset)
|
||||
{
|
||||
stio_mchar_t* p = s, *d;
|
||||
stio_mchar_t* sp = STIO_NULL, * ep = STIO_NULL;
|
||||
int delim_mode;
|
||||
int cnt = 0;
|
||||
|
||||
if (delim == STIO_NULL) delim_mode = 0;
|
||||
else
|
||||
{
|
||||
delim_mode = 1;
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
if (!IS_MSPACE(*d)) delim_mode = 2;
|
||||
}
|
||||
|
||||
if (delim_mode == 0)
|
||||
{
|
||||
/* skip preceding space characters */
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
|
||||
/* when 0 is given as "delim", it has an effect of cutting
|
||||
preceding and trailing space characters off "s". */
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp == 0) sp = p;
|
||||
ep = p;
|
||||
p++;
|
||||
}
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (*p != STIO_MT('\0')) return -1;
|
||||
|
||||
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
|
||||
else
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*p)
|
||||
{
|
||||
if (!IS_MSPACE(*p))
|
||||
{
|
||||
if (sp == 0) sp = p;
|
||||
ep = p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
|
||||
else
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (delim_mode == 1)
|
||||
{
|
||||
stio_mchar_t* o;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
o = p;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (o != p) { stio_mbscpy (o, p); p = o; }
|
||||
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
o = p;
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0'))
|
||||
{
|
||||
if (o != p) cnt++;
|
||||
break;
|
||||
}
|
||||
if (IS_MSPACE (*p))
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* if (delim_mode == 2) */
|
||||
{
|
||||
stio_mchar_t* o;
|
||||
int ok;
|
||||
|
||||
while (*p != STIO_MT('\0'))
|
||||
{
|
||||
o = p;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (o != p) { stio_mbscpy (o, p); p = o; }
|
||||
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (*p == STIO_MT('\0')) ok = 1;
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
{
|
||||
if (*p == *d)
|
||||
{
|
||||
ok = 1;
|
||||
stio_mbscpy (p, p + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok == 0) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
o = p; sp = ep = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0'))
|
||||
{
|
||||
if (ep)
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
p = &ep[1];
|
||||
}
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
{
|
||||
if (*p == *d)
|
||||
{
|
||||
if (sp == STIO_NULL)
|
||||
{
|
||||
stio_mbscpy (o, p); p = o;
|
||||
*p++ = STIO_MT('\0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stio_mbscpy (&ep[1], p);
|
||||
stio_mbscpy (o, sp);
|
||||
o[ep - sp + 1] = STIO_MT('\0');
|
||||
p = &o[ep - sp + 2];
|
||||
}
|
||||
cnt++;
|
||||
/* last empty field after delim */
|
||||
if (*p == STIO_MT('\0')) cnt++;
|
||||
goto exit_point;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_MSPACE (*p))
|
||||
{
|
||||
if (sp == STIO_NULL) sp = p;
|
||||
ep = p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
exit_point:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int stio_mbsspl (
|
||||
stio_mchar_t* s, const stio_mchar_t* delim,
|
||||
stio_mchar_t lquote, stio_mchar_t rquote, stio_mchar_t escape)
|
||||
{
|
||||
return stio_mbsspltrn (s, delim, lquote, rquote, escape, STIO_NULL);
|
||||
}
|
378
stio/lib/stio.c
378
stio/lib/stio.c
@ -33,7 +33,6 @@
|
||||
|
||||
#define DEV_CAPA_ALL_WATCHED (STIO_DEV_CAPA_IN_WATCHED | STIO_DEV_CAPA_OUT_WATCHED | STIO_DEV_CAPA_PRI_WATCHED)
|
||||
|
||||
#define IS_MSPACE(x) ((x) == STIO_MT(' ') || (x) == STIO_MT('\t'))
|
||||
|
||||
static int schedule_kill_zombie_job (stio_dev_t* dev);
|
||||
static int kill_and_free_device (stio_dev_t* dev, int force);
|
||||
@ -252,7 +251,8 @@ printf ("has urgent data...\n");
|
||||
|
||||
send_leftover:
|
||||
ulen = urem;
|
||||
x = dev->dev_mth->write (dev, uptr, &ulen, &q->dstadr);
|
||||
printf ("&&&&&&&&&&&&&&&&&&&&&&&&&&&&7WRITING..........................\n");
|
||||
x = dev->dev_mth->write (dev, uptr, &ulen, &q->dstaddr);
|
||||
if (x <= -1)
|
||||
{
|
||||
stio_dev_halt (dev);
|
||||
@ -286,7 +286,7 @@ printf ("has urgent data...\n");
|
||||
}
|
||||
|
||||
unlink_wq (stio, q);
|
||||
y = dev->dev_evcb->on_write (dev, q->olen, q->ctx, &q->dstadr);
|
||||
y = dev->dev_evcb->on_write (dev, q->olen, q->ctx, &q->dstaddr);
|
||||
STIO_MMGR_FREE (stio->mmgr, q);
|
||||
|
||||
if (y <= -1)
|
||||
@ -331,7 +331,7 @@ printf ("has urgent data...\n");
|
||||
|
||||
if (dev && stio->revs[i].events & EPOLLIN)
|
||||
{
|
||||
stio_devadr_t srcadr;
|
||||
stio_devaddr_t srcaddr;
|
||||
stio_iolen_t len;
|
||||
int x;
|
||||
|
||||
@ -341,7 +341,7 @@ printf ("has urgent data...\n");
|
||||
while (1)
|
||||
{
|
||||
len = STIO_COUNTOF(stio->bigbuf);
|
||||
x = dev->dev_mth->read (dev, stio->bigbuf, &len, &srcadr);
|
||||
x = dev->dev_mth->read (dev, stio->bigbuf, &len, &srcaddr);
|
||||
if (x <= -1)
|
||||
{
|
||||
stio_dev_halt (dev);
|
||||
@ -363,7 +363,7 @@ printf ("has urgent data...\n");
|
||||
stio->renew_watch = 1;
|
||||
|
||||
/* call the on_read callback to report EOF */
|
||||
if (dev->dev_evcb->on_read (dev, stio->bigbuf, len, &srcadr) <= -1 ||
|
||||
if (dev->dev_evcb->on_read (dev, stio->bigbuf, len, &srcaddr) <= -1 ||
|
||||
(dev->dev_capa & STIO_DEV_CAPA_OUT_CLOSED))
|
||||
{
|
||||
/* 1. input ended and its reporting failed or
|
||||
@ -382,7 +382,7 @@ printf ("has urgent data...\n");
|
||||
* when x == 0 or <= -1. you can */
|
||||
|
||||
/* data available */
|
||||
y = dev->dev_evcb->on_read (dev, stio->bigbuf, len, &srcadr);
|
||||
y = dev->dev_evcb->on_read (dev, stio->bigbuf, len, &srcaddr);
|
||||
if (y <= -1)
|
||||
{
|
||||
stio_dev_halt (dev);
|
||||
@ -877,11 +877,10 @@ int stio_dev_watch (stio_dev_t* dev, stio_dev_watch_cmd_t cmd, int events)
|
||||
|
||||
if (epoll_op == EPOLL_CTL_MOD && (dev_capa & DEV_CAPA_ALL_WATCHED) == (dev->dev_capa & DEV_CAPA_ALL_WATCHED))
|
||||
{
|
||||
/* skip calling epoll_ctl */
|
||||
/* no change in the device capacity. skip calling epoll_ctl */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("MODING cmd=%d %d\n", (int)cmd, (int)dev->dev_mth->getsyshnd(dev));
|
||||
if (epoll_ctl (dev->stio->mux, epoll_op, dev->dev_mth->getsyshnd(dev), &ev) == -1)
|
||||
{
|
||||
dev->stio->errnum = stio_syserrtoerrnum(errno);
|
||||
@ -930,7 +929,7 @@ static void on_write_timeout (stio_t* stio, const stio_ntime_t* now, stio_tmrjob
|
||||
dev = q->dev;
|
||||
|
||||
dev->stio->errnum = STIO_ETMOUT;
|
||||
x = dev->dev_evcb->on_write (dev, -1, q->ctx, &q->dstadr);
|
||||
x = dev->dev_evcb->on_write (dev, -1, q->ctx, &q->dstaddr);
|
||||
|
||||
STIO_ASSERT (q->tmridx == STIO_TMRIDX_INVALID);
|
||||
STIO_WQ_UNLINK(q);
|
||||
@ -939,7 +938,7 @@ 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_iolen_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_devaddr_t* dstaddr)
|
||||
{
|
||||
const stio_uint8_t* uptr;
|
||||
stio_iolen_t urem, ulen;
|
||||
@ -968,7 +967,7 @@ static int __dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, con
|
||||
do
|
||||
{
|
||||
ulen = urem;
|
||||
x = dev->dev_mth->write (dev, data, &ulen, dstadr);
|
||||
x = dev->dev_mth->write (dev, data, &ulen, dstaddr);
|
||||
if (x <= -1) return -1;
|
||||
else if (x == 0)
|
||||
{
|
||||
@ -994,18 +993,18 @@ static int __dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, con
|
||||
dev->dev_capa |= STIO_DEV_CAPA_OUT_CLOSED;
|
||||
}
|
||||
|
||||
if (dev->dev_evcb->on_write (dev, len, wrctx, dstadr) <= -1) return -1;
|
||||
if (dev->dev_evcb->on_write (dev, len, wrctx, dstaddr) <= -1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulen = urem;
|
||||
|
||||
x = dev->dev_mth->write (dev, data, &ulen, dstadr);
|
||||
x = dev->dev_mth->write (dev, data, &ulen, dstaddr);
|
||||
if (x <= -1) return -1;
|
||||
else if (x == 0) goto enqueue_data;
|
||||
|
||||
/* partial writing is still considered ok for a non-stream device */
|
||||
if (dev->dev_evcb->on_write (dev, ulen, wrctx, dstadr) <= -1) return -1;
|
||||
if (dev->dev_evcb->on_write (dev, ulen, wrctx, dstaddr) <= -1) return -1;
|
||||
}
|
||||
|
||||
return 1; /* written immediately and called on_write callback */
|
||||
@ -1014,11 +1013,12 @@ enqueue_data:
|
||||
if (!(dev->dev_capa & STIO_DEV_CAPA_OUT_QUEUED))
|
||||
{
|
||||
/* writing queuing is not requested. so return failure */
|
||||
dev->stio->errnum = STIO_ENOCAPA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* queue the remaining data*/
|
||||
q = (stio_wq_t*)STIO_MMGR_ALLOC (dev->stio->mmgr, STIO_SIZEOF(*q) + (dstadr? dstadr->len: 0) + urem);
|
||||
q = (stio_wq_t*)STIO_MMGR_ALLOC (dev->stio->mmgr, STIO_SIZEOF(*q) + (dstaddr? dstaddr->len: 0) + urem);
|
||||
if (!q)
|
||||
{
|
||||
dev->stio->errnum = STIO_ENOMEM;
|
||||
@ -1029,23 +1029,22 @@ enqueue_data:
|
||||
q->dev = dev;
|
||||
q->ctx = wrctx;
|
||||
|
||||
if (dstadr)
|
||||
if (dstaddr)
|
||||
{
|
||||
q->dstadr.ptr = (stio_uint8_t*)(q + 1);
|
||||
q->dstadr.len = dstadr->len;
|
||||
STIO_MEMCPY (q->dstadr.ptr, dstadr->ptr, dstadr->len);
|
||||
q->dstaddr.ptr = (stio_uint8_t*)(q + 1);
|
||||
q->dstaddr.len = dstaddr->len;
|
||||
STIO_MEMCPY (q->dstaddr.ptr, dstaddr->ptr, dstaddr->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
q->dstadr.len = 0;
|
||||
q->dstaddr.len = 0;
|
||||
}
|
||||
|
||||
q->ptr = (stio_uint8_t*)(q + 1) + q->dstadr.len;
|
||||
q->ptr = (stio_uint8_t*)(q + 1) + q->dstaddr.len;
|
||||
q->len = urem;
|
||||
q->olen = len;
|
||||
STIO_MEMCPY (q->ptr, uptr, urem);
|
||||
|
||||
|
||||
if (tmout && !stio_isnegtime(tmout))
|
||||
{
|
||||
stio_tmrjob_t tmrjob;
|
||||
@ -1061,6 +1060,7 @@ enqueue_data:
|
||||
if (q->tmridx == STIO_TMRIDX_INVALID)
|
||||
{
|
||||
STIO_MMGR_FREE (dev->stio->mmgr, q);
|
||||
printf ("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZz222222\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1073,6 +1073,7 @@ enqueue_data:
|
||||
{
|
||||
unlink_wq (dev->stio, q);
|
||||
STIO_MMGR_FREE (dev->stio->mmgr, q);
|
||||
printf ("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZz11111\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1081,17 +1082,18 @@ enqueue_data:
|
||||
dev->stio->renew_watch = 1;
|
||||
}
|
||||
|
||||
printf ("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZz\n");
|
||||
return 0; /* request pused to a write queue. */
|
||||
}
|
||||
|
||||
int stio_dev_write (stio_dev_t* dev, const void* data, stio_iolen_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_devaddr_t* dstaddr)
|
||||
{
|
||||
return __dev_write (dev, data, len, STIO_NULL, wrctx, dstadr);
|
||||
return __dev_write (dev, data, len, STIO_NULL, wrctx, dstaddr);
|
||||
}
|
||||
|
||||
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)
|
||||
int stio_dev_timedwrite (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devaddr_t* dstaddr)
|
||||
{
|
||||
return __dev_write (dev, data, len, tmout, wrctx, dstadr);
|
||||
return __dev_write (dev, data, len, tmout, wrctx, dstaddr);
|
||||
}
|
||||
|
||||
int stio_makesyshndasync (stio_t* stio, stio_syshnd_t hnd)
|
||||
@ -1134,8 +1136,15 @@ stio_errnum_t stio_syserrtoerrnum (int no)
|
||||
return STIO_ENFILE;
|
||||
#endif
|
||||
|
||||
#if defined(EAGAIN)
|
||||
#if defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
|
||||
case EAGAIN:
|
||||
case EWOULDBLOCK:
|
||||
return STIO_EAGAIN;
|
||||
#elif defined(EAGAIN)
|
||||
case EAGAIN:
|
||||
return STIO_EAGAIN;
|
||||
#elif defined(EWOULDBLOCK)
|
||||
case EWOULDBLOCK:
|
||||
return STIO_EAGAIN;
|
||||
#endif
|
||||
|
||||
@ -1153,316 +1162,3 @@ stio_errnum_t stio_syserrtoerrnum (int no)
|
||||
return STIO_ESYSERR;
|
||||
}
|
||||
}
|
||||
|
||||
stio_mchar_t* stio_mbsdup (stio_t* stio, const stio_mchar_t* src)
|
||||
{
|
||||
stio_mchar_t* dst;
|
||||
stio_size_t len;
|
||||
|
||||
dst = (stio_mchar_t*)src;
|
||||
while (*dst != STIO_MT('\0')) dst++;
|
||||
len = dst - src;
|
||||
|
||||
dst = STIO_MMGR_ALLOC (stio->mmgr, (len + 1) * STIO_SIZEOF(*src));
|
||||
if (!dst)
|
||||
{
|
||||
stio->errnum = STIO_ENOMEM;
|
||||
return STIO_NULL;
|
||||
}
|
||||
|
||||
STIO_MEMCPY (dst, src, (len + 1) * STIO_SIZEOF(*src));
|
||||
return dst;
|
||||
}
|
||||
|
||||
stio_size_t stio_mbscpy (stio_mchar_t* buf, const stio_mchar_t* str)
|
||||
{
|
||||
stio_mchar_t* org = buf;
|
||||
while ((*buf++ = *str++) != STIO_MT('\0'));
|
||||
return buf - org - 1;
|
||||
}
|
||||
|
||||
int stio_mbsspltrn (
|
||||
stio_mchar_t* s, const stio_mchar_t* delim,
|
||||
stio_mchar_t lquote, stio_mchar_t rquote,
|
||||
stio_mchar_t escape, const stio_mchar_t* trset)
|
||||
{
|
||||
stio_mchar_t* p = s, *d;
|
||||
stio_mchar_t* sp = STIO_NULL, * ep = STIO_NULL;
|
||||
int delim_mode;
|
||||
int cnt = 0;
|
||||
|
||||
if (delim == STIO_NULL) delim_mode = 0;
|
||||
else
|
||||
{
|
||||
delim_mode = 1;
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
if (!IS_MSPACE(*d)) delim_mode = 2;
|
||||
}
|
||||
|
||||
if (delim_mode == 0)
|
||||
{
|
||||
/* skip preceding space characters */
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
|
||||
/* when 0 is given as "delim", it has an effect of cutting
|
||||
preceding and trailing space characters off "s". */
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp == 0) sp = p;
|
||||
ep = p;
|
||||
p++;
|
||||
}
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (*p != STIO_MT('\0')) return -1;
|
||||
|
||||
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
|
||||
else
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*p)
|
||||
{
|
||||
if (!IS_MSPACE(*p))
|
||||
{
|
||||
if (sp == 0) sp = p;
|
||||
ep = p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
|
||||
else
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (delim_mode == 1)
|
||||
{
|
||||
stio_mchar_t* o;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
o = p;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (o != p) { stio_mbscpy (o, p); p = o; }
|
||||
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
o = p;
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0'))
|
||||
{
|
||||
if (o != p) cnt++;
|
||||
break;
|
||||
}
|
||||
if (IS_MSPACE (*p))
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* if (delim_mode == 2) */
|
||||
{
|
||||
stio_mchar_t* o;
|
||||
int ok;
|
||||
|
||||
while (*p != STIO_MT('\0'))
|
||||
{
|
||||
o = p;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (o != p) { stio_mbscpy (o, p); p = o; }
|
||||
|
||||
if (lquote != STIO_MT('\0') && *p == lquote)
|
||||
{
|
||||
stio_mbscpy (p, p + 1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0')) return -1;
|
||||
|
||||
if (escape != STIO_MT('\0') && *p == escape)
|
||||
{
|
||||
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
|
||||
{
|
||||
const stio_mchar_t* ep = trset;
|
||||
while (*ep != STIO_MT('\0'))
|
||||
{
|
||||
if (p[1] == *ep++)
|
||||
{
|
||||
p[1] = *ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stio_mbscpy (p, p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == rquote)
|
||||
{
|
||||
*p++ = STIO_MT('\0');
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
while (IS_MSPACE(*p)) p++;
|
||||
if (*p == STIO_MT('\0')) ok = 1;
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
{
|
||||
if (*p == *d)
|
||||
{
|
||||
ok = 1;
|
||||
stio_mbscpy (p, p + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok == 0) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
o = p; sp = ep = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*p == STIO_MT('\0'))
|
||||
{
|
||||
if (ep)
|
||||
{
|
||||
ep[1] = STIO_MT('\0');
|
||||
p = &ep[1];
|
||||
}
|
||||
cnt++;
|
||||
break;
|
||||
}
|
||||
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
|
||||
{
|
||||
if (*p == *d)
|
||||
{
|
||||
if (sp == STIO_NULL)
|
||||
{
|
||||
stio_mbscpy (o, p); p = o;
|
||||
*p++ = STIO_MT('\0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stio_mbscpy (&ep[1], p);
|
||||
stio_mbscpy (o, sp);
|
||||
o[ep - sp + 1] = STIO_MT('\0');
|
||||
p = &o[ep - sp + 2];
|
||||
}
|
||||
cnt++;
|
||||
/* last empty field after delim */
|
||||
if (*p == STIO_MT('\0')) cnt++;
|
||||
goto exit_point;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_MSPACE (*p))
|
||||
{
|
||||
if (sp == STIO_NULL) sp = p;
|
||||
ep = p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
exit_point:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int stio_mbsspl (
|
||||
stio_mchar_t* s, const stio_mchar_t* delim,
|
||||
stio_mchar_t lquote, stio_mchar_t rquote, stio_mchar_t escape)
|
||||
{
|
||||
return stio_mbsspltrn (s, delim, lquote, rquote, escape, STIO_NULL);
|
||||
}
|
||||
|
143
stio/lib/stio.h
143
stio/lib/stio.h
@ -48,8 +48,8 @@ struct stio_ntime_t
|
||||
#define STIO_SYSHND_INVALID (-1)
|
||||
#endif
|
||||
|
||||
typedef struct stio_devadr_t stio_devadr_t;
|
||||
struct stio_devadr_t
|
||||
typedef struct stio_devaddr_t stio_devaddr_t;
|
||||
struct stio_devaddr_t
|
||||
{
|
||||
int len;
|
||||
void* ptr;
|
||||
@ -79,7 +79,8 @@ struct stio_devadr_t
|
||||
# error UNKNOWN ENDIAN
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ========================================================================= */
|
||||
|
||||
typedef struct stio_t stio_t;
|
||||
typedef struct stio_dev_t stio_dev_t;
|
||||
typedef struct stio_dev_mth_t stio_dev_mth_t;
|
||||
@ -133,7 +134,8 @@ typedef void (*stio_tmrjob_updater_t) (
|
||||
struct stio_dev_mth_t
|
||||
{
|
||||
/* ------------------------------------------------------------------ */
|
||||
int (*make) (stio_dev_t* dev, void* ctx); /* mandatory. called in stio_makedev() */
|
||||
/* mandatory. called in stio_makedev() */
|
||||
int (*make) (stio_dev_t* dev, void* ctx);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* mandatory. called in stio_killdev(). also called in stio_makedev() upon
|
||||
@ -144,7 +146,9 @@ struct stio_dev_mth_t
|
||||
* until the method returns 0.
|
||||
*
|
||||
* when 'force' is 1, the called should not return -1. If it does, the
|
||||
* method is not called again.
|
||||
* method is called once more only with the 'force' value of 2.
|
||||
*
|
||||
* when 'force' is 2, the device is destroyed regardless of the return value.
|
||||
*/
|
||||
int (*kill) (stio_dev_t* dev, int force);
|
||||
|
||||
@ -156,10 +160,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_iolen_t* len, stio_devadr_t* srcadr);
|
||||
int (*read) (stio_dev_t* dev, void* data, stio_iolen_t* len, stio_devaddr_t* srcaddr);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
int (*write) (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr);
|
||||
int (*write) (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devaddr_t* dstaddr);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
int (*ioctl) (stio_dev_t* dev, int cmd, void* arg);
|
||||
@ -176,28 +180,28 @@ 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_iolen_t len, const stio_devadr_t* srcadr);
|
||||
int (*on_read) (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr);
|
||||
|
||||
/* 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_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr);
|
||||
int (*on_write) (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr);
|
||||
};
|
||||
|
||||
struct stio_wq_t
|
||||
{
|
||||
stio_wq_t* next;
|
||||
stio_wq_t* prev;
|
||||
stio_wq_t* next;
|
||||
stio_wq_t* prev;
|
||||
|
||||
stio_iolen_t olen; /* original data length */
|
||||
stio_uint8_t* ptr; /* pointer to data */
|
||||
stio_uint8_t* ptr; /* pointer to data */
|
||||
stio_iolen_t len; /* remaining data length */
|
||||
void* ctx;
|
||||
stio_dev_t* dev; /* back-pointer to the device */
|
||||
void* ctx;
|
||||
stio_dev_t* dev; /* back-pointer to the device */
|
||||
|
||||
stio_tmridx_t tmridx;
|
||||
stio_devadr_t dstadr;
|
||||
stio_tmridx_t tmridx;
|
||||
stio_devaddr_t dstaddr;
|
||||
};
|
||||
|
||||
#define STIO_WQ_INIT(wq) ((wq)->next = (wq)->prev = (wq))
|
||||
@ -311,9 +315,9 @@ typedef enum stio_dev_event_t stio_dev_event_t;
|
||||
#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
|
||||
#define STIO_ETHADDR_LEN 6
|
||||
#define STIO_IP4ADDR_LEN 4
|
||||
#define STIO_IP6ADDR_LEN 16
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
@ -333,29 +337,29 @@ typedef enum stio_dev_event_t stio_dev_event_t;
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
struct STIO_PACKED stio_ethadr_t
|
||||
struct STIO_PACKED stio_ethaddr_t
|
||||
{
|
||||
stio_uint8_t v[STIO_ETHADR_LEN];
|
||||
stio_uint8_t v[STIO_ETHADDR_LEN];
|
||||
};
|
||||
typedef struct stio_ethadr_t stio_ethadr_t;
|
||||
typedef struct stio_ethaddr_t stio_ethaddr_t;
|
||||
|
||||
struct STIO_PACKED stio_ip4adr_t
|
||||
struct STIO_PACKED stio_ip4addr_t
|
||||
{
|
||||
stio_uint8_t v[STIO_IP4ADR_LEN];
|
||||
stio_uint8_t v[STIO_IP4ADDR_LEN];
|
||||
};
|
||||
typedef struct stio_ip4adr_t stio_ip4adr_t;
|
||||
typedef struct stio_ip4addr_t stio_ip4addr_t;
|
||||
|
||||
struct STIO_PACKED stio_ip6adr_t
|
||||
struct STIO_PACKED stio_ip6addr_t
|
||||
{
|
||||
stio_uint8_t v[STIO_IP6ADR_LEN];
|
||||
stio_uint8_t v[STIO_IP6ADDR_LEN];
|
||||
};
|
||||
typedef struct stio_ip6adr_t stio_ip6adr_t;
|
||||
typedef struct stio_ip6addr_t stio_ip6addr_t;
|
||||
|
||||
|
||||
struct STIO_PACKED stio_ethhdr_t
|
||||
{
|
||||
stio_uint8_t dest[STIO_ETHADR_LEN];
|
||||
stio_uint8_t source[STIO_ETHADR_LEN];
|
||||
stio_uint8_t dest[STIO_ETHADDR_LEN];
|
||||
stio_uint8_t source[STIO_ETHADDR_LEN];
|
||||
stio_uint16_t proto;
|
||||
};
|
||||
typedef struct stio_ethhdr_t stio_ethhdr_t;
|
||||
@ -373,10 +377,10 @@ typedef struct stio_arphdr_t stio_arphdr_t;
|
||||
/* arp payload for ipv4 over ethernet */
|
||||
struct STIO_PACKED 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 */
|
||||
stio_uint8_t sha[STIO_ETHADDR_LEN]; /* source hardware address */
|
||||
stio_uint8_t spa[STIO_IP4ADDR_LEN]; /* source protocol address */
|
||||
stio_uint8_t tha[STIO_ETHADDR_LEN]; /* target hardware address */
|
||||
stio_uint8_t tpa[STIO_IP4ADDR_LEN]; /* target protocol address */
|
||||
};
|
||||
typedef struct stio_etharp_t stio_etharp_t;
|
||||
|
||||
@ -475,21 +479,21 @@ STIO_EXPORT int stio_dev_read (
|
||||
* it returns 0. otherwise it returns -1.
|
||||
*/
|
||||
STIO_EXPORT int stio_dev_write (
|
||||
stio_dev_t* dev,
|
||||
const void* data,
|
||||
stio_iolen_t len,
|
||||
void* wrctx,
|
||||
const stio_devadr_t* dstadr
|
||||
stio_dev_t* dev,
|
||||
const void* data,
|
||||
stio_iolen_t len,
|
||||
void* wrctx,
|
||||
const stio_devaddr_t* dstaddr
|
||||
);
|
||||
|
||||
|
||||
STIO_EXPORT 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
|
||||
stio_dev_t* dev,
|
||||
const void* data,
|
||||
stio_iolen_t len,
|
||||
const stio_ntime_t* tmout,
|
||||
void* wrctx,
|
||||
const stio_devaddr_t* dstaddr
|
||||
);
|
||||
|
||||
STIO_EXPORT void stio_dev_halt (
|
||||
@ -497,7 +501,7 @@ STIO_EXPORT void stio_dev_halt (
|
||||
);
|
||||
|
||||
|
||||
/* ------------------------------------------------ */
|
||||
/* ========================================================================= */
|
||||
|
||||
#define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
|
||||
#define stio_cleartime(x) stio_inittime(x,0,0)
|
||||
@ -565,6 +569,53 @@ STIO_EXPORT stio_tmrjob_t* stio_gettmrjob (
|
||||
stio_tmridx_t index
|
||||
);
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
|
||||
#if defined(STIO_HAVE_UINT16_T)
|
||||
STIO_EXPORT stio_uint16_t stio_ntoh16 (
|
||||
stio_uint16_t x
|
||||
);
|
||||
|
||||
STIO_EXPORT stio_uint16_t stio_hton16 (
|
||||
stio_uint16_t x
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(STIO_HAVE_UINT32_T)
|
||||
STIO_EXPORT stio_uint32_t stio_ntoh32 (
|
||||
stio_uint32_t x
|
||||
);
|
||||
|
||||
STIO_EXPORT stio_uint32_t stio_hton32 (
|
||||
stio_uint32_t x
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(STIO_HAVE_UINT64_T)
|
||||
STIO_EXPORT stio_uint64_t stio_ntoh64 (
|
||||
stio_uint64_t x
|
||||
);
|
||||
|
||||
STIO_EXPORT stio_uint64_t stio_hton64 (
|
||||
stio_uint64_t x
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(STIO_HAVE_UINT128_T)
|
||||
STIO_EXPORT stio_uint128_t stio_ntoh128 (
|
||||
stio_uint128_t x
|
||||
);
|
||||
|
||||
STIO_EXPORT stio_uint128_t stio_hton128 (
|
||||
stio_uint128_t x
|
||||
);
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user