groupsock/include/GroupsockHelper.hh File Reference

#include "NetAddress.hh"

Include dependency graph for GroupsockHelper.hh:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

class  NoReuse

Defines

#define SET_SOCKADDR_SIN_LEN(var)
#define MAKE_SOCKADDR_IN(var, adr, prt)

Functions

int setupDatagramSocket (UsageEnvironment &env, Port port, Boolean setLoopback=True)
int setupStreamSocket (UsageEnvironment &env, Port port, Boolean makeNonBlocking=True)
int readSocket (UsageEnvironment &env, int socket, unsigned char *buffer, unsigned bufferSize, struct sockaddr_in &fromAddress, struct timeval *timeout=NULL)
int readSocketExact (UsageEnvironment &env, int socket, unsigned char *buffer, unsigned bufferSize, struct sockaddr_in &fromAddress, struct timeval *timeout=NULL)
Boolean writeSocket (UsageEnvironment &env, int socket, struct in_addr address, Port port, u_int8_t ttlArg, unsigned char *buffer, unsigned bufferSize)
unsigned getSendBufferSize (UsageEnvironment &env, int socket)
unsigned getReceiveBufferSize (UsageEnvironment &env, int socket)
unsigned setSendBufferTo (UsageEnvironment &env, int socket, unsigned requestedSize)
unsigned setReceiveBufferTo (UsageEnvironment &env, int socket, unsigned requestedSize)
unsigned increaseSendBufferTo (UsageEnvironment &env, int socket, unsigned requestedSize)
unsigned increaseReceiveBufferTo (UsageEnvironment &env, int socket, unsigned requestedSize)
Boolean makeSocketNonBlocking (int sock)
Boolean socketJoinGroup (UsageEnvironment &env, int socket, netAddressBits groupAddress)
Boolean socketLeaveGroup (UsageEnvironment &, int socket, netAddressBits groupAddress)
Boolean socketJoinGroupSSM (UsageEnvironment &env, int socket, netAddressBits groupAddress, netAddressBits sourceFilterAddr)
Boolean socketLeaveGroupSSM (UsageEnvironment &, int socket, netAddressBits groupAddress, netAddressBits sourceFilterAddr)
Boolean getSourcePort (UsageEnvironment &env, int socket, Port &port)
netAddressBits ourIPAddress (UsageEnvironment &env)
netAddressBits chooseRandomIPv4SSMAddress (UsageEnvironment &env)
char const * timestampString ()
netAddressBits our_inet_addr (char const *)
char * our_inet_ntoa (struct in_addr)
hostent * our_gethostbyname (char *name)
void our_srandom (int x)
long our_random ()
u_int32_t our_random32 ()

Variables

netAddressBits SendingInterfaceAddr
netAddressBits ReceivingInterfaceAddr


Define Documentation

#define MAKE_SOCKADDR_IN ( var,
adr,
prt   ) 

Value:

/*adr,prt must be in network order*/\
    struct sockaddr_in var;\
    var.sin_family = AF_INET;\
    var.sin_addr.s_addr = (adr);\
    var.sin_port = (prt);\
    SET_SOCKADDR_SIN_LEN(var);

Definition at line 98 of file GroupsockHelper.hh.

Referenced by MP3HTTPSource::createNew(), getSourcePort(), RTSPClient::openConnectionFromURL(), setupDatagramSocket(), RTSPClient::setupHTTPTunneling(), setupStreamSocket(), and writeSocket().

#define SET_SOCKADDR_SIN_LEN ( var   ) 

Definition at line 95 of file GroupsockHelper.hh.


Function Documentation

netAddressBits chooseRandomIPv4SSMAddress ( UsageEnvironment env  ) 

Definition at line 688 of file GroupsockHelper.cpp.

References env, our_random(), and ourIPAddress().

Referenced by main().

00688                                                                  {
00689   // First, a hack to ensure that our random number generator is seeded:
00690   (void) ourIPAddress(env);
00691 
00692   // Choose a random address in the range [232.0.1.0, 232.255.255.255)
00693   // i.e., [0xE8000100, 0xE8FFFFFF)
00694   netAddressBits const first = 0xE8000100, lastPlus1 = 0xE8FFFFFF;
00695   netAddressBits const range = lastPlus1 - first;
00696 
00697   return htonl(first + ((netAddressBits)our_random())%range);
00698 }

