mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
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:
147
Csocket.cpp
147
Csocket.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user