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.

307 lines
9.8KB

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