home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / ExternalIpCheck.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-08-03  |  7.1 KB  |  363 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. #include "stdafx.h"
  20. #include "ExternalIpCheck.h"
  21. #include "ServerThread.h"
  22. #include "Options.h"
  23.  
  24. //////////////////////////////////////////////////////////////////////
  25. // Konstruktion/Destruktion
  26. //////////////////////////////////////////////////////////////////////
  27.  
  28. #define TIMERINTERVAL 30
  29.  
  30. CExternalIpCheck::CExternalIpCheck(CServerThread *pOwner)
  31. {
  32.     ASSERT(pOwner);
  33.     m_pOwner = pOwner;
  34.  
  35.     m_bActive = FALSE;
  36.     m_nRetryCount = 0;
  37.     m_nTimerID = SetTimer(0, 0, TIMERINTERVAL * 1000, 0);
  38.     m_bTriggerUpdateCalled = FALSE;
  39.     m_nFailedConnections = 0;
  40.     m_nElapsedSeconds = 0;
  41.     
  42.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  43.         return;
  44.     
  45.     if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 2)
  46.         Start();
  47.     else if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 1)
  48.     {
  49.         CStdString hostname = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIP);
  50.         SOCKADDR_IN sockAddr;
  51.         memset(&sockAddr,0,sizeof(sockAddr));
  52.         
  53.         sockAddr.sin_family = AF_INET;
  54.         sockAddr.sin_addr.s_addr = inet_addr(hostname);
  55.         
  56.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  57.         {
  58.             LPHOSTENT lphost;
  59.             lphost = gethostbyname(hostname);
  60.             if (lphost != NULL)
  61.                 sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  62.             else
  63.             {
  64.                 Close();
  65.                 m_nRetryCount++;
  66.                 m_bActive = FALSE;
  67.                 return;
  68.             }
  69.         }
  70.         
  71.         const char *ip = inet_ntoa(sockAddr.sin_addr);
  72.         
  73.         if (!ip)
  74.             return;
  75.         
  76.         m_IP = ip;
  77.     }
  78. }
  79.  
  80. CExternalIpCheck::~CExternalIpCheck()
  81. {
  82.     Close();
  83. }
  84.  
  85. void CExternalIpCheck::OnReceive(int nErrorCode)
  86. {
  87.     if (!m_bActive)
  88.         return;
  89.  
  90.     if (nErrorCode)
  91.     {
  92.         m_bActive = FALSE;
  93.         Close();
  94.         m_nRetryCount++;
  95.         return;
  96.     }
  97.     char buffer[1000];
  98.     int len = Receive(buffer, 999);
  99.  
  100.     if (len == SOCKET_ERROR)
  101.     {
  102.         if (GetLastError() == WSAEWOULDBLOCK)
  103.             return;
  104.     
  105.         Close();
  106.         m_nRetryCount++;
  107.         m_bActive = FALSE;
  108.         return;
  109.     }
  110.  
  111.     buffer[len] = 0;
  112.     char *p = strstr(buffer, "\r\n\r\n");
  113.     if (!p)
  114.         p = strstr(buffer, "\n\n");
  115.  
  116.     if (!p)
  117.     {
  118.         Close();
  119.         m_nRetryCount++;
  120.         m_bActive = FALSE;
  121.         return;
  122.     }
  123.     
  124.     
  125.     while (*p && (*p == '\n' || *p == '\r'))
  126.         p++;
  127.  
  128.     if (!*p)
  129.     {
  130.         Close();
  131.         m_nRetryCount++;
  132.         m_bActive = FALSE;
  133.         return;
  134.     }
  135.  
  136.     char * ip = p;
  137.     while (*p && *p != '\n' && *p != '\r')
  138.         p++;
  139.     *p = 0;
  140.     
  141.     SOCKADDR_IN sockAddr;
  142.     memset(&sockAddr,0,sizeof(sockAddr));
  143.     
  144.     sockAddr.sin_family = AF_INET;
  145.     sockAddr.sin_addr.s_addr = inet_addr(ip);
  146.     
  147.     if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  148.     {
  149.         LPHOSTENT lphost;
  150.         lphost = gethostbyname(ip);
  151.         if (lphost != NULL)
  152.             sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  153.         else
  154.         {
  155.             Close();
  156.             m_nRetryCount++;
  157.             m_bActive = FALSE;
  158.             return;
  159.         }
  160.     }
  161.     
  162.     ip = inet_ntoa(sockAddr.sin_addr);
  163.  
  164.     if (!ip)
  165.     {        
  166.         Close();
  167.         m_nRetryCount++;
  168.         m_bActive = FALSE;
  169.         return;
  170.     }
  171.     
  172.     m_IP = ip;
  173.     m_nFailedConnections = 0;
  174.  
  175.     Close();
  176.     m_nRetryCount = 0;
  177.     m_bActive = FALSE;
  178. }
  179.  
  180. void CExternalIpCheck::OnConnect(int nErrorCode)
  181. {
  182.     if (!m_bActive)
  183.         return;
  184.  
  185.     if (nErrorCode)
  186.     {
  187.         m_bActive = FALSE;
  188.         Close();
  189.         m_nRetryCount++;
  190.         return;
  191.     }
  192.     
  193.     CStdString address = "GET " + m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIPSERVER) + " HTTP/1.0\r\n\r\n";
  194.     const char *buffer = address;
  195.     int len = strlen(buffer);
  196.     if (Send(buffer, len) != len)
  197.     {
  198.         m_bActive = FALSE;
  199.         Close();
  200.         m_nRetryCount++;
  201.     }
  202.  
  203.     OnReceive(0);
  204. }
  205.  
  206. void CExternalIpCheck::OnTimer()
  207. {
  208.     if (m_nElapsedSeconds <= 1000000)
  209.         m_nElapsedSeconds += TIMERINTERVAL;
  210.  
  211.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  212.     {
  213.         m_nRetryCount = 0;
  214.         Close();
  215.         m_bActive = FALSE;
  216.         return;
  217.     }
  218.     else if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 1)
  219.     {
  220.         m_nRetryCount = 0;
  221.         Close();
  222.         m_bActive = FALSE;
  223.  
  224.         CStdString hostname = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIP);
  225.         SOCKADDR_IN sockAddr;
  226.         memset(&sockAddr,0,sizeof(sockAddr));
  227.         
  228.         sockAddr.sin_family = AF_INET;
  229.         sockAddr.sin_addr.s_addr = inet_addr(hostname);
  230.         
  231.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  232.         {
  233.             LPHOSTENT lphost;
  234.             lphost = gethostbyname(hostname);
  235.             if (lphost != NULL)
  236.                 sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  237.             else
  238.             {
  239.                 Close();
  240.                 m_nRetryCount++;
  241.                 m_bActive = FALSE;
  242.                 return;
  243.             }
  244.         }
  245.         
  246.         const char *ip = inet_ntoa(sockAddr.sin_addr);
  247.         
  248.         if (!ip)
  249.             return;
  250.     
  251.         m_IP = ip;
  252.         m_nFailedConnections = 0;
  253.         return;
  254.     }
  255.  
  256.     if (!m_bActive && m_nRetryCount)
  257.     {
  258.         if (m_nElapsedSeconds > 60 && m_nRetryCount < 10)
  259.         {
  260.             Start();
  261.             return;
  262.         }
  263.         else if (m_nElapsedSeconds > 300 && m_nRetryCount < 20)
  264.         {
  265.             Start();
  266.             return;
  267.         }
  268.         else if (m_nElapsedSeconds > 900 && m_nRetryCount < 25)
  269.         {
  270.             Start();
  271.             return;
  272.         }
  273.         else if (m_nElapsedSeconds > 3600)
  274.         {
  275.             Start();
  276.             return;
  277.         }
  278.     }
  279.     else if (m_bActive)
  280.     {
  281.         if (m_nElapsedSeconds > 30)
  282.         {
  283.             m_bActive = FALSE;
  284.             Close();
  285.             m_nRetryCount++;
  286.             m_nElapsedSeconds = 0;
  287.         }
  288.     }
  289.     else
  290.     {
  291.         if (m_nElapsedSeconds > 300 && m_bTriggerUpdateCalled)
  292.             Start();
  293.         else if (m_nElapsedSeconds > 3600)
  294.             Start();
  295.     }
  296. }
  297.  
  298. void CExternalIpCheck::OnClose(int nErrorCode)
  299. {
  300.     if (m_bActive)
  301.     {
  302.         m_bActive = FALSE;
  303.         Close();
  304.         m_nRetryCount++;
  305.     }
  306. }
  307.  
  308. void CExternalIpCheck::Start()
  309. {
  310.     if (m_bActive)
  311.         return;
  312.  
  313.     CStdString address = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIPSERVER);
  314.     if (address.Left(7) == "http://")
  315.         address = address.Mid(7);
  316.     int pos = address.Find('/');
  317.     if (pos != -1)
  318.         address = address.Left(pos);
  319.     if (address == "")
  320.         return;
  321.  
  322.     m_bTriggerUpdateCalled = FALSE;
  323.  
  324.     m_nElapsedSeconds = 0;
  325.     Create();
  326.  
  327.     BOOL res = Connect(address, 80);
  328.     if (res == SOCKET_ERROR && GetLastError() != WSAEWOULDBLOCK)
  329.         m_nRetryCount++;
  330.     else
  331.         m_bActive = TRUE;
  332. }
  333.  
  334. void CExternalIpCheck::TriggerUpdate()
  335. {
  336.     if (m_bActive)
  337.         return;
  338.  
  339.     m_bTriggerUpdateCalled = TRUE;
  340.     if (m_nFailedConnections < 100000)
  341.         m_nFailedConnections++;
  342. }
  343.  
  344. CStdString CExternalIpCheck::GetIP() const
  345. {
  346.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  347.         return "";
  348.  
  349.     CStdString ip;
  350.     switch (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  351.     {
  352.     case 0:
  353.         return "";
  354.     case 1:
  355.     case 2:
  356. //        if (m_nFailedConnections < 5)
  357.             ip = m_IP;
  358.         
  359.         break;
  360.     }
  361.     
  362.     return ip;
  363. }