Jack2
1.9.8
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 00021 #include "JackNetWinSocket.h" 00022 00023 namespace Jack 00024 { 00025 //utility ********************************************************************************************************* 00026 SERVER_EXPORT int GetHostName(char * name, int size) 00027 { 00028 if (gethostname(name, size) == SOCKET_ERROR) { 00029 jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE)); 00030 strcpy(name, "default"); 00031 return -1; 00032 } 00033 return 0; 00034 } 00035 00036 win_net_error_t NetErrorList[] = 00037 { 00038 E(0, "No error"), 00039 E(WSAEINTR, "Interrupted system call"), 00040 E(WSAEBADF, "Bad file number"), 00041 E(WSAEACCES, "Permission denied"), 00042 E(WSAEFAULT, "Bad address"), 00043 E(WSAEINVAL, "Invalid argument"), 00044 E(WSAEMFILE, "Too many open sockets"), 00045 E(WSAEWOULDBLOCK, "Operation would block"), 00046 E(WSAEINPROGRESS, "Operation now in progress"), 00047 E(WSAEALREADY, "Operation already in progress"), 00048 E(WSAENOTSOCK, "Socket operation on non-socket"), 00049 E(WSAEDESTADDRREQ, "Destination address required"), 00050 E(WSAEMSGSIZE, "Message too long"), 00051 E(WSAEPROTOTYPE, "Protocol wrong type for socket"), 00052 E(WSAENOPROTOOPT, "Bad protocol option"), 00053 E(WSAEPROTONOSUPPORT, "Protocol not supported"), 00054 E(WSAESOCKTNOSUPPORT, "Socket type not supported"), 00055 E(WSAEOPNOTSUPP, "Operation not supported on socket"), 00056 E(WSAEPFNOSUPPORT, "Protocol family not supported"), 00057 E(WSAEAFNOSUPPORT, "Address family not supported"), 00058 E(WSAEADDRINUSE, "Address already in use"), 00059 E(WSAEADDRNOTAVAIL, "Can't assign requested address"), 00060 E(WSAENETDOWN, "Network is down"), 00061 E(WSAENETUNREACH, "Network is unreachable"), 00062 E(WSAENETRESET, "Net connection reset"), 00063 E(WSAECONNABORTED, "Software caused connection abort"), 00064 E(WSAECONNRESET, "Connection reset by peer"), 00065 E(WSAENOBUFS, "No buffer space available"), 00066 E(WSAEISCONN, "Socket is already connected"), 00067 E(WSAENOTCONN, "Socket is not connected"), 00068 E(WSAESHUTDOWN, "Can't send after socket shutdown"), 00069 E(WSAETOOMANYREFS, "Too many references, can't splice"), 00070 E(WSAETIMEDOUT, "Connection timed out"), 00071 E(WSAECONNREFUSED, "Connection refused"), 00072 E(WSAELOOP, "Too many levels of symbolic links"), 00073 E(WSAENAMETOOLONG, "File name too long"), 00074 E(WSAEHOSTDOWN, "Host is down"), 00075 E(WSAEHOSTUNREACH, "No route to host"), 00076 E(WSAENOTEMPTY, "Directory not empty"), 00077 E(WSAEPROCLIM, "Too many processes"), 00078 E(WSAEUSERS, "Too many users"), 00079 E(WSAEDQUOT, "Disc quota exceeded"), 00080 E(WSAESTALE, "Stale NFS file handle"), 00081 E(WSAEREMOTE, "Too many levels of remote in path"), 00082 E(WSASYSNOTREADY, "Network system is unavailable"), 00083 E(WSAVERNOTSUPPORTED, "Winsock version out of range"), 00084 E(WSANOTINITIALISED, "WSAStartup not yet called"), 00085 E(WSAEDISCON, "Graceful shutdown in progress"), 00086 E(WSAHOST_NOT_FOUND, "Host not found"), 00087 E(WSANO_DATA, "No host data of that type was found"), 00088 { -1, NULL }, 00089 }; 00090 00091 SERVER_EXPORT const char* PrintError(int error) 00092 { 00093 int i; 00094 for (i = 0; NetErrorList[i].code >= 0; ++i) { 00095 if (error == NetErrorList[i].code) 00096 return NetErrorList[i].msg; 00097 } 00098 return strerror(error); 00099 } 00100 00101 //construct/destruct*********************************************************************************************** 00102 JackNetWinSocket::JackNetWinSocket() 00103 { 00104 fSockfd = 0; 00105 fSendAddr.sin_family = AF_INET; 00106 fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); 00107 memset(&fSendAddr.sin_zero, 0, 8); 00108 fRecvAddr.sin_family = AF_INET; 00109 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); 00110 memset(&fRecvAddr.sin_zero, 0, 8); 00111 } 00112 00113 JackNetWinSocket::JackNetWinSocket(const char* ip, int port) 00114 { 00115 fSockfd = 0; 00116 fPort = port; 00117 fSendAddr.sin_family = AF_INET; 00118 fSendAddr.sin_port = htons(port); 00119 fSendAddr.sin_addr.s_addr = inet_addr(ip); 00120 memset(&fSendAddr.sin_zero, 0, 8); 00121 fRecvAddr.sin_family = AF_INET; 00122 fRecvAddr.sin_port = htons(port); 00123 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); 00124 memset(&fRecvAddr.sin_zero, 0, 8); 00125 } 00126 00127 JackNetWinSocket::JackNetWinSocket(const JackNetWinSocket& socket) 00128 { 00129 fSockfd = 0; 00130 fPort = socket.fPort; 00131 fSendAddr = socket.fSendAddr; 00132 fRecvAddr = socket.fRecvAddr; 00133 } 00134 00135 JackNetWinSocket::~JackNetWinSocket() 00136 { 00137 Close(); 00138 } 00139 00140 JackNetWinSocket& JackNetWinSocket::operator=(const JackNetWinSocket& socket) 00141 { 00142 if (this != &socket) { 00143 fSockfd = 0; 00144 fPort = socket.fPort; 00145 fSendAddr = socket.fSendAddr; 00146 fRecvAddr = socket.fRecvAddr; 00147 } 00148 return *this; 00149 } 00150 00151 //socket*********************************************************************************************************** 00152 int JackNetWinSocket::NewSocket() 00153 { 00154 if (fSockfd) { 00155 Close(); 00156 Reset(); 00157 } 00158 fSockfd = socket(AF_INET, SOCK_DGRAM, 0); 00159 return fSockfd; 00160 } 00161 00162 bool JackNetWinSocket::IsLocal(char* ip) 00163 { 00164 if (strcmp(ip, "127.0.0.1") == 0) { 00165 return true; 00166 } 00167 00168 char host_name[32]; 00169 gethostname(host_name, sizeof(host_name)); 00170 00171 struct hostent* host = gethostbyname(host_name); 00172 if (host) { 00173 for (int i = 0; host->h_addr_list[i] != 0; ++i) { 00174 struct in_addr addr; 00175 memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr)); 00176 if (strcmp(inet_ntoa(addr), ip) == 0) { 00177 return true; 00178 } 00179 } 00180 return false; 00181 } else { 00182 return false; 00183 } 00184 } 00185 00186 int JackNetWinSocket::Bind() 00187 { 00188 return bind(fSockfd, reinterpret_cast<SOCKADDR*>(&fRecvAddr), sizeof(SOCKADDR)); 00189 } 00190 00191 int JackNetWinSocket::BindWith(const char* ip) 00192 { 00193 fRecvAddr.sin_addr.s_addr = inet_addr(ip); 00194 return Bind(); 00195 } 00196 00197 int JackNetWinSocket::BindWith(int port) 00198 { 00199 fRecvAddr.sin_port = htons(port); 00200 return Bind(); 00201 } 00202 00203 int JackNetWinSocket::Connect() 00204 { 00205 return connect(fSockfd, reinterpret_cast<SOCKADDR*>(&fSendAddr), sizeof(SOCKADDR)); 00206 } 00207 00208 int JackNetWinSocket::ConnectTo(const char* ip) 00209 { 00210 fSendAddr.sin_addr.s_addr = inet_addr(ip); 00211 return Connect(); 00212 } 00213 00214 void JackNetWinSocket::Close() 00215 { 00216 if (fSockfd) 00217 closesocket(fSockfd); 00218 fSockfd = 0; 00219 } 00220 00221 void JackNetWinSocket::Reset() 00222 { 00223 fSendAddr.sin_family = AF_INET; 00224 fSendAddr.sin_port = htons(fPort); 00225 fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); 00226 memset(&fSendAddr.sin_zero, 0, 8); 00227 fRecvAddr.sin_family = AF_INET; 00228 fRecvAddr.sin_port = htons(fPort); 00229 fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); 00230 memset(&fRecvAddr.sin_zero, 0, 8); 00231 } 00232 00233 bool JackNetWinSocket::IsSocket() 00234 { 00235 return(fSockfd) ? true : false; 00236 } 00237 00238 //IP/PORT*********************************************************************************************************** 00239 void JackNetWinSocket::SetPort(int port) 00240 { 00241 fPort = port; 00242 fSendAddr.sin_port = htons(port); 00243 fRecvAddr.sin_port = htons(port); 00244 } 00245 00246 int JackNetWinSocket::GetPort() 00247 { 00248 return fPort; 00249 } 00250 00251 //address*********************************************************************************************************** 00252 int JackNetWinSocket::SetAddress(const char* ip, int port) 00253 { 00254 fSendAddr.sin_addr.s_addr = inet_addr(ip); 00255 fSendAddr.sin_port = htons(port); 00256 return 0; 00257 } 00258 00259 char* JackNetWinSocket::GetSendIP() 00260 { 00261 return inet_ntoa(fSendAddr.sin_addr); 00262 } 00263 00264 char* JackNetWinSocket::GetRecvIP() 00265 { 00266 return inet_ntoa(fRecvAddr.sin_addr); 00267 } 00268 00269 //utility************************************************************************************************************ 00270 int JackNetWinSocket::GetName(char* name) 00271 { 00272 return gethostname(name, 255); 00273 } 00274 00275 int JackNetWinSocket::JoinMCastGroup(const char* ip) 00276 { 00277 struct ip_mreq multicast_req; 00278 multicast_req.imr_multiaddr.s_addr = inet_addr(ip); 00279 multicast_req.imr_interface.s_addr = htonl(INADDR_ANY); 00280 //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...) 00281 return SetOption(IPPROTO_IP, 12, &multicast_req, sizeof(multicast_req)); 00282 } 00283 00284 //options************************************************************************************************************ 00285 int JackNetWinSocket::SetOption(int level, int optname, const void* optval, SOCKLEN optlen) 00286 { 00287 return setsockopt(fSockfd, level, optname, static_cast<const char*>(optval), optlen); 00288 } 00289 00290 int JackNetWinSocket::GetOption(int level, int optname, void* optval, SOCKLEN* optlen) 00291 { 00292 return getsockopt(fSockfd, level, optname, static_cast<char*>(optval), optlen); 00293 } 00294 00295 //tiemout************************************************************************************************************ 00296 int JackNetWinSocket::SetTimeOut(int usec) 00297 { 00298 jack_log("JackNetWinSocket::SetTimeout %d usec", usec); 00299 00300 //negative timeout, or exceeding 10s, return 00301 if (( usec < 0) || (usec > 10000000)) 00302 return SOCKET_ERROR; 00303 int time = usec / 1000; 00304 return SetOption(SOL_SOCKET, SO_RCVTIMEO, &time, sizeof(time)); 00305 } 00306 00307 //local loop********************************************************************************************************* 00308 int JackNetWinSocket::SetLocalLoop() 00309 { 00310 //char disable = 0; 00311 /* 00312 see http://msdn.microsoft.com/en-us/library/aa916098.aspx 00313 Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to 00314 which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. 00315 */ 00316 char disable = 1; 00317 return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable)); 00318 } 00319 00320 //network operations************************************************************************************************* 00321 int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags) 00322 { 00323 return sendto(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), sizeof(SOCKADDR)); 00324 } 00325 00326 int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip) 00327 { 00328 fSendAddr.sin_addr.s_addr = inet_addr(ip); 00329 return SendTo(buffer, nbytes, flags); 00330 } 00331 00332 int JackNetWinSocket::Send(const void* buffer, size_t nbytes, int flags) 00333 { 00334 return send(fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags); 00335 } 00336 00337 int JackNetWinSocket::RecvFrom(void* buffer, size_t nbytes, int flags) 00338 { 00339 SOCKLEN addr_len = sizeof(SOCKADDR); 00340 return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fRecvAddr), &addr_len); 00341 } 00342 00343 int JackNetWinSocket::Recv(void* buffer, size_t nbytes, int flags) 00344 { 00345 return recv(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags); 00346 } 00347 00348 int JackNetWinSocket::CatchHost(void* buffer, size_t nbytes, int flags) 00349 { 00350 SOCKLEN addr_len = sizeof(SOCKADDR); 00351 return recvfrom(fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*>(&fSendAddr), &addr_len); 00352 } 00353 00354 net_error_t JackNetWinSocket::GetError() 00355 { 00356 switch (NET_ERROR_CODE) 00357 { 00358 case WSABASEERR: 00359 return NET_NO_ERROR; 00360 case WSAETIMEDOUT: 00361 return NET_NO_DATA; 00362 case WSAEWOULDBLOCK: 00363 return NET_NO_DATA; 00364 case WSAECONNREFUSED: 00365 return NET_CONN_ERROR; 00366 case WSAECONNRESET: 00367 return NET_CONN_ERROR; 00368 case WSAEACCES: 00369 return NET_CONN_ERROR; 00370 case WSAECONNABORTED: 00371 return NET_CONN_ERROR; 00372 case WSAEHOSTDOWN: 00373 return NET_CONN_ERROR; 00374 case WSAEHOSTUNREACH: 00375 return NET_CONN_ERROR; 00376 default: 00377 return NET_OP_ERROR; 00378 } 00379 } 00380 } 00381