#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.
| #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 90 of file GroupsockHelper.hh.
Referenced by RTSPClient::connectToServer(), getSourcePort(), setupDatagramSocket(), setupStreamSocket(), and writeSocket().
| #define SET_SOCKADDR_SIN_LEN | ( | var | ) |
Definition at line 87 of file GroupsockHelper.hh.
| netAddressBits chooseRandomIPv4SSMAddress | ( | UsageEnvironment & | env | ) |
Definition at line 660 of file GroupsockHelper.cpp.
References env, our_random(), and ourIPAddress().
Referenced by main().
00660 { 00661 // First, a hack to ensure that our random number generator is seeded: 00662 (void) ourIPAddress(env); 00663 00664 // Choose a random address in the range [232.0.1.0, 232.255.255.255) 00665 // i.e., [0xE8000100, 0xE8FFFFFF) 00666 netAddressBits const first = 0xE8000100, lastPlus1 = 0xE8FFFFFF; 00667 netAddressBits const range = lastPlus1 - first; 00668 00669 return ntohl(first + ((netAddressBits)our_random())%range); 00670 }
| unsigned getReceiveBufferSize | ( | UsageEnvironment & | env, | |
| int | socket | |||
| ) |
Definition at line 354 of file GroupsockHelper.cpp.
References env, and getBufferSize().
Referenced by continueAfterDESCRIBE().
00354 { 00355 return getBufferSize(env, SO_RCVBUF, socket); 00356 }
| unsigned getSendBufferSize | ( | UsageEnvironment & | env, | |
| int | socket | |||
| ) |
Definition at line 351 of file GroupsockHelper.cpp.
References env, and getBufferSize().
00351 { 00352 return getBufferSize(env, SO_SNDBUF, socket); 00353 }
| Boolean getSourcePort | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| Port & | port | |||
| ) |
Definition at line 522 of file GroupsockHelper.cpp.
References env, False, getSourcePort0(), MAKE_SOCKADDR_IN, socketErr(), and True.
Referenced by MediaSubsession::initiate(), RTSPServer::setUpOurSocket(), SIPClient::SIPClient(), and OutputSocket::write().
00522 { 00523 portNumBits portNum = 0; 00524 if (!getSourcePort0(socket, portNum) || portNum == 0) { 00525 // Hack - call bind(), then try again: 00526 MAKE_SOCKADDR_IN(name, INADDR_ANY, 0); 00527 bind(socket, (struct sockaddr*)&name, sizeof name); 00528 00529 if (!getSourcePort0(socket, portNum) || portNum == 0) { 00530 socketErr(env, "getsockname() error: "); 00531 return False; 00532 } 00533 } 00534 00535 port = Port(portNum); 00536 return True; 00537 }
| _groupsockPriv* groupsockPriv | ( | UsageEnvironment & | env | ) |
Definition at line 53 of file GroupsockHelper.cpp.
References env, UsageEnvironment::groupsockPriv, NULL, _groupsockPriv::reuseFlag, and _groupsockPriv::socketTable.
Referenced by getSocketTable(), NoReuse::NoReuse(), setupDatagramSocket(), setupStreamSocket(), and NoReuse::~NoReuse().
00053 { 00054 if (env.groupsockPriv == NULL) { // We need to create it 00055 _groupsockPriv* result = new _groupsockPriv; 00056 result->socketTable = NULL; 00057 result->reuseFlag = 1; // default value => allow reuse of socket numbers 00058 env.groupsockPriv = result; 00059 } 00060 return (_groupsockPriv*)(env.groupsockPriv); 00061 }
| unsigned increaseReceiveBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 399 of file GroupsockHelper.cpp.
References env, and increaseBufferTo().
Referenced by BasicUDPSource::BasicUDPSource(), MediaSubsession::initiate(), and MultiFramedRTPSource::MultiFramedRTPSource().
00400 { 00401 return increaseBufferTo(env, SO_RCVBUF, socket, requestedSize); 00402 }
| unsigned increaseSendBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 395 of file GroupsockHelper.cpp.
References env, and increaseBufferTo().
Referenced by OnDemandServerMediaSubsession::getStreamParameters(), RTSPServer::incomingConnectionHandler(), RTPInterface::RTPInterface(), DarwinInjector::setDestination(), RTSPServer::setUpOurSocket(), and PassiveServerMediaSubsession::startStream().
00396 { 00397 return increaseBufferTo(env, SO_SNDBUF, socket, requestedSize); 00398 }
| Boolean makeSocketBlocking | ( | int | sock | ) |
Definition at line 184 of file GroupsockHelper.cpp.
Referenced by RTPInterface::sendDataOverTCP().
00184 { 00185 #if defined(__WIN32__) || defined(_WIN32) 00186 unsigned long arg = 0; 00187 return ioctlsocket(sock, FIONBIO, &arg) == 0; 00188 #elif defined(VXWORKS) 00189 int arg = 0; 00190 return ioctl(sock, FIONBIO, (int)&arg) == 0; 00191 #else 00192 int curFlags = fcntl(sock, F_GETFL, 0); 00193 return fcntl(sock, F_SETFL, curFlags&(~O_NONBLOCK)) >= 0; 00194 #endif 00195 }
| Boolean makeSocketNonBlocking | ( | int | sock | ) |
Definition at line 171 of file GroupsockHelper.cpp.
Referenced by BasicUDPSource::BasicUDPSource(), ByteStreamFileSource::ByteStreamFileSource(), RTSPServer::incomingConnectionHandler(), RTPInterface::RTPInterface(), RTPInterface::sendDataOverTCP(), setupStreamSocket(), and WAVAudioFileSource::WAVAudioFileSource().
00171 { 00172 #if defined(__WIN32__) || defined(_WIN32) 00173 unsigned long arg = 1; 00174 return ioctlsocket(sock, FIONBIO, &arg) == 0; 00175 #elif defined(VXWORKS) 00176 int arg = 1; 00177 return ioctl(sock, FIONBIO, (int)&arg) == 0; 00178 #else 00179 int curFlags = fcntl(sock, F_GETFL, 0); 00180 return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0; 00181 #endif 00182 }
| netAddressBits our_inet_addr | ( | char const * | ) |
Definition at line 15 of file inet.c.
Referenced by MPEG2TransportUDPServerMediaSubsession::createNewStreamSource(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), main(), NetAddressList::NetAddressList(), ourIPAddress(), and startReplicaUDPSink().
| long our_random | ( | ) |
Definition at line 388 of file inet.c.
References DEG_3, SEP_3, and TYPE_0.
Referenced by FileSink::addData(), chooseRandomIPv4SSMAddress(), MP3ADUdeinterleaver::doGetNextFrame(), MP3FromADUSource::doGetNextFrame(), drand30(), MediaSession::MediaSession(), MultiFramedRTPSource::networkReadHandler1(), our_random32(), our_srandom(), ProxyRTSPClient::scheduleDESCRIBECommand(), ProxyRTSPClient::scheduleLivenessCommand(), and MultiFramedRTPSink::sendPacketIfNecessary().
00388 { 00389 long i; 00390 00391 if (rand_type == TYPE_0) { 00392 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 00393 } else { 00394 /* Make copies of "rptr" and "fptr" before working with them, in case we're being called concurrently by multiple threads: */ 00395 long* rp = rptr; 00396 long* fp = fptr; 00397 00398 /* Make sure "rp" and "fp" are separated by the correct distance (again, allowing for concurrent access): */ 00399 if (!(fp == rp+SEP_3 || fp+DEG_3 == rp+SEP_3)) { 00400 /* A rare case that should occur only if we're being called concurrently by multiple threads. */ 00401 /* Restore the proper separation between the pointers: */ 00402 if (rp <= fp) rp = fp-SEP_3; else rp = fp+DEG_3-SEP_3; 00403 } 00404 00405 *fp += *rp; 00406 i = (*fp >> 1) & 0x7fffffff; /* chucking least random bit */ 00407 if (++fp >= end_ptr) { 00408 fp = state; 00409 ++rp; 00410 } else if (++rp >= end_ptr) { 00411 rp = state; 00412 } 00413 00414 /* Restore "rptr" and "fptr" from our working copies: */ 00415 rptr = rp; 00416 fptr = fp; 00417 } 00418 00419 return i; 00420 }
| u_int32_t our_random32 | ( | ) |
Definition at line 423 of file inet.c.
References our_random().
Referenced by RTSPServer::RTSPClientConnection::handleRequestBytes(), SIPClient::invite(), and DarwinInjector::setDestination().
00423 { 00424 /* Return a 32-bit random number. 00425 Because "our_random()" returns a 31-bit random number, we call it a second 00426 time, to generate the high bit. 00427 (Actually, to increase the likelhood of randomness, we take the middle 16 bits of two successive calls to "our_random()") 00428 */ 00429 long random_1 = our_random(); 00430 u_int32_t random16_1 = (u_int32_t)(random_1&0x00FFFF00); 00431 00432 long random_2 = our_random(); 00433 u_int32_t random16_2 = (u_int32_t)(random_2&0x00FFFF00); 00434 00435 return (random16_1<<8) | (random16_2>>8); 00436 }
| void our_srandom | ( | int | x | ) |
Referenced by our_initstate(), and ourIPAddress().
| netAddressBits ourIPAddress | ( | UsageEnvironment & | env | ) |
Definition at line 549 of file GroupsockHelper.cpp.
References badAddressForUs(), closeSocket, NetAddress::data(), env, iter, 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().
00549 { 00550 static netAddressBits ourAddress = 0; 00551 int sock = -1; 00552 struct in_addr testAddr; 00553 00554 if (ourAddress == 0) { 00555 // We need to find our source address 00556 struct sockaddr_in fromAddr; 00557 fromAddr.sin_addr.s_addr = 0; 00558 00559 // Get our address by sending a (0-TTL) multicast packet, 00560 // receiving it, and looking at the source address used. 00561 // (This is kinda bogus, but it provides the best guarantee 00562 // that other nodes will think our address is the same as we do.) 00563 do { 00564 loopbackWorks = 0; // until we learn otherwise 00565 00566 testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary 00567 Port testPort(15947); // ditto 00568 00569 sock = setupDatagramSocket(env, testPort); 00570 if (sock < 0) break; 00571 00572 if (!socketJoinGroup(env, sock, testAddr.s_addr)) break; 00573 00574 unsigned char testString[] = "hostIdTest"; 00575 unsigned testStringLength = sizeof testString; 00576 00577 if (!writeSocket(env, sock, testAddr, testPort, 0, 00578 testString, testStringLength)) break; 00579 00580 // Block until the socket is readable (with a 5-second timeout): 00581 fd_set rd_set; 00582 FD_ZERO(&rd_set); 00583 FD_SET((unsigned)sock, &rd_set); 00584 const unsigned numFds = sock+1; 00585 struct timeval timeout; 00586 timeout.tv_sec = 5; 00587 timeout.tv_usec = 0; 00588 int result = select(numFds, &rd_set, NULL, NULL, &timeout); 00589 if (result <= 0) break; 00590 00591 unsigned char readBuffer[20]; 00592 int bytesRead = readSocket(env, sock, 00593 readBuffer, sizeof readBuffer, 00594 fromAddr); 00595 if (bytesRead != (int)testStringLength 00596 || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) { 00597 break; 00598 } 00599 00600 // We use this packet's source address, if it's good: 00601 loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr); 00602 } while (0); 00603 00604 if (sock >= 0) { 00605 socketLeaveGroup(env, sock, testAddr.s_addr); 00606 closeSocket(sock); 00607 } 00608 00609 if (!loopbackWorks) do { 00610 // We couldn't find our address using multicast loopback, 00611 // so try instead to look it up directly - by first getting our host name, and then resolving this host name 00612 char hostname[100]; 00613 hostname[0] = '\0'; 00614 int result = gethostname(hostname, sizeof hostname); 00615 if (result != 0 || hostname[0] == '\0') { 00616 env.setResultErrMsg("initial gethostname() failed"); 00617 break; 00618 } 00619 00620 // Try to resolve "hostname" to an IP address: 00621 NetAddressList addresses(hostname); 00622 NetAddressList::Iterator iter(addresses); 00623 NetAddress const* address; 00624 00625 // Take the first address that's not bad: 00626 netAddressBits addr = 0; 00627 while ((address = iter.nextAddress()) != NULL) { 00628 netAddressBits a = *(netAddressBits*)(address->data()); 00629 if (!badAddressForUs(a)) { 00630 addr = a; 00631 break; 00632 } 00633 } 00634 00635 // Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below: 00636 fromAddr.sin_addr.s_addr = addr; 00637 } while (0); 00638 00639 // Make sure we have a good address: 00640 netAddressBits from = fromAddr.sin_addr.s_addr; 00641 if (badAddressForUs(from)) { 00642 char tmp[100]; 00643 sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val()); 00644 env.setResultMsg(tmp); 00645 from = 0; 00646 } 00647 00648 ourAddress = from; 00649 00650 // Use our newly-discovered IP address, and the current time, 00651 // to initialize the random number generator's seed: 00652 struct timeval timeNow; 00653 gettimeofday(&timeNow, NULL); 00654 unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec; 00655 our_srandom(seed); 00656 } 00657 return ourAddress; 00658 }
| int readSocket | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned char * | buffer, | |||
| unsigned | bufferSize, | |||
| struct sockaddr_in & | fromAddress | |||
| ) |
Definition at line 267 of file GroupsockHelper.cpp.
References env, UsageEnvironment::getErrno(), socketErr(), and SOCKLEN_T.
Referenced by Groupsock::handleRead(), RTPInterface::handleRead(), RTSPClient::incomingDataHandler1(), RTSPServer::RTSPClientConnection::incomingRequestHandler1(), ourIPAddress(), and SocketDescriptor::tcpReadHandler1().
00269 { 00270 SOCKLEN_T addressSize = sizeof fromAddress; 00271 int bytesRead = recvfrom(socket, (char*)buffer, bufferSize, 0, 00272 (struct sockaddr*)&fromAddress, 00273 &addressSize); 00274 if (bytesRead < 0) { 00275 //##### HACK to work around bugs in Linux and Windows: 00276 int err = env.getErrno(); 00277 if (err == 111 /*ECONNREFUSED (Linux)*/ 00278 #if defined(__WIN32__) || defined(_WIN32) 00279 // What a piece of crap Windows is. Sometimes 00280 // recvfrom() returns -1, but with an 'errno' of 0. 00281 // This appears not to be a real error; just treat 00282 // it as if it were a read of zero bytes, and hope 00283 // we don't have to do anything else to 'reset' 00284 // this alleged error: 00285 || err == 0 || err == EWOULDBLOCK 00286 #else 00287 || err == EAGAIN 00288 #endif 00289 || err == 113 /*EHOSTUNREACH (Linux)*/) { // Why does Linux return this for datagram sock? 00290 fromAddress.sin_addr.s_addr = 0; 00291 return 0; 00292 } 00293 //##### END HACK 00294 socketErr(env, "recvfrom() error: "); 00295 } else if (bytesRead == 0) { 00296 // "recvfrom()" on a stream socket can return 0 if the remote end has closed the connection. Treat this as an error: 00297 return -1; 00298 } 00299 00300 return bytesRead; 00301 }
| void reclaimGroupsockPriv | ( | UsageEnvironment & | env | ) |
Definition at line 63 of file GroupsockHelper.cpp.
References env, UsageEnvironment::groupsockPriv, NULL, _groupsockPriv::reuseFlag, and _groupsockPriv::socketTable.
Referenced by setupDatagramSocket(), setupStreamSocket(), unsetGroupsockBySocket(), and NoReuse::~NoReuse().
00063 { 00064 _groupsockPriv* priv = (_groupsockPriv*)(env.groupsockPriv); 00065 if (priv->socketTable == NULL && priv->reuseFlag == 1/*default value*/) { 00066 // We can delete the structure (to save space); it will get created again, if needed: 00067 delete priv; 00068 env.groupsockPriv = NULL; 00069 } 00070 }
| unsigned setReceiveBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 370 of file GroupsockHelper.cpp.
References env, and setBufferTo().
Referenced by continueAfterDESCRIBE().
00371 { 00372 return setBufferTo(env, SO_RCVBUF, socket, requestedSize); 00373 }
| unsigned setSendBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 366 of file GroupsockHelper.cpp.
References env, and setBufferTo().
00367 { 00368 return setBufferTo(env, SO_SNDBUF, socket, requestedSize); 00369 }
| int setupDatagramSocket | ( | UsageEnvironment & | env, | |
| Port | port | |||
| ) |
Definition at line 90 of file GroupsockHelper.cpp.
References closeSocket, createSocket(), env, groupsockPriv(), initializeWinsockIfNecessary, MAKE_SOCKADDR_IN, Port::num(), ReceivingInterfaceAddr, reclaimGroupsockPriv(), _groupsockPriv::reuseFlag, SendingInterfaceAddr, and socketErr().
Referenced by Socket::changePort(), ourIPAddress(), and Socket::Socket().
00090 { 00091 if (!initializeWinsockIfNecessary()) { 00092 socketErr(env, "Failed to initialize 'winsock': "); 00093 return -1; 00094 } 00095 00096 int newSocket = createSocket(SOCK_DGRAM); 00097 if (newSocket < 0) { 00098 socketErr(env, "unable to create datagram socket: "); 00099 return newSocket; 00100 } 00101 00102 int reuseFlag = groupsockPriv(env)->reuseFlag; 00103 reclaimGroupsockPriv(env); 00104 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, 00105 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00106 socketErr(env, "setsockopt(SO_REUSEADDR) error: "); 00107 closeSocket(newSocket); 00108 return -1; 00109 } 00110 00111 #if defined(__WIN32__) || defined(_WIN32) 00112 // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP 00113 #else 00114 #ifdef SO_REUSEPORT 00115 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, 00116 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00117 socketErr(env, "setsockopt(SO_REUSEPORT) error: "); 00118 closeSocket(newSocket); 00119 return -1; 00120 } 00121 #endif 00122 00123 #ifdef IP_MULTICAST_LOOP 00124 const u_int8_t loop = 1; 00125 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP, 00126 (const char*)&loop, sizeof loop) < 0) { 00127 socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: "); 00128 closeSocket(newSocket); 00129 return -1; 00130 } 00131 #endif 00132 #endif 00133 00134 // Note: Windoze requires binding, even if the port number is 0 00135 netAddressBits addr = INADDR_ANY; 00136 #if defined(__WIN32__) || defined(_WIN32) 00137 #else 00138 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { 00139 #endif 00140 if (port.num() == 0) addr = ReceivingInterfaceAddr; 00141 MAKE_SOCKADDR_IN(name, addr, port.num()); 00142 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { 00143 char tmpBuffer[100]; 00144 sprintf(tmpBuffer, "bind() error (port number: %d): ", 00145 ntohs(port.num())); 00146 socketErr(env, tmpBuffer); 00147 closeSocket(newSocket); 00148 return -1; 00149 } 00150 #if defined(__WIN32__) || defined(_WIN32) 00151 #else 00152 } 00153 #endif 00154 00155 // Set the sending interface for multicasts, if it's not the default: 00156 if (SendingInterfaceAddr != INADDR_ANY) { 00157 struct in_addr addr; 00158 addr.s_addr = SendingInterfaceAddr; 00159 00160 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF, 00161 (const char*)&addr, sizeof addr) < 0) { 00162 socketErr(env, "error setting outgoing multicast interface: "); 00163 closeSocket(newSocket); 00164 return -1; 00165 } 00166 } 00167 00168 return newSocket; 00169 }
| int setupStreamSocket | ( | UsageEnvironment & | env, | |
| Port | port, | |||
| Boolean | makeNonBlocking = True | |||
| ) |
Definition at line 197 of file GroupsockHelper.cpp.
References closeSocket, createSocket(), env, groupsockPriv(), initializeWinsockIfNecessary, MAKE_SOCKADDR_IN, makeSocketNonBlocking(), Port::num(), ReceivingInterfaceAddr, reclaimGroupsockPriv(), _groupsockPriv::reuseFlag, and socketErr().
Referenced by RTSPClient::openConnection(), RTSPClient::responseHandlerForHTTP_GET1(), and RTSPServer::setUpOurSocket().
00198 { 00199 if (!initializeWinsockIfNecessary()) { 00200 socketErr(env, "Failed to initialize 'winsock': "); 00201 return -1; 00202 } 00203 00204 int newSocket = createSocket(SOCK_STREAM); 00205 if (newSocket < 0) { 00206 socketErr(env, "unable to create stream socket: "); 00207 return newSocket; 00208 } 00209 00210 int reuseFlag = groupsockPriv(env)->reuseFlag; 00211 reclaimGroupsockPriv(env); 00212 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, 00213 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00214 socketErr(env, "setsockopt(SO_REUSEADDR) error: "); 00215 closeSocket(newSocket); 00216 return -1; 00217 } 00218 00219 // SO_REUSEPORT doesn't really make sense for TCP sockets, so we 00220 // normally don't set them. However, if you really want to do this 00221 // #define REUSE_FOR_TCP 00222 #ifdef REUSE_FOR_TCP 00223 #if defined(__WIN32__) || defined(_WIN32) 00224 // Windoze doesn't properly handle SO_REUSEPORT 00225 #else 00226 #ifdef SO_REUSEPORT 00227 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, 00228 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00229 socketErr(env, "setsockopt(SO_REUSEPORT) error: "); 00230 closeSocket(newSocket); 00231 return -1; 00232 } 00233 #endif 00234 #endif 00235 #endif 00236 00237 // Note: Windoze requires binding, even if the port number is 0 00238 #if defined(__WIN32__) || defined(_WIN32) 00239 #else 00240 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { 00241 #endif 00242 MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num()); 00243 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { 00244 char tmpBuffer[100]; 00245 sprintf(tmpBuffer, "bind() error (port number: %d): ", 00246 ntohs(port.num())); 00247 socketErr(env, tmpBuffer); 00248 closeSocket(newSocket); 00249 return -1; 00250 } 00251 #if defined(__WIN32__) || defined(_WIN32) 00252 #else 00253 } 00254 #endif 00255 00256 if (makeNonBlocking) { 00257 if (!makeSocketNonBlocking(newSocket)) { 00258 socketErr(env, "failed to make non-blocking: "); 00259 closeSocket(newSocket); 00260 return -1; 00261 } 00262 } 00263 00264 return newSocket; 00265 }
| Boolean socketJoinGroup | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| netAddressBits | groupAddress | |||
| ) |
Definition at line 404 of file GroupsockHelper.cpp.
References env, False, UsageEnvironment::getErrno(), IsMulticastAddress(), ReceivingInterfaceAddr, socketErr(), and True.
Referenced by Groupsock::changeDestinationParameters(), Groupsock::Groupsock(), and ourIPAddress().
00405 { 00406 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00407 00408 struct ip_mreq imr; 00409 imr.imr_multiaddr.s_addr = groupAddress; 00410 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00411 if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, 00412 (const char*)&imr, sizeof (struct ip_mreq)) < 0) { 00413 #if defined(__WIN32__) || defined(_WIN32) 00414 if (env.getErrno() != 0) { 00415 // That piece-of-shit toy operating system (Windows) sometimes lies 00416 // about setsockopt() failing! 00417 #endif 00418 socketErr(env, "setsockopt(IP_ADD_MEMBERSHIP) error: "); 00419 return False; 00420 #if defined(__WIN32__) || defined(_WIN32) 00421 } 00422 #endif 00423 } 00424 00425 return True; 00426 }
| Boolean socketJoinGroupSSM | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| netAddressBits | groupAddress, | |||
| netAddressBits | sourceFilterAddr | |||
| ) |
Definition at line 466 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().
00468 { 00469 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00470 00471 struct ip_mreq_source imr; 00472 #ifdef ANDROID 00473 imr.imr_multiaddr = groupAddress; 00474 imr.imr_sourceaddr = sourceFilterAddr; 00475 imr.imr_interface = ReceivingInterfaceAddr; 00476 #else 00477 imr.imr_multiaddr.s_addr = groupAddress; 00478 imr.imr_sourceaddr.s_addr = sourceFilterAddr; 00479 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00480 #endif 00481 if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, 00482 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { 00483 socketErr(env, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP) error: "); 00484 return False; 00485 } 00486 00487 return True; 00488 }
| Boolean socketLeaveGroup | ( | UsageEnvironment & | , | |
| int | socket, | |||
| netAddressBits | groupAddress | |||
| ) |
Definition at line 428 of file GroupsockHelper.cpp.
References False, IsMulticastAddress(), ReceivingInterfaceAddr, and True.
Referenced by Groupsock::changeDestinationParameters(), Groupsock::multicastSendOnly(), ourIPAddress(), and Groupsock::~Groupsock().
00429 { 00430 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00431 00432 struct ip_mreq imr; 00433 imr.imr_multiaddr.s_addr = groupAddress; 00434 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00435 if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, 00436 (const char*)&imr, sizeof (struct ip_mreq)) < 0) { 00437 return False; 00438 } 00439 00440 return True; 00441 }
| Boolean socketLeaveGroupSSM | ( | UsageEnvironment & | , | |
| int | socket, | |||
| netAddressBits | groupAddress, | |||
| netAddressBits | sourceFilterAddr | |||
| ) |
Definition at line 490 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().
00492 { 00493 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00494 00495 struct ip_mreq_source imr; 00496 #ifdef ANDROID 00497 imr.imr_multiaddr = groupAddress; 00498 imr.imr_sourceaddr = sourceFilterAddr; 00499 imr.imr_interface = ReceivingInterfaceAddr; 00500 #else 00501 imr.imr_multiaddr.s_addr = groupAddress; 00502 imr.imr_sourceaddr.s_addr = sourceFilterAddr; 00503 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00504 #endif 00505 if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, 00506 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { 00507 return False; 00508 } 00509 00510 return True; 00511 }
| char const* timestampString | ( | ) |
Definition at line 672 of file GroupsockHelper.cpp.
References NULL.
Referenced by operator<<().
00672 { 00673 struct timeval tvNow; 00674 gettimeofday(&tvNow, NULL); 00675 00676 #if !defined(_WIN32_WCE) 00677 static char timeString[9]; // holds hh:mm:ss plus trailing '\0' 00678 char const* ctimeResult = ctime((time_t*)&tvNow.tv_sec); 00679 if (ctimeResult == NULL) { 00680 sprintf(timeString, "??:??:??"); 00681 } else { 00682 char const* from = &ctimeResult[11]; 00683 int i; 00684 for (i = 0; i < 8; ++i) { 00685 timeString[i] = from[i]; 00686 } 00687 timeString[i] = '\0'; 00688 } 00689 #else 00690 // WinCE apparently doesn't have "ctime()", so instead, construct 00691 // a timestamp string just using the integer and fractional parts 00692 // of "tvNow": 00693 static char timeString[50]; 00694 sprintf(timeString, "%lu.%06ld", tvNow.tv_sec, tvNow.tv_usec); 00695 #endif 00696 00697 return (char const*)&timeString; 00698 }
| Boolean writeSocket | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| struct in_addr | address, | |||
| Port | port, | |||
| u_int8_t | ttlArg, | |||
| unsigned char * | buffer, | |||
| unsigned | bufferSize | |||
| ) |
Definition at line 303 of file GroupsockHelper.cpp.
References env, False, MAKE_SOCKADDR_IN, Port::num(), socketErr(), True, and TTL_TYPE.
Referenced by ourIPAddress(), and OutputSocket::write().
00306 { 00307 do { 00308 if (ttlArg != 0) { 00309 // Before sending, set the socket's TTL: 00310 #if defined(__WIN32__) || defined(_WIN32) 00311 #define TTL_TYPE int 00312 #else 00313 #define TTL_TYPE u_int8_t 00314 #endif 00315 TTL_TYPE ttl = (TTL_TYPE)ttlArg; 00316 if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, 00317 (const char*)&ttl, sizeof ttl) < 0) { 00318 socketErr(env, "setsockopt(IP_MULTICAST_TTL) error: "); 00319 break; 00320 } 00321 } 00322 00323 MAKE_SOCKADDR_IN(dest, address.s_addr, port.num()); 00324 int bytesSent = sendto(socket, (char*)buffer, bufferSize, 0, 00325 (struct sockaddr*)&dest, sizeof dest); 00326 if (bytesSent != (int)bufferSize) { 00327 char tmpBuf[100]; 00328 sprintf(tmpBuf, "writeSocket(%d), sendTo() error: wrote %d bytes instead of %u: ", socket, bytesSent, bufferSize); 00329 socketErr(env, tmpBuf); 00330 break; 00331 } 00332 00333 return True; 00334 } while (0); 00335 00336 return False; 00337 }
Definition at line 36 of file GroupsockHelper.cpp.
Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP(), main(), RTSPServer::rtspURLPrefix(), setupDatagramSocket(), setupStreamSocket(), socketJoinGroup(), socketJoinGroupSSM(), socketLeaveGroup(), and socketLeaveGroupSSM().
Definition at line 35 of file GroupsockHelper.cpp.
Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP(), and setupDatagramSocket().
1.5.2