summaryrefslogtreecommitdiff
path: root/httpd/listener.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'httpd/listener.cpp')
-rw-r--r--httpd/listener.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/httpd/listener.cpp b/httpd/listener.cpp
new file mode 100644
index 0000000..57c334d
--- /dev/null
+++ b/httpd/listener.cpp
@@ -0,0 +1,167 @@
+/* listener.cpp
+ * Copyright (C) 2003 Tommi Maekitalo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
+ * NON-INFRINGEMENT. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "tnt/listener.h"
+#include "tnt/tntnet.h"
+#include <cxxtools/log.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef WITH_GNUTLS
+# include "tnt/gnutls.h"
+#endif
+
+#ifdef WITH_OPENSSL
+# include "tnt/openssl.h"
+#endif
+
+log_define("tntnet.listener")
+
+static void doListenRetry(cxxtools::net::Server& server,
+ const char* ipaddr, unsigned short int port)
+{
+ for (unsigned n = 1; true; ++n)
+ {
+ try
+ {
+ log_debug("listen " << ipaddr << ':' << port);
+ server.listen(ipaddr, port, tnt::Listener::getBacklog());
+ return;
+ }
+ catch (const cxxtools::net::Exception& e)
+ {
+ log_debug("cxxtools::net::Exception caught: errno=" << e.getErrno() << " msg=" << e.what());
+ if (e.getErrno() != EADDRINUSE || n > tnt::Listener::getListenRetry())
+ {
+ log_debug("rethrow exception");
+ throw;
+ }
+ log_warn("address " << ipaddr << ':' << port << " in use - retry; n = " << n);
+ ::sleep(1);
+ }
+ }
+}
+
+namespace tnt
+{
+ void ListenerBase::doStop()
+ {
+ log_warn("stop listener " << ipaddr << ':' << port);
+ try
+ {
+ // connect once to wake up listener, so it will check stop-flag
+ cxxtools::net::Stream(ipaddr, port);
+ }
+ catch (const std::exception& e)
+ {
+ log_warn("error waking up listener: " << e.what() << " try 127.0.0.1");
+ cxxtools::net::Stream("127.0.0.1", port);
+ }
+ }
+
+ int Listener::backlog = 16;
+ unsigned Listener::listenRetry = 5;
+
+ Listener::Listener(const std::string& ipaddr, unsigned short int port, Jobqueue& q)
+ : ListenerBase(ipaddr, port),
+ queue(q)
+ {
+ log_info("listen ip=" << ipaddr << " port=" << port);
+ doListenRetry(server, ipaddr.c_str(), port);
+ }
+
+ void Listener::run()
+ {
+ // accept-loop
+ log_debug("enter accept-loop");
+ while (!Tntnet::shouldStop())
+ {
+ try
+ {
+ Tcpjob* j = new Tcpjob;
+ Jobqueue::JobPtr p(j);
+ j->accept(server);
+ log_debug("connection accepted");
+
+ if (Tntnet::shouldStop())
+ break;
+
+ queue.put(p);
+ }
+ catch (const std::exception& e)
+ {
+ log_error("error in accept-loop: " << e.what());
+ }
+ }
+
+ log_debug("stop listener");
+ }
+
+#ifdef WITH_GNUTLS
+#define USE_SSL
+
+#endif
+
+#ifdef WITH_OPENSSL
+#define USE_SSL
+
+#endif
+
+#ifdef USE_SSL
+ Ssllistener::Ssllistener(const char* certificateFile,
+ const char* keyFile,
+ const std::string& ipaddr, unsigned short int port,
+ Jobqueue& q)
+ : ListenerBase(ipaddr, port),
+ server(certificateFile, keyFile),
+ queue(q)
+ {
+ log_info("listen ip=" << ipaddr << " port=" << port << " (ssl)");
+ doListenRetry(server, ipaddr.c_str(), port);
+ }
+
+ void Ssllistener::run()
+ {
+ // accept-loop
+ log_debug("enter accept-loop (ssl)");
+ while (!Tntnet::shouldStop())
+ {
+ try
+ {
+ SslTcpjob* j = new SslTcpjob;
+ Jobqueue::JobPtr p(j);
+ j->accept(server);
+
+ if (Tntnet::shouldStop())
+ break;
+
+ queue.put(p);
+ }
+ catch (const std::exception& e)
+ {
+ log_error("error in ssl-accept-loop: " << e.what());
+ }
+ }
+
+ log_debug("stop ssl-listener");
+ }
+
+#endif // USE_SSL
+
+}