unsigned getReceiveBufferSize ( UsageEnvironment env,
int  socket 
)

Definition at line 375 of file GroupsockHelper.cpp.

References env, and getBufferSize().

Referenced by main().

00375                                                                  {
00376   return getBufferSize(env, SO_RCVBUF, socket);
00377 }

unsigned getSendBufferSize ( UsageEnvironment env,
int  socket 
)

Definition at line 372 of file GroupsockHelper.cpp.

References env, and getBufferSize().

00372                                                               {
00373   return getBufferSize(env, SO_SNDBUF, socket);
00374 }

Boolean getSourcePort ( UsageEnvironment env,
int  socket,
Port port 
)

Definition at line 540 of file GroupsockHelper.cpp.

References env, False, getSourcePort0(), MAKE_SOCKADDR_IN, socketErr(), and True.

Referenced by MediaSubsession::initiate(), HTTPSink::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), RTSPServer::setUpOurSocket(), SIPClient::SIPClient(), and OutputSocket::write().

00540                                                                      {
00541   portNumBits portNum = 0;
00542   if (!getSourcePort0(socket, portNum) || portNum == 0) {
00543     // Hack - call bind(), then try again:
00544     MAKE_SOCKADDR_IN(name, INADDR_ANY, 0);
00545     bind(socket, (struct sockaddr*)&name, sizeof name);
00546 
00547     if (!getSourcePort0(socket, portNum) || portNum == 0) {
00548       socketErr(env, "getsockname() error: ");
00549       return False;
00550     }
00551   }
00552 
00553   port = Port(portNum);
00554   return True;
00555 }

unsigned increaseReceiveBufferTo ( UsageEnvironment env,
int  socket,
unsigned  requestedSize 
)

Definition at line 420 of file GroupsockHelper.cpp.

References env, and increaseBufferTo().

Referenced by BasicUDPSource::BasicUDPSource(), MP3HTTPSource::createNew(), and MultiFramedRTPSource::MultiFramedRTPSource().

00421                                                                      {
00422   return increaseBufferTo(env, SO_RCVBUF, socket, requestedSize);
00423 }

unsigned increaseSendBufferTo ( UsageEnvironment env,
int  socket,
unsigned  requestedSize 
)

Definition at line 416 of file GroupsockHelper.cpp.

References env, and increaseBufferTo().

Referenced by RTSPOverHTTPServer::incomingConnectionHandler1(), RTSPServer::incomingConnectionHandler1(), RTPInterface::RTPInterface(), DarwinInjector::setDestination(), HTTPSink::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), and RTSPServer::setUpOurSocket().

00417                                                                   {
00418   return increaseBufferTo(env, SO_SNDBUF, socket, requestedSize);
00419 }

Boolean makeSocketNonBlocking ( int  sock  ) 

Definition at line 137 of file GroupsockHelper.cpp.

Referenced by BasicUDPSource::BasicUDPSource(), RTSPOverHTTPServer::incomingConnectionHandler1(), RTSPServer::incomingConnectionHandler1(), RTSPClient::openConnectionFromURL(), RTPInterface::RTPInterface(), and setupStreamSocket().

00137                                         {
00138 #if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)
00139   unsigned long arg = 1;
00140   return ioctlsocket(sock, FIONBIO, &arg) == 0;
00141 #elif defined(VXWORKS)
00142   int arg = 1;
00143   return ioctl(sock, FIONBIO, (int)&arg) == 0;
00144 #else
00145   int curFlags = fcntl(sock, F_GETFL, 0);
00146   return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0;
00147 #endif
00148 }

struct hostent* our_gethostbyname ( char *  name  )  [read]

Definition at line 87 of file inet.c.

References initializeWinsockIfNecessary, and NULL.

Referenced by NetAddressList::NetAddressList().

00089 {
00090         if (!initializeWinsockIfNecessary()) return NULL;
00091 
00092         return (struct hostent*) gethostbyname(name);
00093 }

netAddressBits our_inet_addr ( char const *   ) 

Definition at line 17 of file inet.c.

Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP(), main(), NetAddressList::NetAddressList(), and ourIPAddress().

00019 {
00020         return inet_addr(cp);
00021 }

char* our_inet_ntoa ( struct  in_addr  ) 

Definition at line 24 of file inet.c.

Referenced by ServerMediaSession::generateSDPDescription(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), Groupsock::handleRead(), RTSPServer::incomingConnectionHandler1(), RTSPOverHTTPServer::incomingConnectionHandler1(), RTCPInstance::incomingReportHandler1(), RTSPServer::RTSPClientSession::livenessTimeoutTask(), main(), operator<<(), RTSPServer::rtspURLPrefix(), PassiveServerMediaSubsession::sdpLines(), DarwinInjector::setDestination(), OnDemandServerMediaSubsession::setSDPLinesFromRTPSink(), and SIPClient::SIPClient().

00026 {
00027 #ifndef VXWORKS
00028   return inet_ntoa(in);
00029 #else
00030   /* according the man pages of inet_ntoa :
00031 
00032      NOTES
00033      The return value from inet_ntoa() points to a  buffer  which
00034      is  overwritten on each call.  This buffer is implemented as
00035      thread-specific data in multithreaded applications.
00036 
00037      the vxworks version of inet_ntoa allocates a buffer for each
00038      ip address string, and does not reuse the same buffer.
00039 
00040      this is merely to simulate the same behaviour (not multithread
00041      safe though):
00042   */
00043   static char result[INET_ADDR_LEN];
00044   inet_ntoa_b(in, result);
00045   return(result);
00046 #endif
00047 }

long our_random (  ) 

Definition at line 99 of file inet.c.

Referenced by FileSink::addData(), chooseRandomIPv4SSMAddress(), MP3ADUdeinterleaver::doGetNextFrame(), MP3FromADUSource::doGetNextFrame(), drand30(), SIPClient::invite(), MediaSession::MediaSession(), MultiFramedRTPSource::networkReadHandler(), our_random32(), MultiFramedRTPSink::sendPacketIfNecessary(), and DarwinInjector::setDestination().

00099                   {
00100 #if defined(__WIN32__) || defined(_WIN32)
00101   return rand();
00102 #else
00103   return random();
00104 #endif
00105 }

u_int32_t our_random32 (  ) 

Definition at line 446 of file inet.c.

References our_random().

00446                          {
00447   // Return a 32-bit random number.
00448   // Because "our_random()" returns a 31-bit random number, we call it a second
00449   // time, to generate the high bit:
00450   long random1 = our_random();
00451   long random2 = our_random();
00452   return (u_int32_t)((random2<<31) | random1);
00453 }

void our_srandom ( int  x  ) 

Referenced by ourIPAddress().

netAddressBits ourIPAddress ( UsageEnvironment env  ) 

Definition at line 567 of file GroupsockHelper.cpp.

References badAddress(), closeSocket, env, if(), loopbackWorks, NULL, our_inet_addr(), our_srandom(), readSocket(), UsageEnvironment::setResultErrMsg(), UsageEnvironment::setResultMsg(), setupDatagramSocket(), socketJoinGroup(), socketLeaveGroup(), and writeSocket().

Referenced by chooseRandomIPv4SSMAddress(), ServerMediaSession::generateSDPDescription(), Groupsock::Groupsock(), Groupsock::output(), RTSPServer::rtspURLPrefix(), SIPClient::SIPClient(), and Groupsock::wasLoopedBackFromUs().

