Commit 32477ab4 authored by tonu@x3.internalnet's avatar tonu@x3.internalnet

.del-vio-global.h~c261412c01b2f4 Delete: vio/vio-global.h

.del-viotypes.h~f5a38e7326bd50f3	Delete: vio/viotypes.h
.del-violite.h~58d2942a52ea7a83	Delete: vio/violite.h
.del-VioSSLFactoriesFd.h~1d63ae149a63f85	Delete: vio/VioSSLFactoriesFd.h
.del-VioPipe.cc~12cf83b9a2f48f6c	Delete: vio/VioPipe.cc
.del-VioSSLAcceptorFd.cc~4c828f3688ed74ec	Delete: vio/VioSSLAcceptorFd.cc
.del-VioSSL.cc~6e85340b11fa42a8	Delete: vio/VioSSL.cc
.del-VioSSLFactoriesFd.cc~89f6bf5073937947	Delete: vio/VioSSLFactoriesFd.cc
.del-vioelitexx.cc~3eaba70da792a7fc	Delete: vio/vioelitexx.cc
.del-version.cc~7237acf12bed4a97	Delete: vio/version.cc
.del-VioSocket.cc~71c615783f29b5e1	Delete: vio/VioSocket.cc
.del-VioSSL.h~70d367b7ec8cac3e	Delete: vio/VioSSL.h
.del-VioPipe.h~21cebbe61a1da546	Delete: vio/VioPipe.h
.del-VioFd.h~8294293a88c7b4b8	Delete: vio/VioFd.h
.del-VioFd.cc~6e444647affef63b	Delete: vio/VioFd.cc
.del-VioConnectorFd.h~58bc11cdc885b951	Delete: vio/VioConnectorFd.h
.del-VioAcceptorFd.cc~a5a08947a31f88de	Delete: vio/VioAcceptorFd.cc
.del-VioConnectorFd.cc~ddbd7821c43c83a2	Delete: vio/VioConnectorFd.cc
.del-VioAcceptorFd.h~7f9c4358477ba9a3	Delete: vio/VioAcceptorFd.h
.del-Vio.cc~60737ce02ab2bc25	Delete: vio/Vio.cc
.del-Vio.h~f4416b2949647602	Delete: vio/Vio.h
.del-VioSocket.h~a26d535bd5a1a6	Delete: vio/VioSocket.h
parent f2dee22a
heikki@donna.mysql.fi
jani@hynda.mysql.fi
jcole@abel.spaceapes.com
jcole@main.burghcom.com
jcole@tetra.spaceapes.com
monty@donna.mysql.fi
monty@work.mysql.com
paul@central.snake.net
sasha@mysql.sashanet.com
serg@serg.mysql.com
tonu@x3.internalnet
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include "vio-global.h"
VIO_NS_BEGIN
void
Vio::release()
{
delete this;
}
Vio::~Vio()
{
}
VIO_NS_END
/*
* Abstract Virtual IO interface - class Vio. Heavily
* influenced by Berkeley sockets and oriented toward MySQL.
*/
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
** Modified by Monty
*/
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
class Vio {
public:
virtual bool is_open() const = 0;
virtual int read(vio_ptr buf, int size) = 0;
virtual int write(const vio_ptr buf, int size) = 0;
virtual int blocking(bool onoff) = 0;
virtual bool blocking() const = 0;
virtual bool fcntl() const = 0;
virtual int fastsend(bool onoff = true) = 0;
virtual int keepalive(bool onoff) = 0;
virtual bool should_retry() const = 0;
virtual int close() = 0;
virtual void release();
virtual const char* description() const = 0;
virtual bool peer_addr(char *buf) const = 0;
virtual const char* cipher_description() const = 0;
virtual int vio_errno();
virtual ~Vio();
};
/* Macros to simulate the violite C interface */
Vio *vio_new(my_socket sd, enum enum_vio_type type,
my_bool localhost);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
#endif
#define vio_delete(vio) delete vio
#define vio_read(vio,buf,size) vio->read(buf,size)
#define vio_write(vio,buf,size) vio->write(buf,size)
#define vio_blocking(vio,mode) vio->blocking(mode)
#define vio_is_blocking(vio) vio->is_blocking()
#define vio_fastsend(vio,mode) vio->fastsend(mode)
#define vio_keepalive(vio,mode) vio->keepalive(mode)
#define vio_shouldretry(vio) vio->shouldretry(mode)
#define vio_close(vio) vio->close()
#define vio_description(vio) vio->description()
#define vio_errno(Vio *vio) vio->errno()
#define vio_peer_addr(vio,buf) vio->peer_addr(buf)
#define vio_in_addr(vio,in) vio->in_addr(in)
VIO_NS_END
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
#include "vio-global.h"
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
VIO_NS_BEGIN
VioAcceptorFd::~VioAcceptorFd()
{
}
VIO_NS_END
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
/*
* Abstract acceptor.
*/
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioAcceptorFd
{
public:
virtual ~VioAcceptorFd();
virtual Vio* accept( int fd) = 0;
};
VIO_NS_END
/*
* Unneccessary virtual destructor.
*/
#include "vio-global.h"
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include "viotypes.h"
#include "Vio.h"
#include "VioConnectorFd.h"
VIO_NS_BEGIN
VioConnectorFd::~VioConnectorFd()
{
}
VIO_NS_END
/*
* Abstract connector. The file (or socket) descriptor has to be
* prepared.
*/
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioConnectorFd
{
public:
virtual ~VioConnectorFd();
virtual Vio* connect(int fd) = 0;
};
VIO_NS_END
/*
** Virtual I/O library for files
** Written by Andrei Errapart <andreie@no.spam.ee>
** Checked and modfied by Monty
*/
#include "vio-global.h"
#include <assert.h>
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
VIO_NS_BEGIN
VioFd::VioFd( int fd) : fd_(fd)
{
sprintf(desc_, "VioFd(%d)", fd_);
}
VioFd:: ~VioFd()
{
if (fd_ >= 0)
{
it r = ::close(fd_);
if ( r < 0)
{
/* FIXME: error handling (Not Critical for MySQL) */
}
}
}
bool
VioFd::open() const
{
return fd_ >= 0;
}
int
VioFd::read(vio_ptr buf, int size)
{
assert(fd_>=0);
return ::read(fd_, buf, size);
}
int
VioFd::write(const vio_ptr buf, int size)
{
assert(fd_>=0);
return ::write(fd_, buf, size);
}
int
VioFd::blocking(bool onoff)
{
if (onoff)
return 0;
else
return -1;
}
bool
VioFd::blocking() const
{
return true;
}
int
VioFd::fastsend(bool tmp)
{
return 0;
}
int
VioFd::keepalive(boolonoff)
{
return -2; // Why -2 ? (monty)
}
bool
VioFd::fcntl() const
{
return FALSE;
}
bool
VioFd::should_retry() const
{
return FALSE;
}
int
VioFd::fcntl(int cmd)
{
assert(fd_>=0);
return ::fcntl(fd_, cmd);
}
int
VioFd::fcntl(int cmd, long arg)
{
assert(fd_>=0);
return ::fcntl(fd_, cmd, arg);
}
int
VioFd::fcntl(int cmd, struct flock* lock)
{
assert(fd_>=0);
return ::fcntl(fd_, cmd, lock);
}
int
VioFd::close()
{
int r = -2;
if (fd_>=0)
{
if ((r= ::close(fd_)) == 0)
fd_ = -1;
}
else
{
/* FIXME: error handling */
}
return r;
}
const char*
VioFd::description() const
{
return desc_;
}
const char*
VioFd::peer_addr() const
{
return "";
}
const char*
VioFd::peer_name() const
{
return "localhost";
}
const char*
VioFd::cipher_description() const
{
return "";
}
VIO_NS_END
/*
* Concrete Vio around a file descriptor.
*/
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioFd : public Vio
{
public:
VioFd( int fd);
virtual ~VioFd();
virtual bool open() const;
virtual int read( vio_ptr buf, int size);
virtual int write( const vio_ptr buf, int size);
virtual bool blocking() const;
virtual int blocking(bool onoff);
virtual int fastsend(bool onoff=true);
virtual int keepalive( bool onoff);
virtual bool fcntl() const;
virtual bool should_retry() const;
virtual int fcntl( int cmd);
virtual int fcntl( int cmd, long arg);
virtual int fcntl( int cmd, struct flock* lock);
virtual int close();
virtual const char* description() const;
virtual const char* peer_addr() const;
virtual bool peer_name(char *buf) const;
virtual const char* cipher_description() const;
private:
int fd_;
char desc_[100];
};
VIO_NS_END
/*
** Virtual I/O library for Windows named pipes
** Written by Monty
*/
#ifdef __WIN32__
#include "vio-global.h"
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
VIO_NS_BEGIN
VIO_NS_END
#endif /* WIN32 */
/*
* Concrete Vio around Handle.
*/
#ifdef __WIN__
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioPipe : public Vio
{
public:
VioPipe(int fd);
virtual ~VioPipe();
virtual bool is_open() const;
virtual int read(vio_ptr buf, int size);
virtual int write(const vio_ptr buf, int size);
virtual int blocking(bool onoff);
virtual bool blocking() const;
virtual bool fcntl() const;
virtual int fastsend(bool onoff = true);
virtual int keepalive(bool onoff);
virtual bool should_retry() const;
virtual int close();
virtual void release();
virtual const char* description() const;
virtual bool peer_addr(char *buf) const;
virtual const char* cipher_description() const { return "";}
virtual int vio_errno();
private:
};
VIO_NS_END
#endif /* WIN32 */
/*
** Virtual I/O library for SSL wrapper
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
/*
* This file has some huge DBUG_ statements. Boy, this is silly...
*/
#include "vio-global.h"
#ifdef VIO_HAVE_OPENSSL
#include <assert.h>
#include <netinet/in.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
VIO_NS_BEGIN
#define this_ssl_con my_static_cast(SSL*)(this->ssl_con_)
#define this_bio my_static_cast(BIO*)(this->bio_)
typedef char* dataptr_t;
static void
report_errors()
{
unsigned long l;
const char* file;
const char* data;
int line,flags;
DBUG_ENTER("VioSSLConnectorFd::report_errors");
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
char buf[200];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
}
DBUG_VOID_RETURN;
}
//FIXME: duplicate code!
VioSSL::VioSSL(int fd,
vio_ptr ssl_context,
int state)
: bio_(0), ssl_con_(0), open_(FALSE), sd_(new VioSocket(fd))
{
DBUG_ENTER("VioSSL::VioSSL");
DBUG_PRINT("enter", ("this=%p, fd=%d, ssl_context=%p, state=%d",
this, fd, ssl_context, state));
assert(fd!=0);
assert(ssl_context!=0);
assert(state==state_connect || state==state_accept);
if (!init_bio_(fd, ssl_context, state, BIO_NOCLOSE))
open_ = true;
DBUG_VOID_RETURN;
}
VioSSL::VioSSL(VioSocket* sd,
vio_ptr ssl_context,
int state)
:bio_(0), ssl_con_(0), open_(FALSE), sd_(sd)
{
DBUG_ENTER("VioSSL::VioSSL");
DBUG_PRINT("enter",
("this=%p, sd=%s, ssl_context=%p, state=%d",
this, sd ? sd->description() : "0", ssl_context, state));
assert(sd != 0);
assert(ssl_context != 0);
assert(state == state_connect || state==state_accept);
if (!init_bio_(sd->sd_, ssl_context, state, BIO_NOCLOSE))
open_ = true;
DBUG_VOID_RETURN;
}
VioSSL::~VioSSL()
{
DBUG_ENTER("VioSSL::~VioSSL");
DBUG_PRINT("enter", ("this=%p", this));
if (ssl_con_!=0)
{
SSL_shutdown(this_ssl_con);
SSL_free(this_ssl_con);
}
if (sd_!=0)
delete sd_;
/* FIXME: no need to close bio? */
/*
if (bio_!=0)
BIO_free(this_bio);
*/
DBUG_VOID_RETURN;
}
bool
VioSSL::is_open() const
{
return open_;
}
int
VioSSL::read(vio_ptr buf, int size)
{
int r;
DBUG_ENTER("VioSSL::read");
DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
assert(this_ssl_con != 0);
r = SSL_read(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
if ( r< 0)
report_errors();
DBUG_PRINT("exit", ("r=%d", r));
DBUG_RETURN(r);
}
int
VioSSL::write(const vio_ptr buf, int size)
{
int r;
DBUG_ENTER("VioSSL::write");
DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
assert(this_ssl_con!=0);
r = SSL_write(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
if (r<0)
report_errors();
DBUG_PRINT("exit", ("r=%d", r));
DBUG_RETURN(r);
}
int
VioSSL::blocking(bool onoff)
{
int r;
DBUG_ENTER("VioSSL::blocking");
DBUG_PRINT("enter", ("this=%p, onoff=%s", this, onoff?"true":"false"));
r = sd_->blocking(onoff);
DBUG_PRINT("exit", ("r=%d", (int)r ));
DBUG_RETURN(r);
}
bool
VioSSL::blocking() const
{
bool r;
DBUG_ENTER("VioSSL::blocking");
DBUG_PRINT("enter", ("this=%p", this));
r = sd_->blocking();
DBUG_PRINT("exit", ("r=%d", (int)r ));
DBUG_RETURN(r);
}
int
VioSSL::fastsend(bool onoff)
{
int r;
DBUG_ENTER("VioSSL::fastsend");
DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
r = sd_->fastsend(onoff);
DBUG_PRINT("exit", ("r=%d", (int)r ));
DBUG_RETURN(r);
}
int VioSSL::keepalive(bool onoff)
{
int r;
DBUG_ENTER("VioSSL::keepalive");
DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
r = sd_->keepalive(onoff);
DBUG_PRINT("exit", ("r=%d", int(r) ));
DBUG_RETURN(r);
}
bool
VioSSL::fcntl() const
{
bool r;
DBUG_ENTER("VioSSL::fcntl");
DBUG_PRINT("enter", ("this=%p", this));
r = sd_->fcntl();
DBUG_PRINT("exit", ("r=%d", (int)r ));
DBUG_RETURN(r);
}
bool
VioSSL::should_retry() const
{
bool r;
DBUG_ENTER("VioSSL::should_retry");
DBUG_PRINT("enter", ("this=%p", this));
r = sd_->should_retry();
DBUG_PRINT("exit", ("r=%d", (int)r ));
DBUG_RETURN(r);
}
int
VioSSL::close()
{
int r= -2;
DBUG_ENTER("VioSSL::close");
DBUG_PRINT("enter", ("this=%p", this));
if (ssl_con)
{
r = SSL_shutdown(this_ssl_con);
SSL_free(this_ssl_con);
ssl_con_ = 0;
BIO_free(this_bio);
bio_ = 0;
}
DBUG_PRINT("exit", ("r=%d", r));
DBUG_RETURN(r);
}
const char*
VioSSL::description() const
{
return desc_;
}
const char*
VioSSL::peer_addr() const
{
if (sd_!=0)
return sd != 0 ? sd_->peer_addr() : "";
}
const char*
VioSSL::peer_name() const
{
return sd != 0 ? sd_->peer_name() : "";
}
const char*
VioSSL::cipher_description() const
{
return SSL_get_cipher_name(this_ssl_con);
}
int
VioSSL::init_bio_(int fd,
vio_ptr ssl_context,
int state,
int bio_flags)
{
DBUG_ENTER("VioSSL::init_bio_");
DBUG_PRINT("enter",
("this=%p, fd=%p, ssl_context=%p, state=%d, bio_flags=%d",
this, fd, ssl_context, state, bio_flags));
if (!(ssl_con_ = SSL_new(my_static_cast(SSL_CTX*)(ssl_context))))
{
DBUG_PRINT("error", ("SSL_new failure"));
report_errors();
DBUG_RETURN(-1);
}
if (!(bio_ = BIO_new_socket(fd, bio_flags)))
{
DBUG_PRINT("error", ("BIO_new_socket failure"));
report_errors();
SSL_free(ssl_con_);
ssl_con_ =0;
DBUG_RETURN(-1);
}
SSL_set_bio(this_ssl_con, this_bio, this_bio);
switch(state) {
case state_connect:
SSL_set_connect_state(this_ssl_con);
break;
case state_accept:
SSL_set_accept_state(this_ssl_con);
break;
default:
assert(0);
}
sprintf(desc_, "VioSSL(%d)", fd);
ssl_cip_ = new SSL_CIPHER ;
DBUG_RETURN(0);
}
VIO_NS_END
#endif /* VIO_HAVE_OPENSSL */
/*
* Concrete Vio around OpenSSL's SSL structure.
*/
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioSocket;
class VioSSL : public Vio
{
public:
enum {
state_connect = 1,
state_accept = 2
};
public:
VioSSL(int fd, vio_ptr ssl_context, int state);
VioSSL(VioSocket* sd, vio_ptr ssl_context, int state);
virtual ~VioSSL();
virtual bool open() const;
virtual int read( vio_ptr buf, int size);
virtual int write( const vio_ptr buf, int size);
virtual bool blocking() const;
virtual int blocking(bool onoff);
virtual int fastsend(bool onoff=true);
virtual int keepalive(bool onoff);
virtual bool fcntl() const;
virtual bool should_retry() const;
virtual int close();
virtual const char* description() const;
virtual const char* peer_addr() const;
virtual const char* peer_name() const;
virtual const char* cipher_description() const;
private:
int init_bio_(int fd,
vio_ptr ssl_context,
int state,
int bio_flags);
vio_ptr bio_;
vio_ptr ssl_con_;
vio_ptr ssl_cip_;
char desc_[100];
bool open_;
VioSocket* sd_;
};
VIO_NS_END
#endif /* VIO_HAVE_OPENSSL */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
#include "vio-global.h"
#ifdef VIO_HAVE_OPENSSL
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include <netinet/in.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/asn1.h>
VIO_NS_BEGIN
#define this_ssl_method my_static_cast(SSL_METHOD*)(this->ssl_method_)
#define this_ssl_context my_static_cast(SSL_CTX*)(this->ssl_context_)
typedef unsigned char* ssl_data_ptr_t;
static bool ssl_algorithms_added = FALSE;
static bool ssl_error_strings_loaded= FALSE;
static int verify_depth = 0;
static int verify_error = X509_V_OK;
static int
vio_verify_callback(int ok, X509_STORE_CTX *ctx)
{
DBUG_ENTER("vio_verify_callback");
DBUG_PRINT("enter", ("ok=%d, ctx=%p", ok, ctx));
char buf[256];
X509* err_cert;
int err,depth;
err_cert=X509_STORE_CTX_get_current_cert(ctx);
err= X509_STORE_CTX_get_error(ctx);
depth= X509_STORE_CTX_get_error_depth(ctx);
X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buff));
if (!ok)
{
DBUG_PRINT("error",("verify error:num=%d:%s\n",err,
X509_verify_cert_error_string(err)));
if (verify_depth >= depth)
{
ok=1;
verify_error=X509_V_OK;
}
else
{
ok=0;
verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
}
}
switch (ctx->error) {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
DBUG_PRINT("info",("issuer= %s\n",buf));
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
DBUG_PRINT("error", ("notBefore"));
//ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
DBUG_PRINT("error", ("notAfter error"));
//ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));
break;
}
DBUG_PRINT("exit", ("r=%d", ok));
DBUG_RETURN(ok);
}
static int
vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{
DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx=%p, cert_file=%p, key_file=%p",
ctx, cert_file, key_file));
if (cert_file != NULL)
{
if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
{
DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
/* FIX stderr */
ERR_print_errors_fp(stderr);
DBUG_RETURN(0);
}
if (key_file == NULL)
key_file = cert_file;
if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
SSL_FILETYPE_PEM) <= 0)
{
DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
/* FIX stderr */
ERR_print_errors_fp(stderr);
DBUG_RETURN(0);
}
/* If we are using DSA, we can copy the parameters from
* the private key */
/* Now we know that a key and cert have been set against
* the SSL context */
if (!SSL_CTX_check_private_key(ctx))
{
DBUG_PRINT("error", ("Private key does not match the certificate public key\n"));
DBUG_RETURN(0);
}
}
DBUG_RETURN(1);
}
/************************ VioSSLConnectorFd **********************************/
VioSSLConnectorFd::VioSSLConnectorFd(const char* key_file,
const char* cert_file,
const char* ca_file,
const char* ca_path)
:ssl_context_(0),ssl_method_(0)
{
DBUG_ENTER("VioSSLConnectorFd::VioSSLConnectorFd");
DBUG_PRINT("enter",
("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
this, key_file, cert_file, ca_path, ca_file));
/* FIXME: constants! */
int verify = SSL_VERIFY_PEER;
if (!ssl_algorithms_added)
{
DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
ssl_algorithms_added = true;
SSLeay_add_ssl_algorithms();
}
if (!ssl_error_strings_loaded)
{
DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
ssl_error_strings_loaded = true;
SSL_load_error_strings();
}
ssl_method_ = SSLv3_client_method();
ssl_context_ = SSL_CTX_new(this_ssl_method);
if (ssl_context_ == 0)
{
DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors();
goto ctor_failure;
}
/*
* SSL_CTX_set_options
* SSL_CTX_set_info_callback
* SSL_CTX_set_cipher_list
*/
SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
{
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors();
goto ctor_failure;
}
if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file,ca_path)==0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
goto ctor_failure;
}
}
DBUG_VOID_RETURN;
ctor_failure:
DBUG_PRINT("exit", ("there was an error"));
DBUG_VOID_RETURN;
}
VioSSLConnectorFd::~VioSSLConnectorFd()
{
DBUG_ENTER("VioSSLConnectorFd::~VioSSLConnectorFd");
DBUG_PRINT("enter", ("this=%p", this));
if (ssl_context_!=0)
SSL_CTX_free(this_ssl_context);
DBUG_VOID_RETURN;
}
VioSSL* VioSSLConnectorFd::connect( int fd)
{
DBUG_ENTER("VioSSLConnectorFd::connect");
DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_connect));
}
VioSSL*
VioSSLConnectorFd::connect( VioSocket* sd)
{
DBUG_ENTER("VioSSLConnectorFd::connect");
DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_connect));
}
void
VioSSLConnectorFd::report_errors()
{
unsigned long l;
const char* file;
const char* data;
int line,flags;
DBUG_ENTER("VioSSLConnectorFd::report_errors");
DBUG_PRINT("enter", ("this=%p", this));
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
char buf[200];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
}
DBUG_VOID_RETURN;
}
/************************ VioSSLAcceptorFd **********************************/
VioSSLAcceptorFd::VioSSLAcceptorFd(const char* key_file,
const char* cert_file,
const char* ca_file,
const char* ca_path)
:ssl_context_(0), ssl_method_(0)
{
DBUG_ENTER("VioSSLAcceptorFd::VioSSLAcceptorFd");
DBUG_PRINT("enter",
("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
this, key_file, cert_file, ca_path, ca_file));
/* FIXME: constants! */
int verify = (SSL_VERIFY_PEER |
SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
SSL_VERIFY_CLIENT_ONCE);
session_id_context_ = static_cast<vio_ptr>(this);
if (!ssl_algorithms_added)
{
DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
ssl_algorithms_added = true;
SSLeay_add_ssl_algorithms();
}
if (!ssl_error_strings_loaded)
{
DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
ssl_error_strings_loaded = true;
SSL_load_error_strings();
}
ssl_method_ = SSLv3_server_method();
ssl_context_ = SSL_CTX_new(this_ssl_method);
if (ssl_context_==0)
{
DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors();
goto ctor_failure;
}
/*
* SSL_CTX_set_quiet_shutdown(ctx,1);
*
*/
SSL_CTX_sess_set_cache_size(this_ssl_context,128);
/* DH?
*/
SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
/*
* Double cast needed at least for egcs-1.1.2 to
* supress warnings:
* 1) ANSI C++ blaah implicit cast from 'void*' to 'unsigned char*'
* 2) static_cast from 'void**' to 'unsigned char*'
* Wish I had a copy of standard handy...
*/
SSL_CTX_set_session_id_context(this_ssl_context,
my_static_cast(ssl_data_ptr_t)
(my_static_cast(void*)(&session_id_context_)),
sizeof(session_id_context_));
/*
* SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
*/
if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
{
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors();
goto ctor_failure;
}
if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file, ca_path)==0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
goto ctor_failure;
}
}
DBUG_VOID_RETURN;
ctor_failure:
DBUG_PRINT("exit", ("there was an error"));
DBUG_VOID_RETURN;
}
VioSSLAcceptorFd::~VioSSLAcceptorFd()
{
DBUG_ENTER("VioSSLAcceptorFd::~VioSSLAcceptorFd");
DBUG_PRINT("enter", ("this=%p", this));
if (ssl_context_!=0)
SSL_CTX_free(this_ssl_context);
DBUG_VOID_RETURN;
}
VioSSL*
VioSSLAcceptorFd::accept(int fd)
{
DBUG_ENTER("VioSSLAcceptorFd::accept");
DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_accept));
}
VioSSL*
VioSSLAcceptorFd::accept(VioSocket* sd)
{
DBUG_ENTER("VioSSLAcceptorFd::accept");
DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_accept));
}
void
VioSSLAcceptorFd::report_errors()
{
unsigned long l;
const char* file;
const char* data;
int line,flags;
DBUG_ENTER("VioSSLConnectorFd::report_errors");
DBUG_PRINT("enter", ("this=%p", this));
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
char buf[200];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
}
DBUG_VOID_RETURN;
}
VIO_NS_END
#endif /* VIO_HAVE_OPENSSL */
/*
* Wrapper around SSL_CTX.
*/
#ifdef VIO_HAVE_OPENSSL
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
VIO_NS_BEGIN
class VioSSLAcceptorFd : public VioAcceptorFd
{
public:
VioSSLAcceptorFd(const char* key_file,
const char* cert_file,
const char* ca_file,
const char* ca_path);
virtual ~VioSSLAcceptorFd();
virtual VioSSL* accept(int fd);
virtual VioSSL* accept(VioSocket* sd);
private:
VioSSLAcceptorFd(const VioSSLAcceptorFd& rhs);//undefined
VioSSLAcceptorFd& operator=(const VioSSLAcceptorFd& rhs);//undefined
private:
void report_errors();
vio_ptr ssl_;
vio_ptr ssl_context_;
vio_ptr ssl_method_;
vio_ptr session_id_context_;
};
VIO_NS_END
/*
* The Factory where Vio's are made!
*/
class VioSSLConnectorFd : public VioConnectorFd
{
public:
VioSSLConnectorFd(const char* key_file,
const char* cert_file,
const char* ca_file,
const char* ca_path);
virtual ~VioSSLConnectorFd();
virtual VioSSL* connect(int fd);
virtual VioSSL* connect(VioSocket* sd);
private:
VioSSLConnectorFd(const VioSSLConnectorFd& rhs);//undefined
VioSSLConnectorFd& operator=(const VioSSLConnectorFd& rhs);//undefined
private:
void report_errors();
vio_ptr ssl_context_;
vio_ptr ssl_method_;
vio_ptr ssl_;
};
VIO_NS_END
#endif /* VIO_HAVE_OPENSSL */
/* Copyright Abandoned 2000 Monty Program KB
This file is public domain and comes with NO WARRANTY of any kind */
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
#include "vio-global.h"
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include <assert.h>
/*
* Probably no need to clean this up
*/
#ifdef _WIN32
#include <winsock.h>
#endif
#include <sys/types.h>
#if !defined(__WIN32__) && !defined(MSDOS)
#include <sys/socket.h>
#endif
#if !defined(MSDOS) && !defined(__WIN32__) && !defined(HAVE_BROKEN_NETINET_INCLUDES)
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#if !defined(alpha_linux_port)
#include <netinet/tcp.h>
#endif
#if defined(__EMX__)
#include <sys/ioctl.h>
#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
#undef HAVE_FCNTL
#endif
#endif
#if defined(MSDOS) || defined(__WIN32__)
#ifdef __WIN32__
#undef errno
#undef EINTR
#undef EAGAIN
#define errno WSAGetLastError()
#define EINTR WSAEINTR
#define EAGAIN WSAEINPROGRESS
#endif
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK EAGAIN
#endif
#ifdef __cplusplus
extern "C" { // Because of SCO 3.2V4.2
#endif
#ifndef __WIN32__
#include <sys/resource.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#include <netdb.h>
#include <sys/utsname.h>
#endif // __WIN32__
#ifdef __cplusplus
}
#endif
VIO_NS_BEGIN
#define this_ssl_cip my_static_cast(SSL_CIPHER*)(this->ssl_cip_)
VioSocket::VioSocket(vio_socket sd, enum_vio_type type, bool localhost)
:sd_(sd), localhost_(localhost), fcntl_(0),
fcntl_set_(FALSE), cipher_description_(0)
{
DBUG_ENTER("VioSocket::VioSocket");
DBUG_PRINT("enter", ("sd=%d", sd));
if (type == VIO_TYPE_SOCKET)
sprintf(desc_,"Socket (%d)",sd_);
else
sprintf(desc_,"TCP/IP (%d)",sd_);
DBUG_VOID_RETURN;
}
VioSocket::~VioSocket()
{
DBUG_ENTER("VioSocket::~VioSocket");
DBUG_PRINT("enter", ("sd_=%d", sd_));
if (sd_>=0)
close();
DBUG_VOID_RETURN;
}
bool
VioSocket::is_open() const
{
return sd_>=0;
}
int
VioSocket::read(vio_ptr buf, int size)
{
int r;
DBUG_ENTER("VioSocket::read");
DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
assert(sd_>=0);
#if defined(MSDOS) || defined(__WIN32__)
r = ::recv(sd_, buf, size,0);
#else
r = ::read(sd_, buf, size);
#endif
#ifndef DBUG_OFF
if ( r < 0)
{
DBUG_PRINT("error", ("Got error %d during read",errno));
}
#endif /* DBUG_OFF */
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
int
VioSocket::write(vio_ptr buf, int size)
{
int r;
DBUG_ENTER("VioSocket::write");
DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
assert(sd_>=0);
#if defined(__WIN32__)
r = ::send(sd_, buf, size,0);
#else
r = ::write(sd_, buf, size);
#endif /* __WIN32__ */
#ifndef DBUG_OFF
if (r < 0)
{
DBUG_PRINT("error", ("Got error %d on write",errno));
}
#endif /* DBUG_OFF */
DBUG_RETURN(r);
}
int
VioSocket::blocking(bool set_blocking_mode)
{
int r= 0;
DBUG_ENTER("VioSocket::blocking");
DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
#if !defined(___WIN32__) && !defined(__EMX__)
#if !defined(NO_FCNTL_NONBLOCK)
assert(sd_>=0);
int old_fcntl=fcntl_;
if (!fcntl_set_)
{
fcntl_set_ = true;
old_fcntl= fcntl_ = fcntl(F_GETFL);
}
if (set_blocking_mode)
fcntl_&=~O_NONBLOCK; //clear bit
else
fcntl_|=O_NONBLOCK; //set bit
if (old_fcntl != fcntl_)
r = ::fcntl(sd_, F_SETFL, fcntl_);
#endif /* !defined(NO_FCNTL_NONBLOCK) */
#else /* !defined(__WIN32__) && !defined(__EMX__) */
{
ulong arg;
int old_fcntl=vio->fcntl_mode;
if (!vio->fcntl_set)
{
vio->fcntl_set = TRUE;
old_fnctl=vio->fcntl_mode=0;
}
if (set_blocking_mode)
{
arg = 0;
fcntl_&=~ O_NONBLOCK; //clear bit
}
else
{
arg = 1;
fcntl_|= O_NONBLOCK; //set bit
}
if (old_fcntl != fcntl_)
r = ioctlsocket(sd_,FIONBIO,(void*)&arg,sizeof(arg));
}
#endif
DBUG_RETURN(r);
}
bool
VioSocket::blocking() const
{
DBUG_ENTER("VioSocket::blocking");
bool r = !(fcntl_ & O_NONBLOCK);
DBUG_PRINT("exit", ("%d", (int)r));
DBUG_RETURN(r);
}
int
VioSocket::fastsend(bool onoff)
{
int r=0;
DBUG_ENTER("VioSocket::fastsend");
DBUG_PRINT("enter", ("onoff:%d", (int)onoff));
assert(sd_>=0);
#ifdef IPTOS_THROUGHPUT
#ifndef __EMX__
int tos = IPTOS_THROUGHPUT;
if (!setsockopt(sd_, IPPROTO_IP, IP_TOS, (void*) &tos, sizeof(tos)))
#endif /* !__EMX__ */
{
int nodelay = 1;
if (setsockopt(sd_, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
sizeof(nodelay)))
{
DBUG_PRINT("warning",
("Couldn't set socket option for fast send"));
r= -1;
}
}
#endif /* IPTOS_THROUGHPUT */
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(0);
}
int
VioSocket::keepalive(bool set_keep_alive)
{
DBUG_ENTER("VioSocket::keepalive");
DBUG_PRINT("enter", ("sd_=%d, set_keep_alive=%d", sd_,
(int) set_keep_alive));
assert(sd_>=0);
uint opt= set_keep_alive ? 1 : 0;
DBUG_RETURN(setsockopt(sd_, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt,
sizeof(opt)));
}
bool
VioSocket::should_retry() const
{
int en = errno;
return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
}
int
VioSocket::close()
{
DBUG_ENTER("VioSocket::close");
assert(sd_>=0);
int r=0;
if (::shutdown(sd_,2))
r= -1;
if (::closesocket(sd_))
r= -1;
if (r)
{
DBUG_PRINT("error", ("close() failed, error: %d",errno));
/* FIXME: error handling (not critical for MySQL) */
}
sd_ = -1;
DBUG_RETURN(r);
}
int
VioSocket::shutdown(int how)
{
DBUG_ENTER("VioSocket::shutdown");
DBUG_PRINT("enter", ("how=%d", how));
assert(sd_>=0);
int r = ::shutdown(sd_, how);
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
const char*
VioSocket::description() const
{
return desc_;
}
bool
VioSocket::peer_addr(char *buf) const
{
DBUG_ENTER("VioSocket::peer_addr");
DBUG_PRINT("enter", ("sd_=%d", sd_));
if (localhost_)
{
strmov(buf,"127.0.0.1");
}
else
{
size_socket addrLen= sizeof(struct sockaddr);
if (getpeername(sd_, my_reinterpret_cast(struct sockaddr *) (&remote_),
&addrLen) != 0)
{
DBUG_PRINT("exit", ("getpeername, error: %d", errno));
DBUG_RETURN(1);
}
my_inet_ntoa(remote_.sin_addr,buf);
}
DBUG_PRINT("exit", ("addr=%s", buf));
DBUG_RETURN(0);
}
const char*
VioSocket::cipher_description() const
{
DBUG_ENTER("VioSocket::cipher_description");
char *r = cipher_description_ ? cipher_description_:"";
DBUG_PRINT("exit", ("name: %s", r));
DBUG_RETURN(r);
}
VIO_NS_END
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
/*
* Concrete Vio around socket. Doesn't differ much from VioFd.
*/
#ifdef WIN32
typedef SOCKET vio_socket;
#else
typedef int vio_socket;
#endif /* WIN32 */
VIO_NS_BEGIN
class VioSSL;
class VioSocket : public Vio
{
public:
VioSocket(vio_socket sd, bool localhost=true);
virtual ~VioSocket();
virtual bool is_open() const;
virtual int read(vio_ptr buf, int size);
virtual int write(const vio_ptr buf, int size);
virtual int blocking(bool onoff);
virtual bool blocking() const;
virtual int fastsend(bool onoff=true);
virtual int keepalive(bool onoff);
virtual bool should_retry() const;
virtual int close();
virtual const char* description() const;
virtual bool peer_addr(char *buf) const;
virtual const char* cipher_description() const;
virtual int vio_errno();
int shutdown(int how);
private:
vio_socket sd_;
const bool localhost_;
int fcntl_;
bool fcntl_set_;
char desc_[30];
mutable struct sockaddr_in local_;
mutable struct sockaddr_in remote_;
mutable char* cipher_description_;
friend class VioSSL; // he wants to tinker with this->sd_;
};
VIO_NS_END
#endif /* vio_VioSocket_h_ */
#include "vio-global.h"
extern "C" const char*
vio_version()
{
return "0.2";
}
#include <global.h>
#if !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL)
#define VIO_HAVE_OPENSSL HAVE_OPENSSL
#endif /* !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL) */
#include "viotypes.h"
#include "Vio.h"
#include "VioAcceptorFd.h"
#include "VioFd.h"
#include "VioPipe.h"
#include "VioSocket.h"
#ifdef VIO_HAVE_OPENSSL
#include "VioSSL.h"
#include "VioSSLFactoriesFd.h"
#endif /* VIO_HAVE_OPENSSL */
#if VIO_HAVE_NAMESPACES
#define VIO_STD_NS std
#define VIO_STD_NS_USING using namespace std;
#define VIO_NS VirtualIO
#define VIO_NS_BEGIN namespace VIO_NS {
#define VIO_NS_END }
#define VIO_NS_USING using namespace VIO_NS;
#else
#define VIO_STD_NS
#define VIO_STD_NS_USING
#define VIO_NS
#define VIO_NS_BEGIN
#define VIO_NS_END
#define VIO_NS_USING
#endif
/* Copyright Abandoned 2000 Monty Program KB
This file is public domain and comes with NO WARRANTY of any kind */
/*
* Renamed of violite.cc to violitexx.cc because of clashes
* with violite.c
* This file implements the same functions as in violite.c, but now using
* the Vio class
*/
#include "vio-global.h"
Vio*
vio_new(my_socket sd, enum_vio_type type, my_bool localhost)
{
return my_reinterpret_cast(Vio*) (new VioSocket(sd, type, localhost));
}
#ifdef __WIN32__
Vio
*vio_new_win32pipe(HANDLE hPipe)
{
return my_reinterpret_cast(Vio*) (new VioPipe(hPipe));
}
#endif
/* Copyright Abandoned 2000 Monty Program KB
This file is public domain and comes with NO WARRANTY of any kind */
/*
* Vio Lite.
* Purpose: include file for Vio that will work with C and C++
*/
#ifndef vio_violite_h_
#define vio_violite_h_
#include "my_net.h" /* needed because of struct in_addr */
#ifdef HAVE_VIO
#include <Vio.h> /* Full VIO interface */
#else
/* Simple vio interface in C; The functions are implemented in violite.c */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef Vio_defined
#define Vio_defined
struct st_vio; /* Only C */
typedef struct st_vio Vio;
#endif
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
Vio* vio_new(my_socket sd,
enum enum_vio_type type,
my_bool localhost);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
#endif
void vio_delete(Vio* vio);
/*
* vio_read and vio_write should have the same semantics
* as read(2) and write(2).
*/
int vio_read( Vio* vio,
gptr buf, int size);
int vio_write( Vio* vio,
const gptr buf,
int size);
/*
* Whenever the socket is set to blocking mode or not.
*/
int vio_blocking( Vio* vio,
my_bool onoff);
my_bool vio_is_blocking( Vio* vio);
/*
* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
*/
int vio_fastsend( Vio* vio,
my_bool onoff);
/*
* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
*/
int vio_keepalive( Vio* vio,
my_bool onoff);
/*
* Whenever we should retry the last read/write operation.
*/
my_bool vio_should_retry( Vio* vio);
/*
* When the workday is over...
*/
int vio_close( Vio* vio);
/*
* Short text description of the socket for those, who are curious..
*/
const char* vio_description( Vio* vio);
/* Return the type of the connection */
enum enum_vio_type vio_type(Vio* vio);
/* Return last error number */
int vio_errno(Vio *vio);
/* Get socket number */
my_socket vio_fd(Vio *vio);
/*
* Remote peer's address and name in text form.
*/
my_bool vio_peer_addr(Vio * vio, char *buf);
/* Remotes in_addr */
void vio_in_addr(Vio *vio, struct in_addr *in);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_VIO */
#endif /* vio_violite_h_ */
/*
** Virtual I/O library
** Written by Andrei Errapart <andreie@no.spam.ee>
*/
/*
* Some typedefs to external types.
*/
#ifndef vio_viotypes_h_
#define vio_viotypes_h_
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
typedef int vio_bool_t;
typedef void* vio_ptr_t;
#ifdef __cplusplus
VIO_NS_BEGIN
typedef vio_ptr_t vio_ptr;
typedef char* vio_cstring;
typedef int32_t vio_int32;
typedef u_int32_t vio_uint32;
typedef vio_bool_t vio_bool;
VIO_NS_END
#endif /* __cplusplus */
#endif /* vio_types_h_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment