Merge branch 'master' into server_no_deadlock
[jack2.git] / windows / JackNetWinSocket.cpp
blob94390b4db27a2caed0ea71681c4c2e0ac0a04bcb
1 /*
2 Copyright (C) 2008 Romain Moret at Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackNetWinSocket.h"
22 namespace Jack
24 //utility *********************************************************************************************************
25 SERVER_EXPORT int GetHostName ( char * name, int size )
27 if ( gethostname ( name, size ) == SOCKET_ERROR )
29 jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) );
30 strcpy ( name, "default" );
31 return -1;
33 return 0;
36 win_net_error_t NetErrorList[] =
38 E ( 0, "No error" ),
39 E ( WSAEINTR, "Interrupted system call" ),
40 E ( WSAEBADF, "Bad file number" ),
41 E ( WSAEACCES, "Permission denied" ),
42 E ( WSAEFAULT, "Bad address" ),
43 E ( WSAEINVAL, "Invalid argument" ),
44 E ( WSAEMFILE, "Too many open sockets" ),
45 E ( WSAEWOULDBLOCK, "Operation would block" ),
46 E ( WSAEINPROGRESS, "Operation now in progress" ),
47 E ( WSAEALREADY, "Operation already in progress" ),
48 E ( WSAENOTSOCK, "Socket operation on non-socket" ),
49 E ( WSAEDESTADDRREQ, "Destination address required" ),
50 E ( WSAEMSGSIZE, "Message too long" ),
51 E ( WSAEPROTOTYPE, "Protocol wrong type for socket" ),
52 E ( WSAENOPROTOOPT, "Bad protocol option" ),
53 E ( WSAEPROTONOSUPPORT, "Protocol not supported" ),
54 E ( WSAESOCKTNOSUPPORT, "Socket type not supported" ),
55 E ( WSAEOPNOTSUPP, "Operation not supported on socket" ),
56 E ( WSAEPFNOSUPPORT, "Protocol family not supported" ),
57 E ( WSAEAFNOSUPPORT, "Address family not supported" ),
58 E ( WSAEADDRINUSE, "Address already in use" ),
59 E ( WSAEADDRNOTAVAIL, "Can't assign requested address" ),
60 E ( WSAENETDOWN, "Network is down" ),
61 E ( WSAENETUNREACH, "Network is unreachable" ),
62 E ( WSAENETRESET, "Net connection reset" ),
63 E ( WSAECONNABORTED, "Software caused connection abort" ),
64 E ( WSAECONNRESET, "Connection reset by peer" ),
65 E ( WSAENOBUFS, "No buffer space available" ),
66 E ( WSAEISCONN, "Socket is already connected" ),
67 E ( WSAENOTCONN, "Socket is not connected" ),
68 E ( WSAESHUTDOWN, "Can't send after socket shutdown" ),
69 E ( WSAETOOMANYREFS, "Too many references, can't splice" ),
70 E ( WSAETIMEDOUT, "Connection timed out" ),
71 E ( WSAECONNREFUSED, "Connection refused" ),
72 E ( WSAELOOP, "Too many levels of symbolic links" ),
73 E ( WSAENAMETOOLONG, "File name too long" ),
74 E ( WSAEHOSTDOWN, "Host is down" ),
75 E ( WSAEHOSTUNREACH, "No route to host" ),
76 E ( WSAENOTEMPTY, "Directory not empty" ),
77 E ( WSAEPROCLIM, "Too many processes" ),
78 E ( WSAEUSERS, "Too many users" ),
79 E ( WSAEDQUOT, "Disc quota exceeded" ),
80 E ( WSAESTALE, "Stale NFS file handle" ),
81 E ( WSAEREMOTE, "Too many levels of remote in path" ),
82 E ( WSASYSNOTREADY, "Network system is unavailable" ),
83 E ( WSAVERNOTSUPPORTED, "Winsock version out of range" ),
84 E ( WSANOTINITIALISED, "WSAStartup not yet called" ),
85 E ( WSAEDISCON, "Graceful shutdown in progress" ),
86 E ( WSAHOST_NOT_FOUND, "Host not found" ),
87 E ( WSANO_DATA, "No host data of that type was found" ),
88 { -1, NULL },
91 SERVER_EXPORT const char* PrintError ( int error )
93 int i;
94 for ( i = 0; NetErrorList[i].code >= 0; ++i )
96 if ( error == NetErrorList[i].code )
97 return NetErrorList[i].msg;
99 return strerror ( error );
102 //construct/destruct***********************************************************************************************
103 JackNetWinSocket::JackNetWinSocket()
105 fSockfd = 0;
106 fSendAddr.sin_family = AF_INET;
107 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
108 memset ( &fSendAddr.sin_zero, 0, 8 );
109 fRecvAddr.sin_family = AF_INET;
110 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
111 memset ( &fRecvAddr.sin_zero, 0, 8 );
114 JackNetWinSocket::JackNetWinSocket ( const char* ip, int port )
116 fSockfd = 0;
117 fPort = port;
118 fSendAddr.sin_family = AF_INET;
119 fSendAddr.sin_port = htons ( port );
120 fSendAddr.sin_addr.s_addr = inet_addr ( ip );
121 memset ( &fSendAddr.sin_zero, 0, 8 );
122 fRecvAddr.sin_family = AF_INET;
123 fRecvAddr.sin_port = htons ( port );
124 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
125 memset ( &fRecvAddr.sin_zero, 0, 8 );
128 JackNetWinSocket::JackNetWinSocket ( const JackNetWinSocket& socket )
130 fSockfd = 0;
131 fPort = socket.fPort;
132 fSendAddr = socket.fSendAddr;
133 fRecvAddr = socket.fRecvAddr;
136 JackNetWinSocket::~JackNetWinSocket()
138 Close();
141 JackNetWinSocket& JackNetWinSocket::operator= ( const JackNetWinSocket& socket )
143 if ( this != &socket )
145 fSockfd = 0;
146 fPort = socket.fPort;
147 fSendAddr = socket.fSendAddr;
148 fRecvAddr = socket.fRecvAddr;
150 return *this;
153 //socket***********************************************************************************************************
154 int JackNetWinSocket::NewSocket()
156 if ( fSockfd )
158 Close();
159 Reset();
161 fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
162 return fSockfd;
165 int JackNetWinSocket::Bind()
167 return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) );
170 int JackNetWinSocket::BindWith ( const char* ip )
172 fRecvAddr.sin_addr.s_addr = inet_addr ( ip );
173 return Bind();
176 int JackNetWinSocket::BindWith ( int port )
178 fRecvAddr.sin_port = htons ( port );
179 return Bind();
182 int JackNetWinSocket::Connect()
184 return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
187 int JackNetWinSocket::ConnectTo ( const char* ip )
189 fSendAddr.sin_addr.s_addr = inet_addr ( ip );
190 return Connect();
193 void JackNetWinSocket::Close()
195 if ( fSockfd )
196 closesocket ( fSockfd );
197 fSockfd = 0;
200 void JackNetWinSocket::Reset()
202 fSendAddr.sin_family = AF_INET;
203 fSendAddr.sin_port = htons ( fPort );
204 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
205 memset ( &fSendAddr.sin_zero, 0, 8 );
206 fRecvAddr.sin_family = AF_INET;
207 fRecvAddr.sin_port = htons ( fPort );
208 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
209 memset ( &fRecvAddr.sin_zero, 0, 8 );
212 bool JackNetWinSocket::IsSocket()
214 return ( fSockfd ) ? true : false;
217 //IP/PORT***********************************************************************************************************
218 void JackNetWinSocket::SetPort ( int port )
220 fPort = port;
221 fSendAddr.sin_port = htons ( port );
222 fRecvAddr.sin_port = htons ( port );
225 int JackNetWinSocket::GetPort()
227 return fPort;
230 //address***********************************************************************************************************
231 int JackNetWinSocket::SetAddress ( const char* ip, int port )
233 fSendAddr.sin_addr.s_addr = inet_addr ( ip );
234 fSendAddr.sin_port = htons ( port );
235 return 0;
238 char* JackNetWinSocket::GetSendIP()
240 return inet_ntoa ( fSendAddr.sin_addr );
243 char* JackNetWinSocket::GetRecvIP()
245 return inet_ntoa ( fRecvAddr.sin_addr );
248 //utility************************************************************************************************************
249 int JackNetWinSocket::GetName ( char* name )
251 return gethostname ( name, 255 );
254 int JackNetWinSocket::JoinMCastGroup ( const char* ip )
256 struct ip_mreq multicast_req;
257 multicast_req.imr_multiaddr.s_addr = inet_addr ( ip );
258 multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
259 //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
260 return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) );
263 //options************************************************************************************************************
264 int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen )
266 return setsockopt ( fSockfd, level, optname, static_cast<const char*> ( optval ), optlen );
269 int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen )
271 return getsockopt ( fSockfd, level, optname, static_cast<char*> ( optval ), optlen );
274 //tiemout************************************************************************************************************
275 int JackNetWinSocket::SetTimeOut ( int usec )
277 jack_log ( "JackNetWinSocket::SetTimeout %d usec", usec );
279 //negative timeout, or exceeding 10s, return
280 if ( ( usec < 0 ) || ( usec > 10000000 ) )
281 return SOCKET_ERROR;
282 int time = usec / 1000;
283 return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) );
286 //local loop*********************************************************************************************************
287 int JackNetWinSocket::SetLocalLoop()
289 //char disable = 0;
291 see http://msdn.microsoft.com/en-us/library/aa916098.aspx
292 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
293 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
295 char disable = 1;
296 return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
299 //network operations*************************************************************************************************
300 int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
302 return sendto ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) );
305 int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
307 fSendAddr.sin_addr.s_addr = inet_addr ( ip );
308 return SendTo ( buffer, nbytes, flags );
311 int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags )
313 return send ( fSockfd, reinterpret_cast<const char*> ( buffer ), nbytes, flags );
316 int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
318 SOCKLEN addr_len = sizeof ( SOCKADDR );
319 return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len );
322 int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags )
324 return recv ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags );
327 int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
329 SOCKLEN addr_len = sizeof ( SOCKADDR );
330 return recvfrom ( fSockfd, reinterpret_cast<char*> ( buffer ), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len );
333 net_error_t JackNetWinSocket::GetError()
335 switch ( NET_ERROR_CODE )
337 case WSABASEERR:
338 return NET_NO_ERROR;
339 case WSAETIMEDOUT:
340 return NET_NO_DATA;
341 case WSAEWOULDBLOCK:
342 return NET_NO_DATA;
343 case WSAECONNREFUSED:
344 return NET_CONN_ERROR;
345 case WSAECONNRESET:
346 return NET_CONN_ERROR;
347 case WSAEACCES:
348 return NET_CONN_ERROR;
349 case WSAECONNABORTED:
350 return NET_CONN_ERROR;
351 case WSAEHOSTDOWN:
352 return NET_CONN_ERROR;
353 case WSAEHOSTUNREACH:
354 return NET_CONN_ERROR;
355 default:
356 return NET_OP_ERROR;