00567                                                    {
00568   static netAddressBits ourAddress = 0;
00569   int sock = -1;
00570   struct in_addr testAddr;
00571 
00572   if (ourAddress == 0) {
00573     // We need to find our source address
00574     struct sockaddr_in fromAddr;
00575     fromAddr.sin_addr.s_addr = 0;
00576 
00577     // Get our address by sending a (0-TTL) multicast packet,
00578     // receiving it, and looking at the source address used.
00579     // (This is kinda bogus, but it provides the best guarantee
00580     // that other nodes will think our address is the same as we do.)
00581     do {
00582       loopbackWorks = 0; // until we learn otherwise
00583 
00584       testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
00585       Port testPort(15947); // ditto
00586 
00587       sock = setupDatagramSocket(env, testPort);
00588       if (sock < 0) break;
00589 
00590       if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;
00591 
00592       unsigned char testString[] = "hostIdTest";
00593       unsigned testStringLength = sizeof testString;
00594 
00595       if (!writeSocket(env, sock, testAddr, testPort, 0,
00596                        testString, testStringLength)) break;
00597 
00598       unsigned char readBuffer[20];
00599       struct timeval timeout;
00600       timeout.tv_sec = 5;
00601       timeout.tv_usec = 0;
00602       int bytesRead = readSocket(env, sock,
00603                                  readBuffer, sizeof readBuffer,
00604                                  fromAddr, &timeout);
00605       if (bytesRead == 0 // timeout occurred
00606           || bytesRead != (int)testStringLength
00607           || strncmp((char*)readBuffer, (char*)testString,
00608                      testStringLength) != 0) {
00609         break;
00610       }
00611 
00612       loopbackWorks = 1;
00613     } while (0);
00614 
00615     if (!loopbackWorks) do {
00616       // We couldn't find our address using multicast loopback
00617       // so try instead to look it up directly.
00618       char hostname[100];
00619       hostname[0] = '\0';
00620 #ifndef CRIS
00621       gethostname(hostname, sizeof hostname);
00622 #endif
00623       if (hostname[0] == '\0') {
00624         env.setResultErrMsg("initial gethostname() failed");
00625         break;
00626       }
00627 
00628 #if defined(VXWORKS)
00629 #include <hostLib.h>
00630       if (ERROR == (ourAddress = hostGetByName( hostname ))) break;
00631 #else
00632       struct hostent* hstent
00633         = (struct hostent*)gethostbyname(hostname);
00634       if (hstent == NULL || hstent->h_length != 4) {
00635         env.setResultErrMsg("initial gethostbyname() failed");
00636         break;
00637       }
00638       // Take the first address that's not bad
00639       // (This code, like many others, won't handle IPv6)
00640       netAddressBits addr = 0;
00641       for (unsigned i = 0; ; ++i) {
00642         char* addrPtr = hstent->h_addr_list[i];
00643         if (addrPtr == NULL) break;
00644 
00645         netAddressBits a = *(netAddressBits*)addrPtr;
00646         if (!badAddress(a)) {
00647           addr = a;
00648           break;
00649         }
00650       }
00651       if (addr != 0) {
00652         fromAddr.sin_addr.s_addr = addr;
00653       } else {
00654         env.setResultMsg("no address");
00655         break;
00656       }
00657     } while (0);
00658 
00659     // Make sure we have a good address:
00660     netAddressBits from = fromAddr.sin_addr.s_addr;
00661     if (badAddress(from)) {
00662       char tmp[100];
00663       sprintf(tmp,
00664               "This computer has an invalid IP address: 0x%x",
00665               (netAddressBits)(ntohl(from)));
00666       env.setResultMsg(tmp);
00667       from = 0;
00668     }
00669 
00670     ourAddress = from;
00671 #endif
00672 
00673     if (sock >= 0) {
00674       socketLeaveGroup(env, sock, testAddr.s_addr);
00675       closeSocket(sock);
00676     }
00677 
00678     // Use our newly-discovered IP address, and the current time,
00679     // to initialize the random number generator's seed:
00680     struct timeval timeNow;
00681     gettimeofday(&timeNow, NULL);
00682     unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
00683     our_srandom(seed);
00684   }
00685   return ourAddress;
00686 }

int readSocket ( UsageEnvironment env,
int  socket,
unsigned char *  buffer,
unsigned  bufferSize,
struct sockaddr_in &  fromAddress,
struct timeval *  timeout = NULL 
)

Definition at line 254 of file GroupsockHelper.cpp.

References blockUntilReadable(), env, UsageEnvironment::getErrno(), NULL, socketErr(), and SOCKLEN_T.

Referenced by RTSPClient::describeURL(), RTSPClient::getMediaSessionParameter(), RTSPClient::getResponse1(), Groupsock::handleRead(), RTPInterface::handleRead(), RTSPOverHTTPServer::HTTPClientConnection::incomingRequestHandler1(), RTSPServer::RTSPClientSession::incomingRequestHandler1(), ourIPAddress(), readSocketExact(), and SocketDescriptor::tcpReadHandler().

