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.

291 lines
9.3KB

  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 SOCKET_ERROR;
  26. }
  27. return 0;
  28. }
  29. //construct/destruct***********************************************************************************************
  30. JackNetUnixSocket::JackNetUnixSocket()
  31. {
  32. fSockfd = 0;
  33. fPort = 0;
  34. fSendAddr.sin_family = AF_INET;
  35. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  36. memset ( &fSendAddr.sin_zero, 0, 8 );
  37. fRecvAddr.sin_family = AF_INET;
  38. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  39. memset ( &fRecvAddr.sin_zero, 0, 8 );
  40. }
  41. JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port )
  42. {
  43. fSockfd = 0;
  44. fPort = port;
  45. fSendAddr.sin_family = AF_INET;
  46. fSendAddr.sin_port = htons ( port );
  47. inet_aton ( ip, &fSendAddr.sin_addr );
  48. memset ( &fSendAddr.sin_zero, 0, 8 );
  49. fRecvAddr.sin_family = AF_INET;
  50. fRecvAddr.sin_port = htons ( port );
  51. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  52. memset ( &fRecvAddr.sin_zero, 0, 8 );
  53. }
  54. JackNetUnixSocket::~JackNetUnixSocket()
  55. {
  56. Close();
  57. }
  58. //socket***********************************************************************************************************
  59. int JackNetUnixSocket::NewSocket()
  60. {
  61. if ( fSockfd )
  62. {
  63. Close();
  64. Reset();
  65. }
  66. fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
  67. return fSockfd;
  68. }
  69. int JackNetUnixSocket::Bind()
  70. {
  71. return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) );
  72. }
  73. int JackNetUnixSocket::BindWith ( const char* ip )
  74. {
  75. int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr );
  76. if ( addr_conv < 0 )
  77. return addr_conv;
  78. return Bind();
  79. }
  80. int JackNetUnixSocket::BindWith ( int port )
  81. {
  82. fRecvAddr.sin_port = htons ( port );
  83. return Bind();
  84. }
  85. int JackNetUnixSocket::Connect()
  86. {
  87. return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
  88. }
  89. int JackNetUnixSocket::ConnectTo ( const char* ip )
  90. {
  91. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  92. if ( addr_conv < 0 )
  93. return addr_conv;
  94. return Connect();
  95. }
  96. void JackNetUnixSocket::Close()
  97. {
  98. if ( fSockfd )
  99. close ( fSockfd );
  100. fSockfd = 0;
  101. }
  102. void JackNetUnixSocket::Reset()
  103. {
  104. fSendAddr.sin_family = AF_INET;
  105. fSendAddr.sin_port = htons ( fPort );
  106. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  107. memset ( &fSendAddr.sin_zero, 0, 8 );
  108. fRecvAddr.sin_family = AF_INET;
  109. fRecvAddr.sin_port = htons ( fPort );
  110. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  111. memset ( &fRecvAddr.sin_zero, 0, 8 );
  112. }
  113. bool JackNetUnixSocket::IsSocket()
  114. {
  115. return ( fSockfd ) ? true : false;
  116. }
  117. //IP/PORT***********************************************************************************************************
  118. void JackNetUnixSocket::SetPort ( int port )
  119. {
  120. fPort = port;
  121. fSendAddr.sin_port = htons ( port );
  122. fRecvAddr.sin_port = htons ( port );
  123. }
  124. int JackNetUnixSocket::GetPort()
  125. {
  126. return fPort;
  127. }
  128. //address***********************************************************************************************************
  129. int JackNetUnixSocket::SetAddress ( const char* ip, int port )
  130. {
  131. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  132. if ( addr_conv < 0 )
  133. return addr_conv;
  134. fSendAddr.sin_port = htons ( port );
  135. return 0;
  136. }
  137. char* JackNetUnixSocket::GetSendIP()
  138. {
  139. return inet_ntoa ( fSendAddr.sin_addr );
  140. }
  141. char* JackNetUnixSocket::GetRecvIP()
  142. {
  143. return inet_ntoa ( fRecvAddr.sin_addr );
  144. }
  145. //utility************************************************************************************************************
  146. int JackNetUnixSocket::GetName ( char* name )
  147. {
  148. return gethostname ( name, 255 );
  149. }
  150. int JackNetUnixSocket::JoinMCastGroup ( const char* ip )
  151. {
  152. struct ip_mreq multicast_req;
  153. inet_aton ( ip, &multicast_req.imr_multiaddr );
  154. multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
  155. return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) );
  156. }
  157. void JackNetUnixSocket::CopyParams ( JackNetUnixSocket* socket )
  158. {
  159. fPort = socket->fPort;
  160. fSendAddr = socket->fSendAddr;
  161. fRecvAddr = socket->fRecvAddr;
  162. }
  163. //options************************************************************************************************************
  164. int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen )
  165. {
  166. return setsockopt ( fSockfd, level, optname, optval, optlen );
  167. }
  168. int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen )
  169. {
  170. return getsockopt ( fSockfd, level, optname, optval, optlen );
  171. }
  172. //timeout************************************************************************************************************
  173. int JackNetUnixSocket::SetTimeOut ( int& us )
  174. {
  175. //negative timeout, or exceding 10s, return
  176. if ( ( us < 0 ) || ( us > 10000000 ) )
  177. return SOCKET_ERROR;
  178. struct timeval timeout;
  179. //less than 1sec
  180. if ( us < 1000000 )
  181. {
  182. timeout.tv_sec = 0;
  183. timeout.tv_usec = us;
  184. }
  185. //more than 1sec
  186. else
  187. {
  188. float sec = static_cast<float>( us ) / 1000000.f;
  189. timeout.tv_sec = ( int ) sec;
  190. float usec = ( sec - static_cast<float> ( timeout.tv_sec ) ) * 1000000;
  191. timeout.tv_usec = ( int ) usec;
  192. }
  193. return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) );
  194. }
  195. //local loop**********************************************************************************************************
  196. int JackNetUnixSocket::SetLocalLoop()
  197. {
  198. char disable = 0;
  199. return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
  200. }
  201. //network operations**************************************************************************************************
  202. int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
  203. {
  204. return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
  205. }
  206. int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
  207. {
  208. int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
  209. if ( addr_conv < 1 )
  210. return addr_conv;
  211. return SendTo ( buffer, nbytes, flags );
  212. }
  213. int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags )
  214. {
  215. return send ( fSockfd, buffer, nbytes, flags );
  216. }
  217. int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
  218. {
  219. socklen_t addr_len = sizeof ( socket_address_t );
  220. return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len );
  221. }
  222. int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags )
  223. {
  224. return recv ( fSockfd, buffer, nbytes, flags );
  225. }
  226. int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
  227. {
  228. socklen_t addr_len = sizeof ( socket_address_t );
  229. return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len );
  230. }
  231. net_error_t JackNetUnixSocket::GetError()
  232. {
  233. switch ( errno )
  234. {
  235. case EAGAIN:
  236. return NET_NO_DATA;
  237. case ECONNABORTED:
  238. return NET_CONN_ERROR;
  239. case EINVAL:
  240. return NET_CONN_ERROR;
  241. case ECONNREFUSED:
  242. return NET_CONN_ERROR;
  243. case ECONNRESET:
  244. return NET_CONN_ERROR;
  245. case EHOSTDOWN:
  246. return NET_CONN_ERROR;
  247. case EHOSTUNREACH:
  248. return NET_CONN_ERROR;
  249. default:
  250. return NET_OP_ERROR;
  251. }
  252. }
  253. }