PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/dep/acelite/ace/SOCK_Connector.cpp

https://gitlab.com/mohsencs/SunWellCore
C++ | 350 lines | 284 code | 34 blank | 32 comment | 84 complexity | 118229c8cd62e7a036b89540428690fc MD5 | raw file
  1. #include "ace/SOCK_Connector.h"
  2. #include "ace/INET_Addr.h"
  3. #include "ace/Log_Category.h"
  4. #include "ace/OS_NS_unistd.h"
  5. #include "ace/OS_NS_sys_socket.h"
  6. #include "ace/os_include/os_fcntl.h"
  7. #if !defined (ACE_HAS_WINCE)
  8. #include "ace/OS_QoS.h"
  9. #endif // ACE_HAS_WINCE
  10. #if !defined (__ACE_INLINE__)
  11. #include "ace/SOCK_Connector.inl"
  12. #endif /* __ACE_INLINE__ */
  13. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  14. ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Connector)
  15. void
  16. ACE_SOCK_Connector::dump (void) const
  17. {
  18. #if defined (ACE_HAS_DUMP)
  19. ACE_TRACE ("ACE_SOCK_Connector::dump");
  20. #endif /* ACE_HAS_DUMP */
  21. }
  22. int
  23. ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
  24. int protocol_family,
  25. int protocol,
  26. int reuse_addr)
  27. {
  28. ACE_TRACE ("ACE_SOCK_Connector::shared_open");
  29. // Only open a new socket if we don't already have a valid handle.
  30. if (new_stream.get_handle () == ACE_INVALID_HANDLE
  31. && new_stream.open (SOCK_STREAM,
  32. protocol_family,
  33. protocol,
  34. reuse_addr) == -1)
  35. return -1;
  36. else
  37. return 0;
  38. }
  39. int
  40. ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
  41. int protocol_family,
  42. int protocol,
  43. ACE_Protocol_Info *protocolinfo,
  44. ACE_SOCK_GROUP g,
  45. u_long flags,
  46. int reuse_addr)
  47. {
  48. ACE_TRACE ("ACE_SOCK_Connector::shared_open");
  49. // Only open a new socket if we don't already have a valid handle.
  50. if (new_stream.get_handle () == ACE_INVALID_HANDLE
  51. && new_stream.open (SOCK_STREAM,
  52. protocol_family,
  53. protocol,
  54. protocolinfo,
  55. g,
  56. flags,
  57. reuse_addr) == -1)
  58. return -1;
  59. else
  60. return 0;
  61. }
  62. int
  63. ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
  64. const ACE_Time_Value *timeout,
  65. const ACE_Addr &local_sap)
  66. {
  67. ACE_TRACE ("ACE_SOCK_Connector::shared_connect_start");
  68. if (local_sap != ACE_Addr::sap_any)
  69. {
  70. sockaddr *laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
  71. int const size = local_sap.get_size ();
  72. if (ACE_OS::bind (new_stream.get_handle (), laddr, size) == -1)
  73. {
  74. // Save/restore errno.
  75. ACE_Errno_Guard error (errno);
  76. new_stream.close ();
  77. return -1;
  78. }
  79. }
  80. // Enable non-blocking, if required.
  81. if (timeout != 0 && new_stream.enable (ACE_NONBLOCK) == -1)
  82. return -1;
  83. else
  84. return 0;
  85. }
  86. int
  87. ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream,
  88. const ACE_Time_Value *timeout,
  89. int result)
  90. {
  91. ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish");
  92. // Save/restore errno.
  93. ACE_Errno_Guard error (errno);
  94. if (result == -1 && timeout != 0)
  95. {
  96. // Check whether the connection is in progress.
  97. if (error == EINPROGRESS || error == EWOULDBLOCK)
  98. {
  99. // This expression checks if we were polling.
  100. if (*timeout == ACE_Time_Value::zero)
  101. {
  102. #if defined(ACE_WIN32)
  103. // In order to detect when the socket that has been
  104. // bound to is in TIME_WAIT we need to do the connect
  105. // (which will always return EWOULDBLOCK) and then do an
  106. // ACE::handle_timed_complete() (with timeout==0,
  107. // i.e. poll). This will do a select() on the handle
  108. // which will immediately return with the handle in an
  109. // error state. The error code is then retrieved with
  110. // getsockopt(). Good sockets however will return from
  111. // the select() with ETIME - in this case return
  112. // EWOULDBLOCK so the wait strategy can complete the
  113. // connection.
  114. if(ACE::handle_timed_complete (new_stream.get_handle (),
  115. timeout) == ACE_INVALID_HANDLE)
  116. {
  117. int const tmp = errno;
  118. if (tmp != ETIME)
  119. {
  120. error = tmp;
  121. }
  122. else
  123. error = EWOULDBLOCK;
  124. }
  125. else
  126. result = 0;
  127. #else /* ACE_WIN32 */
  128. error = EWOULDBLOCK;
  129. #endif /* ACE_WIN32 */
  130. }
  131. // Wait synchronously using timeout.
  132. else if (this->complete (new_stream, 0, timeout) == -1)
  133. error = errno;
  134. else
  135. return 0;
  136. }
  137. }
  138. // EISCONN is treated specially since this routine may be used to
  139. // check if we are already connected.
  140. if (result != -1 || error == EISCONN)
  141. {
  142. // Start out with non-blocking disabled on the new_stream.
  143. result = new_stream.disable (ACE_NONBLOCK);
  144. if (result == -1)
  145. {
  146. new_stream.close ();
  147. }
  148. }
  149. else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
  150. {
  151. new_stream.close ();
  152. }
  153. return result;
  154. }
  155. // Actively connect and produce a new ACE_SOCK_Stream if things go well...
  156. int
  157. ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
  158. const ACE_Addr &remote_sap,
  159. const ACE_Time_Value *timeout,
  160. const ACE_Addr &local_sap,
  161. int reuse_addr,
  162. int /* flags */,
  163. int /* perms */,
  164. int protocol)
  165. {
  166. ACE_TRACE ("ACE_SOCK_Connector::connect");
  167. if (this->shared_open (new_stream,
  168. remote_sap.get_type (),
  169. protocol,
  170. reuse_addr) == -1)
  171. return -1;
  172. else if (this->shared_connect_start (new_stream,
  173. timeout,
  174. local_sap) == -1)
  175. return -1;
  176. int result = ACE_OS::connect (new_stream.get_handle (),
  177. reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
  178. remote_sap.get_size ());
  179. return this->shared_connect_finish (new_stream, timeout, result);
  180. }
  181. #if !defined (ACE_HAS_WINCE)
  182. int
  183. ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
  184. const ACE_Addr &remote_sap,
  185. ACE_QoS_Params qos_params,
  186. const ACE_Time_Value *timeout,
  187. const ACE_Addr &local_sap,
  188. ACE_Protocol_Info * protocolinfo,
  189. ACE_SOCK_GROUP g,
  190. u_long flags,
  191. int reuse_addr,
  192. int /* perms */)
  193. {
  194. ACE_TRACE ("ACE_SOCK_Connector::connect");
  195. if (this->shared_open (new_stream,
  196. remote_sap.get_type (),
  197. 0,
  198. protocolinfo,
  199. g,
  200. flags,
  201. reuse_addr) == -1)
  202. return -1;
  203. else if (this->shared_connect_start (new_stream,
  204. timeout,
  205. local_sap) == -1)
  206. return -1;
  207. int result = ACE_OS::connect (new_stream.get_handle (),
  208. reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
  209. remote_sap.get_size (),
  210. qos_params);
  211. return this->shared_connect_finish (new_stream, timeout, result);
  212. }
  213. #endif // ACE_HAS_WINCE
  214. // Try to complete a non-blocking connection.
  215. int
  216. ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
  217. ACE_Addr *remote_sap,
  218. const ACE_Time_Value *tv)
  219. {
  220. ACE_TRACE ("ACE_SOCK_Connector::complete");
  221. ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (), tv);
  222. // We failed to get connected.
  223. if (h == ACE_INVALID_HANDLE)
  224. {
  225. #if defined (ACE_NON_BLOCKING_BUG_DELAY) && ACE_NON_BLOCKING_BUG_DELAY > 0
  226. // Win32 has a timing problem - if you check to see if the
  227. // connection has completed too fast, it will fail - so wait
  228. // <ACE_NON_BLOCKING_BUG_DELAY> microseconds to let it catch up
  229. // then retry to see if it's a real failure.
  230. ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
  231. ACE_OS::sleep (time);
  232. h = ACE::handle_timed_complete (new_stream.get_handle (), tv);
  233. if (h == ACE_INVALID_HANDLE)
  234. {
  235. #endif /* ACE_NON_BLOCKING_BUG_DELAY */
  236. // Save/restore errno.
  237. ACE_Errno_Guard error (errno);
  238. new_stream.close ();
  239. return -1;
  240. #if defined (ACE_NON_BLOCKING_BUG_DELAY) && ACE_NON_BLOCKING_BUG_DELAY > 0
  241. }
  242. #endif /* ACE_NON_BLOCKING_BUG_DELAY */
  243. }
  244. if (remote_sap != 0)
  245. {
  246. int len = remote_sap->get_size ();
  247. sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
  248. if (ACE_OS::getpeername (h,
  249. addr,
  250. &len) == -1)
  251. {
  252. // Save/restore errno.
  253. ACE_Errno_Guard error (errno);
  254. new_stream.close ();
  255. return -1;
  256. }
  257. }
  258. // Start out with non-blocking disabled on the <new_stream>.
  259. new_stream.disable (ACE_NONBLOCK);
  260. return 0;
  261. }
  262. ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
  263. const ACE_Addr &remote_sap,
  264. const ACE_Time_Value *timeout,
  265. const ACE_Addr &local_sap,
  266. int reuse_addr,
  267. int flags,
  268. int perms,
  269. int protocol)
  270. {
  271. ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
  272. if (this->connect (new_stream,
  273. remote_sap,
  274. timeout,
  275. local_sap,
  276. reuse_addr,
  277. flags,
  278. perms,
  279. protocol) == -1
  280. && timeout != 0
  281. && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
  282. ACELIB_ERROR ((LM_ERROR,
  283. ACE_TEXT ("%p\n"),
  284. ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
  285. }
  286. #if !defined (ACE_HAS_WINCE)
  287. ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
  288. const ACE_Addr &remote_sap,
  289. ACE_QoS_Params qos_params,
  290. const ACE_Time_Value *timeout,
  291. 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 perms)
  297. {
  298. ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
  299. if (this->connect (new_stream,
  300. remote_sap,
  301. qos_params,
  302. timeout,
  303. local_sap,
  304. protocolinfo,
  305. g,
  306. flags,
  307. reuse_addr,
  308. perms) == -1
  309. && timeout != 0
  310. && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
  311. ACELIB_ERROR ((LM_ERROR,
  312. ACE_TEXT ("%p\n"),
  313. ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
  314. }
  315. #endif // ACE_HAS_WINCE
  316. ACE_END_VERSIONED_NAMESPACE_DECL