jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
8.5KB

  1. /*
  2. Copyright (C) 2008 Romain Moret at Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackNetUnixSocket.h"
  16. namespace Jack
  17. {
  18. //utility *********************************************************************************************************
  19. int GetHostName ( char * name, int size )
  20. {
  21. if ( gethostname ( name, size) == SOCKET_ERROR )
  22. {
  23. jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) );
  24. strcpy ( name, "default" );
  25. return -1;
  26. }
  27. return 0;
  28. }
  29. //construct/destruct***********************************************************************************************
  30. JackNetUnixSocket::JackNetUnixSocket()
  31. {
  32. fSockfd = 0;
  33. fSendAddr.sin_family = AF_INET;
  34. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  35. memset ( &fSendAddr.sin_zero, 0, 8 );
  36. fRecvAddr.sin_family = AF_INET;
  37. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  38. memset ( &fRecvAddr.sin_zero, 0, 8 );
  39. }
  40. JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port )
  41. {
  42. fSockfd = 0;
  43. fPort = port;
  44. fSendAddr.sin_family = AF_INET;
  45. fSendAddr.sin_port = htons ( port );
  46. inet_aton ( ip, &fSendAddr.sin_addr );
  47. memset ( &fSendAddr.sin_zero, 0, 8 );
  48. fRecvAddr.sin_family = AF_INET;
  49. fRecvAddr.sin_port = htons ( port );
  50. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  51. memset ( &fRecvAddr.sin_zero, 0, 8 );
  52. }
  53. JackNetUnixSocket::~JackNetUnixSocket()
  54. {
  55. Close();
  56. }
  57. //socket***********************************************************************************************************
  58. int JackNetUnixSocket::NewSocket()
  59. {
  60. if ( fSockfd )
  61. {
  62. Close();
  63. Reset();
  64. }
  65. fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
  66. return fSockfd;
  67. }
  68. int JackNetUnixSocket::Bind()
  69. {
  70. return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) );
  71. }
  72. int JackNetUnixSocket::BindWith ( const char* ip )
  73. {
  74. int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr );
  75. if ( addr_conv < 0 )
  76. return addr_conv;
  77. return Bind();
  78. }
  79. int JackNetUnixSocket::BindWith ( int port )
  80. {
  81. fRecvAddr.sin_port = htons ( port );
  82. return Bind();
  83. }
  84. int JackNetUnixSocket::Connect()
  85. {
  86. return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
  87. }
  88. int JackNetUnixSocket::ConnectTo ( const char* ip )
  89. {
  90. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  91. if ( addr_conv < 0 )
  92. return addr_conv;
  93. return Connect();
  94. }
  95. void JackNetUnixSocket::Close()
  96. {
  97. if ( fSockfd )
  98. close ( fSockfd );
  99. fSockfd = 0;
  100. }
  101. void JackNetUnixSocket::Reset()
  102. {
  103. fSendAddr.sin_family = AF_INET;
  104. fSendAddr.sin_port = htons ( fPort );
  105. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  106. memset ( &fSendAddr.sin_zero, 0, 8 );
  107. fRecvAddr.sin_family = AF_INET;
  108. fRecvAddr.sin_port = htons ( fPort );
  109. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  110. memset ( &fRecvAddr.sin_zero, 0, 8 );
  111. }
  112. bool JackNetUnixSocket::IsSocket()
  113. {
  114. return ( fSockfd ) ? true : false;
  115. }
  116. //IP/PORT***********************************************************************************************************
  117. void JackNetUnixSocket::SetPort ( int port )
  118. {
  119. fPort = port;
  120. fSendAddr.sin_port = htons ( port );
  121. fRecvAddr.sin_port = htons ( port );
  122. }
  123. int JackNetUnixSocket::GetPort()
  124. {
  125. return fPort;
  126. }
  127. //address***********************************************************************************************************
  128. int JackNetUnixSocket::SetAddress ( const char* ip, int port )
  129. {
  130. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  131. if ( addr_conv < 0 )
  132. return addr_conv;
  133. fSendAddr.sin_port = htons ( port );
  134. return 0;
  135. }
  136. char* JackNetUnixSocket::GetSendIP()
  137. {
  138. return inet_ntoa ( fSendAddr.sin_addr );
  139. }
  140. char* JackNetUnixSocket::GetRecvIP()
  141. {
  142. return inet_ntoa ( fRecvAddr.sin_addr );
  143. }
  144. //utility************************************************************************************************************
  145. int JackNetUnixSocket::GetName ( char* name )
  146. {
  147. return gethostname ( name, 255 );
  148. }
  149. int JackNetUnixSocket::JoinMCastGroup ( const char* ip )
  150. {
  151. struct ip_mreq multicast_req;
  152. inet_aton ( ip, &multicast_req.imr_multiaddr );
  153. multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
  154. return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) );
  155. }
  156. void JackNetUnixSocket::CopyParams ( JackNetUnixSocket* socket )
  157. {
  158. fPort = socket->fPort;
  159. fSendAddr = socket->fSendAddr;
  160. fRecvAddr = socket->fRecvAddr;
  161. }
  162. //options************************************************************************************************************
  163. int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen )
  164. {
  165. return setsockopt ( fSockfd, level, optname, optval, optlen );
  166. }
  167. int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen )
  168. {
  169. return getsockopt ( fSockfd, level, optname, optval, optlen );
  170. }
  171. //timeout*************************************************************************************************************
  172. int JackNetUnixSocket::SetTimeOut ( int& msec )
  173. {
  174. //negative timeout, or exceeding 10s, return
  175. if ( ( msec < 0 ) || ( msec > 10000 ) )
  176. return -1;
  177. struct timeval timeout;
  178. //less than 1sec
  179. if ( msec < 1000 )
  180. {
  181. timeout.tv_sec = 0;
  182. timeout.tv_usec = msec * 1000;
  183. return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) );
  184. }
  185. //more than 1sec
  186. if ( msec >= 1000 )
  187. {
  188. float sec = static_cast<float>( msec ) / 1000.0f;
  189. timeout.tv_sec = ( int ) sec;
  190. float usec = ( sec - timeout.tv_sec ) * 1000000;
  191. timeout.tv_usec = ( int ) usec;
  192. return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) );
  193. }
  194. return -1;
  195. }
  196. //local loop**********************************************************************************************************
  197. int JackNetUnixSocket::SetLocalLoop()
  198. {
  199. char disable = 0;
  200. return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
  201. }
  202. //network operations**************************************************************************************************
  203. int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
  204. {
  205. return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
  206. }
  207. int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
  208. {
  209. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  210. if ( addr_conv < 1 )
  211. return addr_conv;
  212. return SendTo ( buffer, nbytes, flags );
  213. }
  214. int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags )
  215. {
  216. return send ( fSockfd, buffer, nbytes, flags );
  217. }
  218. int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
  219. {
  220. socklen_t addr_len = sizeof ( socket_address_t );
  221. return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len );
  222. }
  223. int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags )
  224. {
  225. return recv ( fSockfd, buffer, nbytes, flags );
  226. }
  227. int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
  228. {
  229. socklen_t addr_len = sizeof ( socket_address_t );
  230. return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len );
  231. }
  232. net_error_t JackNetUnixSocket::GetError()
  233. {
  234. switch ( errno )
  235. {
  236. case EAGAIN:
  237. return NET_NO_DATA;
  238. case ECONNABORTED:
  239. return NET_CONN_ERROR;
  240. case ECONNREFUSED:
  241. return NET_CONN_ERROR;
  242. case ECONNRESET:
  243. return NET_CONN_ERROR;
  244. case EHOSTDOWN:
  245. return NET_CONN_ERROR;
  246. case EHOSTUNREACH:
  247. return NET_CONN_ERROR;
  248. default:
  249. return NET_OP_ERROR;
  250. }
  251. }
  252. }