00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <stddef.h>
00038 #include <string.h>
00039 #include <fcntl.h>
00040 #include <errno.h>
00041
00042 #ifndef _MSC_VER
00043 #include <signal.h>
00044 #endif
00045
00046 #include "stratagus.h"
00047 #include "net_lowlevel.h"
00048 #include "network.h"
00049
00050
00051
00052
00053
00054 #define MAX_LOC_IP 10
00055
00056 #if defined(_MSC_VER) || defined(__MINGW32__)
00057 typedef const char *setsockopttype;
00058 typedef char *recvfrombuftype;
00059 typedef char *recvbuftype;
00060 typedef const char *sendtobuftype;
00061 typedef const char *sendbuftype;
00062 typedef int socklen_t;
00063 #else
00064 typedef const void *setsockopttype;
00065 typedef void *recvfrombuftype;
00066 typedef void *recvbuftype;
00067 typedef const void *sendtobuftype;
00068 typedef const void *sendbuftype;
00069 #endif
00070
00071
00072
00073
00074
00075 int NetLastSocket;
00076 unsigned long NetLastHost;
00077 int NetLastPort;
00078
00079 unsigned long NetLocalAddrs[MAX_LOC_IP];
00080
00081
00082
00083
00084
00085 #ifdef USE_WINSOCK // {
00086
00090 int NetInit(void)
00091 {
00092 WSADATA wsaData;
00093
00094
00095 if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
00096 fprintf(stderr, "Couldn't initialize Winsock 2\n");
00097 return -1;
00098 }
00099 return 0;
00100 }
00101
00105 void NetExit(void)
00106 {
00107
00108 if (WSACleanup() == SOCKET_ERROR) {
00109 if (WSAGetLastError() == WSAEINPROGRESS) {
00110 WSACancelBlockingCall();
00111 WSACleanup();
00112 }
00113 }
00114 }
00115
00121 void NetCloseUDP(Socket sockfd)
00122 {
00123 closesocket(sockfd);
00124 }
00125
00131 void NetCloseTCP(Socket sockfd)
00132 {
00133 closesocket(sockfd);
00134 }
00135
00136 #endif // } !USE_WINSOCK
00137
00138 #if !defined(USE_WINSOCK) // {
00139
00143 int NetInit(void)
00144 {
00145 return 0;
00146 }
00147
00151 void NetExit(void)
00152 {
00153 }
00154
00160 void NetCloseUDP(Socket sockfd)
00161 {
00162 close(sockfd);
00163 }
00164
00170 void NetCloseTCP(Socket sockfd)
00171 {
00172 close(sockfd);
00173 }
00174
00175 #endif // } !USE_WINSOCK
00176
00184 #ifdef USE_WINSOCK
00185 int NetSetNonBlocking(Socket sockfd)
00186 {
00187 unsigned long opt = 1;
00188 return ioctlsocket(sockfd, FIONBIO, &opt);
00189 }
00190 #else
00191 int NetSetNonBlocking(Socket sockfd)
00192 {
00193 int flags = fcntl(sockfd, F_GETFL, 0);
00194 return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
00195 }
00196 #endif
00197
00203 unsigned long NetResolveHost(const std::string &host)
00204 {
00205 unsigned long addr;
00206
00207 if (!host.empty()) {
00208 addr = inet_addr(host.c_str());
00209 if (addr == INADDR_NONE) {
00210 struct hostent *he;
00211
00212 he = 0;
00213 he = gethostbyname(host.c_str());
00214 if (he) {
00215 addr = 0;
00216 Assert(he->h_length == 4);
00217 memcpy(&addr, he->h_addr, he->h_length);
00218 }
00219 }
00220 return addr;
00221 }
00222 return INADDR_NONE;
00223 }
00224
00233 #ifdef USE_WINSOCK // {
00234
00235
00236
00237
00238 int NetSocketAddr(const Socket sock)
00239 {
00240 INTERFACE_INFO localAddr[MAX_LOC_IP];
00241 DWORD bytesReturned;
00242 SOCKADDR_IN *pAddrInet;
00243 u_long SetFlags;
00244 int i;
00245 int nif;
00246 int wsError;
00247 int numLocalAddr;
00248
00249 nif = 0;
00250 if (sock != (Socket)-1) {
00251 wsError = WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &localAddr,
00252 sizeof(localAddr), &bytesReturned, NULL, NULL);
00253 if (wsError == SOCKET_ERROR) {
00254 DebugPrint("SIOCGIFCONF:WSAIoctl(SIO_GET_INTERFACE_LIST) - errno %d\n" _C_
00255 WSAGetLastError());
00256 }
00257
00258
00259 numLocalAddr = (bytesReturned / sizeof(INTERFACE_INFO));
00260 for (i = 0; i < numLocalAddr; ++i) {
00261 SetFlags = localAddr[i].iiFlags;
00262 if ((SetFlags & IFF_UP) == 0) {
00263 continue;
00264 }
00265 if ((SetFlags & IFF_LOOPBACK)) {
00266 continue;
00267 }
00268 pAddrInet = (SOCKADDR_IN *)&localAddr[i].iiAddress;
00269 NetLocalAddrs[nif] = pAddrInet->sin_addr.s_addr;
00270 ++nif;
00271 if (nif == MAX_LOC_IP) {
00272 break;
00273 }
00274 }
00275 }
00276 return nif;
00277 }
00278 #else // } { !USE_WINSOCK
00279 #ifdef unix // {
00280
00281
00282
00283 int NetSocketAddr(const Socket sock)
00284 {
00285 char buf[4096];
00286 char *cp;
00287 char *cplim;
00288 struct ifconf ifc;
00289 struct ifreq ifreq;
00290 struct ifreq *ifr;
00291 struct sockaddr_in *sap;
00292 struct sockaddr_in sa;
00293 int i;
00294 int nif;
00295
00296 nif = 0;
00297 if (sock != (Socket)-1) {
00298 ifc.ifc_len = sizeof(buf);
00299 ifc.ifc_buf = buf;
00300 if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
00301 DebugPrint("SIOCGIFCONF - errno %d\n" _C_ errno);
00302 return 0;
00303 }
00304
00305 ifr = ifc.ifc_req;
00306 cplim = buf + ifc.ifc_len;
00307 for (cp = buf; cp < cplim;
00308 cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_ifru)) {
00309 ifr = (struct ifreq *)cp;
00310 ifreq = *ifr;
00311 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
00312 DebugPrint("%s: SIOCGIFFLAGS - errno %d\n" _C_
00313 ifr->ifr_name _C_ errno);
00314 continue;
00315 }
00316 if ((ifreq.ifr_flags & IFF_UP) == 0 ||
00317 ifr->ifr_addr.sa_family == AF_UNSPEC) {
00318 continue;
00319 }
00320
00321 if (ifr->ifr_addr.sa_family != AF_INET) {
00322 continue;
00323 }
00324 if (ifreq.ifr_flags & IFF_LOOPBACK) {
00325 continue;
00326 }
00327 sap = (struct sockaddr_in *)&ifr->ifr_addr;
00328 sa = *sap;
00329 NetLocalAddrs[nif] = sap->sin_addr.s_addr;
00330 if (ifreq.ifr_flags & IFF_POINTOPOINT) {
00331 if (ioctl(sock, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
00332 DebugPrint("%s: SIOCGIFDSTADDR - errno %d\n" _C_
00333 ifr->ifr_name _C_ errno);
00334
00335 continue;
00336 }
00337 if (ifr->ifr_addr.sa_family == AF_UNSPEC) {
00338 continue;
00339 }
00340 }
00341
00342 if (nif) {
00343 for (i = 0; i < nif; ++i) {
00344 if (sa.sin_addr.s_addr == NetLocalAddrs[i]) {
00345 i = -1;
00346 break;
00347 }
00348 }
00349 if (i == -1) {
00350 continue;
00351 }
00352 }
00353 ++nif;
00354 if (nif == MAX_LOC_IP) {
00355 break;
00356 }
00357 }
00358 }
00359 return nif;
00360 }
00361 #else // } !unix
00362
00363 int NetSocketAddr(const Socket sock)
00364 {
00365 NetLocalAddrs[0] = htonl(0x7f000001);
00366 return 1;
00367 }
00368 #endif
00369 #endif // } !USE_WINSOCK
00370
00378 Socket NetOpenUDP(int port)
00379 {
00380 Socket sockfd;
00381
00382
00383 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00384 if (sockfd == INVALID_SOCKET) {
00385 return (Socket)-1;
00386 }
00387
00388 if (port) {
00389 struct sockaddr_in sock_addr;
00390
00391 memset(&sock_addr, 0, sizeof(sock_addr));
00392 sock_addr.sin_family = AF_INET;
00393 sock_addr.sin_addr.s_addr = INADDR_ANY;
00394 sock_addr.sin_port = htons(port);
00395
00396 if (bind(sockfd, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) {
00397 fprintf(stderr, "Couldn't bind to local port\n");
00398 NetCloseUDP(sockfd);
00399 return (Socket)-1;
00400 }
00401 NetLastHost = sock_addr.sin_addr.s_addr;
00402 NetLastPort = sock_addr.sin_port;
00403 }
00404 return sockfd;
00405 }
00406
00414 Socket NetOpenTCP(int port)
00415 {
00416 Socket sockfd;
00417
00418 sockfd = socket(AF_INET, SOCK_STREAM, 0);
00419 if (sockfd == INVALID_SOCKET) {
00420 return (Socket)-1;
00421 }
00422
00423 if (port) {
00424 struct sockaddr_in sock_addr;
00425 int opt;
00426
00427 memset(&sock_addr, 0, sizeof(sock_addr));
00428 sock_addr.sin_family = AF_INET;
00429 sock_addr.sin_addr.s_addr = INADDR_ANY;
00430 sock_addr.sin_port = htons(port);
00431
00432 opt = 1;
00433 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (setsockopttype)&opt, sizeof(opt));
00434
00435 if (bind(sockfd,(struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) {
00436 fprintf(stderr, "Couldn't bind to local port\n");
00437 NetCloseTCP(sockfd);
00438 return (Socket)-1;
00439 }
00440 NetLastHost = sock_addr.sin_addr.s_addr;
00441 NetLastPort = sock_addr.sin_port;
00442 }
00443 NetLastSocket = sockfd;
00444 return sockfd;
00445 }
00446
00456 int NetConnectTCP(Socket sockfd, unsigned long addr, int port)
00457 {
00458 struct sockaddr_in sa;
00459 #ifndef __BEOS__
00460 int opt;
00461
00462 opt = 1;
00463 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (setsockopttype)&opt, sizeof(opt));
00464 opt = 0;
00465 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (setsockopttype)&opt, sizeof(opt));
00466 #endif
00467
00468 if (addr == INADDR_NONE) {
00469 return -1;
00470 }
00471
00472 memset(&sa, 0, sizeof(sa));
00473 memcpy(&sa.sin_addr, &addr, sizeof(addr));
00474 sa.sin_family = AF_INET;
00475 sa.sin_port = htons(port);
00476
00477 if (connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
00478 fprintf(stderr, "connect to %d.%d.%d.%d:%d failed\n",
00479 NIPQUAD(ntohl(addr)), port);
00480 return -1;
00481 }
00482
00483 return sockfd;
00484 }
00485
00494 int NetSocketReady(Socket sockfd, int timeout)
00495 {
00496 int retval;
00497 struct timeval tv;
00498 fd_set mask;
00499
00500
00501 do {
00502
00503 FD_ZERO(&mask);
00504 FD_SET(sockfd, &mask);
00505
00506
00507 tv.tv_sec = timeout / 1000;
00508 tv.tv_usec = (timeout % 1000) * 1000;
00509
00510
00511 retval = select(sockfd + 1, &mask, NULL, NULL, &tv);
00512 #ifdef USE_WINSOCK
00513 } while (retval == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
00514 #else
00515 } while (retval == -1 && errno == EINTR);
00516 #endif
00517
00518 return retval;
00519 }
00520
00529 int NetSocketSetReady(SocketSet *set, int timeout)
00530 {
00531 int retval;
00532 struct timeval tv;
00533 fd_set mask;
00534
00535
00536 do {
00537
00538 FD_ZERO(&mask);
00539 for (size_t i = 0; i < set->Sockets.size(); ++i) {
00540 FD_SET(set->Sockets[i], &mask);
00541 }
00542
00543
00544 tv.tv_sec = timeout / 1000;
00545 tv.tv_usec = (timeout % 1000) * 1000;
00546
00547
00548 retval = select(set->MaxSockFD + 1, &mask, NULL, NULL, &tv);
00549 #ifdef USE_WINSOCK
00550 } while (retval == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
00551 #else
00552 } while (retval == -1 && errno == EINTR);
00553 #endif
00554
00555 for (size_t i = 0; i < set->Sockets.size(); ++i) {
00556 set->SocketReady[i] = FD_ISSET(set->Sockets[i], &mask);
00557 }
00558
00559 return retval;
00560 }
00561
00570 int NetSocketSetSocketReady(SocketSet *set, Socket socket)
00571 {
00572 for (size_t i = 0; i < set->Sockets.size(); ++i) {
00573 if (set->Sockets[i] == socket) {
00574 return set->SocketReady[i];
00575 }
00576 }
00577 DebugPrint("Socket not found in socket set\n");
00578 return 0;
00579 }
00580
00590 int NetRecvUDP(Socket sockfd, void *buf, int len)
00591 {
00592 socklen_t n;
00593 int l;
00594 struct sockaddr_in sock_addr;
00595
00596 n = sizeof(struct sockaddr_in);
00597 if ((l = recvfrom(sockfd, (recvfrombuftype)buf, len, 0, (struct sockaddr *)&sock_addr, &n)) < 0) {
00598 PrintFunction();
00599 fprintf(stdout, "Could not read from UDP socket\n");
00600 return -1;
00601 }
00602
00603
00604
00605
00606 NetLastHost = sock_addr.sin_addr.s_addr;
00607 NetLastPort = sock_addr.sin_port;
00608
00609 return l;
00610 }
00611
00621 int NetRecvTCP(Socket sockfd, void *buf, int len)
00622 {
00623 int ret;
00624
00625 NetLastSocket = sockfd;
00626 ret = recv(sockfd, (recvbuftype)buf, len, 0);
00627 if (ret > 0) {
00628 return ret;
00629 }
00630 if (ret == 0) {
00631 return -1;
00632 }
00633 #ifdef USE_WINSOCK
00634 if (WSAGetLastError() == WSAEWOULDBLOCK) {
00635 #else
00636 if (errno == EWOULDBLOCK || errno == EAGAIN) {
00637 #endif
00638 return 0;
00639 }
00640 return ret;
00641 }
00642
00654 int NetSendUDP(Socket sockfd, unsigned long host, int port,
00655 const void *buf, int len)
00656 {
00657 int n;
00658 struct sockaddr_in sock_addr;
00659
00660 n = sizeof(struct sockaddr_in);
00661 sock_addr.sin_addr.s_addr = host;
00662 sock_addr.sin_port = port;
00663 sock_addr.sin_family = AF_INET;
00664
00665
00666
00667 return sendto(sockfd, (sendtobuftype)buf, len, 0, (struct sockaddr *)&sock_addr, n);
00668 }
00669
00679 int NetSendTCP(Socket sockfd, const void *buf, int len)
00680 {
00681 return send(sockfd, (sendbuftype)buf, len, 0);
00682 }
00683
00691 int NetListenTCP(Socket sockfd)
00692 {
00693 return listen(sockfd, PlayerMax);
00694 }
00695
00703 Socket NetAcceptTCP(Socket sockfd)
00704 {
00705 struct sockaddr_in sa;
00706 socklen_t len;
00707
00708 len = sizeof(struct sockaddr_in);
00709 NetLastSocket = accept(sockfd, (struct sockaddr *)&sa, &len);
00710 NetLastHost = sa.sin_addr.s_addr;
00711 NetLastPort = sa.sin_port;
00712 return NetLastSocket;
00713 }
00714
00720 void SocketSet::AddSocket(Socket socket)
00721 {
00722 Sockets.push_back(socket);
00723 SocketReady.push_back(0);
00724 if (socket > MaxSockFD) {
00725 MaxSockFD = socket;
00726 }
00727 }
00728
00734 void SocketSet::DelSocket(Socket socket)
00735 {
00736 std::vector<Socket>::iterator i;
00737 std::vector<int>::iterator j;
00738
00739 for (i = Sockets.begin(), j = SocketReady.begin(); i != Sockets.end(); ++i, ++j) {
00740 if (*i == socket) {
00741 Sockets.erase(i);
00742 SocketReady.erase(j);
00743 break;
00744 }
00745 }
00746 if (socket == MaxSockFD) {
00747 MaxSockFD = 0;
00748 for (i = Sockets.begin(); i != Sockets.end(); ++i) {
00749 if (*i > MaxSockFD) {
00750 MaxSockFD = *i;
00751 }
00752 }
00753 }
00754 }
00755