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.

359 lines
13KB

  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 "JackNetWinSocket.h"
  16. namespace Jack
  17. {
  18. //utility *********************************************************************************************************
  19. SERVER_EXPORT 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. struct
  30. {
  31. int code;
  32. char* msg;
  33. } NetErrorList[] =
  34. {
  35. E ( 0, "No error" ),
  36. E ( WSAEINTR, "Interrupted system call" ),
  37. E ( WSAEBADF, "Bad file number" ),
  38. E ( WSAEACCES, "Permission denied" ),
  39. E ( WSAEFAULT, "Bad address" ),
  40. E ( WSAEINVAL, "Invalid argument" ),
  41. E ( WSAEMFILE, "Too many open sockets" ),
  42. E ( WSAEWOULDBLOCK, "Operation would block" ),
  43. E ( WSAEINPROGRESS, "Operation now in progress" ),
  44. E ( WSAEALREADY, "Operation already in progress" ),
  45. E ( WSAENOTSOCK, "Socket operation on non-socket" ),
  46. E ( WSAEDESTADDRREQ, "Destination address required" ),
  47. E ( WSAEMSGSIZE, "Message too long" ),
  48. E ( WSAEPROTOTYPE, "Protocol wrong type for socket" ),
  49. E ( WSAENOPROTOOPT, "Bad protocol option" ),
  50. E ( WSAEPROTONOSUPPORT, "Protocol not supported" ),
  51. E ( WSAESOCKTNOSUPPORT, "Socket type not supported" ),
  52. E ( WSAEOPNOTSUPP, "Operation not supported on socket" ),
  53. E ( WSAEPFNOSUPPORT, "Protocol family not supported" ),
  54. E ( WSAEAFNOSUPPORT, "Address family not supported" ),
  55. E ( WSAEADDRINUSE, "Address already in use" ),
  56. E ( WSAEADDRNOTAVAIL, "Can't assign requested address" ),
  57. E ( WSAENETDOWN, "Network is down" ),
  58. E ( WSAENETUNREACH, "Network is unreachable" ),
  59. E ( WSAENETRESET, "Net connection reset" ),
  60. E ( WSAECONNABORTED, "Software caused connection abort" ),
  61. E ( WSAECONNRESET, "Connection reset by peer" ),
  62. E ( WSAENOBUFS, "No buffer space available" ),
  63. E ( WSAEISCONN, "Socket is already connected" ),
  64. E ( WSAENOTCONN, "Socket is not connected" ),
  65. E ( WSAESHUTDOWN, "Can't send after socket shutdown" ),
  66. E ( WSAETOOMANYREFS, "Too many references, can't splice" ),
  67. E ( WSAETIMEDOUT, "Connection timed out" ),
  68. E ( WSAECONNREFUSED, "Connection refused" ),
  69. E ( WSAELOOP, "Too many levels of symbolic links" ),
  70. E ( WSAENAMETOOLONG, "File name too long" ),
  71. E ( WSAEHOSTDOWN, "Host is down" ),
  72. E ( WSAEHOSTUNREACH, "No route to host" ),
  73. E ( WSAENOTEMPTY, "Directory not empty" ),
  74. E ( WSAEPROCLIM, "Too many processes" ),
  75. E ( WSAEUSERS, "Too many users" ),
  76. E ( WSAEDQUOT, "Disc quota exceeded" ),
  77. E ( WSAESTALE, "Stale NFS file handle" ),
  78. E ( WSAEREMOTE, "Too many levels of remote in path" ),
  79. E ( WSASYSNOTREADY, "Network system is unavailable" ),
  80. E ( WSAVERNOTSUPPORTED, "Winsock version out of range" ),
  81. E ( WSANOTINITIALISED, "WSAStartup not yet called" ),
  82. E ( WSAEDISCON, "Graceful shutdown in progress" ),
  83. E ( WSAHOST_NOT_FOUND, "Host not found" ),
  84. E ( WSANO_DATA, "No host data of that type was found" ),
  85. { -1, NULL },
  86. };
  87. SERVER_EXPORT const char* PrintError ( int error )
  88. {
  89. int i;
  90. for ( i = 0; NetErrorList[i].code >= 0; ++i )
  91. {
  92. if ( error == NetErrorList[i].code )
  93. return NetErrorList[i].msg;
  94. }
  95. return strerror ( error );
  96. }
  97. //construct/destruct***********************************************************************************************
  98. JackNetWinSocket::JackNetWinSocket()
  99. {
  100. fSockfd = 0;
  101. fSendAddr.sin_family = AF_INET;
  102. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  103. memset ( &fSendAddr.sin_zero, 0, 8 );
  104. fRecvAddr.sin_family = AF_INET;
  105. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  106. memset ( &fRecvAddr.sin_zero, 0, 8 );
  107. }
  108. JackNetWinSocket::JackNetWinSocket ( const char* ip, int port )
  109. {
  110. fSockfd = 0;
  111. fPort = port;
  112. fSendAddr.sin_family = AF_INET;
  113. fSendAddr.sin_port = htons ( port );
  114. fSendAddr.sin_addr.s_addr = inet_addr ( ip );
  115. memset ( &fSendAddr.sin_zero, 0, 8 );
  116. fRecvAddr.sin_family = AF_INET;
  117. fRecvAddr.sin_port = htons ( port );
  118. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  119. memset ( &fRecvAddr.sin_zero, 0, 8 );
  120. }
  121. JackNetWinSocket::JackNetWinSocket ( const JackNetWinSocket& socket )
  122. {
  123. fSockfd = 0;
  124. fPort = socket.fPort;
  125. fSendAddr = socket.fSendAddr;
  126. fRecvAddr = socket.fRecvAddr;
  127. }
  128. JackNetWinSocket::~JackNetWinSocket()
  129. {
  130. Close();
  131. }
  132. JackNetWinSocket& JackNetWinSocket::operator= ( const JackNetWinSocket& socket )
  133. {
  134. if ( this != &socket )
  135. {
  136. fSockfd = 0;
  137. fPort = socket.fPort;
  138. fSendAddr = socket.fSendAddr;
  139. fRecvAddr = socket.fRecvAddr;
  140. }
  141. return *this;
  142. }
  143. //socket***********************************************************************************************************
  144. int JackNetWinSocket::NewSocket()
  145. {
  146. if ( fSockfd )
  147. {
  148. Close();
  149. Reset();
  150. }
  151. fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
  152. return fSockfd;
  153. }
  154. int JackNetWinSocket::Bind()
  155. {
  156. return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) );
  157. }
  158. int JackNetWinSocket::BindWith ( const char* ip )
  159. {
  160. fRecvAddr.sin_addr.s_addr = inet_addr ( ip );
  161. return Bind();
  162. }
  163. int JackNetWinSocket::BindWith ( int port )
  164. {
  165. fRecvAddr.sin_port = htons ( port );
  166. return Bind();
  167. }
  168. int JackNetWinSocket::Connect()
  169. {
  170. return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
  171. }
  172. int JackNetWinSocket::ConnectTo ( const char* ip )
  173. {
  174. fSendAddr.sin_addr.s_addr = inet_addr ( ip );
  175. return Connect();
  176. }
  177. void JackNetWinSocket::Close()
  178. {
  179. if ( fSockfd )
  180. closesocket ( fSockfd );
  181. fSockfd = 0;
  182. }
  183. void JackNetWinSocket::Reset()
  184. {
  185. fSendAddr.sin_family = AF_INET;
  186. fSendAddr.sin_port = htons ( fPort );
  187. fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  188. memset ( &fSendAddr.sin_zero, 0, 8 );
  189. fRecvAddr.sin_family = AF_INET;
  190. fRecvAddr.sin_port = htons ( fPort );
  191. fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
  192. memset ( &fRecvAddr.sin_zero, 0, 8 );
  193. }
  194. bool JackNetWinSocket::IsSocket()
  195. {
  196. return ( fSockfd ) ? true : false;
  197. }
  198. //IP/PORT***********************************************************************************************************
  199. void JackNetWinSocket::SetPort ( int port )
  200. {
  201. fPort = port;
  202. fSendAddr.sin_port = htons ( port );
  203. fRecvAddr.sin_port = htons ( port );
  204. }
  205. int JackNetWinSocket::GetPort()
  206. {
  207. return fPort;
  208. }
  209. //address***********************************************************************************************************
  210. int JackNetWinSocket::SetAddress ( const char* ip, int port )
  211. {
  212. fSendAddr.sin_addr.s_addr = inet_addr ( ip );
  213. fSendAddr.sin_port = htons ( port );
  214. return 0;
  215. }
  216. char* JackNetWinSocket::GetSendIP()
  217. {
  218. return inet_ntoa ( fSendAddr.sin_addr );
  219. }
  220. char* JackNetWinSocket::GetRecvIP()
  221. {
  222. return inet_ntoa ( fRecvAddr.sin_addr );
  223. }
  224. //utility************************************************************************************************************
  225. int JackNetWinSocket::GetName ( char* name )
  226. {
  227. return gethostname ( name, 255 );
  228. }
  229. int JackNetWinSocket::JoinMCastGroup ( const char* ip )
  230. {
  231. struct ip_mreq multicast_req;
  232. multicast_req.imr_multiaddr.s_addr = inet_addr ( ip );
  233. multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
  234. //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
  235. return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) );
  236. }
  237. //options************************************************************************************************************
  238. int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen )
  239. {
  240. return setsockopt ( fSockfd, level, optname, static_cast<const char*> ( optval ), optlen );
  241. }
  242. int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen )
  243. {
  244. return getsockopt ( fSockfd, level, optname, static_cast<char*> ( optval ), optlen );
  245. }
  246. //tiemout************************************************************************************************************
  247. int JackNetWinSocket::SetTimeOut ( int usec )
  248. {
  249. jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec );
  250. //negative timeout, or exceeding 10s, return
  251. if ( ( usec < 0 ) || ( usec > 10000000 ) )
  252. return SOCKET_ERROR;
  253. int time = usec / 1000;
  254. return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) );
  255. }
  256. //local loop*********************************************************************************************************
  257. int JackNetWinSocket::SetLocalLoop()
  258. {
  259. char disable = 0;
  260. return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
  261. }
  262. //network operations*************************************************************************************************
  263. int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
  264. {
  265. return sendto ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
  266. }
  267. int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
  268. {
  269. fSendAddr.sin_addr.s_addr = inet_addr ( ip );
  270. return SendTo ( buffer, nbytes, flags );
  271. }
  272. int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags )
  273. {
  274. return send ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags );
  275. }
  276. int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
  277. {
  278. SOCKLEN addr_len = sizeof ( SOCKADDR );
  279. return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len );
  280. }
  281. int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags )
  282. {
  283. return recv ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags );
  284. }
  285. int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
  286. {
  287. SOCKLEN addr_len = sizeof ( SOCKADDR );
  288. return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len );
  289. }
  290. net_error_t JackNetWinSocket::GetError()
  291. {
  292. switch ( NET_ERROR_CODE )
  293. {
  294. case WSABASEERR:
  295. return NET_NO_ERROR;
  296. case WSAETIMEDOUT:
  297. return NET_NO_DATA;
  298. case WSAEWOULDBLOCK:
  299. return NET_NO_DATA;
  300. case WSAECONNREFUSED:
  301. return NET_CONN_ERROR;
  302. case WSAECONNRESET:
  303. return NET_CONN_ERROR;
  304. case WSAEACCES:
  305. return NET_CONN_ERROR;
  306. case WSAECONNABORTED:
  307. return NET_CONN_ERROR;
  308. case WSAEHOSTDOWN:
  309. return NET_CONN_ERROR;
  310. case WSAEHOSTUNREACH:
  311. return NET_CONN_ERROR;
  312. default:
  313. return NET_OP_ERROR;
  314. }
  315. }
  316. }