mirror of
https://github.com/znc/znc.git
synced 2026-08-07 01:13:25 +02:00
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:
+68
-70
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user