[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-server-cvs
Subject:    [Server-cvs] admin/monitor smonnet.cpp, 1.16.18.1,
From:       dcollins () helixcommunity ! org
Date:       2008-07-28 22:30:46
Message-ID: 200807282233.m6SMXHL6010438 () mailer ! progressive-comp ! com
[Download RAW message or body]

Update of /cvsroot/server/admin/monitor
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv9927/admin/monitor

Modified Files:
      Tag: SERVER_12_1
	smonnet.cpp smonnet.h 
Log Message:
Synopsis
========
Fixes PR 208796 - DoS: Connections to most/all TCP ports never idle timeout (updated)

Branches: SERVER_12_0, SERVER_12_1, HEAD
Reviewers: Atin, JJ


Description
===========

Problem:
~~~~~~~~
If a client connects to the server but does not transmit any data, there
is no mechanism in place to time out the connection.  This allows for an
easy DoS attack, consuming resources on the server and eventually
causing a server restart.

Solution:
~~~~~~~~~
Fix and use the built-in timeout mechanism in CHXSocket.  This timer
causes an EventPending() callback to occur when the timeout fires with
the event HX_SOCK_EVENT_ERROR and the error code HXR_SOCK_TIMEDOUT.

In the server core, we enable the above timeout as soon at the new socket
is established, and disable the timeout when the socket is handed-off to
the relevant protocol object.  IHXSocket::SetOption() is used to enable
and disable it, with the HX_SOCKOPT_APP_IDLETIMEOUT option.

It is disabled because the protocol object will have a better
understanding of what type of activity is appropriate for the specific
connection.  For example, RTSP uses Ping messages rather than timing out
the socket itself.  If the protocol wants to rely on the same CHXSocket
mechanism it is free to re-enable it at any time using SetOption().

A message is logged to the server's error log when this abnormal activity
occurs.  An example of this message is:

15-Jul-2008 09:24:42.228 tmplgpln(20940): HXR_SOCK_TIMEDOUT: A connection to local \
port 1554 was established from host 'n.n.n.n' but it never sent any data.


The default timeout is 30 seconds.  This default may be overidden
by adding the variable <Var ClientConnectionTimeout="nnn"> to 
the top-level of your server config file.

The CHXSocket::Func() callback had an incorrect conversion from ms to sec
causing incorrect behavior.  This is also fixed as part of this.

While debugging this, it was noted that the CHXSocket call to time()
for setting m_tLastPacket was only necessary if the timeout mechanism
was being used.  This per-packet call to time() was causing noticable
and unnecessary overhead in a heavily loaded server (especially given
the one-second resolution!)  I wrapped this in an if() check and now
only set this when the timeout is enabled.


Files Affected
==============

common/netio/platform/posix/sockimp.cpp
server/admin/monitor/smonnet.cpp
server/admin/monitor/smonnet.h
server/engine/core/aliveprot.cpp
server/engine/core/hxprotmgr.cpp
server/engine/core/pub/hxprotmgr.h
server/engine/netio/http_listenresp.cpp
server/engine/netio/mms_listenresp.cpp
server/engine/netio/rtsp_listenresp.cpp
server/engine/netio/servsockimp.cpp


Testing Performed
=================

Unit Tests:
- None

Integration Tests:
- Ran the repro scenario described in the PR and verifid sockets now go
    away after the timeout period.
- Ran in a v12-style uptime in servlab for one day on RHEL4.
- Tested with both IPv6 and IPv4 connections.
- Tested with a short timeout period set in the config file.

Leak Tests:
- Not explicitly tested yet

Performance Tests:
- None

Platforms Tested: linux-rhel4-i686
Build verified: linux-rhel4-i686, sunos-5.10-sparc-server, win32-i386-vc7


QA Hints
========
- An uptime test is recommended.
- Regress the PR:
    + Verify the config flag works.
    + Verify the error log message occurs.



Index: smonnet.cpp
===================================================================
RCS file: /cvsroot/server/admin/monitor/smonnet.cpp,v
retrieving revision 1.16.18.1
retrieving revision 1.16.18.1.6.1
diff -u -d -r1.16.18.1 -r1.16.18.1.6.1
--- smonnet.cpp	16 Jan 2008 09:53:51 -0000	1.16.18.1
+++ smonnet.cpp	28 Jul 2008 22:30:44 -0000	1.16.18.1.6.1
@@ -42,6 +42,8 @@
 #include "hxcom.h"
 #include "hxcomm.h"
 #include "hxplugn.h"
+#include "hxerror.h"
+#include "errmsg_macros.h"
 #include "ihxpckts.h"
 #include "chxpckts.h"
 #include "hxsbuffer.h"
@@ -67,6 +69,7 @@
     , m_pRegistry(NULL)
     , m_SchedulerCallback(0)
     , m_pCommonClassFactory(NULL)
+    , m_pMessages(NULL)
 {
     m_lRefCount = 0;
 
@@ -95,6 +98,7 @@
     m_pContext->QueryInterface(IID_IHXCommonClassFactory, 
                         (void**)&m_pCommonClassFactory);
     
+    m_pContext->QueryInterface(IID_IHXErrorMessages, (void**)&m_pMessages);
     
     m_pCallback = NULL;
 }
@@ -243,6 +247,44 @@
     case HX_SOCK_EVENT_CLOSE:
         CloseConnection();
         break;
+
+    case HX_SOCK_EVENT_ERROR:
+        if (status == HXR_SOCK_TIMEDOUT)
+        {
+            //The connection was established but it never sent any data.
+
+            IHXSockAddr* pAddr = 0;
+
+            IHXBuffer* pRemoteAddrBuf = 0;
+            const char* pszRemoteAddr = "";
+            m_pSock->GetPeerAddr(&pAddr);
+            if (pAddr)
+            {
+                pAddr->GetAddr(&pRemoteAddrBuf);
+                if (pRemoteAddrBuf)
+                {
+                    pszRemoteAddr = pRemoteAddrBuf->GetBuffer();
+                }
+                HX_RELEASE(pAddr);
+            }
+
+            UINT16 uPort = 0;
+            m_pSock->GetLocalAddr(&pAddr); //reuse pAddr
+            if (pAddr)
+            {
+                uPort = pAddr->GetPort();
+                HX_RELEASE(pAddr);
+            }
+
+            LOGMSG(m_pMessages, HXLOG_WARNING, "HXR_SOCK_TIMEDOUT: A connection to \
local port %d was established from host '%s' but it never sent any data.\n", uPort, \
pszRemoteAddr); +
+            m_pSock->Close();
+            HX_RELEASE(m_pSock);
+            HX_RELEASE(pRemoteAddrBuf);
+            break;
+        }
+        //Fall-through for all other types of errors...
+
     default:
         HX_ASSERT(FALSE);
     }

Index: smonnet.h
===================================================================
RCS file: /cvsroot/server/admin/monitor/smonnet.h,v
retrieving revision 1.10
retrieving revision 1.10.30.1
diff -u -d -r1.10 -r1.10.30.1
--- smonnet.h	15 Sep 2005 19:00:47 -0000	1.10
+++ smonnet.h	28 Jul 2008 22:30:44 -0000	1.10.30.1
@@ -95,6 +95,7 @@
     CallbackHandle              m_SchedulerCallback;
     IUnknown*                   m_pContext;
     IHXRegistry*                m_pRegistry;
+    IHXErrorMessages*           m_pMessages;
 
     BOOL                        m_bClosePending;
     BOOL                        m_bValidPassword;


_______________________________________________
Server-cvs mailing list
Server-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/server-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic