/src/rp/rpn/rpnSocket.cpp

https://github.com/ALTIBASE/altibase · C++ · 320 lines · 224 code · 55 blank · 41 comment · 28 complexity · 7739e86ebb394def8905da0a9d855673 MD5 · raw file

  1. /**
  2. * Copyright (c) 1999~2017, Altibase Corp. and/or its affiliates. All rights reserved.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <idl.h>
  17. #include <ide.h>
  18. #include <idu.h>
  19. #include <rpError.h>
  20. #include <rpnSocket.h>
  21. /*
  22. * After calling this function, aInetAddressInfo must be freed.
  23. */
  24. static IDE_RC getInetAddrInfo( SChar * aIPAddress,
  25. UInt aIPAddressLength,
  26. UShort aPortNumber,
  27. acp_inet_addr_info_t ** aInetAddressInfo,
  28. SInt * aFamily )
  29. {
  30. UChar sTempAddr[ID_SIZEOF(struct in6_addr)];
  31. SChar sPortString[ IDL_IP_PORT_MAX_LEN ] = { 0, };
  32. acp_sint32_t sFamily = 0;
  33. SInt sAddrFlag = 0;
  34. acp_rc_t sRC = ACP_RC_SUCCESS;
  35. idlOS::snprintf( sPortString, ID_SIZEOF(sPortString), "%"ID_UINT32_FMT"", aPortNumber );
  36. *aInetAddressInfo = NULL;
  37. /*
  38. * sun 2.8 not defined
  39. */
  40. #if defined(AI_NUMERICSERV)
  41. sAddrFlag = ACP_INET_AI_NUMERICSERV; /* port_no */
  42. #endif
  43. /*
  44. * GettAddrInfo can handle IP Address
  45. * MANUAL :
  46. * If the AI_NUMERICHOST bit is set, it indicates that hostname should be treated as a
  47. * numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted
  48. */
  49. sAddrFlag |= ACP_INET_AI_NUMERICHOST;
  50. /* inet_pton() returns a positive value on success */
  51. /* check to see if ipv4 address. ex) ddd.ddd.ddd.ddd */
  52. if ( idlOS::inet_pton( AF_INET,
  53. aIPAddress,
  54. sTempAddr ) > 0 )
  55. {
  56. sFamily = AF_INET;
  57. }
  58. /* check to see if ipv6 address. ex) h:h:h:h:h:h:h:h */
  59. /* bug-30835: support link-local address with zone index.
  60. * before: inet_pton(inet6)
  61. * after : strchr(':')
  62. * inet_pton does not support zone index form. */
  63. else if ( idlOS::strnchr( aIPAddress, ':', aIPAddressLength ) != NULL )
  64. {
  65. sFamily = AF_INET6;
  66. }
  67. /* hostname format. ex) db.server.com */
  68. else
  69. {
  70. /* replication does not support hostname */
  71. IDE_DASSERT( 0 );
  72. IDE_RAISE( ERR_GET_ADDR_INFO );
  73. }
  74. /* address init */
  75. sRC = acpInetGetAddrInfo( aInetAddressInfo,
  76. aIPAddress,
  77. sPortString,
  78. ACP_SOCK_STREAM,
  79. sAddrFlag,
  80. sFamily );
  81. IDE_TEST_RAISE( ( sRC != IDE_SUCCESS ) || ( *aInetAddressInfo == NULL ),
  82. ERR_GET_ADDR_INFO );
  83. *aFamily = sFamily;
  84. return IDE_SUCCESS;
  85. IDE_EXCEPTION( ERR_GET_ADDR_INFO )
  86. {
  87. IDE_SET( ideSetErrorCode( rpERR_ABORT_SOCK_GET_ADDR_INFO_ERROR, aIPAddress, aPortNumber ) );
  88. }
  89. IDE_EXCEPTION_END;
  90. *aInetAddressInfo = NULL;
  91. return IDE_FAILURE;
  92. }
  93. IDE_RC rpnSocketInitailize( rpnSocket * aSocket,
  94. SChar * aIPAddress,
  95. UInt aIPAddressLength,
  96. UShort aPortNumber,
  97. idBool aIsBlockMode )
  98. {
  99. acp_inet_addr_info_t * sInetAddressInfo = NULL;
  100. SInt sFamily = 0;
  101. IDE_DASSERT( aSocket->mIsOpened == ID_FALSE );
  102. IDE_DASSERT( aSocket->mInetAddressInfo == NULL );
  103. IDE_TEST( getInetAddrInfo( aIPAddress,
  104. aIPAddressLength,
  105. aPortNumber,
  106. &sInetAddressInfo,
  107. &sFamily )
  108. != IDE_SUCCESS );
  109. IDU_FIT_POINT_RAISE( "rpnSocketInitailize::acpSockOpen::mSocket", ERR_SOCK_OPEN );
  110. IDE_TEST_RAISE( acpSockOpen( &(aSocket->mSocket),
  111. sFamily,
  112. SOCK_STREAM,
  113. 0 )
  114. != ACP_RC_SUCCESS, ERR_SOCK_OPEN );
  115. aSocket->mIsOpened = ID_TRUE;
  116. IDE_TEST( rpnSocketSetBlockMode( aSocket,
  117. aIsBlockMode )
  118. != IDE_SUCCESS );
  119. aSocket->mInetAddressInfo = sInetAddressInfo;
  120. aSocket->mFamily = sFamily;
  121. return IDE_SUCCESS;
  122. IDE_EXCEPTION( ERR_SOCK_OPEN )
  123. {
  124. IDE_SET( ideSetErrorCode( rpERR_ABORT_SOCKET_OPEN_ERROR ) );
  125. }
  126. IDE_EXCEPTION_END;
  127. if ( sInetAddressInfo != NULL )
  128. {
  129. acpInetFreeAddrInfo( sInetAddressInfo );
  130. sInetAddressInfo = NULL;
  131. }
  132. else
  133. {
  134. /* do nothing */
  135. }
  136. if ( aSocket->mIsOpened == ID_TRUE )
  137. {
  138. (void)acpSockClose( &(aSocket->mSocket) );
  139. aSocket->mIsOpened = ID_FALSE;
  140. }
  141. else
  142. {
  143. /* do nothing */
  144. }
  145. aSocket->mInetAddressInfo = NULL;
  146. return IDE_FAILURE;
  147. }
  148. void rpnSocketFinalize( rpnSocket * aSocket )
  149. {
  150. IDE_DASSERT( aSocket->mIsOpened == ID_TRUE );
  151. IDE_DASSERT( aSocket->mInetAddressInfo != NULL );
  152. if ( aSocket->mIsOpened == ID_TRUE )
  153. {
  154. (void)acpSockClose( &(aSocket->mSocket) );
  155. aSocket->mIsOpened = ID_FALSE;
  156. }
  157. else
  158. {
  159. /* do nothing */
  160. }
  161. if ( aSocket->mInetAddressInfo != NULL )
  162. {
  163. acpInetFreeAddrInfo( aSocket->mInetAddressInfo );
  164. aSocket->mInetAddressInfo = NULL;
  165. }
  166. else
  167. {
  168. /* do nothing */
  169. }
  170. }
  171. IDE_RC rpnSocketSetBlockMode( rpnSocket * aSocket,
  172. idBool aIsBlockMode )
  173. {
  174. acp_bool_t sIsBlockMode = ACP_TRUE;
  175. if ( aIsBlockMode == ID_TRUE )
  176. {
  177. sIsBlockMode = ACP_TRUE;
  178. }
  179. else
  180. {
  181. sIsBlockMode = ACP_FALSE;
  182. }
  183. IDE_TEST_RAISE( acpSockSetBlockMode( &(aSocket->mSocket),
  184. sIsBlockMode )
  185. != IDE_SUCCESS, ERR_SET_BLOCK_MODE );
  186. return IDE_SUCCESS;
  187. IDE_EXCEPTION( ERR_SET_BLOCK_MODE )
  188. {
  189. IDE_SET( ideSetErrorCode( rpERR_ABORT_SOCKET_SET_BLOCK_MODE ) );
  190. }
  191. IDE_EXCEPTION_END;
  192. return IDE_FAILURE;
  193. }
  194. IDE_RC rpnSocketConnect( rpnSocket * aSocket )
  195. {
  196. acp_inet_addr_info_t * sInetAddressInfo = NULL;
  197. acp_rc_t sRC = ACP_RC_SUCCESS;
  198. sInetAddressInfo = aSocket->mInetAddressInfo;
  199. sRC = acpSockConnect( &(aSocket->mSocket),
  200. sInetAddressInfo->ai_addr,
  201. sInetAddressInfo->ai_addrlen );
  202. switch ( sRC )
  203. {
  204. case ACP_RC_SUCCESS:
  205. break;
  206. case ACP_RC_EAGAIN:
  207. case ACP_RC_EINPROGRESS:
  208. case ACP_RC_ETIMEDOUT:
  209. IDE_RAISE( ERR_CONNECT_TIMEOUT );
  210. break;
  211. default:
  212. IDE_RAISE( ERR_CONNECT_FAIL );
  213. break;
  214. }
  215. return IDE_SUCCESS;
  216. IDE_EXCEPTION( ERR_CONNECT_TIMEOUT )
  217. {
  218. IDE_SET( ideSetErrorCode( rpERR_ABORT_TIMEOUT_EXCEED ) );
  219. }
  220. IDE_EXCEPTION( ERR_CONNECT_FAIL )
  221. {
  222. IDE_SET( ideSetErrorCode( rpERR_ABORT_CONNECT_FAIL ) );
  223. }
  224. IDE_EXCEPTION_END;
  225. return IDE_FAILURE;
  226. }
  227. IDE_RC rpnSocketGetOpt( rpnSocket * aSocket,
  228. SInt aLevel,
  229. SInt aOptionName,
  230. void * aOptionValue,
  231. ULong * aOptionLength )
  232. {
  233. acp_sock_len_t sOptionLength = (acp_sock_len_t)*aOptionLength;
  234. IDE_TEST_RAISE ( acpSockGetOpt( &(aSocket->mSocket),
  235. aLevel,
  236. aOptionName,
  237. aOptionValue,
  238. &sOptionLength )
  239. != ACP_RC_SUCCESS, ERR_SOCK_GET_OPT );
  240. *aOptionLength = (ULong)sOptionLength;
  241. return IDE_SUCCESS;
  242. IDE_EXCEPTION( ERR_SOCK_GET_OPT )
  243. {
  244. IDE_SET( ideSetErrorCode( rpERR_ABORT_SOCKET_GET_OPTION ) );
  245. }
  246. IDE_EXCEPTION_END;
  247. return IDE_FAILURE;
  248. }
  249. idBool rpnSocketIsConnecting( UInt aErrorNumber )
  250. {
  251. idBool sIsConnecting = ID_FALSE;
  252. switch ( aErrorNumber )
  253. {
  254. case ACP_RC_EAGAIN:
  255. case ACP_RC_EALREADY:
  256. case ACP_RC_EINPROGRESS:
  257. case ACP_RC_ETIMEDOUT:
  258. sIsConnecting = ID_TRUE;
  259. break;
  260. default:
  261. sIsConnecting = ID_FALSE;
  262. break;
  263. }
  264. return sIsConnecting;
  265. }