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.

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