PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/acelite/ace/SOCK_Acceptor.cpp

https://bitbucket.org/oregon/oregoncore/
C++ | 417 lines | 333 code | 53 blank | 31 comment | 83 complexity | fbfaa04148223027fcab47e27e98083e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, CC-BY-SA-3.0, BSD-2-Clause
  1. #include "ace/SOCK_Acceptor.h"
  2. #include "ace/Log_Category.h"
  3. #include "ace/OS_Errno.h"
  4. #include "ace/OS_NS_string.h"
  5. #include "ace/OS_NS_sys_socket.h"
  6. #include "ace/os_include/os_fcntl.h"
  7. #if !defined (__ACE_INLINE__)
  8. #include "ace/SOCK_Acceptor.inl"
  9. #endif /* __ACE_INLINE__ */
  10. #if !defined (ACE_HAS_WINCE)
  11. #include "ace/OS_QoS.h"
  12. #endif // ACE_HAS_WINCE
  13. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  14. ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Acceptor)
  15. // Do nothing routine for constructor.
  16. ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (void)
  17. {
  18. ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
  19. }
  20. // Performs the timed accept operation.
  21. int
  22. ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value *timeout,
  23. bool restart,
  24. int &in_blocking_mode) const
  25. {
  26. ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_start");
  27. ACE_HANDLE handle = this->get_handle ();
  28. // Handle the case where we're doing a timed <accept>.
  29. if (timeout != 0)
  30. {
  31. if (ACE::handle_timed_accept (handle,
  32. timeout,
  33. restart) == -1)
  34. return -1;
  35. else
  36. {
  37. in_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
  38. ACE_NONBLOCK);
  39. // Set the handle into non-blocking mode if it's not already
  40. // in it.
  41. if (in_blocking_mode
  42. && ACE::set_flags (handle,
  43. ACE_NONBLOCK) == -1)
  44. return -1;
  45. }
  46. }
  47. return 0;
  48. }
  49. int
  50. ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream,
  51. int in_blocking_mode,
  52. bool reset_new_handle) const
  53. {
  54. ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_finish ()");
  55. ACE_HANDLE new_handle = new_stream.get_handle ();
  56. // Check to see if we were originally in blocking mode, and if so,
  57. // set the <new_stream>'s handle and <this> handle to be in blocking
  58. // mode.
  59. if (in_blocking_mode)
  60. {
  61. // Save/restore errno.
  62. ACE_Errno_Guard error (errno);
  63. // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
  64. // originally.
  65. ACE::clr_flags (this->get_handle (),
  66. ACE_NONBLOCK);
  67. ACE::clr_flags (new_handle,
  68. ACE_NONBLOCK);
  69. }
  70. #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
  71. if (reset_new_handle)
  72. // Reset the event association inherited by the new handle.
  73. ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
  74. #else
  75. ACE_UNUSED_ARG (reset_new_handle);
  76. #endif /* ACE_WIN32 */
  77. return new_handle == ACE_INVALID_HANDLE ? -1 : 0;
  78. }
  79. // General purpose routine for accepting new connections.
  80. int
  81. ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
  82. ACE_Addr *remote_addr,
  83. ACE_Time_Value *timeout,
  84. bool restart,
  85. bool reset_new_handle) const
  86. {
  87. ACE_TRACE ("ACE_SOCK_Acceptor::accept");
  88. int in_blocking_mode = 0;
  89. if (this->shared_accept_start (timeout,
  90. restart,
  91. in_blocking_mode) == -1)
  92. return -1;
  93. else
  94. {
  95. // On Win32 the third parameter to <accept> must be a NULL
  96. // pointer if we want to ignore the client's address.
  97. int *len_ptr = 0;
  98. sockaddr *addr = 0;
  99. int len = 0;
  100. if (remote_addr != 0)
  101. {
  102. len = remote_addr->get_size ();
  103. len_ptr = &len;
  104. addr = (sockaddr *) remote_addr->get_addr ();
  105. }
  106. do
  107. new_stream.set_handle (ACE_OS::accept (this->get_handle (),
  108. addr,
  109. len_ptr));
  110. while (new_stream.get_handle () == ACE_INVALID_HANDLE
  111. && restart
  112. && errno == EINTR
  113. && timeout == 0);
  114. // Reset the size of the addr, so the proper UNIX/IPv4/IPv6 family
  115. // is known.
  116. if (new_stream.get_handle () != ACE_INVALID_HANDLE
  117. && remote_addr != 0)
  118. {
  119. remote_addr->set_size (len);
  120. if (addr)
  121. remote_addr->set_type (addr->sa_family);
  122. }
  123. }
  124. return this->shared_accept_finish (new_stream,
  125. in_blocking_mode,
  126. reset_new_handle);
  127. }
  128. #if !defined (ACE_HAS_WINCE)
  129. int
  130. ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
  131. ACE_Accept_QoS_Params qos_params,
  132. ACE_Addr *remote_addr,
  133. ACE_Time_Value *timeout,
  134. bool restart,
  135. bool reset_new_handle) const
  136. {
  137. ACE_TRACE ("ACE_SOCK_Acceptor::accept");
  138. int in_blocking_mode = 0;
  139. if (this->shared_accept_start (timeout,
  140. restart,
  141. in_blocking_mode) == -1)
  142. return -1;
  143. else
  144. {
  145. // On Win32 the third parameter to <accept> must be a NULL
  146. // pointer if we want to ignore the client's address.
  147. int *len_ptr = 0;
  148. int len = 0;
  149. sockaddr *addr = 0;
  150. if (remote_addr != 0)
  151. {
  152. len = remote_addr->get_size ();
  153. len_ptr = &len;
  154. addr = (sockaddr *) remote_addr->get_addr ();
  155. }
  156. do
  157. new_stream.set_handle (ACE_OS::accept (this->get_handle (),
  158. addr,
  159. len_ptr,
  160. qos_params));
  161. while (new_stream.get_handle () == ACE_INVALID_HANDLE
  162. && restart
  163. && errno == EINTR
  164. && timeout == 0);
  165. // Reset the size of the addr, which is only necessary for UNIX
  166. // domain sockets.
  167. if (new_stream.get_handle () != ACE_INVALID_HANDLE
  168. && remote_addr != 0)
  169. remote_addr->set_size (len);
  170. }
  171. return this->shared_accept_finish (new_stream,
  172. in_blocking_mode,
  173. reset_new_handle);
  174. }
  175. #endif // ACE_HAS_WINCE
  176. void
  177. ACE_SOCK_Acceptor::dump (void) const
  178. {
  179. #if defined (ACE_HAS_DUMP)
  180. ACE_TRACE ("ACE_SOCK_Acceptor::dump");
  181. #endif /* ACE_HAS_DUMP */
  182. }
  183. int
  184. ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap,
  185. int protocol_family,
  186. int backlog)
  187. {
  188. ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
  189. int error = 0;
  190. #if defined (ACE_HAS_IPV6)
  191. if (protocol_family == PF_INET6)
  192. {
  193. sockaddr_in6 local_inet6_addr;
  194. ACE_OS::memset (reinterpret_cast<void *> (&local_inet6_addr),
  195. 0,
  196. sizeof local_inet6_addr);
  197. if (local_sap == ACE_Addr::sap_any)
  198. {
  199. local_inet6_addr.sin6_family = AF_INET6;
  200. local_inet6_addr.sin6_port = 0;
  201. local_inet6_addr.sin6_addr = in6addr_any;
  202. }
  203. else
  204. local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ());
  205. # if defined (ACE_WIN32)
  206. // on windows vista and later, Winsock can support dual stack sockets
  207. // but this must be explicitly set prior to the bind. Since this
  208. // behavior is the default on *nix platforms, it should be benigh to
  209. // just do it here. On older platforms the setsockopt will fail, but
  210. // that should be OK.
  211. int zero = 0;
  212. ACE_OS::setsockopt (this->get_handle (),
  213. IPPROTO_IPV6,
  214. IPV6_V6ONLY,
  215. (char *)&zero,
  216. sizeof (zero));
  217. # endif /* ACE_WIN32 */
  218. // We probably don't need a bind_port written here.
  219. // There are currently no supported OS's that define
  220. // ACE_LACKS_WILDCARD_BIND.
  221. if (ACE_OS::bind (this->get_handle (),
  222. reinterpret_cast<sockaddr *> (&local_inet6_addr),
  223. sizeof local_inet6_addr) == -1)
  224. error = 1;
  225. }
  226. else
  227. #endif
  228. if (protocol_family == PF_INET)
  229. {
  230. sockaddr_in local_inet_addr;
  231. ACE_OS::memset (reinterpret_cast<void *> (&local_inet_addr),
  232. 0,
  233. sizeof local_inet_addr);
  234. if (local_sap == ACE_Addr::sap_any)
  235. {
  236. local_inet_addr.sin_port = 0;
  237. }
  238. else
  239. local_inet_addr = *reinterpret_cast<sockaddr_in *> (local_sap.get_addr ());
  240. if (local_inet_addr.sin_port == 0)
  241. {
  242. if (ACE::bind_port (this->get_handle (),
  243. ACE_NTOHL (ACE_UINT32 (local_inet_addr.sin_addr.s_addr))) == -1)
  244. error = 1;
  245. }
  246. else if (ACE_OS::bind (this->get_handle (),
  247. reinterpret_cast<sockaddr *> (&local_inet_addr),
  248. sizeof local_inet_addr) == -1)
  249. error = 1;
  250. }
  251. else if (ACE_OS::bind (this->get_handle (),
  252. (sockaddr *) local_sap.get_addr (),
  253. local_sap.get_size ()) == -1)
  254. error = 1;
  255. if (error != 0
  256. || ACE_OS::listen (this->get_handle (),
  257. backlog) == -1)
  258. {
  259. ACE_Errno_Guard g (errno); // Preserve across close() below.
  260. error = 1;
  261. this->close ();
  262. }
  263. return error ? -1 : 0;
  264. }
  265. int
  266. ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
  267. ACE_Protocol_Info *protocolinfo,
  268. ACE_SOCK_GROUP g,
  269. u_long flags,
  270. int reuse_addr,
  271. int protocol_family,
  272. int backlog,
  273. int protocol)
  274. {
  275. ACE_TRACE ("ACE_SOCK_Acceptor::open");
  276. if (protocol_family == PF_UNSPEC)
  277. protocol_family = local_sap.get_type ();
  278. if (ACE_SOCK::open (SOCK_STREAM,
  279. protocol_family,
  280. protocol,
  281. protocolinfo,
  282. g,
  283. flags,
  284. reuse_addr) == -1)
  285. return -1;
  286. else
  287. return this->shared_open (local_sap,
  288. protocol_family,
  289. backlog);
  290. }
  291. ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
  292. ACE_Protocol_Info *protocolinfo,
  293. ACE_SOCK_GROUP g,
  294. u_long flags,
  295. int reuse_addr,
  296. int protocol_family,
  297. int backlog,
  298. int protocol)
  299. {
  300. ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
  301. if (this->open (local_sap,
  302. protocolinfo,
  303. g,
  304. flags,
  305. reuse_addr,
  306. protocol_family,
  307. backlog,
  308. protocol) == -1)
  309. ACELIB_ERROR ((LM_ERROR,
  310. ACE_TEXT ("%p\n"),
  311. ACE_TEXT ("ACE_SOCK_Acceptor")));
  312. }
  313. // General purpose routine for performing server ACE_SOCK creation.
  314. int
  315. ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
  316. int reuse_addr,
  317. int protocol_family,
  318. int backlog,
  319. int protocol)
  320. {
  321. ACE_TRACE ("ACE_SOCK_Acceptor::open");
  322. if (local_sap != ACE_Addr::sap_any)
  323. protocol_family = local_sap.get_type ();
  324. else if (protocol_family == PF_UNSPEC)
  325. {
  326. #if defined (ACE_HAS_IPV6)
  327. protocol_family = ACE::ipv6_enabled () ? PF_INET6 : PF_INET;
  328. #else
  329. protocol_family = PF_INET;
  330. #endif /* ACE_HAS_IPV6 */
  331. }
  332. if (ACE_SOCK::open (SOCK_STREAM,
  333. protocol_family,
  334. protocol,
  335. reuse_addr) == -1)
  336. return -1;
  337. else
  338. return this->shared_open (local_sap,
  339. protocol_family,
  340. backlog);
  341. }
  342. // General purpose routine for performing server ACE_SOCK creation.
  343. ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
  344. int reuse_addr,
  345. int protocol_family,
  346. int backlog,
  347. int protocol)
  348. {
  349. ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
  350. if (this->open (local_sap,
  351. reuse_addr,
  352. protocol_family,
  353. backlog,
  354. protocol) == -1)
  355. ACELIB_ERROR ((LM_ERROR,
  356. ACE_TEXT ("%p\n"),
  357. ACE_TEXT ("ACE_SOCK_Acceptor")));
  358. }
  359. int
  360. ACE_SOCK_Acceptor::close (void)
  361. {
  362. return ACE_SOCK::close ();
  363. }
  364. ACE_END_VERSIONED_NAMESPACE_DECL