Moshe, Kfir schrieb:
>
> Hey
>
>  
>
> I  would like to change the main send and receive function that
> OpenSSL uses to functions written by me
>
> So every packet send\receive by OpenSSL will be actually send\receive
> from my code
>
> BUT: I want to keep the whole TLS\SSL logic as is
>
Yes, easy, just for OpenSSL beginner as I am.
Just take source copy of BIO_s_accept, build your own copy (must create
IOCTLs with higher, unused numbers) and change directly in your own
custom switch() block.

To better understanding, you can use my gauge/progress indicator BIO,
which is hereby released to public without any license or restriction.
But note: BIO_f_gauge is not production quality code, just for my
learning of BIO concept, last week.

Greetings,
Modem Man

#include <string.h> /*strlen*/
#include <time.h> /*strlen*/

#include <openssl\bio.h>
#include <openssl\err.h>

#include "BIO_f_gauge.h"

#ifdef __cplusplus
  extern "C" {
#endif


static int  gauge_write(BIO *h, const char *buf,int num);
static int  gauge_read( BIO *h, char *buf, int size);
static int  gauge_puts( BIO *h, const char *str);
static int  gauge_gets( BIO *h, char *str, int size);
static long gauge_ctrl( BIO *h, int cmd, long arg1, void *arg2);
static int  gauge_new(  BIO *h);
static int  gauge_free( BIO *data);
static long gauge_callback_ctrl( BIO *h, int cmd, bio_info_cb *fp );



typedef struct gauge_struct
        {
        unsigned long            Rx,Tx;
        time_t                   TxStartTime, RxStartTime;
        void                   * GaugeHandle;
        GAUGE_CALLBACK_ROUTINE   GaugeCB;
        } BIO_F_GAUGE_CTX;



/* Sample Gauge foo */
#if 0
void Gauge( BIO *b, void* GaugeHandle, int IsRx )
  {
  FILE *fHnd;
  unsigned long Value, Speed;
  time_t Delta, Last;
  
  Value = BIO_ctrl( b, (IsRx) ? BIO_CTRL_GAUGE_GET_RX     : 
BIO_CTRL_GAUGE_GET_TX,     0, NULL );
  Last  = BIO_ctrl( b, (IsRx) ? BIO_CTRL_GAUGE_GET_RXTIME : 
BIO_CTRL_GAUGE_GET_TXTIME, 0, NULL );
  
  Delta = time(NULL) - Last; /* WinCE: time() emulation or port is avail as 
open source/free */
  if(0==Delta) Delta++;  /* simple div by zero blocker */
  
  Speed = Value / (unsigned long) Delta;
  
  fHnd = (FILE*) GaugeHandle;
  if( fHnd )
    {
    fprintf( fHnd, "== Transfer Speed %s: %lu cps (%lu in %lu)==\n", 
(IsRx)?"Rx":"Tx", Speed, Value, Delta );
    }
  return;
  }
#endif


static BIO_METHOD methods_gauge =
        {
        BIO_TYPE_GAUGE, "gauge",
        gauge_write,
        gauge_read,
        gauge_puts,
        gauge_gets,
        gauge_ctrl,
        gauge_new,
        gauge_free,
        gauge_callback_ctrl,
        };



BIO_METHOD *BIO_f_gauge( void )
        {
        return( &methods_gauge );
        }







static int gauge_new(BIO *bi)
        {
        BIO_F_GAUGE_CTX *ctx;

        ctx=(BIO_F_GAUGE_CTX *)OPENSSL_malloc(sizeof(BIO_F_GAUGE_CTX));
        if (ctx == NULL) return(0);
        ctx->Rx = 0UL;
        ctx->Tx = 0UL;
        ctx->GaugeHandle = (void*) 0;
        ctx->GaugeCB = (GAUGE_CALLBACK_ROUTINE) 0;

        bi->init=1;
        bi->ptr=(char *)ctx;
        bi->flags=0;
        return(1);
        }

static int gauge_free(BIO *a)
        {
        BIO_F_GAUGE_CTX *b;

        if (a == NULL) return(0);
        b=(BIO_F_GAUGE_CTX *)a->ptr;
        OPENSSL_free(a->ptr);
        a->ptr=NULL;
        a->init=0;
        a->flags=0;
        return(1);
        }
        
static int gauge_read(BIO *b, char *out, int outl)
        {
        BIO_F_GAUGE_CTX *ctx;
        int i,num=0;

        if (out == NULL) return(0);
        ctx=(BIO_F_GAUGE_CTX *)b->ptr;

        if ((ctx == NULL) || (b->next_bio == NULL)) return(0);

        BIO_clear_retry_flags(b);
  i=BIO_read( b->next_bio, out, outl );
  if(i>0)
    {
    if( 0==ctx->Rx ) ctx->RxStartTime = time(NULL);  /* WinCE: time() emulation 
or port is avail as open source/free */
    ctx->Rx += i;
    if( ctx->GaugeCB ) ctx->GaugeCB( b, ctx->GaugeHandle, 1 );
    // unclear :   b->num_read += i;
    }
  else  
    {
    BIO_copy_next_retry(b);
    }
  return i; 
        }


static int gauge_write(BIO *b, const char *in, int inl)
        {
        BIO_F_GAUGE_CTX *ctx;
        int i,num=0;

        if ((in == NULL) || (inl <= 0)) return(0);
        ctx=(BIO_F_GAUGE_CTX *)b->ptr;

        if ((ctx == NULL) || (b->next_bio == NULL)) return(0);

        BIO_clear_retry_flags(b);
        i=BIO_write( b->next_bio, in, inl );
  if(i>0)
    {
    if( 0==ctx->Tx ) ctx->TxStartTime = time(NULL);   /* WinCE: time() 
emulation or port is avail as open source/free */
    ctx->Tx += i;
    if( ctx->GaugeCB ) ctx->GaugeCB( b, ctx->GaugeHandle, 0 );
    // unclear :   b->num_write += i;
    }
  else  
    {
    BIO_copy_next_retry(b);
    }
  return i; 
        }

static long gauge_ctrl(BIO *b, int cmd, long num, void *ptr)
        {
        BIO_F_GAUGE_CTX *ctx;
        long ret=1;

        ctx=(BIO_F_GAUGE_CTX *)b->ptr;
        if (ctx == NULL) return(0);

        switch (cmd)
                {
          case BIO_CTRL_GAUGE_SET_FOO: // (0xA0)
            ctx->GaugeCB = (GAUGE_CALLBACK_ROUTINE) ptr;
            return 1;

          case BIO_CTRL_GAUGE_SET_HND: //  (0xA1)
            ctx->GaugeHandle = ptr;
            return 1;

          case BIO_CTRL_GAUGE_GET_RX : // (0xA2)
            {
            unsigned long *pV = (unsigned long *) ptr;
                  ret=(long) ctx->Rx;
                  if( pV ) *pV = ctx->Rx;
            }; break;

          case BIO_CTRL_GAUGE_GET_TX : // (0xA3)
            {
            unsigned long *pV = (unsigned long *) ptr;
                  ret=(long) ctx->Tx;
                  if( pV ) *pV = ctx->Tx;
            }; break;

          case BIO_CTRL_GAUGE_GET_RXTIME: // (0xA4)
            {
            time_t *pV = (time_t *) ptr;
                  ret=(long) ctx->RxStartTime;
                  if( pV ) *pV = ctx->RxStartTime;
            }; break;

          case BIO_CTRL_GAUGE_GET_TXTIME: // (0xA5)
            {
            time_t *pV = (time_t *) ptr;
                  ret=(long) ctx->TxStartTime;
                  if( pV ) *pV = ctx->TxStartTime;
            }; break;

          case BIO_C_DO_STATE_MACHINE:
                  if (b->next_bio == NULL) return(0);
                  BIO_clear_retry_flags(b);
                  ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
                  BIO_copy_next_retry(b);
                  break;
          default:
                  if (b->next_bio == NULL) return(0);
                  ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
                  break;
                }
        return(ret);
        }

static long gauge_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
        {
        long ret=1;

        if (b->next_bio == NULL) return(0);
        switch (cmd)
                {
          default:
                  ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
                  break;
                }
        return(ret);
        }

static int gauge_gets(BIO *b, char *buf, int size)
        {
        BIO_F_GAUGE_CTX *ctx;
        int i;

        ctx=(BIO_F_GAUGE_CTX *)b->ptr;
        if ((ctx == NULL) || (buf == NULL) || (size<0)) return(0);

        i=BIO_read(b->next_bio,buf,size);
  if(i>0)
    {
    if( 0==ctx->Rx ) ctx->RxStartTime = time(NULL);  /* WinCE: time() emulation 
or port is avail as open source/free */
    ctx->Rx += i;
    if( ctx->GaugeCB ) ctx->GaugeCB( b, ctx->GaugeHandle, 1 );
    // unclear :   b->num_read += i;
    }
  else  
    {
    BIO_copy_next_retry(b);
    }
  return i; 
        }



static int gauge_puts(BIO *b, const char *str)
        {
        return(gauge_write(b,str,(int)strlen(str)));
        }


#ifdef __cplusplus
  }
#endif

#ifndef BIO_f_gauge_h_
#define BIO_f_gauge_h_

#include <openssl\bio.h>

#ifdef __cplusplus
  extern "C" {
#endif

#define BIO_TYPE_GAUGE            (0xA0 | BIO_TYPE_FILTER)
#define BIO_CTRL_GAUGE_SET_FOO    (0xA0)
#define BIO_CTRL_GAUGE_SET_HND    (0xA1)
#define BIO_CTRL_GAUGE_GET_RX     (0xA2)
#define BIO_CTRL_GAUGE_GET_TX     (0xA3)
#define BIO_CTRL_GAUGE_GET_RXTIME (0xA4)
#define BIO_CTRL_GAUGE_GET_TXTIME (0xA5)

typedef void (*GAUGE_CALLBACK_ROUTINE)( BIO *b, void* GaugeHandle, int IsRx );
BIO_METHOD *BIO_f_gauge(void);

#ifdef __cplusplus
  }
#endif



#endif /*BIO_f_gauge_h_*/

Reply via email to