summaryrefslogtreecommitdiff
path: root/src/Sockets/ListenSocket.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Sockets/ListenSocket.h')
-rw-r--r--src/Sockets/ListenSocket.h421
1 files changed, 0 insertions, 421 deletions
diff --git a/src/Sockets/ListenSocket.h b/src/Sockets/ListenSocket.h
deleted file mode 100644
index d782fc5..0000000
--- a/src/Sockets/ListenSocket.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/** \file ListenSocket.h
- ** \date 2004-02-13
- ** \author grymse@alhem.net
-**/
-/*
-Copyright (C) 2004-2007 Anders Hedstrom
-
-This library is made available under the terms of the GNU GPL.
-
-If you would like to use this library in a closed-source application,
-a separate license agreement is available. For information about
-the closed-source license agreement for the C++ sockets library,
-please visit http://www.alhem.net/Sockets/license.html and/or
-email license@alhem.net.
-
-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 WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-#ifndef _SOCKETS_ListenSocket_H
-#define _SOCKETS_ListenSocket_H
-#include "sockets-config.h"
-
-#ifdef _WIN32
-#include <stdlib.h>
-#else
-#include <errno.h>
-#endif
-
-#include <cstring>
-#include "ISocketHandler.h"
-#include "Socket.h"
-#include "Utility.h"
-#include "SctpSocket.h"
-#include "Ipv4Address.h"
-#include "Ipv6Address.h"
-#ifdef ENABLE_EXCEPTIONS
-#include "Exception.h"
-#endif
-
-#ifdef SOCKETS_NAMESPACE
-namespace SOCKETS_NAMESPACE {
-#endif
-
-
-/** Binds incoming port number to new Socket class X.
- \ingroup basic */
-template <class X>
-class ListenSocket : public Socket
-{
-public:
- /** Constructor.
- \param h ISocketHandler reference
- \param use_creator Optional use of creator (default true) */
- ListenSocket(ISocketHandler& h,bool use_creator = true) : Socket(h), m_depth(0), m_creator(NULL)
- ,m_bHasCreate(false)
- {
- if (use_creator)
- {
- m_creator = new X(h);
- Socket *tmp = m_creator -> Create();
- if (tmp && dynamic_cast<X *>(tmp))
- {
- m_bHasCreate = true;
- }
- if (tmp)
- {
- delete tmp;
- }
- }
- }
- ~ListenSocket() {
- if (m_creator)
- {
- delete m_creator;
- }
- }
-
- /** Close file descriptor. */
- int Close() {
- if (GetSocket() != INVALID_SOCKET)
- {
- closesocket(GetSocket());
- }
- return 0;
- }
-
- /** Bind and listen to any interface.
- \param port Port (0 is random)
- \param depth Listen queue depth */
- int Bind(port_t port,int depth = 20) {
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- if (IsIpv6())
- {
- Ipv6Address ad(port);
- return Bind(ad, depth);
- }
- else
-#endif
-#endif
- {
- Ipv4Address ad(port);
- return Bind(ad, depth);
- }
- }
-
- int Bind(SocketAddress& ad,int depth) {
-#ifdef USE_SCTP
- if (dynamic_cast<SctpSocket *>(m_creator))
- {
- return Bind(ad, "sctp", depth);
- }
-#endif
- return Bind(ad, "tcp", depth);
- }
-
- /** Bind and listen to any interface, with optional protocol.
- \param port Port (0 is random)
- \param protocol Network protocol
- \param depth Listen queue depth */
- int Bind(port_t port,const std::string& protocol,int depth = 20) {
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- if (IsIpv6())
- {
- Ipv6Address ad(port);
- return Bind(ad, protocol, depth);
- }
- else
-#endif
-#endif
- {
- Ipv4Address ad(port);
- return Bind(ad, protocol, depth);
- }
- }
-
- /** Bind and listen to specific interface.
- \param intf Interface hostname
- \param port Port (0 is random)
- \param depth Listen queue depth */
- int Bind(const std::string& intf,port_t port,int depth = 20) {
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- if (IsIpv6())
- {
- Ipv6Address ad(intf, port);
- if (ad.IsValid())
- {
- return Bind(ad, depth);
- }
- Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
- return -1;
- }
- else
-#endif
-#endif
- {
- Ipv4Address ad(intf, port);
- if (ad.IsValid())
- {
- return Bind(ad, depth);
- }
- Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
- return -1;
- }
- }
-
- /** Bind and listen to specific interface.
- \param intf Interface hostname
- \param port Port (0 is random)
- \param protocol Network protocol
- \param depth Listen queue depth */
- int Bind(const std::string& intf,port_t port,const std::string& protocol,int depth = 20) {
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- if (IsIpv6())
- {
- Ipv6Address ad(intf, port);
- if (ad.IsValid())
- {
- return Bind(ad, protocol, depth);
- }
- Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
- return -1;
- }
- else
-#endif
-#endif
- {
- Ipv4Address ad(intf, port);
- if (ad.IsValid())
- {
- return Bind(ad, protocol, depth);
- }
- Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
- return -1;
- }
- }
-
- /** Bind and listen to ipv4 interface.
- \param a Ipv4 interface address
- \param port Port (0 is random)
- \param depth Listen queue depth */
- int Bind(ipaddr_t a,port_t port,int depth = 20) {
- Ipv4Address ad(a, port);
-#ifdef USE_SCTP
- if (dynamic_cast<SctpSocket *>(m_creator))
- {
- return Bind(ad, "sctp", depth);
- }
-#endif
- return Bind(ad, "tcp", depth);
- }
- /** Bind and listen to ipv4 interface.
- \param a Ipv4 interface address
- \param port Port (0 is random)
- \param protocol Network protocol
- \param depth Listen queue depth */
- int Bind(ipaddr_t a,port_t port,const std::string& protocol,int depth) {
- Ipv4Address ad(a, port);
- return Bind(ad, protocol, depth);
- }
-
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- /** Bind and listen to ipv6 interface.
- \param a Ipv6 interface address
- \param port Port (0 is random)
- \param depth Listen queue depth */
- int Bind(in6_addr a,port_t port,int depth = 20) {
- Ipv6Address ad(a, port);
-#ifdef USE_SCTP
- if (dynamic_cast<SctpSocket *>(m_creator))
- {
- return Bind(ad, "sctp", depth);
- }
-#endif
- return Bind(ad, "tcp", depth);
- }
- /** Bind and listen to ipv6 interface.
- \param a Ipv6 interface address
- \param port Port (0 is random)
- \param protocol Network protocol
- \param depth Listen queue depth */
- int Bind(in6_addr a,port_t port,const std::string& protocol,int depth) {
- Ipv6Address ad(a, port);
- return Bind(ad, protocol, depth);
- }
-#endif
-#endif
-
- /** Bind and listen to network interface.
- \param ad Interface address
- \param protocol Network protocol
- \param depth Listen queue depth */
- int Bind(SocketAddress& ad,const std::string& protocol,int depth) {
- SOCKET s;
- if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET)
- {
- return -1;
- }
- if (bind(s, ad, ad) == -1)
- {
- Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
- closesocket(s);
-#ifdef ENABLE_EXCEPTIONS
- throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
-#endif
- return -1;
- }
- if (listen(s, depth) == -1)
- {
- Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL);
- closesocket(s);
-#ifdef ENABLE_EXCEPTIONS
- throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
-#endif
- return -1;
- }
- m_depth = depth;
- Attach(s);
- return 0;
- }
-
- /** Return assigned port number. */
- port_t GetPort()
- {
- return GetSockPort();
- }
-
- /** Return listen queue depth. */
- int GetDepth()
- {
- return m_depth;
- }
-
- /** OnRead on a ListenSocket receives an incoming connection. */
- void OnRead()
- {
- struct sockaddr sa;
- socklen_t sa_len = sizeof(struct sockaddr);
- SOCKET a_s = accept(GetSocket(), &sa, &sa_len);
-
- if (a_s == INVALID_SOCKET)
- {
- Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR);
- return;
- }
- if (!Handler().OkToAccept(this))
- {
- Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING);
- closesocket(a_s);
- return;
- }
- if (Handler().GetCount() >= FD_SETSIZE)
- {
- Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL);
- closesocket(a_s);
- return;
- }
- Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler());
-#ifdef ENABLE_IPV6
- tmp -> SetIpv6( IsIpv6() );
-#endif
- tmp -> SetParent(this);
- tmp -> Attach(a_s);
- tmp -> SetNonblocking(true);
- {
-#ifdef ENABLE_IPV6
-#ifdef IPPROTO_IPV6
- if (sa_len == sizeof(struct sockaddr_in6))
- {
- struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa;
- if (p -> sin6_family == AF_INET6)
- {
- Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port));
- ad.SetFlowinfo(p -> sin6_flowinfo);
-#ifndef _WIN32
- ad.SetScopeId(p -> sin6_scope_id);
-#endif
- tmp -> SetRemoteAddress(ad);
- }
- }
-#endif
-#endif
- if (sa_len == sizeof(struct sockaddr_in))
- {
- struct sockaddr_in *p = (struct sockaddr_in *)&sa;
- if (p -> sin_family == AF_INET)
- {
- Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port));
- tmp -> SetRemoteAddress(ad);
- }
- }
- }
- tmp -> SetConnected(true);
- tmp -> Init();
- tmp -> SetDeleteByHandler(true);
- Handler().Add(tmp);
-#ifdef HAVE_OPENSSL
- if (tmp -> IsSSL()) // SSL Enabled socket
- {
- // %! OnSSLAccept calls SSLNegotiate that can finish in this one call.
- // %! If that happens and negotiation fails, the 'tmp' instance is
- // %! still added to the list of active sockets in the sockethandler.
- // %! See bugfix for this in SocketHandler::Select - don't Set rwx
- // %! flags if CloseAndDelete() flag is true.
- // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids
- // %! the Add problem altogether, so ignore the above.
- // %! (OnSSLAccept does no longer call SSLNegotiate().)
- tmp -> OnSSLAccept();
- }
- else
-#endif
- {
- tmp -> OnAccept();
- }
- }
-
- /** Please don't use this method.
- "accept()" is handled automatically in the OnRead() method. */
- virtual SOCKET Accept(SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr)
- {
- return accept(socket, saptr, lenptr);
- }
-
- bool HasCreator() { return m_bHasCreate; }
-
- void OnOptions(int,int,int,SOCKET) {
- SetSoReuseaddr(true);
- }
-
-protected:
- ListenSocket(const ListenSocket& s) : Socket(s) {}
-private:
- ListenSocket& operator=(const ListenSocket& ) { return *this; }
- int m_depth;
- X *m_creator;
- bool m_bHasCreate;
-};
-
-
-
-#ifdef SOCKETS_NAMESPACE
-}
-#endif
-
-#endif // _SOCKETS_ListenSocket_H
-