00257                                         {
00258   int bytesRead = -1;
00259   do {
00260     int result = blockUntilReadable(env, socket, timeout);
00261     if (timeout != NULL && result == 0) {
00262       bytesRead = 0;
00263       break;
00264     } else if (result <= 0) {
00265       break;
00266     }
00267 
00268     SOCKLEN_T addressSize = sizeof fromAddress;
00269     bytesRead = recvfrom(socket, (char*)buffer, bufferSize, 0,
00270                          (struct sockaddr*)&fromAddress,
00271                          &addressSize);
00272     if (bytesRead < 0) {
00273       //##### HACK to work around bugs in Linux and Windows:
00274       int err = env.getErrno();
00275       if (err == 111 /*ECONNREFUSED (Linux)*/
00276 #if defined(__WIN32__) || defined(_WIN32)
00277           // What a piece of crap Windows is.  Sometimes
00278           // recvfrom() returns -1, but with an 'errno' of 0.
00279           // This appears not to be a real error; just treat
00280           // it as if it were a read of zero bytes, and hope
00281           // we don't have to do anything else to 'reset'
00282           // this alleged error:
00283           || err == 0
00284 #else
00285           || err == EAGAIN
00286 #endif
00287           || err == 113 /*EHOSTUNREACH (Linux)*/) {
00288                                 //Why does Linux return this for datagram sock?
00289         fromAddress.sin_addr.s_addr = 0;
00290         return 0;
00291       }
00292       //##### END HACK
00293       socketErr(env, "recvfrom() error: ");
00294       break;
00295     }
00296   } while (0);
00297 
00298   return bytesRead;
00299 }

int readSocketExact ( UsageEnvironment env,
int  socket,
unsigned char *  buffer,
unsigned  bufferSize,
struct sockaddr_in &  fromAddress,
struct timeval *  timeout = NULL 
)

Definition at line 302 of file GroupsockHelper.cpp.

References env, and readSocket().

Referenced by RTSPClient::getResponse1(), and SocketDescriptor::tcpReadHandler().

00305                                              {
00306   /* read EXACTLY bufferSize bytes from the socket into the buffer.
00307      fromaddress is address of last read.
00308      return the number of bytes actually read when an error occurs
00309   */
00310   int bsize = bufferSize;
00311   int bytesRead = 0;
00312   int totBytesRead =0;
00313   do {
00314     bytesRead = readSocket (env, socket, buffer + totBytesRead, bsize,
00315                             fromAddress, timeout);
00316     if (bytesRead <= 0) break;
00317     totBytesRead += bytesRead;
00318     bsize -= bytesRead;
00319   } while (bsize != 0);
00320 
00321   return totBytesRead;
00322 }

unsigned setReceiveBufferTo ( UsageEnvironment env,
int  socket,
unsigned  requestedSize 
)

Definition at line 391 of file GroupsockHelper.cpp.

References env, and setBufferTo().

Referenced by main().

00392                                                                 {
00393         return setBufferTo(env, SO_RCVBUF, socket, requestedSize);
00394 }

unsigned setSendBufferTo ( UsageEnvironment env,
int  socket,
unsigned  requestedSize 
)

Definition at line 387 of file GroupsockHelper.cpp.

References env, and setBufferTo().

00388                                                              {
00389         return setBufferTo(env, SO_SNDBUF, socket, requestedSize);
00390 }

int setupDatagramSocket ( UsageEnvironment env,
Port  port,
Boolean  setLoopback = True 
)

Definition at line 52 of file GroupsockHelper.cpp.

References closeSocket, env, initializeWinsockIfNecessary, MAKE_SOCKADDR_IN, Port::num(), ReceivingInterfaceAddr, reuseFlag, SendingInterfaceAddr, and socketErr().

Referenced by Socket::changePort(), ourIPAddress(), and Socket::Socket().

00058   {
00059   if (!initializeWinsockIfNecessary()) {
00060     socketErr(env, "Failed to initialize 'winsock': ");
00061     return -1;
00062   }
00063 
00064   int newSocket = socket(AF_INET, SOCK_DGRAM, 0);
00065   if (newSocket < 0) {
00066     socketErr(env, "unable to create datagram socket: ");
00067     return newSocket;
00068   }
00069 
00070   if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
00071                  (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00072     socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
00073     closeSocket(newSocket);
00074     return -1;
00075   }
00076 
00077 #if defined(__WIN32__) || defined(_WIN32)
00078   // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP
00079 #else
00080 #ifdef SO_REUSEPORT
00081   if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
00082                  (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00083     socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
00084     closeSocket(newSocket);
00085     return -1;
00086   }
00087 #endif
00088 
00089 #ifdef IP_MULTICAST_LOOP
00090   const u_int8_t loop = (u_int8_t)setLoopback;
00091   if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
00092                  (const char*)&loop, sizeof loop) < 0) {
00093     socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: ");
00094     closeSocket(newSocket);
00095     return -1;
00096   }
00097 #endif
00098 #endif
00099 
00100   // Note: Windoze requires binding, even if the port number is 0
00101   netAddressBits addr = INADDR_ANY;
00102 #if defined(__WIN32__) || defined(_WIN32)
00103 #else
00104   if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
00105 #endif
00106     if (port.num() == 0) addr = ReceivingInterfaceAddr;
00107     MAKE_SOCKADDR_IN(name, addr, port.num());
00108     if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
00109       char tmpBuffer[100];
00110       sprintf(tmpBuffer, "bind() error (port number: %d): ",
00111               ntohs(port.num()));
00112       socketErr(env, tmpBuffer);
00113       closeSocket(newSocket);
00114       return -1;
00115     }
00116 #if defined(__WIN32__) || defined(_WIN32)
00117 #else
00118   }
00119 #endif
00120 
00121   // Set the sending interface for multicasts, if it's not the default:
00122   if (SendingInterfaceAddr != INADDR_ANY) {
00123     struct in_addr addr;
00124     addr.s_addr = SendingInterfaceAddr;
00125 
00126     if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF,
00127                    (const char*)&addr, sizeof addr) < 0) {
00128       socketErr(env, "error setting outgoing multicast interface: ");
00129       closeSocket(newSocket);
00130       return -1;
00131     }
00132   }
00133 
00134   return newSocket;
00135 }

int setupStreamSocket ( UsageEnvironment env,
Port  port,
Boolean  makeNonBlocking = True 
)

Definition at line 150 of file GroupsockHelper.cpp.

References closeSocket, env, initializeWinsockIfNecessary, MAKE_SOCKADDR_IN, makeSocketNonBlocking(), Port::num(), ReceivingInterfaceAddr, reuseFlag, and socketErr().

Referenced by MP3HTTPSource::createNew(), RTSPClient::openConnectionFromURL(), RTSPClient::setupHTTPTunneling(), HTTPSink::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), and RTSPServer::setUpOurSocket().

00151                                                           {
00152   if (!initializeWinsockIfNecessary()) {
00153     socketErr(env, "Failed to initialize 'winsock': ");
00154     return -1;
00155   }
00156 
00157   int newSocket = socket(AF_INET, SOCK_STREAM, 0);
00158   if (newSocket < 0) {
00159     socketErr(env, "unable to create stream socket: ");
00160     return newSocket;
00161   }
00162 
00163   if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
00164                  (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00165     socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
00166     closeSocket(newSocket);
00167     return -1;
00168   }
00169 
00170   // SO_REUSEPORT doesn't really make sense for TCP sockets, so we
00171   // normally don't set them.  However, if you really want to do this
00172   // #define REUSE_FOR_TCP
00173 #ifdef REUSE_FOR_TCP
00174 #if defined(__WIN32__) || defined(_WIN32)
00175   // Windoze doesn't properly handle SO_REUSEPORT
00176 #else
00177 #ifdef SO_REUSEPORT
00178   if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
00179                  (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00180     socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
00181     closeSocket(newSocket);
00182     return -1;
00183   }
00184 #endif
00185 #endif
00186 #endif
00187 
00188   // Note: Windoze requires binding, even if the port number is 0
00189 #if defined(__WIN32__) || defined(_WIN32)
00190 #else
00191   if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
00192 #endif
00193     MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
00194     if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
00195       char tmpBuffer[100];
00196       sprintf(tmpBuffer, "bind() error (port number: %d): ",
00197               ntohs(port.num()));
00198       socketErr(env, tmpBuffer);
00199       closeSocket(newSocket);
00200       return -1;
00201     }
00202 #if defined(__WIN32__) || defined(_WIN32)
00203 #else
00204   }
00205 #endif
00206 
00207   if (makeNonBlocking) {
00208     if (!makeSocketNonBlocking(newSocket)) {
00209       socketErr(env, "failed to make non-blocking: ");
00210       closeSocket(newSocket);
00211       return -1;
00212     }
00213   }
00214 
00215   return newSocket;
00216 }

