Jack2  1.9.8
JackNetWinSocket.cpp
1 /*
2  Copyright (C) 2004-2008 Grame
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as published by
6  the Free Software Foundation; either version 2.1 of the License, or
7  (at your option) any later version.
8 
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 Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18  */
19 
20 
21 #include "JackNetWinSocket.h"
22 
23 namespace Jack
24 {
25  //utility *********************************************************************************************************
26  SERVER_EXPORT int GetHostName(char * name, int size)
27  {
28  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;
32  }
33  return 0;
34  }
35 
36  win_net_error_t NetErrorList[] =
37  {
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 },
89  };
90 
91  SERVER_EXPORT const char* PrintError(int error)
92  {
93  int i;
94  for (i = 0; NetErrorList[i].code >= 0; ++i) {
95  if (error == NetErrorList[i].code)
96  return NetErrorList[i].msg;
97  }
98  return strerror(error);
99  }
100 
101  //construct/destruct***********************************************************************************************
102  JackNetWinSocket::JackNetWinSocket()
103  {
104  fSockfd = 0;
105  fSendAddr.sin_family = AF_INET;
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_addr.s_addr = htonl(INADDR_ANY);
110  memset(&fRecvAddr.sin_zero, 0, 8);
111  }
112 
113  JackNetWinSocket::JackNetWinSocket(const char* ip, int port)
114  {
115  fSockfd = 0;
116  fPort = port;
117  fSendAddr.sin_family = AF_INET;
118  fSendAddr.sin_port = htons(port);
119  fSendAddr.sin_addr.s_addr = inet_addr(ip);
120  memset(&fSendAddr.sin_zero, 0, 8);
121  fRecvAddr.sin_family = AF_INET;
122  fRecvAddr.sin_port = htons(port);
123  fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
124  memset(&fRecvAddr.sin_zero, 0, 8);
125  }
126 
127  JackNetWinSocket::JackNetWinSocket(const JackNetWinSocket& socket)
128  {
129  fSockfd = 0;
130  fPort = socket.fPort;
131  fSendAddr = socket.fSendAddr;
132  fRecvAddr = socket.fRecvAddr;
133  }
134 
135  JackNetWinSocket::~JackNetWinSocket()
136  {
137  Close();
138  }
139 
140  JackNetWinSocket& JackNetWinSocket::operator=(const JackNetWinSocket& socket)
141  {
142  if (this != &socket) {
143  fSockfd = 0;
144  fPort = socket.fPort;
145  fSendAddr = socket.fSendAddr;
146  fRecvAddr = socket.fRecvAddr;
147  }
148  return *this;
149  }
150 
151  //socket***********************************************************************************************************
152  int JackNetWinSocket::NewSocket()
153  {
154  if (fSockfd) {
155  Close();
156  Reset();
157  }
158  fSockfd = socket(AF_INET, SOCK_DGRAM, 0);
159  return fSockfd;
160  }
161 
162  bool JackNetWinSocket::IsLocal(char* ip)
163  {
164  if (strcmp(ip, "127.0.0.1") == 0) {
165  return true;
166  }
167 
168  char host_name[32];
169  gethostname(host_name, sizeof(host_name));
170 
171  struct hostent* host = gethostbyname(host_name);
172  if (host) {
173  for (int i = 0; host->h_addr_list[i] != 0; ++i) {
174  struct in_addr addr;
175  memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr));
176  if (strcmp(inet_ntoa(addr), ip) == 0) {
177  return true;
178  }
179  }
180  return false;
181  } else {
182  return false;
183  }
184  }
185 
186  int JackNetWinSocket::Bind()
187  {
188  return bind(fSockfd, reinterpret_cast<SOCKADDR*>(&fRecvAddr), sizeof(SOCKADDR));
189  }
190 
191  int JackNetWinSocket::BindWith(const char* ip)
192  {
193  fRecvAddr.sin_addr.s_addr = inet_addr(ip);
194  return Bind();
195  }
196 
197  int JackNetWinSocket::BindWith(int port)
198  {
199  fRecvAddr.sin_port = htons(port);
200  return Bind();
201  }
202 
203  int JackNetWinSocket::Connect()
204  {
205  return connect(fSockfd, reinterpret_cast<SOCKADDR*>(&fSendAddr), sizeof(SOCKADDR));
206  }
207 
208  int JackNetWinSocket::ConnectTo(const char* ip)
209  {
210  fSendAddr.sin_addr.s_addr = inet_addr(ip);
211  return Connect();
212  }
213 
214  void JackNetWinSocket::Close()
215  {
216  if (fSockfd)
217  closesocket(fSockfd);
218  fSockfd = 0;
219  }
220 
221  void JackNetWinSocket::Reset()
222  {
223  fSendAddr.sin_family = AF_INET;
224  fSendAddr.sin_port = htons(fPort);
225  fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY);
226  memset(&fSendAddr.sin_zero, 0, 8);
227  fRecvAddr.sin_family = AF_INET;
228  fRecvAddr.sin_port = htons(fPort);
229  fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
230  memset(&fRecvAddr.sin_zero, 0, 8);
231  }
232 
233  bool JackNetWinSocket::IsSocket()
234  {
235  return(fSockfd) ? true : false;
236  }
237 
238  //IP/PORT***********************************************************************************************************
239  void JackNetWinSocket::SetPort(int port)
240  {
241  fPort = port;
242  fSendAddr.sin_port = htons(port);
243  fRecvAddr.sin_port = htons(port);
244  }
245 
246  int JackNetWinSocket::GetPort()
247  {
248  return fPort;
249  }
250 
251  //address***********************************************************************************************************
252  int JackNetWinSocket::SetAddress(const char* ip, int port)
253  {
254  fSendAddr.sin_addr.s_addr = inet_addr(ip);
255  fSendAddr.sin_port = htons(port);
256  return 0;
257  }
258 
259  char* JackNetWinSocket::GetSendIP()
260  {
261  return inet_ntoa(fSendAddr.sin_addr);
262  }
263 
264  char* JackNetWinSocket::GetRecvIP()
265  {
266  return inet_ntoa(fRecvAddr.sin_addr);
267  }
268 
269  //utility************************************************************************************************************
270  int JackNetWinSocket::GetName(char* name)
271  {
272  return gethostname(name, 255);
273  }
274 
275  int JackNetWinSocket::JoinMCastGroup(const char* ip)
276  {
277  struct ip_mreq multicast_req;
278  multicast_req.imr_multiaddr.s_addr = inet_addr(ip);
279  multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
280  //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...)
281  return SetOption(IPPROTO_IP, 12, &multicast_req, sizeof(multicast_req));
282  }
283 
284  //options************************************************************************************************************
285  int JackNetWinSocket::SetOption(int level, int optname, const void* optval, SOCKLEN optlen)
286  {
287  return setsockopt(fSockfd, level, optname, static_cast<const char*>(optval), optlen);
288  }
289 
290  int JackNetWinSocket::GetOption(int level, int optname, void* optval, SOCKLEN* optlen)
291  {
292  return getsockopt(fSockfd, level, optname, static_cast<char*>(optval), optlen);
293  }
294 
295  //tiemout************************************************************************************************************
296  int JackNetWinSocket::SetTimeOut(int usec)
297  {
298  jack_log("JackNetWinSocket::SetTimeout %d usec", usec);
299 
300  //negative timeout, or exceeding 10s, return
301  if (( usec < 0) || (usec > 10000000))
302  return SOCKET_ERROR;
303  int time = usec / 1000;
304  return SetOption(SOL_SOCKET, SO_RCVTIMEO, &time, sizeof(time));
305  }
306 
307  //local loop*********************************************************************************************************
308  int JackNetWinSocket::SetLocalLoop()
309  {
310  //char disable = 0;
311  /*
312  see http://msdn.microsoft.com/en-us/library/aa916098.aspx
313  Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
314  which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
315  */
316  char disable = 1;
317  return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable));
318  }
319 
320  //network operations*************************************************************************************************
321  int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags)
322  {
323  return sendto(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), sizeof(SOCKADDR));
324  }
325 
326  int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip)
327  {
328  fSendAddr.sin_addr.s_addr = inet_addr(ip);
329  return SendTo(buffer, nbytes, flags);
330  }
331 
332  int JackNetWinSocket::Send(const void* buffer, size_t nbytes, int flags)
333  {
334  return send(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags);
335  }
336 
337  int JackNetWinSocket::RecvFrom(void* buffer, size_t nbytes, int flags)
338  {
339  SOCKLEN addr_len = sizeof(SOCKADDR);
340  return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fRecvAddr), &addr_len);
341  }
342 
343  int JackNetWinSocket::Recv(void* buffer, size_t nbytes, int flags)
344  {
345  return recv(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags);
346  }
347 
348  int JackNetWinSocket::CatchHost(void* buffer, size_t nbytes, int flags)
349  {
350  SOCKLEN addr_len = sizeof(SOCKADDR);
351  return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), &addr_len);
352  }
353 
354  net_error_t JackNetWinSocket::GetError()
355  {
356  switch (NET_ERROR_CODE)
357  {
358  case WSABASEERR:
359  return NET_NO_ERROR;
360  case WSAETIMEDOUT:
361  return NET_NO_DATA;
362  case WSAEWOULDBLOCK:
363  return NET_NO_DATA;
364  case WSAECONNREFUSED:
365  return NET_CONN_ERROR;
366  case WSAECONNRESET:
367  return NET_CONN_ERROR;
368  case WSAEACCES:
369  return NET_CONN_ERROR;
370  case WSAECONNABORTED:
371  return NET_CONN_ERROR;
372  case WSAEHOSTDOWN:
373  return NET_CONN_ERROR;
374  case WSAEHOSTUNREACH:
375  return NET_CONN_ERROR;
376  default:
377  return NET_OP_ERROR;
378  }
379  }
380 }
381