Update to latest Csocket

This is some stuff I wrote:
- sockets are marked as close-on-exec so that child processes (e.g. from the
  shell module) don't get a copy of all of our sockets.
- This adds separate functions for marking sockets as blocking / non-blocking.
- When a socket is marked for closing, we stop reading lines from it.

I don't think any of these two bugs were actually ever triggered by anyone,
but meh, so what?


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@941 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2008-02-07 17:22:36 +00:00
parent 0b90409018
commit c6664d5ab9
2 changed files with 70 additions and 71 deletions
+68 -70
View File
@@ -28,7 +28,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* $Revision: 1.63 $
* $Revision: 1.65 $
*/
#include "Csocket.h"
@@ -51,6 +51,52 @@ int GetCsockClassIdx()
return( g_iCsockSSLIdx );
}
#ifdef _WIN32
static inline void set_non_blocking(int fd)
{
u_long iOpts = 1;
ioctlsocket( fd, FIONBIO, &iOpts );
}
static inline void set_blocking(int fd)
{
u_long iOpts = 0;
ioctlsocket( fd, FIONBIO, &iOpts );
}
static inline void set_close_on_exec(int fd)
{
// TODO add this for windows
// see http://gcc.gnu.org/ml/java-patches/2002-q1/msg00696.html
// for infos on how to do this
}
#else
static inline void set_non_blocking(int fd)
{
int fdflags = fcntl(fd, F_GETFL, 0);
if ( fdflags < 0 )
return; // Ignore errors
fcntl( fd, F_SETFL, fdflags|O_NONBLOCK );
}
static inline void set_blocking(int fd)
{
int fdflags = fcntl(fd, F_GETFL, 0);
if ( fdflags < 0 )
return; // Ignore errors
fdflags &= ~O_NONBLOCK;
fcntl( fd, F_SETFL, fdflags );
}
static inline void set_close_on_exec(int fd)
{
int fdflags = fcntl(fd, F_GETFD, 0);
if ( fdflags < 0 )
return; // Ignore errors
fcntl( fd, F_SETFD, fdflags|FD_CLOEXEC);
}
#endif /* _WIN32 */
#ifdef HAVE_LIBSSL
Csock *GetCsockFromCTX( X509_STORE_CTX *pCTX )
{
@@ -762,13 +808,7 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup )
}
// 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 */
set_non_blocking( m_iReadSock );
m_iConnType = OUTBOUND;
@@ -792,15 +832,7 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup )
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 */
set_blocking( m_iReadSock );
}
if ( m_eConState != CST_OK )
@@ -908,13 +940,7 @@ bool Csock::Listen( u_short iPort, int iMaxConns, const CS_STRING & sBindHost, u
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 */
set_non_blocking( m_iReadSock );
}
return( true );
@@ -951,16 +977,13 @@ int Csock::Accept( CS_STRING & sHost, u_short & iRPort )
if ( iSock != -1 )
{
// Make it close-on-exec
set_close_on_exec( iSock );
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 */
set_non_blocking( m_iReadSock );
}
if ( !ConnectionFrom( sHost, iRPort ) )
@@ -1212,13 +1235,7 @@ 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 */
set_non_blocking( m_iReadSock );
}
int iErr = SSL_connect( m_ssl );
@@ -1234,15 +1251,7 @@ 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 */
set_blocking( m_iReadSock );
}
return( bPass );
@@ -1631,7 +1640,7 @@ void Csock::PushBuff( const char *data, int len, bool bStartAtZero )
if ( data )
m_sbuffer.append( data, len );
while( !m_bPauseRead )
while( !m_bPauseRead && GetCloseType() == CLT_DONT )
{
CS_STRING::size_type iFind = m_sbuffer.find( "\n", iStartPos );
@@ -1757,23 +1766,11 @@ 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 */
set_non_blocking( m_iReadSock );
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 */
set_non_blocking( m_iWriteSock );
}
BlockIO( false );
@@ -2215,19 +2212,20 @@ int Csock::SOCKET( bool bListen )
#ifdef HAVE_IPV6
int iRet = socket( ( GetIPv6() ? PF_INET6 : PF_INET ), SOCK_STREAM, IPPROTO_TCP );
#else
// missing wrapper around ipv6 for systems missing ipv6, Uli Schlachter <psycho@foex-gaming.com>
int iRet = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
#endif /* HAVE_IPV6 */
if ( iRet >= 0 ) {
set_close_on_exec( iRet );
if ( ( iRet > -1 ) && ( bListen ) )
{
const int on = 1;
if ( bListen ) {
const int on = 1;
if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof( on ) ) != 0 )
PERROR( "setsockopt" );
} else if ( iRet == -1 )
if ( setsockopt( iRet, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof( on ) ) != 0 )
PERROR( "setsockopt" );
}
} else
PERROR( "socket" );
return( iRet );