Boolean socketJoinGroup ( UsageEnvironment env,
int  socket,
netAddressBits  groupAddress 
)

Definition at line 425 of file GroupsockHelper.cpp.

References env, False, UsageEnvironment::getErrno(), IsMulticastAddress(), ReceivingInterfaceAddr, socketErr(), and True.

Referenced by Groupsock::changeDestinationParameters(), Groupsock::Groupsock(), and ourIPAddress().

00426                                                     {
00427   if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
00428 
00429   struct ip_mreq imr;
00430   imr.imr_multiaddr.s_addr = groupAddress;
00431   imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00432   if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
00433                  (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
00434 #if defined(__WIN32__) || defined(_WIN32)
00435     if (env.getErrno() != 0) {
00436       // That piece-of-shit toy operating system (Windows) sometimes lies
00437       // about setsockopt() failing!
00438 #endif
00439       socketErr(env, "setsockopt(IP_ADD_MEMBERSHIP) error: ");
00440       return False;
00441 #if defined(__WIN32__) || defined(_WIN32)
00442     }
00443 #endif
00444   }
00445 
00446   return True;
00447 }

Boolean socketJoinGroupSSM ( UsageEnvironment env,
int  socket,
netAddressBits  groupAddress,
netAddressBits  sourceFilterAddr 
)

Definition at line 496 of file GroupsockHelper.cpp.

References env, False, ip_mreq_source::imr_interface, ip_mreq_source::imr_multiaddr, ip_mreq_source::imr_sourceaddr, IP_ADD_SOURCE_MEMBERSHIP, IsMulticastAddress(), ReceivingInterfaceAddr, socketErr(), and True.

Referenced by Groupsock::Groupsock().

00498                                                             {
00499   if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
00500 
00501   struct ip_mreq_source imr;
00502   imr.imr_multiaddr.s_addr = groupAddress;
00503   imr.imr_sourceaddr.s_addr = sourceFilterAddr;
00504   imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00505   if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
00506                  (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
00507     socketErr(env, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP) error: ");
00508     return False;
00509   }
00510 
00511   return True;
00512 }

Boolean socketLeaveGroup ( UsageEnvironment ,
int  socket,
netAddressBits  groupAddress 
)

Definition at line 449 of file GroupsockHelper.cpp.

References False, IsMulticastAddress(), ReceivingInterfaceAddr, and True.

Referenced by Groupsock::changeDestinationParameters(), Groupsock::multicastSendOnly(), ourIPAddress(), and Groupsock::~Groupsock().

00450                                                       {
00451   if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
00452 
00453   struct ip_mreq imr;
00454   imr.imr_multiaddr.s_addr = groupAddress;
00455   imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00456   if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
00457                  (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
00458     return False;
00459   }
00460 
00461   return True;
00462 }

Boolean socketLeaveGroupSSM ( UsageEnvironment ,
int  socket,
netAddressBits  groupAddress,
netAddressBits  sourceFilterAddr 
)

Definition at line 514 of file GroupsockHelper.cpp.

References False, ip_mreq_source::imr_interface, ip_mreq_source::imr_multiaddr, ip_mreq_source::imr_sourceaddr, IP_DROP_SOURCE_MEMBERSHIP, IsMulticastAddress(), ReceivingInterfaceAddr, and True.

Referenced by Groupsock::~Groupsock().

00516                                                              {
00517   if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
00518 
00519   struct ip_mreq_source imr;
00520   imr.imr_multiaddr.s_addr = groupAddress;
00521   imr.imr_sourceaddr.s_addr = sourceFilterAddr;
00522   imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00523   if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP,
00524                  (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
00525     return False;
00526   }
00527 
00528   return True;
00529 }

char const* timestampString (  ) 

Definition at line 700 of file GroupsockHelper.cpp.

References NULL.

Referenced by operator<<().

00700