bring Csocket up to date, includes new needed function GetSockByFD()

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@332 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
imaginos
2005-05-18 03:22:52 +00:00
parent f8dc1a112a
commit 2d1602ec4c
8 changed files with 1415 additions and 1210 deletions

View File

@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 1999-2004 Jim Hull <imaginos@imaginos.net>
* Copyright (c) 1999-2005 Jim Hull <imaginos@imaginos.net>
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -31,9 +31,16 @@
* $Revision$
*/
#include "main.h"
#include "Csocket.h"
using namespace std;
#ifndef _NO_CSOCKET_NS // some people may not want to use a namespace
namespace Csocket
{
#endif /* _NO_CSOCKET_NS */
#ifdef HAVE_LIBSSL
bool InitSSL( ECompType eCompressionType )
{
@@ -44,6 +51,7 @@ bool InitSSL( ECompType eCompressionType )
return( false );
}
#ifndef _WIN32
if ( access( "/dev/urandom", R_OK ) == 0 )
RAND_load_file( "/dev/urandom", 1024 );
else if( access( "/dev/random", R_OK ) == 0 )
@@ -53,6 +61,7 @@ bool InitSSL( ECompType eCompressionType )
CS_DEBUG( "Unable to locate entropy location! Tried /dev/urandom and /dev/random" );
return( false );
}
#endif /* _WIN32 */
COMP_METHOD *cm = NULL;
@@ -90,12 +99,12 @@ void SSLErrors( const char *filename, u_int iLineNum )
void __Perror( const CS_STRING & s )
{
#ifdef __sun
CS_DEBUG( s << ": " << strerror( errno ) );
#if defined(__sun) || defined(_WIN32)
CS_DEBUG( s << ": " << strerror( GetSockError() ) );
#else
char buff[512];
memset( (char *)buff, '\0', 512 );
if ( strerror_r( errno, buff, 511 ) == 0 )
if ( strerror_r( GetSockError(), buff, 511 ) == 0 )
CS_DEBUG( s << ": " << buff );
else
CS_DEBUG( s << ": Unknown Error Occured" );
@@ -104,11 +113,18 @@ void __Perror( const CS_STRING & s )
unsigned long long millitime()
{
struct timeval tv;
unsigned long long iTime = 0;
#ifdef _WIN32
struct timeb tm;
ftime( &tm );
iTime = tm.time * 1000;
iTime += tm.millitm;
#else
struct timeval tv;
gettimeofday( &tv, NULL );
iTime = (unsigned long long )tv.tv_sec * 1000;
iTime += ( (unsigned long long)tv.tv_usec / 1000 );
#endif /* _WIN32 */
return( iTime );
}
@@ -155,6 +171,11 @@ bool GetHostByName( const CS_STRING & sHostName, struct in_addr *paddr )
return( bRet );
}
#ifndef _NO_CSOCKET_NS // some people may not want to use a namespace
}
using namespace Csocket;
#endif /* _NO_CSOCKET_NS */
CCron::CCron()
{
m_iCycles = 0;
@@ -245,14 +266,20 @@ Csock *Csock::GetSockObj( const CS_STRING & sHostname, int iPort )
return( NULL );
}
#ifdef _WIN32
#define CS_CLOSE closesocket
#else
#define CS_CLOSE close
#endif /* _WIN32 */
Csock::~Csock()
{
if ( m_iReadSock != m_iWriteSock )
{
close( m_iReadSock );
close( m_iWriteSock );
CS_CLOSE( m_iReadSock );
CS_CLOSE( m_iWriteSock );
} else
close( m_iReadSock );
CS_CLOSE( m_iReadSock );
m_iReadSock = -1;
m_iWriteSock = -1;
@@ -363,7 +390,11 @@ bool Csock::Connect( const CS_STRING & sBindHost )
bBound = true;
break;
}
#ifdef _WIN32
Sleep( 5000 );
#else
usleep( 5000 ); // quick pause, common lets BIND!)(!*!
#endif /* _WIN32 */
}
if ( !bBound )
@@ -374,24 +405,40 @@ bool Csock::Connect( const CS_STRING & sBindHost )
}
// set it none blocking
#ifdef _WIN32
u_long iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl (m_iReadSock, F_GETFL, 0);
fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
m_iConnType = OUTBOUND;
// connect
int ret = connect( m_iReadSock, (struct sockaddr *)&m_address, sizeof( m_address ) );
if ( ( ret == -1 ) && ( errno != EINPROGRESS ) )
#ifndef _WIN32
if ( ( ret == -1 ) && ( GetSockError() != EINPROGRESS ) )
#else
if ( ( ret == -1 ) && ( GetSockError() != EINPROGRESS ) && ( GetSockError() != WSAEWOULDBLOCK ) )
#endif /* _WIN32 */
{
CS_DEBUG( "Connect Failed. ERRNO [" << errno << "] FD [" << m_iReadSock << "]" );
CS_DEBUG( "Connect Failed. ERRNO [" << GetSockError() << "] FD [" << m_iReadSock << "]" );
return( false );
}
if ( m_bBLOCK )
{
#ifdef _WIN32
u_long iOpts = 0;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
// unset the flags afterwords, rather than have connect block
int fdflags = fcntl (m_iReadSock, F_GETFL, 0);
fdflags &= ~O_NONBLOCK;
fcntl( m_iReadSock, F_SETFL, fdflags );
#endif /* _WIN32 */
}
return( true );
@@ -418,7 +465,7 @@ int Csock::WriteSelect()
if ( ret == -1 )
{
if ( errno == EINTR )
if ( GetSockError() == EINTR )
return( SEL_EAGAIN );
else
return( SEL_ERR );
@@ -448,7 +495,7 @@ int Csock::ReadSelect()
if ( ret == -1 )
{
if ( errno == EINTR )
if ( GetSockError() == EINTR )
return( SEL_EAGAIN );
else
return( SEL_ERR );
@@ -475,7 +522,8 @@ bool Csock::Listen( int iPort, int iMaxConns, const CS_STRING & sBindHost, u_int
return( false );
}
m_address.sin_port = htons( iPort );
bzero(&(m_address.sin_zero), 8);
memset( &(m_address.sin_zero), '\0', sizeof( m_address.sin_zero ) );
// TODO bzero(&(m_address.sin_zero), 8);
if ( bind( m_iReadSock, (struct sockaddr *) &m_address, sizeof( m_address ) ) == -1 )
return( false );
@@ -486,8 +534,13 @@ bool Csock::Listen( int iPort, int iMaxConns, const CS_STRING & sBindHost, u_int
if ( !m_bBLOCK )
{
// set it none blocking
#ifdef _WIN32
u_long iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl ( m_iReadSock, F_GETFL, 0);
fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
}
return( true );
@@ -504,8 +557,13 @@ int Csock::Accept( CS_STRING & sHost, int & iRPort )
if ( !m_bBLOCK )
{
// make it none blocking
#ifdef _WIN32
u_long iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl (iSock, F_GETFL, 0);
fcntl( iSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
}
getpeername( iSock, (struct sockaddr *) &client, &clen );
@@ -742,8 +800,13 @@ bool Csock::ConnectSSL( const CS_STRING & sBindhost )
if ( m_bBLOCK )
{
#ifdef _WIN32
u_long iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl ( m_iReadSock, F_GETFL, 0);
fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
}
int iErr = SSL_connect( m_ssl );
@@ -759,9 +822,14 @@ bool Csock::ConnectSSL( const CS_STRING & sBindhost )
if ( m_bBLOCK )
{
// unset the flags afterwords, rather then have connect block
#ifdef _WIN32
u_long iOpts = 0;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl (m_iReadSock, F_GETFL, 0);
fdflags &= ~O_NONBLOCK;
fcntl( m_iReadSock, F_SETFL, fdflags );
#endif /* _WIN32 */
}
@@ -824,7 +892,7 @@ bool Csock::Write( const char *data, int len )
int iErr = SSL_write( m_ssl, m_sSSLBuffer.data(), m_sSSLBuffer.length() );
if ( ( iErr < 0 ) && ( errno == ECONNREFUSED ) )
if ( ( iErr < 0 ) && ( GetSockError() == ECONNREFUSED ) )
{
// If ret == -1, the underlying BIO reported an I/O error (man SSL_get_error)
ConnectionRefused();
@@ -874,16 +942,25 @@ bool Csock::Write( const char *data, int len )
return( true );
}
#endif /* HAVE_LIBSSL */
#ifdef _WIN32
int bytes = send( m_iWriteSock, m_sSend.data(), iBytesToSend, 0 );
#else
int bytes = write( m_iWriteSock, m_sSend.data(), iBytesToSend );
#endif /* _WIN32 */
if ( ( bytes == -1 ) && ( errno == ECONNREFUSED ) )
if ( ( bytes == -1 ) && ( GetSockError() == ECONNREFUSED ) )
{
ConnectionRefused();
return( false );
}
if ( ( bytes <= 0 ) && ( errno != EAGAIN ) )
#ifdef _WIN32
if ( ( bytes <= 0 ) && ( GetSockError() != WSAEWOULDBLOCK ) )
return( false );
#else
if ( ( bytes <= 0 ) && ( GetSockError() != EAGAIN ) )
return( false );
#endif /* _WIN32 */
// delete the bytes we sent
if ( bytes > 0 )
@@ -928,18 +1005,27 @@ int Csock::Read( char *data, int len )
bytes = SSL_read( m_ssl, data, len );
else
#endif /* HAVE_LIBSSL */
#ifdef _WIN32
bytes = recv( m_iReadSock, data, len, 0 );
#else
bytes = read( m_iReadSock, data, len );
#endif /* _WIN32 */
if ( bytes == -1 )
{
if ( errno == ECONNREFUSED )
if ( GetSockError() == ECONNREFUSED )
return( READ_CONNREFUSED );
if ( errno == ETIMEDOUT )
if ( GetSockError() == ETIMEDOUT )
return( READ_TIMEDOUT );
if ( ( errno == EINTR ) || ( errno == EAGAIN ) )
if ( ( GetSockError() == EINTR ) || ( GetSockError() == EAGAIN ) )
return( READ_EAGAIN );
#ifdef _WIN32
if ( GetSockError() == WSAEWOULDBLOCK )
return( READ_EAGAIN );
#endif /* _WIN32 */
#ifdef HAVE_LIBSSL
if ( m_bssl )
{
@@ -986,7 +1072,7 @@ CS_STRING Csock::GetRemoteIP()
if ( iSock <= 0 )
{
cerr << "What the hell is wrong with my fd!?" << endl;
std::cerr << "What the hell is wrong with my fd!?" << endl;
return( "" );
}
@@ -1156,13 +1242,23 @@ void Csock::BlockIO( bool bBLOCK ) { m_bBLOCK = bBLOCK; }
void Csock::NonBlockingIO()
{
#ifdef _WIN32
u_long iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
int fdflags = fcntl ( m_iReadSock, F_GETFL, 0);
fcntl( m_iReadSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
if ( m_iReadSock != m_iWriteSock )
{
#ifdef _WIN32
iOpts = 1;
ioctlsocket( m_iReadSock, FIONBIO, &iOpts );
#else
fdflags = fcntl ( m_iWriteSock, F_GETFL, 0);
fcntl( m_iWriteSock, F_SETFL, fdflags|O_NONBLOCK );
#endif /* _WIN32 */
}
BlockIO( false );
@@ -1404,8 +1500,8 @@ void Csock::DisableReadLine() { m_bEnableReadLine = false; }
void Csock::ReachedMaxBuffer()
{
cerr << "Warning, Max Buffer length Warning Threshold has been hit" << endl;
cerr << "If you don't care, then set SetMaxBufferThreshold to 0" << endl;
std::cerr << "Warning, Max Buffer length Warning Threshold has been hit" << endl;
std::cerr << "If you don't care, then set SetMaxBufferThreshold to 0" << endl;
}
int Csock::GetPending()
@@ -1450,7 +1546,7 @@ int Csock::SOCKET( bool bListen )
{
const int on = 1;
if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR, &on, sizeof( on ) ) != 0 )
if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof( on ) ) != 0 )
PERROR( "setsockopt" );
} else if ( iRet == -1 )
@@ -1496,3 +1592,4 @@ void Csock::Init( const CS_STRING & sHostname, int iport, int itimeout )
m_bPauseRead = false;
m_iTimeoutType = TMO_ALL;
}