PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/znc-0.093-r2060/znc-msvc/Listener.cpp

https://gitlab.com/BGCX261/znc-msvc-svn-to-git
C++ | 125 lines | 85 code | 24 blank | 16 comment | 19 complexity | 9a3ac2e16133c36e18dc6da84707aadc MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Copyright (C) 2004-2010 See the AUTHORS file for details.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License version 2 as published
  6. * by the Free Software Foundation.
  7. */
  8. #include "stdafx.hpp"
  9. #include "Listener.h"
  10. CListener::~CListener() {
  11. if (m_pListener)
  12. CZNC::Get().GetManager().DelSockByAddr(m_pListener);
  13. }
  14. bool CListener::Listen() {
  15. if (!m_uPort || m_pListener) {
  16. return false;
  17. }
  18. m_pListener = new CRealListener(this);
  19. bool bSSL = false;
  20. #ifdef HAVE_LIBSSL
  21. if (IsSSL()) {
  22. bSSL = true;
  23. m_pListener->SetPemLocation(CZNC::Get().GetPemLocation());
  24. }
  25. #endif
  26. return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN,
  27. m_pListener, 0, m_eAddr);
  28. }
  29. void CListener::ResetRealListener() {
  30. m_pListener = NULL;
  31. }
  32. CRealListener::~CRealListener() {
  33. m_pParent->ResetRealListener();
  34. }
  35. bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) {
  36. bool bHostAllowed = CZNC::Get().IsHostAllowed(sHost);
  37. DEBUG(GetSockName() << " == ConnectionFrom(" << sHost << ", " << uPort << ") [" << (bHostAllowed ? "Allowed" : "Not allowed") << "]");
  38. return bHostAllowed;
  39. }
  40. Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) {
  41. CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort, m_pParent->GetAcceptType());
  42. if (CZNC::Get().AllowConnectionFrom(sHost)) {
  43. CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort);
  44. } else {
  45. pClient->Write(":irc.znc.in 464 unknown-nick :Too many anonymous connections from your IP\r\n");
  46. pClient->Close(Csock::CLT_AFTERWRITE);
  47. CZNC::Get().GetModules().OnFailedLogin("", sHost);
  48. }
  49. return pClient;
  50. }
  51. void CRealListener::SockError(int iErrno) {
  52. DEBUG(GetSockName() << " == SockError(" << strerror(iErrno) << ")");
  53. if (iErrno == EMFILE) {
  54. // We have too many open fds, let's close this listening port to be able to continue
  55. // to work, next rehash will (try to) reopen it.
  56. Close();
  57. }
  58. }
  59. CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::EAcceptType eAcceptType) : CZNCSock(sHostname, uPort) {
  60. m_eAcceptType = eAcceptType;
  61. // The socket will time out in 120 secs, no matter what.
  62. // This has to be fixed up later, if desired.
  63. SetTimeout(120, 0);
  64. EnableReadLine();
  65. }
  66. void CIncomingConnection::ReadLine(const CString& sLine) {
  67. bool bIsHTTP = (sLine.WildCmp("GET * HTTP/1.?\r\n") || sLine.WildCmp("POST * HTTP/1.?\r\n"));
  68. bool bAcceptHTTP = (m_eAcceptType == CListener::ACCEPT_ALL)
  69. || (m_eAcceptType == CListener::ACCEPT_HTTP);
  70. bool bAcceptIRC = (m_eAcceptType == CListener::ACCEPT_ALL)
  71. || (m_eAcceptType == CListener::ACCEPT_IRC);
  72. Csock *pSock = NULL;
  73. if (!bIsHTTP) {
  74. // Let's assume it's an IRC connection
  75. if (!bAcceptIRC) {
  76. Write("ERROR :We don't take kindly to your types around here!\r\n");
  77. Close(CLT_AFTERWRITE);
  78. DEBUG("Refused IRC connection to non IRC port");
  79. return;
  80. }
  81. pSock = new CClient();
  82. CZNC::Get().GetManager().SwapSockByAddr(pSock, this);
  83. // And don't forget to give it some sane name / timeout
  84. pSock->SetSockName("USR::???");
  85. } else {
  86. // This is a HTTP request, let the webmods handle it
  87. if (!bAcceptHTTP) {
  88. Write("HTTP/1.0 403 Access Denied\r\n\r\nWeb Access is not enabled.\r\n");
  89. Close(CLT_AFTERWRITE);
  90. DEBUG("Refused HTTP connection to non HTTP port");
  91. return;
  92. }
  93. pSock = new CWebSock();
  94. CZNC::Get().GetManager().SwapSockByAddr(pSock, this);
  95. // And don't forget to give it some sane name / timeout
  96. pSock->SetSockName("WebMod::Client");
  97. }
  98. // TODO can we somehow get rid of this?
  99. pSock->ReadLine(sLine);
  100. pSock->PushBuff("", 0, true);
  101. }