00001 
00032 #include "linden_common.h"
00033 
00034 #include "net.h"
00035 
00036 
00037 #include <stdexcept>
00038 
00039 #if LL_WINDOWS
00040         #define WIN32_LEAN_AND_MEAN
00041         #include <winsock2.h>
00042         #include <windows.h>
00043 #else
00044         #include <sys/types.h>
00045         #include <sys/socket.h>
00046         #include <netinet/in.h>
00047         #include <arpa/inet.h>
00048         #include <fcntl.h>
00049         #include <errno.h>
00050 #endif
00051 
00052 
00053 #include "network.h"
00054 #include "llerror.h"
00055 #include "llhost.h"
00056 #include "lltimer.h"
00057 #include "indra_constants.h"
00058 
00059 
00060 
00061 #if LL_WINDOWS
00062 
00063 SOCKADDR_IN stDstAddr;
00064 SOCKADDR_IN stSrcAddr;
00065 SOCKADDR_IN stLclAddr;
00066 static WSADATA stWSAData;
00067 
00068 #else
00069 
00070 struct sockaddr_in stDstAddr;
00071 struct sockaddr_in stSrcAddr;
00072 struct sockaddr_in stLclAddr;
00073 
00074 #if LL_DARWIN
00075 #ifndef _SOCKLEN_T
00076 #define _SOCKLEN_T
00077 typedef int socklen_t;
00078 #endif
00079 #endif
00080 
00081 #endif
00082 
00083 
00084 const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1";
00085 
00086 #if LL_DARWIN
00087         
00088         const int       SEND_BUFFER_SIZE        = 200000;
00089         const int       RECEIVE_BUFFER_SIZE     = 200000;
00090 #else // LL_DARWIN
00091         const int       SEND_BUFFER_SIZE        = 400000;
00092         const int       RECEIVE_BUFFER_SIZE     = 400000;
00093 #endif // LL_DARWIN
00094 
00095 
00096 
00097 LLHost get_sender()
00098 {
00099         return LLHost(stSrcAddr.sin_addr.s_addr, ntohs(stSrcAddr.sin_port));
00100 }
00101 
00102 U32 get_sender_ip(void) 
00103 {
00104         return stSrcAddr.sin_addr.s_addr;
00105 }
00106 
00107 U32 get_sender_port() 
00108 {
00109         return ntohs(stSrcAddr.sin_port);
00110 }
00111 
00112 const char* u32_to_ip_string(U32 ip)
00113 {
00114         static char buffer[MAXADDRSTR];   
00115 
00116         
00117         in_addr in;
00118         in.s_addr = ip;
00119         char* result = inet_ntoa(in);
00120 
00121         
00122         if (result != NULL)
00123         {
00124                 strncpy( buffer, result, MAXADDRSTR );    
00125                 buffer[MAXADDRSTR-1] = '\0';
00126                 return buffer;
00127         }
00128         else
00129         {
00130                 return "(bad IP addr)";
00131         }
00132 }
00133 
00134 
00135 
00136 char *u32_to_ip_string(U32 ip, char *ip_string)
00137 {
00138         char *result;
00139         in_addr in;
00140 
00141         
00142         in.s_addr = ip;
00143         result = inet_ntoa(in);
00144 
00145         
00146         if (result != NULL)
00147         {
00148                 
00149                 strcpy(ip_string, result);      
00150                 return ip_string;
00151         }
00152         else
00153         {
00154                 return NULL;
00155         }
00156 }
00157 
00158 
00159 
00160 U32 ip_string_to_u32(const char* ip_string)
00161 {
00162         return inet_addr(ip_string);
00163 }
00164 
00165 
00167 
00169 
00170 #if LL_WINDOWS
00171  
00172 S32 start_net(S32& socket_out, int& nPort) 
00173 {                       
00174         
00175     
00176         int nRet;
00177         int hSocket;
00178 
00179         int snd_size = SEND_BUFFER_SIZE;
00180         int rec_size = RECEIVE_BUFFER_SIZE;
00181         int buff_size = 4;
00182  
00183         
00184         if(WSAStartup(0x0202, &stWSAData))
00185         {
00186                 S32 err = WSAGetLastError();
00187                 WSACleanup();
00188                 llwarns << "Windows Sockets initialization failed, err " << err << llendl;
00189                 return 1;
00190         }
00191 
00192         
00193     hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0);
00194     if (hSocket == INVALID_SOCKET)
00195         {
00196                 S32 err = WSAGetLastError();
00197                 WSACleanup();
00198                 llwarns << "socket() failed, err " << err << llendl;
00199                 return 2;
00200         }
00201 
00202         
00203         stLclAddr.sin_family      = AF_INET;
00204         stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00205         stLclAddr.sin_port        = htons(nPort);
00206 
00207         S32 attempt_port = nPort;
00208         llinfos << "attempting to connect on port " << attempt_port << llendl;
00209         nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr));
00210 
00211         if (nRet == SOCKET_ERROR)
00212         {
00213                 
00214                 if (WSAGetLastError() == WSAEADDRINUSE)
00215                 {
00216                         
00217                         for(attempt_port = PORT_DISCOVERY_RANGE_MIN;
00218                                 attempt_port <= PORT_DISCOVERY_RANGE_MAX;
00219                                 attempt_port++)
00220                         {
00221                                 stLclAddr.sin_port = htons(attempt_port);
00222                                 llinfos << "trying port " << attempt_port << llendl;
00223                                 nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr));
00224 
00225                                 if (!(nRet == SOCKET_ERROR && 
00226                                         WSAGetLastError() == WSAEADDRINUSE))
00227                                 {
00228                                         break;
00229                                 }
00230                         }
00231 
00232                         if (nRet == SOCKET_ERROR)
00233                         {
00234                                 llwarns << "startNet() : Couldn't find available network port." << llendl;
00235                                 
00236                                 return 3;
00237                         }
00238                 }
00239                 else
00240                 
00241                 {
00242                         llwarns << llformat("bind() port: %d failed, Err: %d\n", nPort, WSAGetLastError()) << llendl;
00243                         
00244                         return 4;
00245                 }
00246         }
00247 
00248         sockaddr_in socket_address;
00249         S32 socket_address_size = sizeof(socket_address);
00250         getsockname(hSocket, (SOCKADDR*) &socket_address, &socket_address_size);
00251         attempt_port = ntohs(socket_address.sin_port);
00252 
00253         llinfos << "connected on port " << attempt_port << llendl;
00254         nPort = attempt_port;
00255         
00256         
00257         unsigned long argp = 1;
00258         nRet = ioctlsocket (hSocket, FIONBIO, &argp);
00259         if (nRet == SOCKET_ERROR) 
00260         {
00261                 printf("Failed to set socket non-blocking, Err: %d\n", 
00262                 WSAGetLastError());
00263         }
00264 
00265         
00266         nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size);
00267         if (nRet)
00268         {
00269                 llinfos << "Can't set receive buffer size!" << llendl;
00270         }
00271 
00272         nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size);
00273         if (nRet)
00274         {
00275                 llinfos << "Can't set send buffer size!" << llendl;
00276         }
00277 
00278         getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size);
00279         getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size);
00280 
00281         llinfos << "startNet - receive buffer size : " << rec_size << llendl;
00282         llinfos << "startNet - send buffer size    : " << snd_size << llendl;
00283 
00284         
00285         char achMCAddr[MAXADDRSTR] = " ";        
00286         stDstAddr.sin_family =      AF_INET;
00287     stDstAddr.sin_addr.s_addr = inet_addr(achMCAddr);
00288     stDstAddr.sin_port =        htons(nPort);
00289 
00290         socket_out = hSocket;
00291         return 0;
00292 }
00293 
00294 void end_net(S32& socket_out)
00295 {
00296         if (socket_out >= 0)
00297         {
00298                 shutdown(socket_out, SD_BOTH);
00299                 closesocket(socket_out);
00300         }
00301         WSACleanup();
00302 }
00303 
00304 S32 receive_packet(int hSocket, char * receiveBuffer)
00305 {
00306         
00307         
00308         
00309         int nRet;
00310         int addr_size = sizeof(struct sockaddr_in);
00311 
00312         nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, 0, (struct sockaddr*)&stSrcAddr, &addr_size);
00313         if (nRet == SOCKET_ERROR ) 
00314         {
00315                 if (WSAEWOULDBLOCK == WSAGetLastError())
00316                         return 0;
00317                 if (WSAECONNRESET == WSAGetLastError())
00318                         return 0;
00319                 llinfos << "receivePacket() failed, Error: " << WSAGetLastError() << llendl;
00320         }
00321         
00322         return nRet;
00323 }
00324 
00325 
00326 BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort)
00327 {
00328         
00329         
00330         int nRet = 0;
00331         U32 last_error = 0;
00332 
00333         stDstAddr.sin_addr.s_addr = recipient;
00334         stDstAddr.sin_port = htons(nPort);
00335         do
00336         {
00337                 nRet = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr));                                   
00338 
00339                 if (nRet == SOCKET_ERROR ) 
00340                 {
00341                         last_error = WSAGetLastError();
00342                         if (last_error != WSAEWOULDBLOCK)
00343                         {
00344                                 
00345                                 
00346                                 
00347                                 
00348                                 
00349                                 if (WSAECONNRESET == WSAGetLastError())
00350                                 {
00351                                         return TRUE;
00352                                 }
00353                                 llinfos << "sendto() failed to " << u32_to_ip_string(recipient) << ":" << nPort 
00354                                         << ", Error " << last_error << llendl;
00355                         }
00356                 }
00357         } while (  (nRet == SOCKET_ERROR)
00358                          &&(last_error == WSAEWOULDBLOCK));
00359 
00360         return (nRet != SOCKET_ERROR);
00361 }
00362 
00364 
00366 
00367 #else
00368 
00369 
00370 S32 start_net(S32& socket_out, int& nPort)
00371 {
00372         int hSocket, nRet;
00373         int snd_size = SEND_BUFFER_SIZE;
00374         int rec_size = RECEIVE_BUFFER_SIZE;
00375 
00376         socklen_t buff_size = 4;
00377     
00378         
00379     hSocket = socket(AF_INET, SOCK_DGRAM, 0);
00380     if (hSocket < 0)
00381         {
00382                 llwarns << "socket() failed" << llendl;
00383                 return 1;
00384         }
00385 
00386         
00387         
00388         if (NET_USE_OS_ASSIGNED_PORT == nPort)
00389         {
00390                 
00391         }
00392         else
00393         {
00394             
00395                 stLclAddr.sin_family      = AF_INET;
00396                 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00397                 stLclAddr.sin_port        = htons(nPort);
00398                 U32 attempt_port = nPort;
00399                 llinfos << "attempting to connect on port " << attempt_port << llendl;
00400 
00401                 nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr));
00402                 if (nRet < 0)
00403                 {
00404                         
00405                         if (errno == EADDRINUSE)
00406                         {
00407                                 
00408                                 for(attempt_port = PORT_DISCOVERY_RANGE_MIN;
00409                                         attempt_port <= PORT_DISCOVERY_RANGE_MAX;
00410                                         attempt_port++)
00411                                 {
00412                                         stLclAddr.sin_port = htons(attempt_port);
00413                                         llinfos << "trying port " << attempt_port << llendl;
00414                                         nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr));
00415                                         if (!((nRet < 0) && (errno == EADDRINUSE)))
00416                                         {
00417                                                 break;
00418                                         }
00419                                 }
00420                                 if (nRet < 0)
00421                                 {
00422                                         llwarns << "startNet() : Couldn't find available network port." << llendl;
00423                                         
00424                                         return 3;
00425                                 }
00426                         }
00427                         
00428                         else
00429                         {
00430                                 llwarns << llformat ("bind() port: %d failed, Err: %s\n", nPort, strerror(errno)) << llendl;
00431                                 
00432                                 return 4;
00433                         }
00434                 }
00435                 llinfos << "connected on port " << attempt_port << llendl;
00436                 nPort = attempt_port;
00437         }
00438         
00439         fcntl(hSocket, F_SETFL, O_NONBLOCK);
00440         
00441         nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size);
00442         if (nRet)
00443         {
00444                 llinfos << "Can't set receive size!" << llendl;
00445         }
00446         nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size);
00447         if (nRet)
00448         {
00449                 llinfos << "Can't set send size!" << llendl;
00450         }
00451         getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size);
00452         getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size);
00453 
00454         llinfos << "startNet - receive buffer size : " << rec_size << llendl;
00455         llinfos << "startNet - send buffer size    : " << snd_size << llendl;
00456 
00457         
00458         char achMCAddr[MAXADDRSTR] = "127.0.0.1";        
00459         stDstAddr.sin_family =      AF_INET;
00460         stDstAddr.sin_addr.s_addr = inet_addr(achMCAddr);
00461         stDstAddr.sin_port =        htons(nPort);
00462 
00463         socket_out = hSocket;
00464         return 0;
00465 }
00466 
00467 void end_net(S32& socket_out)
00468 {
00469         if (socket_out >= 0)
00470         {
00471                 close(socket_out);
00472         }
00473 }
00474 
00475 int receive_packet(int hSocket, char * receiveBuffer)
00476 {
00477         
00478         
00479         
00480         
00481         int nRet;
00482         socklen_t addr_size = sizeof(struct sockaddr_in);
00483 
00484         nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, 0, (struct sockaddr*)&stSrcAddr, &addr_size);
00485 
00486         if (nRet == -1)
00487         {
00488                 
00489                 return 0;
00490         }
00491 
00492         return nRet;
00493 }
00494 
00495 BOOL send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient, int nPort)
00496 {
00497         int             ret;
00498         BOOL    success;
00499         BOOL    resend;
00500         S32             send_attempts = 0;
00501 
00502         stDstAddr.sin_addr.s_addr = recipient;
00503         stDstAddr.sin_port = htons(nPort);
00504 
00505         do
00506         {
00507                 ret = sendto(hSocket, sendBuffer, size, 0,      (struct sockaddr*)&stDstAddr, sizeof(stDstAddr));
00508                 send_attempts++;
00509 
00510                 if (ret >= 0)
00511                 {
00512                         
00513                         success = TRUE;
00514                         resend = FALSE;
00515                 }
00516                 else
00517                 {
00518                         
00519                         success = FALSE;
00520 
00521                         if (errno == EAGAIN)
00522                         {
00523                                 
00524                                 llinfos << "sendto() reported buffer full, resending (attempt " << send_attempts << ")" << llendl;
00525                                 llinfos << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << llendl;
00526                                 resend = TRUE;
00527                         }
00528                         else if (errno == ECONNREFUSED)
00529                         {
00530                                 
00531                                 llinfos << "sendto() reported connection refused, resending (attempt " << send_attempts << ")" << llendl;
00532                                 llinfos << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << llendl;
00533                                 resend = TRUE;
00534                         }
00535                         else
00536                         {
00537                                 
00538                                 llinfos << "sendto() failed: " << errno << ", " << strerror(errno) << llendl;
00539                                 llinfos << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << llendl;
00540                                 resend = FALSE;
00541                         }
00542                 }
00543         }
00544         while ( resend && send_attempts < 3);
00545 
00546         if (send_attempts >= 3)
00547         {
00548                 llinfos << "sendPacket() bailed out of send!" << llendl;
00549                 return FALSE;
00550         }
00551 
00552         return success;
00553 }
00554 
00555 #endif
00556 
00557