Logo
~Sockets~
~Examples~
~Contact~


ListenSocket.h

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2004-2007  Anders Hedstrom
00007 
00008 This library is made available under the terms of the GNU GPL.
00009 
00010 If you would like to use this library in a closed-source application,
00011 a separate license agreement is available. For information about 
00012 the closed-source license agreement for the C++ sockets library,
00013 please visit http://www.alhem.net/Sockets/license.html and/or
00014 email license@alhem.net.
00015 
00016 This program is free software; you can redistribute it and/or
00017 modify it under the terms of the GNU General Public License
00018 as published by the Free Software Foundation; either version 2
00019 of the License, or (at your option) any later version.
00020 
00021 This program is distributed in the hope that it will be useful, 
00022 but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 GNU General Public License for more details.
00025 
00026 You should have received a copy of the GNU General Public License
00027 along with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00029 */
00030 #ifndef _SOCKETS_ListenSocket_H
00031 #define _SOCKETS_ListenSocket_H
00032 #include "sockets-config.h"
00033 
00034 #ifdef _WIN32
00035 #include <stdlib.h>
00036 #else
00037 #include <errno.h>
00038 #endif
00039 
00040 #include "ISocketHandler.h"
00041 #include "Socket.h"
00042 #include "Utility.h"
00043 #include "SctpSocket.h"
00044 #include "Ipv4Address.h"
00045 #include "Ipv6Address.h"
00046 
00047 #ifdef SOCKETS_NAMESPACE
00048 namespace SOCKETS_NAMESPACE {
00049 #endif
00050 
00051 
00054 template <class X>
00055 class ListenSocket : public Socket
00056 {
00057 public:
00061         ListenSocket(ISocketHandler& h,bool use_creator = true) : Socket(h), m_port(0), m_depth(0), m_creator(NULL)
00062         ,m_bHasCreate(false)
00063         {
00064                 if (use_creator)
00065                 {
00066                         m_creator = new X(h);
00067                         Socket *tmp = m_creator -> Create();
00068                         if (tmp && dynamic_cast<X *>(tmp))
00069                         {
00070                                 m_bHasCreate = true;
00071                         }
00072                         if (tmp)
00073                         {
00074                                 delete tmp;
00075                         }
00076                 }
00077         }
00078         ~ListenSocket() {
00079                 if (m_creator)
00080                 {
00081                         delete m_creator;
00082                 }
00083         }
00084 
00086         int Close() {
00087                 if (GetSocket() != INVALID_SOCKET)
00088                 {
00089                         closesocket(GetSocket());
00090                 }
00091                 return 0;
00092         }
00093 
00097         int Bind(port_t port,int depth = 20) {
00098 #ifdef ENABLE_IPV6
00099 #ifdef IPPROTO_IPV6
00100                 if (IsIpv6())
00101                 {
00102                         Ipv6Address ad(port);
00103                         return Bind(ad, depth);
00104                 }
00105                 else
00106 #endif
00107 #endif
00108                 {
00109                         Ipv4Address ad(port);
00110                         return Bind(ad, depth);
00111                 }
00112         }
00113 
00114         int Bind(SocketAddress& ad,int depth) {
00115 #ifdef USE_SCTP
00116                 if (dynamic_cast<SctpSocket *>(m_creator))
00117                 {
00118                         return Bind(ad, "sctp", depth);
00119                 }
00120 #endif
00121                 return Bind(ad, "tcp", depth);
00122         }
00123 
00128         int Bind(port_t port,const std::string& protocol,int depth = 20) {
00129 #ifdef ENABLE_IPV6
00130 #ifdef IPPROTO_IPV6
00131                 if (IsIpv6())
00132                 {
00133                         Ipv6Address ad(port);
00134                         return Bind(ad, protocol, depth);
00135                 }
00136                 else
00137 #endif
00138 #endif
00139                 {
00140                         Ipv4Address ad(port);
00141                         return Bind(ad, protocol, depth);
00142                 }
00143         }
00144 
00149         int Bind(const std::string& intf,port_t port,int depth = 20) {
00150 #ifdef ENABLE_IPV6
00151 #ifdef IPPROTO_IPV6
00152                 if (IsIpv6())
00153                 {
00154                         Ipv6Address ad(intf, port);
00155                         if (ad.IsValid())
00156                         {
00157                                 return Bind(ad, depth);
00158                         }
00159                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00160                         return -1;
00161                 }
00162                 else
00163 #endif
00164 #endif
00165                 {
00166                         Ipv4Address ad(intf, port);
00167                         if (ad.IsValid())
00168                         {
00169                                 return Bind(ad, depth);
00170                         }
00171                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00172                         return -1;
00173                 }
00174         }
00175 
00181         int Bind(const std::string& intf,port_t port,const std::string& protocol,int depth = 20) {
00182 #ifdef ENABLE_IPV6
00183 #ifdef IPPROTO_IPV6
00184                 if (IsIpv6())
00185                 {
00186                         Ipv6Address ad(intf, port);
00187                         if (ad.IsValid())
00188                         {
00189                                 return Bind(ad, protocol, depth);
00190                         }
00191                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00192                         return -1;
00193                 }
00194                 else
00195 #endif
00196 #endif
00197                 {
00198                         Ipv4Address ad(intf, port);
00199                         if (ad.IsValid())
00200                         {
00201                                 return Bind(ad, protocol, depth);
00202                         }
00203                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00204                         return -1;
00205                 }
00206         }
00207 
00212         int Bind(ipaddr_t a,port_t port,int depth = 20) {
00213                 Ipv4Address ad(a, port);
00214 #ifdef USE_SCTP
00215                 if (dynamic_cast<SctpSocket *>(m_creator))
00216                 {
00217                         return Bind(ad, "sctp", depth);
00218                 }
00219 #endif
00220                 return Bind(ad, "tcp", depth);
00221         }
00227         int Bind(ipaddr_t a,port_t port,const std::string& protocol,int depth) {
00228                 Ipv4Address ad(a, port);
00229                 return Bind(ad, protocol, depth);
00230         }
00231 
00232 #ifdef ENABLE_IPV6
00233 #ifdef IPPROTO_IPV6
00234 
00238         int Bind(in6_addr a,port_t port,int depth = 20) {
00239                 Ipv6Address ad(a, port);
00240 #ifdef USE_SCTP
00241                 if (dynamic_cast<SctpSocket *>(m_creator))
00242                 {
00243                         return Bind(ad, "sctp", depth);
00244                 }
00245 #endif
00246                 return Bind(ad, "tcp", depth);
00247         }
00253         int Bind(in6_addr a,port_t port,const std::string& protocol,int depth) {
00254                 Ipv6Address ad(a, port);
00255                 return Bind(ad, protocol, depth);
00256         }
00257 #endif
00258 #endif
00259 
00264         int Bind(SocketAddress& ad,const std::string& protocol,int depth) {
00265                 SOCKET s;
00266                 if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET)
00267                 {
00268                         return -1;
00269                 }
00270                 if (bind(s, ad, ad) == -1)
00271                 {
00272                         Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00273                         closesocket(s);
00274                         return -1;
00275                 }
00276                 if (listen(s, depth) == -1)
00277                 {
00278                         Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00279                         closesocket(s);
00280                         return -1;
00281                 }
00282                 // retrieve bound port
00283 #ifdef ENABLE_IPV6
00284 #ifdef IPPROTO_IPV6
00285                 if (IsIpv6())
00286                 {
00287                         struct sockaddr_in6 sa;
00288                         socklen_t sockaddr_length = sizeof(struct sockaddr_in6);
00289                         getsockname(s, (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length);
00290                         m_port = ntohs(sa.sin6_port);
00291                 }
00292                 else
00293 #endif
00294 #endif
00295                 {
00296                         struct sockaddr_in sa;
00297                         socklen_t sockaddr_length = sizeof(struct sockaddr_in);
00298                         getsockname(s, (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length);
00299                         m_port = ntohs(sa.sin_port);
00300                 }
00301                 m_depth = depth;
00302                 Attach(s);
00303                 return 0;
00304         }
00305 
00307         port_t GetPort()
00308         {
00309                 return m_port;
00310         }
00311 
00313         int GetDepth()
00314         {
00315                 return m_depth;
00316         }
00317 
00319         void OnRead()
00320         {
00321                 struct sockaddr sa;
00322                 socklen_t sa_len = sizeof(struct sockaddr);
00323                 SOCKET a_s = accept(GetSocket(), &sa, &sa_len);
00324 
00325                 if (a_s == INVALID_SOCKET)
00326                 {
00327                         Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR);
00328                         return;
00329                 }
00330                 if (!Handler().OkToAccept(this))
00331                 {
00332                         Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING);
00333                         closesocket(a_s);
00334                         return;
00335                 }
00336                 if (Handler().GetCount() >= FD_SETSIZE)
00337                 {
00338                         Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL);
00339                         closesocket(a_s);
00340                         return;
00341                 }
00342                 Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler());
00343 #ifdef ENABLE_IPV6
00344                 tmp -> SetIpv6( IsIpv6() );
00345 #endif
00346                 tmp -> SetParent(this);
00347                 tmp -> Attach(a_s);
00348                 tmp -> SetNonblocking(true);
00349                 {
00350 #ifdef ENABLE_IPV6
00351 #ifdef IPPROTO_IPV6
00352                         if (sa_len == sizeof(struct sockaddr_in6))
00353                         {
00354                                 struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa;
00355                                 if (p -> sin6_family == AF_INET6)
00356                                 {
00357                                         Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port));
00358                                         ad.SetFlowinfo(p -> sin6_flowinfo);
00359 #ifndef _WIN32
00360                                         ad.SetScopeId(p -> sin6_scope_id);
00361 #endif
00362                                         tmp -> SetRemoteAddress(ad);
00363                                 }
00364                         }
00365 #endif
00366 #endif
00367                         if (sa_len == sizeof(struct sockaddr_in))
00368                         {
00369                                 struct sockaddr_in *p = (struct sockaddr_in *)&sa;
00370                                 if (p -> sin_family == AF_INET)
00371                                 {
00372                                         Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port));
00373                                         tmp -> SetRemoteAddress(ad);
00374                                 }
00375                         }
00376                 }
00377                 tmp -> SetConnected(true);
00378                 tmp -> Init();
00379                 tmp -> SetDeleteByHandler(true);
00380                 Handler().Add(tmp);
00381 #ifdef HAVE_OPENSSL
00382                 if (tmp -> IsSSL()) // SSL Enabled socket
00383                 {
00384                         // %! OnSSLAccept calls SSLNegotiate that can finish in this one call.
00385                         // %! If that happens and negotiation fails, the 'tmp' instance is
00386                         // %! still added to the list of active sockets in the sockethandler.
00387                         // %! See bugfix for this in SocketHandler::Select - don't Set rwx
00388                         // %! flags if CloseAndDelete() flag is true.
00389                         // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids
00390                         // %! the Add problem altogether, so ignore the above.
00391                         // %! (OnSSLAccept does no longer call SSLNegotiate().)
00392                         tmp -> OnSSLAccept();
00393                 }
00394                 else
00395 #endif
00396                 {
00397                         tmp -> OnAccept();
00398                 }
00399         }
00400 
00403         virtual SOCKET Accept(SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr)
00404         {
00405                 return accept(socket, saptr, lenptr);
00406         }
00407 
00408         bool HasCreator() { return m_bHasCreate; }
00409 
00410         void OnOptions(int,int,int,SOCKET) {
00411                 SetSoReuseaddr(true);
00412         }
00413 
00414 protected:
00415         ListenSocket(const ListenSocket& s) : Socket(s) {}
00416 private:
00417         ListenSocket& operator=(const ListenSocket& ) { return *this; }
00418         port_t m_port;
00419         int m_depth;
00420         X *m_creator;
00421         bool m_bHasCreate;
00422 };
00423 
00424 
00425 
00426 #ifdef SOCKETS_NAMESPACE
00427 }
00428 #endif
00429 
00430 #endif // _SOCKETS_ListenSocket_H
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4