2016-01-26 16:07:52 +00:00
/*
* $ 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 .
*/
2018-12-12 13:15:54 +00:00
# include <mio.h>
# include <mio-sck.h>
# include <mio-pro.h>
2016-01-28 16:44:47 +00:00
2016-01-26 16:02:20 +00:00
# include <stdlib.h>
2016-01-30 05:24:23 +00:00
# include <string.h>
2016-01-26 16:02:20 +00:00
# include <stdio.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <signal.h>
2016-03-29 15:02:01 +00:00
# include <net/if.h>
2016-04-25 14:07:28 +00:00
# include <assert.h>
2016-04-17 17:00:58 +00:00
# if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
# include <openssl / ssl.h>
# if defined(HAVE_OPENSSL_ERR_H)
# include <openssl / err.h>
# endif
# if defined(HAVE_OPENSSL_ENGINE_H)
# include <openssl / engine.h>
# endif
# define USE_SSL
# endif
2016-03-23 13:54:15 +00:00
/* ========================================================================= */
2016-02-04 15:06:20 +00:00
struct mmgr_stat_t
{
2018-12-12 13:15:54 +00:00
mio_size_t total_count ;
2016-02-04 15:06:20 +00:00
} ;
typedef struct mmgr_stat_t mmgr_stat_t ;
static mmgr_stat_t mmgr_stat ;
2018-12-12 13:15:54 +00:00
static void * mmgr_alloc ( mio_mmgr_t * mmgr , mio_size_t size )
2016-01-26 16:02:20 +00:00
{
2016-04-24 17:30:43 +00:00
void * x ;
2016-04-26 05:54:48 +00:00
if ( ( ( mmgr_stat_t * ) mmgr - > ctx ) - > total_count > 300 )
2016-02-04 15:06:20 +00:00
{
printf ( " CRITICAL ERROR ---> too many heap chunks... \n " ) ;
2018-12-12 13:15:54 +00:00
return MIO_NULL ;
2016-02-04 15:06:20 +00:00
}
2016-04-24 17:30:43 +00:00
x = malloc ( size ) ;
2016-02-04 15:06:20 +00:00
if ( x ) ( ( mmgr_stat_t * ) mmgr - > ctx ) - > total_count + + ;
return x ;
2016-01-26 16:02:20 +00:00
}
2018-12-12 13:15:54 +00:00
static void * mmgr_realloc ( mio_mmgr_t * mmgr , void * ptr , mio_size_t size )
2016-01-30 05:24:23 +00:00
{
return realloc ( ptr , size ) ;
}
2018-12-12 13:15:54 +00:00
static void mmgr_free ( mio_mmgr_t * mmgr , void * ptr )
2016-01-26 16:02:20 +00:00
{
2016-02-04 15:06:20 +00:00
( ( mmgr_stat_t * ) mmgr - > ctx ) - > total_count - - ;
2016-01-26 16:02:20 +00:00
return free ( ptr ) ;
}
2016-02-04 15:06:20 +00:00
2018-12-12 13:15:54 +00:00
static mio_mmgr_t mmgr =
2016-01-26 16:02:20 +00:00
{
mmgr_alloc ,
2016-01-30 05:24:23 +00:00
mmgr_realloc ,
2016-01-26 16:02:20 +00:00
mmgr_free ,
2016-02-04 15:06:20 +00:00
& mmgr_stat
} ;
2016-03-23 13:54:15 +00:00
/* ========================================================================= */
2016-04-17 17:00:58 +00:00
# if defined(USE_SSL)
static void cleanup_openssl ( )
{
/* ERR_remove_state() should be called for each thread if the application is thread */
ERR_remove_state ( 0 ) ;
# if defined(HAVE_ENGINE_CLEANUP)
ENGINE_cleanup ( ) ;
# endif
ERR_free_strings ( ) ;
EVP_cleanup ( ) ;
# if defined(HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
CRYPTO_cleanup_all_ex_data ( ) ;
# endif
}
# endif
2016-02-04 15:06:20 +00:00
struct tcp_server_t
{
int tally ;
2016-01-26 16:02:20 +00:00
} ;
2016-02-04 15:06:20 +00:00
typedef struct tcp_server_t tcp_server_t ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
static void tcp_sck_on_disconnect ( mio_dev_sck_t * tcp )
2016-01-26 16:02:20 +00:00
{
2018-12-12 13:15:54 +00:00
switch ( MIO_DEV_SCK_GET_PROGRESS ( tcp ) )
2016-01-30 05:24:23 +00:00
{
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_CONNECTING :
2016-04-25 14:07:28 +00:00
printf ( " OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER \n " , ( int ) tcp - > sck ) ;
2016-04-21 13:26:14 +00:00
break ;
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_CONNECTING_SSL :
2016-04-25 14:07:28 +00:00
printf ( " OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER \n " , ( int ) tcp - > sck ) ;
2016-04-21 13:26:14 +00:00
break ;
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_LISTENING :
2016-04-21 13:26:14 +00:00
printf ( " SHUTTING DOWN THE SERVER SOCKET(%d)... \n " , ( int ) tcp - > sck ) ;
break ;
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_CONNECTED :
2016-04-21 13:26:14 +00:00
printf ( " OUTGOING CLIENT CONNECTION GOT TORN DOWN(%d)....... \n " , ( int ) tcp - > sck ) ;
break ;
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_ACCEPTING_SSL :
2016-04-21 13:26:14 +00:00
printf ( " INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) .... \n " , ( int ) tcp - > sck ) ;
break ;
2018-12-12 13:15:54 +00:00
case MIO_DEV_SCK_ACCEPTED :
2016-04-21 13:26:14 +00:00
printf ( " INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d)....... \n " , ( int ) tcp - > sck ) ;
break ;
default :
2016-04-25 14:07:28 +00:00
printf ( " SOCKET DEVICE DISCONNECTED (%d - %x) \n " , ( int ) tcp - > sck , ( unsigned int ) tcp - > state ) ;
2016-04-21 13:26:14 +00:00
break ;
2016-01-26 16:02:20 +00:00
}
}
2018-12-12 13:15:54 +00:00
static int tcp_sck_on_connect ( mio_dev_sck_t * tcp )
2016-01-26 16:02:20 +00:00
{
2016-01-28 16:44:47 +00:00
2018-12-12 13:15:54 +00:00
mio_sckfam_t fam ;
mio_scklen_t len ;
mio_mchar_t buf1 [ 128 ] , buf2 [ 128 ] ;
2016-04-18 14:21:23 +00:00
2018-12-12 13:15:54 +00:00
memset ( buf1 , 0 , MIO_SIZEOF ( buf1 ) ) ;
memset ( buf2 , 0 , MIO_SIZEOF ( buf2 ) ) ;
2016-04-18 14:21:23 +00:00
2018-12-12 13:15:54 +00:00
mio_getsckaddrinfo ( tcp - > mio , & tcp - > localaddr , & len , & fam ) ;
inet_ntop ( fam , tcp - > localaddr . data , buf1 , MIO_COUNTOF ( buf1 ) ) ;
2016-04-18 14:21:23 +00:00
2018-12-12 13:15:54 +00:00
mio_getsckaddrinfo ( tcp - > mio , & tcp - > remoteaddr , & len , & fam ) ;
inet_ntop ( fam , tcp - > remoteaddr . data , buf2 , MIO_COUNTOF ( buf2 ) ) ;
2016-04-18 14:21:23 +00:00
2018-12-12 13:15:54 +00:00
if ( tcp - > state & MIO_DEV_SCK_CONNECTED )
2016-01-28 16:44:47 +00:00
{
2016-04-18 14:21:23 +00:00
2018-12-12 13:15:54 +00:00
printf ( " device connected to a remote server... LOCAL %s:%d REMOTE %s:%d. " , buf1 , mio_getsckaddrport ( & tcp - > localaddr ) , buf2 , mio_getsckaddrport ( & tcp - > remoteaddr ) ) ;
2016-04-18 14:21:23 +00:00
2016-01-28 16:44:47 +00:00
}
2018-12-12 13:15:54 +00:00
else if ( tcp - > state & MIO_DEV_SCK_ACCEPTED )
2016-01-28 16:44:47 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " device accepted client device... .LOCAL %s:%d REMOTE %s:%d \n " , buf1 , mio_getsckaddrport ( & tcp - > localaddr ) , buf2 , mio_getsckaddrport ( & tcp - > remoteaddr ) ) ;
2016-01-28 16:44:47 +00:00
}
2018-12-12 13:15:54 +00:00
return mio_dev_sck_write ( tcp , " hello " , 5 , MIO_NULL , MIO_NULL ) ;
2016-01-26 16:02:20 +00:00
}
2018-12-12 13:15:54 +00:00
static int tcp_sck_on_write ( mio_dev_sck_t * tcp , mio_iolen_t wrlen , void * wrctx , const mio_sckaddr_t * dstaddr )
2016-01-28 16:44:47 +00:00
{
2016-02-04 15:06:20 +00:00
tcp_server_t * ts ;
2016-02-05 13:25:59 +00:00
if ( wrlen < = - 1 )
{
printf ( " SEDING TIMED OUT........... \n " ) ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_halt ( tcp ) ;
2016-02-05 13:25:59 +00:00
}
else
{
2016-02-04 15:06:20 +00:00
ts = ( tcp_server_t * ) ( tcp + 1 ) ;
2016-02-05 13:25:59 +00:00
printf ( " >>> SENT MESSAGE %d of length %ld \n " , ts - > tally , ( long int ) wrlen ) ;
2016-02-04 15:06:20 +00:00
ts - > tally + + ;
2018-12-12 13:15:54 +00:00
// if (ts->tally >= 2) mio_dev_sck_halt (tcp);
2016-02-04 15:06:20 +00:00
printf ( " ENABLING READING.............................. \n " ) ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_read ( tcp , 1 ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
//mio_dev_sck_timedread (tcp, 1, 1000);
2016-02-05 13:25:59 +00:00
}
2016-01-28 16:44:47 +00:00
return 0 ;
}
2018-12-12 13:15:54 +00:00
static int tcp_sck_on_read ( mio_dev_sck_t * tcp , const void * buf , mio_iolen_t len , const mio_sckaddr_t * srcaddr )
2016-01-28 16:44:47 +00:00
{
2016-04-24 17:30:43 +00:00
int n ;
2016-02-04 15:06:20 +00:00
if ( len < = 0 )
{
printf ( " STREAM DEVICE: EOF RECEIVED... \n " ) ;
/* no outstanding request. but EOF */
2018-12-12 13:15:54 +00:00
mio_dev_sck_halt ( tcp ) ;
2016-02-04 15:06:20 +00:00
return 0 ;
}
printf ( " on read %d \n " , ( int ) len ) ;
2016-04-24 17:30:43 +00:00
{
2018-12-12 13:15:54 +00:00
mio_ntime_t tmout ;
2016-04-24 17:30:43 +00:00
2016-02-02 07:51:17 +00:00
static char a = ' A ' ;
char * xxx = malloc ( 1000000 ) ;
memset ( xxx , a + + , 1000000 ) ;
2016-04-24 17:30:43 +00:00
2018-12-12 13:15:54 +00:00
//return mio_dev_sck_write (tcp, "HELLO", 5, MIO_NULL);
mio_inittime ( & tmout , 5 , 0 ) ;
n = mio_dev_sck_timedwrite ( tcp , xxx , 1000000 , & tmout , MIO_NULL , MIO_NULL ) ;
2016-02-02 07:51:17 +00:00
free ( xxx ) ;
2016-02-04 15:06:20 +00:00
2016-04-24 17:30:43 +00:00
2016-02-04 15:06:20 +00:00
if ( n < = - 1 ) return - 1 ;
2016-04-24 17:30:43 +00:00
}
2016-02-04 15:06:20 +00:00
2016-04-25 14:07:28 +00:00
printf ( " DISABLING READING.............................. \n " ) ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_read ( tcp , 0 ) ;
2016-04-25 14:07:28 +00:00
2016-02-04 15:06:20 +00:00
/* post the write finisher */
2018-12-12 13:15:54 +00:00
n = mio_dev_sck_write ( tcp , MIO_NULL , 0 , MIO_NULL , MIO_NULL ) ;
2016-02-04 15:06:20 +00:00
if ( n < = - 1 ) return - 1 ;
return 0 ;
2016-03-23 13:54:15 +00:00
/* return 1; let the main loop to read more greedily without consulting the multiplexer */
2016-01-28 16:44:47 +00:00
}
2016-03-23 13:54:15 +00:00
/* ========================================================================= */
2018-12-12 13:15:54 +00:00
static void pro_on_close ( mio_dev_pro_t * dev , mio_dev_pro_sid_t sid )
2016-04-25 14:07:28 +00:00
{
printf ( " >>>>>>>>>>>>> ON CLOSE OF SLAVE %d. \n " , sid ) ;
}
2018-12-12 13:15:54 +00:00
static int pro_on_read ( mio_dev_pro_t * dev , const void * data , mio_iolen_t dlen , mio_dev_pro_sid_t sid )
2016-04-25 14:07:28 +00:00
{
printf ( " PROCESS READ DATA on SLAVE[%d]... [%.*s] \n " , ( int ) sid , ( int ) dlen , ( char * ) data ) ;
return 0 ;
}
2018-12-12 13:15:54 +00:00
static int pro_on_write ( mio_dev_pro_t * dev , mio_iolen_t wrlen , void * wrctx )
2016-04-25 14:07:28 +00:00
{
printf ( " PROCESS WROTE DATA... \n " ) ;
return 0 ;
}
/* ========================================================================= */
2018-12-12 13:15:54 +00:00
static int arp_sck_on_read ( mio_dev_sck_t * dev , const void * data , mio_iolen_t dlen , const mio_sckaddr_t * srcaddr )
2016-03-23 13:54:15 +00:00
{
2018-12-12 13:15:54 +00:00
mio_etharp_pkt_t * eap ;
2016-04-25 16:15:36 +00:00
2016-03-30 07:06:54 +00:00
2018-12-12 13:15:54 +00:00
if ( dlen < MIO_SIZEOF ( * eap ) ) return 0 ; /* drop */
2016-03-30 07:06:54 +00:00
2018-12-12 13:15:54 +00:00
eap = ( mio_etharp_pkt_t * ) data ;
2016-04-25 16:15:36 +00:00
2018-12-12 13:15:54 +00:00
printf ( " ARP ON IFINDEX %d OPCODE: %d " , mio_getsckaddrifindex ( srcaddr ) , ntohs ( eap - > arphdr . opcode ) ) ;
2016-04-25 16:15:36 +00:00
2016-03-30 07:06:54 +00:00
printf ( " SHA: %02X:%02X:%02X:%02X:%02X:%02X " , eap - > arppld . sha [ 0 ] , eap - > arppld . sha [ 1 ] , eap - > arppld . sha [ 2 ] , eap - > arppld . sha [ 3 ] , eap - > arppld . sha [ 4 ] , eap - > arppld . sha [ 5 ] ) ;
printf ( " SPA: %d.%d.%d.%d " , eap - > arppld . spa [ 0 ] , eap - > arppld . spa [ 1 ] , eap - > arppld . spa [ 2 ] , eap - > arppld . spa [ 3 ] ) ;
printf ( " THA: %02X:%02X:%02X:%02X:%02X:%02X " , eap - > arppld . tha [ 0 ] , eap - > arppld . tha [ 1 ] , eap - > arppld . tha [ 2 ] , eap - > arppld . tha [ 3 ] , eap - > arppld . tha [ 4 ] , eap - > arppld . tha [ 5 ] ) ;
printf ( " TPA: %d.%d.%d.%d " , eap - > arppld . tpa [ 0 ] , eap - > arppld . tpa [ 1 ] , eap - > arppld . tpa [ 2 ] , eap - > arppld . tpa [ 3 ] ) ;
printf ( " \n " ) ;
2016-03-23 13:54:15 +00:00
return 0 ;
}
2018-12-12 13:15:54 +00:00
static int arp_sck_on_write ( mio_dev_sck_t * dev , mio_iolen_t wrlen , void * wrctx , const mio_sckaddr_t * dstaddr )
2016-03-23 13:54:15 +00:00
{
return 0 ;
}
2018-12-12 13:15:54 +00:00
static void arp_sck_on_disconnect ( mio_dev_sck_t * dev )
2016-04-25 14:07:28 +00:00
{
printf ( " SHUTTING DOWN ARP SOCKET %d... \n " , dev - > sck ) ;
}
2018-12-12 13:15:54 +00:00
static int setup_arp_tester ( mio_t * mio )
2016-04-25 14:07:28 +00:00
{
2018-12-12 13:15:54 +00:00
mio_sckaddr_t ethdst ;
mio_etharp_pkt_t etharp ;
mio_dev_sck_make_t sck_make ;
mio_dev_sck_t * sck ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
memset ( & sck_make , 0 , MIO_SIZEOF ( sck_make ) ) ;
sck_make . type = MIO_DEV_SCK_ARP ;
//sck_make.type = MIO_DEV_SCK_ARP_DGRAM;
2016-04-25 14:07:28 +00:00
sck_make . on_write = arp_sck_on_write ;
sck_make . on_read = arp_sck_on_read ;
sck_make . on_disconnect = arp_sck_on_disconnect ;
2018-12-12 13:15:54 +00:00
sck = mio_dev_sck_make ( mio , 0 , & sck_make ) ;
2016-04-25 14:07:28 +00:00
if ( ! sck )
{
printf ( " Cannot make socket device \n " ) ;
return - 1 ;
}
2018-12-12 13:15:54 +00:00
//mio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (mio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
mio_sckaddr_initforeth ( & ethdst , if_nametoindex ( " enp0s25.3 " ) , ( mio_ethaddr_t * ) " \xAA \xBB \xFF \xCC \xDD \xFF " ) ;
2016-04-25 14:07:28 +00:00
memset ( & etharp , 0 , sizeof ( etharp ) ) ;
2018-12-12 13:15:54 +00:00
memcpy ( etharp . ethhdr . source , " \xB8 \x6B \x23 \x9C \x10 \x76 " , MIO_ETHADDR_LEN ) ;
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", MIO_ETHADDR_LEN);
memcpy ( etharp . ethhdr . dest , " \xAA \xBB \xFF \xCC \xDD \xFF " , MIO_ETHADDR_LEN ) ;
etharp . ethhdr . proto = MIO_CONST_HTON16 ( MIO_ETHHDR_PROTO_ARP ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
etharp . arphdr . htype = MIO_CONST_HTON16 ( MIO_ARPHDR_HTYPE_ETH ) ;
etharp . arphdr . ptype = MIO_CONST_HTON16 ( MIO_ARPHDR_PTYPE_IP4 ) ;
etharp . arphdr . hlen = MIO_ETHADDR_LEN ;
etharp . arphdr . plen = MIO_IP4ADDR_LEN ;
etharp . arphdr . opcode = MIO_CONST_HTON16 ( MIO_ARPHDR_OPCODE_REQUEST ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
memcpy ( etharp . arppld . sha , " \xB8 \x6B \x23 \x9C \x10 \x76 " , MIO_ETHADDR_LEN ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_write ( sck , & etharp , sizeof ( etharp ) , NULL , & ethdst ) < = - 1 )
//if (mio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, ðaddr) <= -1)
2016-04-25 14:07:28 +00:00
{
printf ( " CANNOT WRITE ARP... \n " ) ;
}
return 0 ;
}
2016-04-12 13:56:59 +00:00
/* ========================================================================= */
2016-04-25 14:07:28 +00:00
struct icmpxtn_t
2016-04-12 13:56:59 +00:00
{
2018-12-12 13:15:54 +00:00
mio_uint16_t icmp_seq ;
mio_tmridx_t tmout_jobidx ;
2016-04-25 14:07:28 +00:00
int reply_received ;
} ;
typedef struct icmpxtn_t icmpxtn_t ;
2018-12-12 13:15:54 +00:00
static int schedule_icmp_wait ( mio_dev_sck_t * dev ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
static void send_icmp ( mio_dev_sck_t * dev , mio_uint16_t seq )
2016-04-25 14:07:28 +00:00
{
2018-12-12 13:15:54 +00:00
mio_sckaddr_t dstaddr ;
mio_ip4addr_t ia ;
mio_icmphdr_t * icmphdr ;
mio_uint8_t buf [ 512 ] ;
2016-04-25 14:07:28 +00:00
inet_pton ( AF_INET , " 192.168.1.131 " , & ia ) ;
2018-12-12 13:15:54 +00:00
mio_sckaddr_initforip4 ( & dstaddr , 0 , & ia ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
memset ( buf , 0 , MIO_SIZEOF ( buf ) ) ;
icmphdr = ( mio_icmphdr_t * ) buf ;
icmphdr - > type = MIO_ICMP_ECHO_REQUEST ;
icmphdr - > u . echo . id = MIO_CONST_HTON16 ( 100 ) ;
icmphdr - > u . echo . seq = mio_hton16 ( seq ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
memset ( & buf [ MIO_SIZEOF ( * icmphdr ) ] , ' A ' , MIO_SIZEOF ( buf ) - MIO_SIZEOF ( * icmphdr ) ) ;
icmphdr - > checksum = mio_checksumip ( icmphdr , MIO_SIZEOF ( buf ) ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_write ( dev , buf , MIO_SIZEOF ( buf ) , NULL , & dstaddr ) < = - 1 )
2016-04-25 14:07:28 +00:00
{
printf ( " CANNOT WRITE ICMP... \n " ) ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_halt ( dev ) ;
2016-04-25 14:07:28 +00:00
}
if ( schedule_icmp_wait ( dev ) < = - 1 )
{
printf ( " CANNOT SCHEDULE ICMP WAIT... \n " ) ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_halt ( dev ) ;
2016-04-25 14:07:28 +00:00
}
2016-04-16 16:05:57 +00:00
}
2018-12-12 13:15:54 +00:00
static void on_icmp_due ( mio_t * mio , const mio_ntime_t * now , mio_tmrjob_t * tmrjob )
2016-04-16 16:05:57 +00:00
{
2018-12-12 13:15:54 +00:00
mio_dev_sck_t * dev ;
2016-04-25 14:07:28 +00:00
icmpxtn_t * icmpxtn ;
dev = tmrjob - > ctx ;
icmpxtn = ( icmpxtn_t * ) ( dev + 1 ) ;
if ( icmpxtn - > reply_received )
icmpxtn - > reply_received = 0 ;
else
printf ( " NO ICMP REPLY RECEIVED.... \n " ) ;
send_icmp ( dev , + + icmpxtn - > icmp_seq ) ;
}
2018-12-12 13:15:54 +00:00
static int schedule_icmp_wait ( mio_dev_sck_t * dev )
2016-04-25 14:07:28 +00:00
{
icmpxtn_t * icmpxtn ;
2018-12-12 13:15:54 +00:00
mio_tmrjob_t tmrjob ;
mio_ntime_t fire_after ;
2016-04-25 14:07:28 +00:00
icmpxtn = ( icmpxtn_t * ) ( dev + 1 ) ;
2018-12-12 13:15:54 +00:00
mio_inittime ( & fire_after , 2 , 0 ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
memset ( & tmrjob , 0 , MIO_SIZEOF ( tmrjob ) ) ;
2016-04-25 14:07:28 +00:00
tmrjob . ctx = dev ;
2018-12-12 13:15:54 +00:00
mio_gettime ( & tmrjob . when ) ;
mio_addtime ( & tmrjob . when , & fire_after , & tmrjob . when ) ;
2016-04-25 14:07:28 +00:00
tmrjob . handler = on_icmp_due ;
tmrjob . idxptr = & icmpxtn - > tmout_jobidx ;
2018-12-12 13:15:54 +00:00
assert ( icmpxtn - > tmout_jobidx = = MIO_TMRIDX_INVALID ) ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
return ( mio_instmrjob ( dev - > mio , & tmrjob ) = = MIO_TMRIDX_INVALID ) ? - 1 : 0 ;
2016-04-25 14:07:28 +00:00
}
2018-12-12 13:15:54 +00:00
static int icmp_sck_on_read ( mio_dev_sck_t * dev , const void * data , mio_iolen_t dlen , const mio_sckaddr_t * srcaddr )
2016-04-25 14:07:28 +00:00
{
icmpxtn_t * icmpxtn ;
2018-12-12 13:15:54 +00:00
mio_iphdr_t * iphdr ;
mio_icmphdr_t * icmphdr ;
2016-04-25 14:07:28 +00:00
/* when received, the data contains the IP header.. */
icmpxtn = ( icmpxtn_t * ) ( dev + 1 ) ;
2018-12-12 13:15:54 +00:00
if ( dlen < MIO_SIZEOF ( * iphdr ) + MIO_SIZEOF ( * icmphdr ) )
2016-04-25 14:07:28 +00:00
{
printf ( " INVALID ICMP PACKET.. TOO SHORT...%d \n " , ( int ) dlen ) ;
}
else
{
/* TODO: consider IP options... */
2018-12-12 13:15:54 +00:00
iphdr = ( mio_iphdr_t * ) data ;
2016-04-25 14:07:28 +00:00
2018-12-12 13:15:54 +00:00
if ( iphdr - > ihl * 4 + MIO_SIZEOF ( * icmphdr ) > dlen )
2016-04-25 14:07:28 +00:00
{
2016-04-26 05:54:48 +00:00
printf ( " INVALID ICMP PACKET.. WRONG IHL...%d \n " , ( int ) iphdr - > ihl * 4 ) ;
2016-04-25 14:07:28 +00:00
}
else
{
2018-12-12 13:15:54 +00:00
icmphdr = ( mio_icmphdr_t * ) ( ( mio_uint8_t * ) data + ( iphdr - > ihl * 4 ) ) ;
2016-04-26 05:54:48 +00:00
/* TODO: check srcaddr against target */
2018-12-12 13:15:54 +00:00
if ( icmphdr - > type = = MIO_ICMP_ECHO_REPLY & &
mio_ntoh16 ( icmphdr - > u . echo . seq ) = = icmpxtn - > icmp_seq ) /* TODO: more check.. echo.id.. */
2016-04-26 05:54:48 +00:00
{
icmpxtn - > reply_received = 1 ;
2018-12-12 13:15:54 +00:00
printf ( " ICMP REPLY RECEIVED...ID %d SEQ %d \n " , ( int ) mio_ntoh16 ( icmphdr - > u . echo . id ) , ( int ) mio_ntoh16 ( icmphdr - > u . echo . seq ) ) ;
2016-04-26 05:54:48 +00:00
}
else
{
2018-12-12 13:15:54 +00:00
printf ( " GARBAGE ICMP PACKET...LEN %d SEQ %d,%d \n " , ( int ) dlen , ( int ) icmpxtn - > icmp_seq , ( int ) mio_ntoh16 ( icmphdr - > u . echo . seq ) ) ;
2016-04-26 05:54:48 +00:00
}
2016-04-25 14:07:28 +00:00
}
}
2016-04-12 13:56:59 +00:00
return 0 ;
}
2018-12-12 13:15:54 +00:00
static int icmp_sck_on_write ( mio_dev_sck_t * dev , mio_iolen_t wrlen , void * wrctx , const mio_sckaddr_t * dstaddr )
2016-04-12 13:56:59 +00:00
{
2016-04-25 14:07:28 +00:00
/*icmpxtn_t* icmpxtn;
icmpxtn = ( icmpxtn_t * ) ( dev + 1 ) ; */
return 0 ;
}
2018-12-12 13:15:54 +00:00
static void icmp_sck_on_disconnect ( mio_dev_sck_t * dev )
2016-04-25 14:07:28 +00:00
{
icmpxtn_t * icmpxtn ;
icmpxtn = ( icmpxtn_t * ) ( dev + 1 ) ;
printf ( " SHUTTING DOWN ICMP SOCKET %d... \n " , dev - > sck ) ;
2018-12-12 13:15:54 +00:00
if ( icmpxtn - > tmout_jobidx ! = MIO_TMRIDX_INVALID )
2016-04-25 14:07:28 +00:00
{
2018-12-12 13:15:54 +00:00
mio_deltmrjob ( dev - > mio , icmpxtn - > tmout_jobidx ) ;
icmpxtn - > tmout_jobidx = MIO_TMRIDX_INVALID ;
2016-04-25 14:07:28 +00:00
}
}
2018-12-12 13:15:54 +00:00
static int setup_ping4_tester ( mio_t * mio )
2016-04-25 14:07:28 +00:00
{
2018-12-12 13:15:54 +00:00
mio_dev_sck_make_t sck_make ;
mio_dev_sck_t * sck ;
2016-04-25 14:07:28 +00:00
icmpxtn_t * icmpxtn ;
2018-12-12 13:15:54 +00:00
memset ( & sck_make , 0 , MIO_SIZEOF ( sck_make ) ) ;
sck_make . type = MIO_DEV_SCK_ICMP4 ;
2016-04-25 14:07:28 +00:00
sck_make . on_write = icmp_sck_on_write ;
sck_make . on_read = icmp_sck_on_read ;
sck_make . on_disconnect = icmp_sck_on_disconnect ;
2018-12-12 13:15:54 +00:00
sck = mio_dev_sck_make ( mio , MIO_SIZEOF ( icmpxtn_t ) , & sck_make ) ;
2016-04-25 14:07:28 +00:00
if ( ! sck )
{
printf ( " Cannot make ICMP4 socket device \n " ) ;
return - 1 ;
}
icmpxtn = ( icmpxtn_t * ) ( sck + 1 ) ;
2018-12-12 13:15:54 +00:00
icmpxtn - > tmout_jobidx = MIO_TMRIDX_INVALID ;
2016-04-25 14:07:28 +00:00
icmpxtn - > icmp_seq = 0 ;
2018-12-12 13:15:54 +00:00
/*TODO: mio_dev_sck_setbroadcast (sck, 1);*/
2016-04-25 14:07:28 +00:00
send_icmp ( sck , + + icmpxtn - > icmp_seq ) ;
2016-04-12 13:56:59 +00:00
return 0 ;
}
2016-03-23 13:54:15 +00:00
2016-04-25 14:07:28 +00:00
2016-03-23 13:54:15 +00:00
/* ========================================================================= */
2018-12-12 13:15:54 +00:00
static mio_t * g_mio ;
2016-01-26 16:02:20 +00:00
static void handle_signal ( int sig )
{
2018-12-12 13:15:54 +00:00
if ( g_mio ) mio_stop ( g_mio , MIO_STOPREQ_TERMINATION ) ;
2016-01-26 16:02:20 +00:00
}
int main ( )
{
2016-04-17 17:00:58 +00:00
int i ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
mio_t * mio ;
mio_dev_sck_t * tcp [ 3 ] ;
2016-04-02 15:25:35 +00:00
2016-01-26 16:02:20 +00:00
struct sigaction sigact ;
2018-12-12 13:15:54 +00:00
mio_dev_sck_connect_t tcp_conn ;
mio_dev_sck_listen_t tcp_lstn ;
mio_dev_sck_bind_t tcp_bind ;
mio_dev_sck_make_t tcp_make ;
2016-04-25 14:07:28 +00:00
2016-02-04 15:06:20 +00:00
tcp_server_t * ts ;
2016-01-26 16:02:20 +00:00
2016-04-17 17:00:58 +00:00
# if defined(USE_SSL)
SSL_load_error_strings ( ) ;
SSL_library_init ( ) ;
# endif
2018-12-12 13:15:54 +00:00
mio = mio_open ( & mmgr , 0 , 512 , MIO_NULL ) ;
if ( ! mio )
2016-01-26 16:02:20 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " Cannot open mio \n " ) ;
2016-01-26 16:02:20 +00:00
return - 1 ;
}
2018-12-12 13:15:54 +00:00
g_mio = mio ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
memset ( & sigact , 0 , MIO_SIZEOF ( sigact ) ) ;
2016-01-26 16:02:20 +00:00
sigact . sa_flags = SA_RESTART ;
sigact . sa_handler = handle_signal ;
2018-12-12 13:15:54 +00:00
sigaction ( SIGINT , & sigact , MIO_NULL ) ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
memset ( & sigact , 0 , MIO_SIZEOF ( sigact ) ) ;
2016-02-02 07:51:17 +00:00
sigact . sa_handler = SIG_IGN ;
2018-12-12 13:15:54 +00:00
sigaction ( SIGPIPE , & sigact , MIO_NULL ) ;
2016-01-28 17:32:58 +00:00
2016-04-16 16:05:57 +00:00
/*
2018-12-12 13:15:54 +00:00
memset ( & sigact , 0 , MIO_SIZEOF ( sigact ) ) ;
2016-04-16 16:05:57 +00:00
sigact . sa_handler = SIG_IGN ;
2018-12-12 13:15:54 +00:00
sigaction ( SIGCHLD , & sigact , MIO_NULL ) ;
2016-04-16 16:05:57 +00:00
*/
2018-12-12 13:15:54 +00:00
/*memset (&sin, 0, MIO_SIZEOF(sin));
2016-01-26 16:02:20 +00:00
sin . sin_family = AF_INET ;
2016-02-02 07:51:17 +00:00
sin . sin_port = htons ( 1234 ) ; */
2016-01-26 16:02:20 +00:00
/*
2018-12-12 13:15:54 +00:00
udp = ( mio_dev_udp_t * ) mio_makedev ( mio , MIO_SIZEOF ( * udp ) , & udp_mth , & udp_evcb , & sin ) ;
2016-01-26 16:02:20 +00:00
if ( ! udp )
{
printf ( " Cannot make udp \n " ) ;
goto oops ;
}
*/
2018-12-12 13:15:54 +00:00
memset ( & tcp_make , 0 , MIO_SIZEOF ( & tcp_make ) ) ;
tcp_make . type = MIO_DEV_SCK_TCP4 ;
2016-04-02 15:25:35 +00:00
tcp_make . on_write = tcp_sck_on_write ;
tcp_make . on_read = tcp_sck_on_read ;
2016-04-25 14:07:28 +00:00
tcp_make . on_disconnect = tcp_sck_on_disconnect ;
2018-12-12 13:15:54 +00:00
tcp [ 0 ] = mio_dev_sck_make ( mio , MIO_SIZEOF ( tcp_server_t ) , & tcp_make ) ;
2016-01-30 05:24:23 +00:00
if ( ! tcp [ 0 ] )
2016-01-26 16:02:20 +00:00
{
printf ( " Cannot make tcp \n " ) ;
goto oops ;
}
2016-02-04 15:06:20 +00:00
ts = ( tcp_server_t * ) ( tcp [ 0 ] + 1 ) ;
ts - > tally = 0 ;
2016-01-30 19:08:28 +00:00
2018-12-12 13:15:54 +00:00
memset ( & tcp_conn , 0 , MIO_SIZEOF ( tcp_conn ) ) ;
2016-04-02 15:25:35 +00:00
{
in_addr_t ia = inet_addr ( " 192.168.1.119 " ) ;
2018-12-12 13:15:54 +00:00
mio_sckaddr_initforip4 ( & tcp_conn . remoteaddr , 9999 , ( mio_ip4addr_t * ) & ia ) ;
2016-04-02 15:25:35 +00:00
}
2016-04-21 13:26:14 +00:00
2018-12-12 13:15:54 +00:00
mio_inittime ( & tcp_conn . connect_tmout , 5 , 0 ) ;
2016-04-02 15:25:35 +00:00
tcp_conn . on_connect = tcp_sck_on_connect ;
2018-12-12 13:15:54 +00:00
tcp_conn . options = MIO_DEV_SCK_CONNECT_SSL ;
if ( mio_dev_sck_connect ( tcp [ 0 ] , & tcp_conn ) < = - 1 )
2016-01-26 16:02:20 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " mio_dev_sck_connect() failed.... \n " ) ;
2016-04-21 15:07:58 +00:00
/* carry on regardless of failure */
2016-01-26 16:02:20 +00:00
}
2016-01-28 16:44:47 +00:00
2016-04-17 17:00:58 +00:00
/* -------------------------------------------------------------- */
2018-12-12 13:15:54 +00:00
memset ( & tcp_make , 0 , MIO_SIZEOF ( & tcp_make ) ) ;
tcp_make . type = MIO_DEV_SCK_TCP4 ;
2016-04-02 15:25:35 +00:00
tcp_make . on_write = tcp_sck_on_write ;
tcp_make . on_read = tcp_sck_on_read ;
2016-04-25 14:07:28 +00:00
tcp_make . on_disconnect = tcp_sck_on_disconnect ;
2016-04-17 17:00:58 +00:00
2018-12-12 13:15:54 +00:00
tcp [ 1 ] = mio_dev_sck_make ( mio , MIO_SIZEOF ( tcp_server_t ) , & tcp_make ) ;
2016-01-30 05:24:23 +00:00
if ( ! tcp [ 1 ] )
2016-01-26 16:02:20 +00:00
{
printf ( " Cannot make tcp \n " ) ;
goto oops ;
}
2016-02-04 15:06:20 +00:00
ts = ( tcp_server_t * ) ( tcp [ 1 ] + 1 ) ;
ts - > tally = 0 ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
memset ( & tcp_bind , 0 , MIO_SIZEOF ( tcp_bind ) ) ;
mio_sckaddr_initforip4 ( & tcp_bind . localaddr , 1234 , MIO_NULL ) ;
tcp_bind . options = MIO_DEV_SCK_BIND_REUSEADDR ;
2016-04-17 17:00:58 +00:00
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_bind ( tcp [ 1 ] , & tcp_bind ) < = - 1 )
2016-04-17 17:00:58 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " mio_dev_sck_bind() failed.... \n " ) ;
2016-04-17 17:00:58 +00:00
goto oops ;
}
tcp_lstn . backlogs = 100 ;
tcp_lstn . on_connect = tcp_sck_on_connect ;
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_listen ( tcp [ 1 ] , & tcp_lstn ) < = - 1 )
2016-04-17 17:00:58 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " mio_dev_sck_listen() failed.... \n " ) ;
2016-04-17 17:00:58 +00:00
goto oops ;
}
/* -------------------------------------------------------------- */
2018-12-12 13:15:54 +00:00
memset ( & tcp_make , 0 , MIO_SIZEOF ( & tcp_make ) ) ;
tcp_make . type = MIO_DEV_SCK_TCP4 ;
2016-04-17 17:00:58 +00:00
tcp_make . on_write = tcp_sck_on_write ;
tcp_make . on_read = tcp_sck_on_read ;
2016-04-25 14:07:28 +00:00
tcp_make . on_disconnect = tcp_sck_on_disconnect ;
2016-04-17 17:00:58 +00:00
2018-12-12 13:15:54 +00:00
tcp [ 2 ] = mio_dev_sck_make ( mio , MIO_SIZEOF ( tcp_server_t ) , & tcp_make ) ;
2016-04-17 17:00:58 +00:00
if ( ! tcp [ 2 ] )
{
printf ( " Cannot make tcp \n " ) ;
goto oops ;
}
ts = ( tcp_server_t * ) ( tcp [ 2 ] + 1 ) ;
ts - > tally = 0 ;
2018-12-12 13:15:54 +00:00
memset ( & tcp_bind , 0 , MIO_SIZEOF ( tcp_bind ) ) ;
mio_sckaddr_initforip4 ( & tcp_bind . localaddr , 1235 , MIO_NULL ) ;
tcp_bind . options = MIO_DEV_SCK_BIND_REUSEADDR | /*MIO_DEV_SCK_BIND_REUSEPORT |*/ MIO_DEV_SCK_BIND_SSL ;
tcp_bind . ssl_certfile = MIO_MT ( " localhost.crt " ) ;
tcp_bind . ssl_keyfile = MIO_MT ( " localhost.key " ) ;
mio_inittime ( & tcp_bind . accept_tmout , 5 , 1 ) ;
2016-03-30 16:31:56 +00:00
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_bind ( tcp [ 2 ] , & tcp_bind ) < = - 1 )
2016-03-30 16:31:56 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " mio_dev_sck_bind() failed.... \n " ) ;
2016-03-30 16:31:56 +00:00
goto oops ;
}
2016-01-26 16:02:20 +00:00
tcp_lstn . backlogs = 100 ;
2016-04-02 15:25:35 +00:00
tcp_lstn . on_connect = tcp_sck_on_connect ;
2018-12-12 13:15:54 +00:00
if ( mio_dev_sck_listen ( tcp [ 2 ] , & tcp_lstn ) < = - 1 )
2016-01-26 16:02:20 +00:00
{
2018-12-12 13:15:54 +00:00
printf ( " mio_dev_sck_listen() failed.... \n " ) ;
2016-01-26 16:02:20 +00:00
goto oops ;
}
2016-01-26 16:07:52 +00:00
2018-12-12 13:15:54 +00:00
//mio_dev_sck_sendfile (tcp[2], fd, offset, count);
2016-03-23 13:54:15 +00:00
2018-12-12 13:15:54 +00:00
if ( setup_arp_tester ( mio ) < = - 1 ) goto oops ;
if ( setup_ping4_tester ( mio ) < = - 1 ) goto oops ;
2016-03-29 15:02:01 +00:00
2016-04-12 13:56:59 +00:00
2016-04-17 17:00:58 +00:00
for ( i = 0 ; i < 5 ; i + + )
2016-04-12 13:56:59 +00:00
{
2018-12-12 13:15:54 +00:00
mio_dev_pro_t * pro ;
mio_dev_pro_make_t pro_make ;
2016-04-12 13:56:59 +00:00
2018-12-12 13:15:54 +00:00
memset ( & pro_make , 0 , MIO_SIZEOF ( pro_make ) ) ;
pro_make . flags = MIO_DEV_PRO_READOUT | MIO_DEV_PRO_READERR | MIO_DEV_PRO_WRITEIN /*| MIO_DEV_PRO_FORGET_CHILD*/ ;
2016-04-12 13:56:59 +00:00
//pro_make.cmd = "/bin/ls -laF /usr/bin";
2016-04-16 16:05:57 +00:00
//pro_make.cmd = "/bin/ls -laF";
pro_make . cmd = " ./a " ;
2016-04-12 13:56:59 +00:00
pro_make . on_read = pro_on_read ;
pro_make . on_write = pro_on_write ;
2016-04-16 16:05:57 +00:00
pro_make . on_close = pro_on_close ;
2016-04-12 13:56:59 +00:00
2018-12-12 13:15:54 +00:00
pro = mio_dev_pro_make ( mio , 0 , & pro_make ) ;
2016-04-12 13:56:59 +00:00
if ( ! pro )
{
printf ( " CANNOT CREATE PROCESS PIPE \n " ) ;
goto oops ;
}
2016-04-16 16:05:57 +00:00
2018-12-12 13:15:54 +00:00
mio_dev_pro_write ( pro , " MY MIO LIBRARY \n " , 16 , MIO_NULL ) ;
//mio_dev_pro_killchild (pro);
//mio_dev_pro_close (pro, MIO_DEV_PRO_IN);
//mio_dev_pro_close (pro, MIO_DEV_PRO_OUT);
//mio_dev_pro_close (pro, MIO_DEV_PRO_ERR);
2016-04-12 13:56:59 +00:00
}
2018-12-12 13:15:54 +00:00
mio_loop ( mio ) ;
2016-01-26 16:02:20 +00:00
2018-12-12 13:15:54 +00:00
g_mio = MIO_NULL ;
mio_close ( mio ) ;
2016-04-17 17:00:58 +00:00
# if defined(USE_SSL)
cleanup_openssl ( ) ;
# endif
2016-01-30 05:24:23 +00:00
2016-01-26 16:02:20 +00:00
return 0 ;
oops :
2018-12-12 13:15:54 +00:00
g_mio = MIO_NULL ;
mio_close ( mio ) ;
2016-04-17 17:00:58 +00:00
# if defined(USE_SSL)
cleanup_openssl ( ) ;
# endif
2016-01-26 16:02:20 +00:00
return - 1 ;
}