ListenSocket< X > Class Template ReferenceBinds incoming port number to new Socket class X.
More...
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Public Member Functions | |
| ListenSocket (ISocketHandler &h, bool use_creator=true) | |
| Constructor. | |
| ~ListenSocket () | |
| int | Close () |
| Close file descriptor. | |
| int | Bind (port_t port, int depth=20) |
| Bind and listen to any interface. | |
| int | Bind (SocketAddress &ad, int depth) |
| int | Bind (port_t port, const std::string &protocol, int depth=20) |
| Bind and listen to any interface, with optional protocol. | |
| int | Bind (const std::string &intf, port_t port, int depth=20) |
| Bind and listen to specific interface. | |
| int | Bind (const std::string &intf, port_t port, const std::string &protocol, int depth=20) |
| Bind and listen to specific interface. | |
| int | Bind (ipaddr_t a, port_t port, int depth=20) |
| Bind and listen to ipv4 interface. | |
| int | Bind (ipaddr_t a, port_t port, const std::string &protocol, int depth) |
| Bind and listen to ipv4 interface. | |
| int | Bind (SocketAddress &ad, const std::string &protocol, int depth) |
| Bind and listen to network interface. | |
| port_t | GetPort () |
| Return assigned port number. | |
| int | GetDepth () |
| Return listen queue depth. | |
| void | OnRead () |
| OnRead on a ListenSocket receives an incoming connection. | |
| virtual SOCKET | Accept (SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr) |
| Please don't use this method. | |
| bool | HasCreator () |
| void | OnOptions (int, int, int, SOCKET) |
| Called when a client socket is created, to set socket options. | |
Protected Member Functions | |
| ListenSocket (const ListenSocket &s) | |
Private Member Functions | |
| ListenSocket & | operator= (const ListenSocket &) |
Private Attributes | |
| int | m_depth |
| X * | m_creator |
| bool | m_bHasCreate |
Definition at line 58 of file ListenSocket.h.
| ListenSocket< X >::ListenSocket | ( | ISocketHandler & | h, | |
| bool | use_creator = true | |||
| ) | [inline] |
Constructor.
| h | ISocketHandler reference | |
| use_creator | Optional use of creator (default true) |
Definition at line 64 of file ListenSocket.h.
00064 : Socket(h), m_depth(0), m_creator(NULL) 00065 ,m_bHasCreate(false) 00066 { 00067 if (use_creator) 00068 { 00069 m_creator = new X(h); 00070 Socket *tmp = m_creator -> Create(); 00071 if (tmp && dynamic_cast<X *>(tmp)) 00072 { 00073 m_bHasCreate = true; 00074 } 00075 if (tmp) 00076 { 00077 delete tmp; 00078 } 00079 } 00080 }
| ListenSocket< X >::~ListenSocket | ( | ) | [inline] |
| ListenSocket< X >::ListenSocket | ( | const ListenSocket< X > & | s | ) | [inline, protected] |
| int ListenSocket< X >::Close | ( | ) | [inline, virtual] |
Close file descriptor.
Reimplemented from Socket.
Definition at line 89 of file ListenSocket.h.
References closesocket, and INVALID_SOCKET.
00089 { 00090 if (GetSocket() != INVALID_SOCKET) 00091 { 00092 closesocket(GetSocket()); 00093 } 00094 return 0; 00095 }
| int ListenSocket< X >::Bind | ( | port_t | port, | |
| int | depth = 20 | |||
| ) | [inline] |
Bind and listen to any interface.
| port | Port (0 is random) | |
| depth | Listen queue depth |
Definition at line 100 of file ListenSocket.h.
Referenced by ResolvServer::Run().
00100 { 00101 #ifdef ENABLE_IPV6 00102 #ifdef IPPROTO_IPV6 00103 if (IsIpv6()) 00104 { 00105 Ipv6Address ad(port); 00106 return Bind(ad, depth); 00107 } 00108 else 00109 #endif 00110 #endif 00111 { 00112 Ipv4Address ad(port); 00113 return Bind(ad, depth); 00114 } 00115 }
| int ListenSocket< X >::Bind | ( | SocketAddress & | ad, | |
| int | depth | |||
| ) | [inline] |
Definition at line 117 of file ListenSocket.h.
00117 { 00118 #ifdef USE_SCTP 00119 if (dynamic_cast<SctpSocket *>(m_creator)) 00120 { 00121 return Bind(ad, "sctp", depth); 00122 } 00123 #endif 00124 return Bind(ad, "tcp", depth); 00125 }
| int ListenSocket< X >::Bind | ( | port_t | port, | |
| const std::string & | protocol, | |||
| int | depth = 20 | |||
| ) | [inline] |
Bind and listen to any interface, with optional protocol.
| port | Port (0 is random) | |
| protocol | Network protocol | |
| depth | Listen queue depth |
Definition at line 131 of file ListenSocket.h.
00131 { 00132 #ifdef ENABLE_IPV6 00133 #ifdef IPPROTO_IPV6 00134 if (IsIpv6()) 00135 { 00136 Ipv6Address ad(port); 00137 return Bind(ad, protocol, depth); 00138 } 00139 else 00140 #endif 00141 #endif 00142 { 00143 Ipv4Address ad(port); 00144 return Bind(ad, protocol, depth); 00145 } 00146 }
| int ListenSocket< X >::Bind | ( | const std::string & | intf, | |
| port_t | port, | |||
| int | depth = 20 | |||
| ) | [inline] |
Bind and listen to specific interface.
| intf | Interface hostname | |
| port | Port (0 is random) | |
| depth | Listen queue depth |
Definition at line 152 of file ListenSocket.h.
References Ipv4Address::IsValid(), and LOG_LEVEL_FATAL.
00152 { 00153 #ifdef ENABLE_IPV6 00154 #ifdef IPPROTO_IPV6 00155 if (IsIpv6()) 00156 { 00157 Ipv6Address ad(intf, port); 00158 if (ad.IsValid()) 00159 { 00160 return Bind(ad, depth); 00161 } 00162 Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); 00163 return -1; 00164 } 00165 else 00166 #endif 00167 #endif 00168 { 00169 Ipv4Address ad(intf, port); 00170 if (ad.IsValid()) 00171 { 00172 return Bind(ad, depth); 00173 } 00174 Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); 00175 return -1; 00176 } 00177 }
| int ListenSocket< X >::Bind | ( | const std::string & | intf, | |
| port_t | port, | |||
| const std::string & | protocol, | |||
| int | depth = 20 | |||
| ) | [inline] |
Bind and listen to specific interface.
| intf | Interface hostname | |
| port | Port (0 is random) | |
| protocol | Network protocol | |
| depth | Listen queue depth |
Definition at line 184 of file ListenSocket.h.
References Ipv4Address::IsValid(), and LOG_LEVEL_FATAL.
00184 { 00185 #ifdef ENABLE_IPV6 00186 #ifdef IPPROTO_IPV6 00187 if (IsIpv6()) 00188 { 00189 Ipv6Address ad(intf, port); 00190 if (ad.IsValid()) 00191 { 00192 return Bind(ad, protocol, depth); 00193 } 00194 Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); 00195 return -1; 00196 } 00197 else 00198 #endif 00199 #endif 00200 { 00201 Ipv4Address ad(intf, port); 00202 if (ad.IsValid()) 00203 { 00204 return Bind(ad, protocol, depth); 00205 } 00206 Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); 00207 return -1; 00208 } 00209 }
| int ListenSocket< X >::Bind | ( | ipaddr_t | a, | |
| port_t | port, | |||
| int | depth = 20 | |||
| ) | [inline] |
Bind and listen to ipv4 interface.
| a | Ipv4 interface address | |
| port | Port (0 is random) | |
| depth | Listen queue depth |
Definition at line 215 of file ListenSocket.h.
00215 { 00216 Ipv4Address ad(a, port); 00217 #ifdef USE_SCTP 00218 if (dynamic_cast<SctpSocket *>(m_creator)) 00219 { 00220 return Bind(ad, "sctp", depth); 00221 } 00222 #endif 00223 return Bind(ad, "tcp", depth); 00224 }
| int ListenSocket< X >::Bind | ( | ipaddr_t | a, | |
| port_t | port, | |||
| const std::string & | protocol, | |||
| int | depth | |||
| ) | [inline] |
Bind and listen to ipv4 interface.
| a | Ipv4 interface address | |
| port | Port (0 is random) | |
| protocol | Network protocol | |
| depth | Listen queue depth |
Definition at line 230 of file ListenSocket.h.
00230 { 00231 Ipv4Address ad(a, port); 00232 return Bind(ad, protocol, depth); 00233 }
| int ListenSocket< X >::Bind | ( | SocketAddress & | ad, | |
| const std::string & | protocol, | |||
| int | depth | |||
| ) | [inline] |
Bind and listen to network interface.
| ad | Interface address | |
| protocol | Network protocol | |
| depth | Listen queue depth |
Definition at line 267 of file ListenSocket.h.
References closesocket, Errno, SocketAddress::GetFamily(), SocketAddress::GetPort(), INVALID_SOCKET, Utility::l2string(), LOG_LEVEL_FATAL, and StrError.
00267 { 00268 SOCKET s; 00269 if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET) 00270 { 00271 return -1; 00272 } 00273 // socket must be nonblocking for async connect 00274 if (!SetNonblocking(true, s)) 00275 { 00276 closesocket(s); 00277 return -1; 00278 } 00279 if (bind(s, ad, ad) == -1) 00280 { 00281 Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00282 closesocket(s); 00283 #ifdef ENABLE_EXCEPTIONS 00284 throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); 00285 #endif 00286 return -1; 00287 } 00288 if (listen(s, depth) == -1) 00289 { 00290 Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00291 closesocket(s); 00292 #ifdef ENABLE_EXCEPTIONS 00293 throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); 00294 #endif 00295 return -1; 00296 } 00297 m_depth = depth; 00298 Attach(s); 00299 return 0; 00300 }
| port_t ListenSocket< X >::GetPort | ( | ) | [inline, virtual] |
Return assigned port number.
Reimplemented from Socket.
Definition at line 303 of file ListenSocket.h.
00304 { 00305 return GetSockPort(); 00306 }
| int ListenSocket< X >::GetDepth | ( | ) | [inline] |
Return listen queue depth.
Definition at line 309 of file ListenSocket.h.
00310 { 00311 return m_depth; 00312 }
| void ListenSocket< X >::OnRead | ( | ) | [inline, virtual] |
OnRead on a ListenSocket receives an incoming connection.
Reimplemented from Socket.
Definition at line 315 of file ListenSocket.h.
References closesocket, Errno, INVALID_SOCKET, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, and StrError.
00316 { 00317 struct sockaddr sa; 00318 int max = 10; // process max 10 incoming connection in one call 00319 while (max--) 00320 { 00321 socklen_t sa_len = sizeof(struct sockaddr); 00322 SOCKET a_s = accept(GetSocket(), &sa, &sa_len); 00323 00324 if (a_s == INVALID_SOCKET) 00325 { 00326 // EAGAIN or EWOULDBLOCK 00327 #ifdef _WIN32 00328 if (Errno != WSAEWOULDBLOCK) 00329 #else 00330 if (Errno != EWOULDBLOCK) 00331 #endif 00332 { 00333 Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR); 00334 } 00335 return; 00336 } 00337 if (!Handler().OkToAccept(this)) 00338 { 00339 Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING); 00340 closesocket(a_s); 00341 return; 00342 } 00343 if (Handler().GetCount() >= FD_SETSIZE) 00344 { 00345 Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL); 00346 closesocket(a_s); 00347 return; 00348 } 00349 Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler()); 00350 #ifdef ENABLE_IPV6 00351 tmp -> SetIpv6( IsIpv6() ); 00352 #endif 00353 tmp -> SetParent(this); 00354 tmp -> Attach(a_s); 00355 tmp -> SetNonblocking(true); 00356 { 00357 #ifdef ENABLE_IPV6 00358 #ifdef IPPROTO_IPV6 00359 if (sa_len == sizeof(struct sockaddr_in6)) 00360 { 00361 struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa; 00362 if (p -> sin6_family == AF_INET6) 00363 { 00364 Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port)); 00365 ad.SetFlowinfo(p -> sin6_flowinfo); 00366 #ifndef _WIN32 00367 ad.SetScopeId(p -> sin6_scope_id); 00368 #endif 00369 tmp -> SetRemoteAddress(ad); 00370 } 00371 } 00372 #endif 00373 #endif 00374 if (sa_len == sizeof(struct sockaddr_in)) 00375 { 00376 struct sockaddr_in *p = (struct sockaddr_in *)&sa; 00377 if (p -> sin_family == AF_INET) 00378 { 00379 Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port)); 00380 tmp -> SetRemoteAddress(ad); 00381 } 00382 } 00383 } 00384 tmp -> SetConnected(true); 00385 tmp -> Init(); 00386 tmp -> SetDeleteByHandler(true); 00387 Handler().Add(tmp); 00388 #ifdef HAVE_OPENSSL 00389 if (tmp -> IsSSL()) // SSL Enabled socket 00390 { 00391 // %! OnSSLAccept calls SSLNegotiate that can finish in this one call. 00392 // %! If that happens and negotiation fails, the 'tmp' instance is 00393 // %! still added to the list of active sockets in the sockethandler. 00394 // %! See bugfix for this in SocketHandler::Select - don't Set rwx 00395 // %! flags if CloseAndDelete() flag is true. 00396 // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids 00397 // %! the Add problem altogether, so ignore the above. 00398 // %! (OnSSLAccept does no longer call SSLNegotiate().) 00399 tmp -> OnSSLAccept(); 00400 } 00401 else 00402 #endif 00403 { 00404 tmp -> OnAccept(); 00405 } 00406 } // while (true) 00407 }
| virtual SOCKET ListenSocket< X >::Accept | ( | SOCKET | socket, | |
| struct sockaddr * | saptr, | |||
| socklen_t * | lenptr | |||
| ) | [inline, virtual] |
Please don't use this method.
"accept()" is handled automatically in the OnRead() method.
Definition at line 411 of file ListenSocket.h.
| bool ListenSocket< X >::HasCreator | ( | ) | [inline] |
| void ListenSocket< X >::OnOptions | ( | int | family, | |
| int | type, | |||
| int | protocol, | |||
| SOCKET | s | |||
| ) | [inline, virtual] |
Called when a client socket is created, to set socket options.
| family | AF_INET, AF_INET6, etc | |
| type | SOCK_STREAM, SOCK_DGRAM, etc | |
| protocol | Protocol number (tcp, udp, sctp, etc) | |
| s | Socket file descriptor |
Implements Socket.
Definition at line 418 of file ListenSocket.h.
00418 { 00419 SetSoReuseaddr(true); 00420 }
| ListenSocket& ListenSocket< X >::operator= | ( | const ListenSocket< X > & | ) | [inline, private] |
int ListenSocket< X >::m_depth [private] |
Definition at line 426 of file ListenSocket.h.
X* ListenSocket< X >::m_creator [private] |
Definition at line 427 of file ListenSocket.h.
bool ListenSocket< X >::m_bHasCreate [private] |
Definition at line 428 of file ListenSocket.h.
1.4.4