Jack2 1.9.12

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 #include "JackError.h"
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 int millisec = usec / 1000;
300 return SetOption(SOL_SOCKET, SO_RCVTIMEO, &millisec, sizeof(millisec));
301 }
302
303 //local loop*********************************************************************************************************
304 int JackNetWinSocket::SetLocalLoop()
305 {
306 //char disable = 0;
307 /*
308 see http://msdn.microsoft.com/en-us/library/aa916098.aspx
309 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to
310 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer.
311 */
312 char disable = 1;
313 return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable));
314 }
315
316 //network operations*************************************************************************************************
317 int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags)
318 {
319 return sendto(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), sizeof(SOCKADDR));
320 }
321
322 int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip)
323 {
324 fSendAddr.sin_addr.s_addr = inet_addr(ip);
325 fSendAddr.sin_port = htons(fPort);
326 return SendTo(buffer, nbytes, flags);
327 }
328
329 int JackNetWinSocket::Send(const void* buffer, size_t nbytes, int flags)
330 {
331 return send(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags);
332 }
333
334 int JackNetWinSocket::RecvFrom(void* buffer, size_t nbytes, int flags)
335 {
336 SOCKLEN addr_len = sizeof(SOCKADDR);
337 return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fRecvAddr), &addr_len);
338 }
339
340 int JackNetWinSocket::Recv(void* buffer, size_t nbytes, int flags)
341 {
342 return recv(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags);
343 }
344
345 int JackNetWinSocket::CatchHost(void* buffer, size_t nbytes, int flags)
346 {
347 SOCKLEN addr_len = sizeof(SOCKADDR);
348 return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), &addr_len);
349 }
350
351 net_error_t JackNetWinSocket::GetError()
352 {
353 switch (NET_ERROR_CODE)
354 {
355 case WSABASEERR:
356 return NET_NO_ERROR;
357 case WSAETIMEDOUT:
358 return NET_NO_DATA;
359 case WSAEWOULDBLOCK:
360 return NET_NO_DATA;
361 case WSAECONNREFUSED:
362 return NET_CONN_ERROR;
363 case WSAECONNRESET:
364 return NET_CONN_ERROR;
365 case WSAEACCES:
366 return NET_CONN_ERROR;
367 case WSAECONNABORTED:
368 return NET_CONN_ERROR;
369 case WSAEHOSTDOWN:
370 return NET_CONN_ERROR;
371 case WSAEHOSTUNREACH:
372 return NET_CONN_ERROR;
373 default:
374 return NET_OP_ERROR;
375 }
376 }
377 }
378
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108