#include "GroupsockHelper.hh"#include <stdarg.h>#include <time.h>#include <fcntl.h>#include <stdio.h>Include dependency graph for GroupsockHelper.cpp:

Go to the source code of this file.
| #define initializeWinsockIfNecessary | ( | ) | 1 |
Definition at line 30 of file GroupsockHelper.cpp.
Referenced by BasicUsageEnvironment::BasicUsageEnvironment(), our_gethostbyname(), setupDatagramSocket(), and setupStreamSocket().
| #define IP_ADD_SOURCE_MEMBERSHIP 25 |
| #define IP_DROP_SOURCE_MEMBERSHIP 26 |
| #define TTL_TYPE u_int8_t |
Referenced by writeSocket().
| static Boolean badAddress | ( | netAddressBits | addr | ) | [static] |
Definition at line 482 of file GroupsockHelper.cpp.
Referenced by ourIPAddress().
00482 { 00483 // Check for some possible erroneous addresses: 00484 netAddressBits hAddr = ntohl(addr); 00485 return (hAddr == 0x7F000001 /* 127.0.0.1 */ 00486 || hAddr == 0 00487 || hAddr == (netAddressBits)(~0)); 00488 }
| netAddressBits chooseRandomIPv4SSMAddress | ( | UsageEnvironment & | env | ) |
Definition at line 617 of file GroupsockHelper.cpp.
References env, our_random(), and ourIPAddress().
Referenced by main().
00617 { 00618 // First, a hack to ensure that our random number generator is seeded: 00619 (void) ourIPAddress(env); 00620 00621 // Choose a random address in the range [232.0.1.0, 232.255.255.255) 00622 // i.e., [0xE8000100, 0xE8FFFFFF) 00623 netAddressBits const first = 0xE8000100, lastPlus1 = 0xE8FFFFFF; 00624 netAddressBits const range = lastPlus1 - first; 00625 00626 return htonl(first + ((netAddressBits)our_random())%range); 00627 }
| static unsigned getBufferSize | ( | UsageEnvironment & | env, | |
| int | bufOptName, | |||
| int | socket | |||
| ) | [static] |
Definition at line 294 of file GroupsockHelper.cpp.
References env, socketErr(), and SOCKLEN_T.
Referenced by getReceiveBufferSize(), getSendBufferSize(), increaseBufferTo(), and setBufferTo().
00295 { 00296 unsigned curSize; 00297 SOCKLEN_T sizeSize = sizeof curSize; 00298 if (getsockopt(socket, SOL_SOCKET, bufOptName, 00299 (char*)&curSize, &sizeSize) < 0) { 00300 socketErr(env, "getBufferSize() error: "); 00301 return 0; 00302 } 00303 00304 return curSize; 00305 }
| unsigned getReceiveBufferSize | ( | UsageEnvironment & | env, | |
| int | socket | |||
| ) |
Definition at line 309 of file GroupsockHelper.cpp.
References env, and getBufferSize().
Referenced by continueAfterDESCRIBE().
00309 { 00310 return getBufferSize(env, SO_RCVBUF, socket); 00311 }
| unsigned getSendBufferSize | ( | UsageEnvironment & | env, | |
| int | socket | |||
| ) |
Definition at line 306 of file GroupsockHelper.cpp.
References env, and getBufferSize().
00306 { 00307 return getBufferSize(env, SO_SNDBUF, socket); 00308 }
| Boolean getSourcePort | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| Port & | port | |||
| ) |
Definition at line 465 of file GroupsockHelper.cpp.
References env, False, getSourcePort0(), MAKE_SOCKADDR_IN, socketErr(), and True.
Referenced by MediaSubsession::initiate(), RTSPServer::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), HTTPSink::setUpOurSocket(), SIPClient::SIPClient(), and OutputSocket::write().
00465 { 00466 portNumBits portNum = 0; 00467 if (!getSourcePort0(socket, portNum) || portNum == 0) { 00468 // Hack - call bind(), then try again: 00469 MAKE_SOCKADDR_IN(name, INADDR_ANY, 0); 00470 bind(socket, (struct sockaddr*)&name, sizeof name); 00471 00472 if (!getSourcePort0(socket, portNum) || portNum == 0) { 00473 socketErr(env, "getsockname() error: "); 00474 return False; 00475 } 00476 } 00477 00478 port = Port(portNum); 00479 return True; 00480 }
| static Boolean getSourcePort0 | ( | int | socket, | |
| portNumBits & | resultPortNum | |||
| ) | [static] |
Definition at line 456 of file GroupsockHelper.cpp.
References False, SOCKLEN_T, and True.
Referenced by getSourcePort().
00456 { 00457 sockaddr_in test; test.sin_port = 0; 00458 SOCKLEN_T len = sizeof test; 00459 if (getsockname(socket, (struct sockaddr*)&test, &len) < 0) return False; 00460 00461 resultPortNum = ntohs(test.sin_port); 00462 return True; 00463 }
| static unsigned increaseBufferTo | ( | UsageEnvironment & | env, | |
| int | bufOptName, | |||
| int | socket, | |||
| unsigned | requestedSize | |||
| ) | [static] |
Definition at line 330 of file GroupsockHelper.cpp.
References env, getBufferSize(), and SOCKLEN_T.
Referenced by increaseReceiveBufferTo(), and increaseSendBufferTo().
00331 { 00332 // First, get the current buffer size. If it's already at least 00333 // as big as what we're requesting, do nothing. 00334 unsigned curSize = getBufferSize(env, bufOptName, socket); 00335 00336 // Next, try to increase the buffer to the requested size, 00337 // or to some smaller size, if that's not possible: 00338 while (requestedSize > curSize) { 00339 SOCKLEN_T sizeSize = sizeof requestedSize; 00340 if (setsockopt(socket, SOL_SOCKET, bufOptName, 00341 (char*)&requestedSize, sizeSize) >= 0) { 00342 // success 00343 return requestedSize; 00344 } 00345 requestedSize = (requestedSize+curSize)/2; 00346 } 00347 00348 return getBufferSize(env, bufOptName, socket); 00349 }
| unsigned increaseReceiveBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 354 of file GroupsockHelper.cpp.
References env, and increaseBufferTo().
Referenced by BasicUDPSource::BasicUDPSource(), MP3HTTPSource::createNew(), MediaSubsession::initiate(), and MultiFramedRTPSource::MultiFramedRTPSource().
00355 { 00356 return increaseBufferTo(env, SO_RCVBUF, socket, requestedSize); 00357 }
| unsigned increaseSendBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 350 of file GroupsockHelper.cpp.
References env, and increaseBufferTo().
Referenced by OnDemandServerMediaSubsession::getStreamParameters(), RTSPServer::incomingConnectionHandler1(), RTSPOverHTTPServer::incomingConnectionHandler1(), RTPInterface::RTPInterface(), DarwinInjector::setDestination(), RTSPServer::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), HTTPSink::setUpOurSocket(), and PassiveServerMediaSubsession::startStream().
00351 { 00352 return increaseBufferTo(env, SO_SNDBUF, socket, requestedSize); 00353 }
| Boolean makeSocketBlocking | ( | int | sock | ) |
Definition at line 144 of file GroupsockHelper.cpp.
00144 { 00145 #if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM) 00146 unsigned long arg = 0; 00147 return ioctlsocket(sock, FIONBIO, &arg) == 0; 00148 #elif defined(VXWORKS) 00149 int arg = 0; 00150 return ioctl(sock, FIONBIO, (int)&arg) == 0; 00151 #else 00152 int curFlags = fcntl(sock, F_GETFL, 0); 00153 return fcntl(sock, F_SETFL, curFlags&(~O_NONBLOCK)) >= 0; 00154 #endif 00155 }
| Boolean makeSocketNonBlocking | ( | int | sock | ) |
Definition at line 131 of file GroupsockHelper.cpp.
Referenced by BasicUDPSource::BasicUDPSource(), RTSPServer::incomingConnectionHandler1(), RTSPOverHTTPServer::incomingConnectionHandler1(), RTPInterface::RTPInterface(), and setupStreamSocket().
00131 { 00132 #if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM) 00133 unsigned long arg = 1; 00134 return ioctlsocket(sock, FIONBIO, &arg) == 0; 00135 #elif defined(VXWORKS) 00136 int arg = 1; 00137 return ioctl(sock, FIONBIO, (int)&arg) == 0; 00138 #else 00139 int curFlags = fcntl(sock, F_GETFL, 0); 00140 return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0; 00141 #endif 00142 }
| netAddressBits ourIPAddress | ( | UsageEnvironment & | env | ) |
Definition at line 492 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().
00492 { 00493 static netAddressBits ourAddress = 0; 00494 int sock = -1; 00495 struct in_addr testAddr; 00496 00497 if (ourAddress == 0) { 00498 // We need to find our source address 00499 struct sockaddr_in fromAddr; 00500 fromAddr.sin_addr.s_addr = 0; 00501 00502 // Get our address by sending a (0-TTL) multicast packet, 00503 // receiving it, and looking at the source address used. 00504 // (This is kinda bogus, but it provides the best guarantee 00505 // that other nodes will think our address is the same as we do.) 00506 do { 00507 loopbackWorks = 0; // until we learn otherwise 00508 00509 testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary 00510 Port testPort(15947); // ditto 00511 00512 sock = setupDatagramSocket(env, testPort); 00513 if (sock < 0) break; 00514 00515 if (!socketJoinGroup(env, sock, testAddr.s_addr)) break; 00516 00517 unsigned char testString[] = "hostIdTest"; 00518 unsigned testStringLength = sizeof testString; 00519 00520 if (!writeSocket(env, sock, testAddr, testPort, 0, 00521 testString, testStringLength)) break; 00522 00523 // Block until the socket is readable (with a 5-second timeout): 00524 fd_set rd_set; 00525 FD_ZERO(&rd_set); 00526 FD_SET((unsigned)sock, &rd_set); 00527 const unsigned numFds = sock+1; 00528 struct timeval timeout; 00529 timeout.tv_sec = 5; 00530 timeout.tv_usec = 0; 00531 int result = select(numFds, &rd_set, NULL, NULL, &timeout); 00532 if (result <= 0) break; 00533 00534 unsigned char readBuffer[20]; 00535 int bytesRead = readSocket(env, sock, 00536 readBuffer, sizeof readBuffer, 00537 fromAddr); 00538 if (bytesRead != (int)testStringLength 00539 || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) { 00540 break; 00541 } 00542 00543 loopbackWorks = 1; 00544 } while (0); 00545 00546 if (!loopbackWorks) do { 00547 // We couldn't find our address using multicast loopback 00548 // so try instead to look it up directly. 00549 char hostname[100]; 00550 hostname[0] = '\0'; 00551 gethostname(hostname, sizeof hostname); 00552 if (hostname[0] == '\0') { 00553 env.setResultErrMsg("initial gethostname() failed"); 00554 break; 00555 } 00556 00557 #if defined(VXWORKS) 00558 #include <hostLib.h> 00559 if (ERROR == (ourAddress = hostGetByName( hostname ))) break; 00560 #else 00561 struct hostent* hstent 00562 = (struct hostent*)gethostbyname(hostname); 00563 if (hstent == NULL || hstent->h_length != 4) { 00564 env.setResultErrMsg("initial gethostbyname() failed"); 00565 break; 00566 } 00567 // Take the first address that's not bad 00568 // (This code, like many others, won't handle IPv6) 00569 netAddressBits addr = 0; 00570 for (unsigned i = 0; ; ++i) { 00571 char* addrPtr = hstent->h_addr_list[i]; 00572 if (addrPtr == NULL) break; 00573 00574 netAddressBits a = *(netAddressBits*)addrPtr; 00575 if (!badAddress(a)) { 00576 addr = a; 00577 break; 00578 } 00579 } 00580 if (addr != 0) { 00581 fromAddr.sin_addr.s_addr = addr; 00582 } else { 00583 env.setResultMsg("no address"); 00584 break; 00585 } 00586 } while (0); 00587 00588 // Make sure we have a good address: 00589 netAddressBits from = fromAddr.sin_addr.s_addr; 00590 if (badAddress(from)) { 00591 char tmp[100]; 00592 sprintf(tmp, 00593 "This computer has an invalid IP address: 0x%x", 00594 (netAddressBits)(ntohl(from))); 00595 env.setResultMsg(tmp); 00596 from = 0; 00597 } 00598 00599 ourAddress = from; 00600 #endif 00601 00602 if (sock >= 0) { 00603 socketLeaveGroup(env, sock, testAddr.s_addr); 00604 closeSocket(sock); 00605 } 00606 00607 // Use our newly-discovered IP address, and the current time, 00608 // to initialize the random number generator's seed: 00609 struct timeval timeNow; 00610 gettimeofday(&timeNow, NULL); 00611 unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec; 00612 our_srandom(seed); 00613 } 00614 return ourAddress; 00615 }
| int readSocket | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned char * | buffer, | |||
| unsigned | bufferSize, | |||
| struct sockaddr_in & | fromAddress | |||
| ) |
Definition at line 225 of file GroupsockHelper.cpp.
References env, UsageEnvironment::getErrno(), socketErr(), and SOCKLEN_T.
Referenced by RTPInterface::handleRead(), Groupsock::handleRead(), RTSPClient::incomingDataHandler1(), RTSPServer::RTSPClientSession::incomingRequestHandler1(), RTSPOverHTTPServer::HTTPClientConnection::incomingRequestHandler1(), ourIPAddress(), and SocketDescriptor::tcpReadHandler1().
00227 { 00228 SOCKLEN_T addressSize = sizeof fromAddress; 00229 int bytesRead = recvfrom(socket, (char*)buffer, bufferSize, 0, 00230 (struct sockaddr*)&fromAddress, 00231 &addressSize); 00232 if (bytesRead < 0) { 00233 //##### HACK to work around bugs in Linux and Windows: 00234 int err = env.getErrno(); 00235 if (err == 111 /*ECONNREFUSED (Linux)*/ 00236 #if defined(__WIN32__) || defined(_WIN32) 00237 // What a piece of crap Windows is. Sometimes 00238 // recvfrom() returns -1, but with an 'errno' of 0. 00239 // This appears not to be a real error; just treat 00240 // it as if it were a read of zero bytes, and hope 00241 // we don't have to do anything else to 'reset' 00242 // this alleged error: 00243 || err == 0 || err == EWOULDBLOCK 00244 #else 00245 || err == EAGAIN 00246 #endif 00247 || err == 113 /*EHOSTUNREACH (Linux)*/) { // Why does Linux return this for datagram sock? 00248 fromAddress.sin_addr.s_addr = 0; 00249 return 0; 00250 } 00251 //##### END HACK 00252 socketErr(env, "recvfrom() error: "); 00253 } 00254 00255 return bytesRead; 00256 }
| static unsigned setBufferTo | ( | UsageEnvironment & | env, | |
| int | bufOptName, | |||
| int | socket, | |||
| unsigned | requestedSize | |||
| ) | [static] |
Definition at line 313 of file GroupsockHelper.cpp.
References env, getBufferSize(), and SOCKLEN_T.
Referenced by setReceiveBufferTo(), and setSendBufferTo().
00314 { 00315 SOCKLEN_T sizeSize = sizeof requestedSize; 00316 setsockopt(socket, SOL_SOCKET, bufOptName, (char*)&requestedSize, sizeSize); 00317 00318 // Get and return the actual, resulting buffer size: 00319 return getBufferSize(env, bufOptName, socket); 00320 }
| unsigned setReceiveBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 325 of file GroupsockHelper.cpp.
References env, and setBufferTo().
Referenced by continueAfterDESCRIBE().
00326 { 00327 return setBufferTo(env, SO_RCVBUF, socket, requestedSize); 00328 }
| unsigned setSendBufferTo | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| unsigned | requestedSize | |||
| ) |
Definition at line 321 of file GroupsockHelper.cpp.
References env, and setBufferTo().
00322 { 00323 return setBufferTo(env, SO_SNDBUF, socket, requestedSize); 00324 }
| int setupDatagramSocket | ( | UsageEnvironment & | env, | |
| Port | port | |||
| ) |
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().
00052 { 00053 if (!initializeWinsockIfNecessary()) { 00054 socketErr(env, "Failed to initialize 'winsock': "); 00055 return -1; 00056 } 00057 00058 int newSocket = socket(AF_INET, SOCK_DGRAM, 0); 00059 if (newSocket < 0) { 00060 socketErr(env, "unable to create datagram socket: "); 00061 return newSocket; 00062 } 00063 00064 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, 00065 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00066 socketErr(env, "setsockopt(SO_REUSEADDR) error: "); 00067 closeSocket(newSocket); 00068 return -1; 00069 } 00070 00071 #if defined(__WIN32__) || defined(_WIN32) 00072 // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP 00073 #else 00074 #ifdef SO_REUSEPORT 00075 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, 00076 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00077 socketErr(env, "setsockopt(SO_REUSEPORT) error: "); 00078 closeSocket(newSocket); 00079 return -1; 00080 } 00081 #endif 00082 00083 #ifdef IP_MULTICAST_LOOP 00084 const u_int8_t loop = 1; 00085 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP, 00086 (const char*)&loop, sizeof loop) < 0) { 00087 socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: "); 00088 closeSocket(newSocket); 00089 return -1; 00090 } 00091 #endif 00092 #endif 00093 00094 // Note: Windoze requires binding, even if the port number is 0 00095 netAddressBits addr = INADDR_ANY; 00096 #if defined(__WIN32__) || defined(_WIN32) 00097 #else 00098 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { 00099 #endif 00100 if (port.num() == 0) addr = ReceivingInterfaceAddr; 00101 MAKE_SOCKADDR_IN(name, addr, port.num()); 00102 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { 00103 char tmpBuffer[100]; 00104 sprintf(tmpBuffer, "bind() error (port number: %d): ", 00105 ntohs(port.num())); 00106 socketErr(env, tmpBuffer); 00107 closeSocket(newSocket); 00108 return -1; 00109 } 00110 #if defined(__WIN32__) || defined(_WIN32) 00111 #else 00112 } 00113 #endif 00114 00115 // Set the sending interface for multicasts, if it's not the default: 00116 if (SendingInterfaceAddr != INADDR_ANY) { 00117 struct in_addr addr; 00118 addr.s_addr = SendingInterfaceAddr; 00119 00120 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF, 00121 (const char*)&addr, sizeof addr) < 0) { 00122 socketErr(env, "error setting outgoing multicast interface: "); 00123 closeSocket(newSocket); 00124 return -1; 00125 } 00126 } 00127 00128 return newSocket; 00129 }
| int setupStreamSocket | ( | UsageEnvironment & | env, | |
| Port | port, | |||
| Boolean | makeNonBlocking | |||
| ) |
Definition at line 157 of file GroupsockHelper.cpp.
References closeSocket, env, initializeWinsockIfNecessary, MAKE_SOCKADDR_IN, makeSocketNonBlocking(), Port::num(), ReceivingInterfaceAddr, reuseFlag, and socketErr().
Referenced by MP3HTTPSource::createNew(), RTSPClient::openConnection(), RTSPClient::responseHandlerForHTTP_GET1(), RTSPServer::setUpOurSocket(), RTSPOverHTTPServer::setUpOurSocket(), and HTTPSink::setUpOurSocket().
00158 { 00159 if (!initializeWinsockIfNecessary()) { 00160 socketErr(env, "Failed to initialize 'winsock': "); 00161 return -1; 00162 } 00163 00164 int newSocket = socket(AF_INET, SOCK_STREAM, 0); 00165 if (newSocket < 0) { 00166 socketErr(env, "unable to create stream socket: "); 00167 return newSocket; 00168 } 00169 00170 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, 00171 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00172 socketErr(env, "setsockopt(SO_REUSEADDR) error: "); 00173 closeSocket(newSocket); 00174 return -1; 00175 } 00176 00177 // SO_REUSEPORT doesn't really make sense for TCP sockets, so we 00178 // normally don't set them. However, if you really want to do this 00179 // #define REUSE_FOR_TCP 00180 #ifdef REUSE_FOR_TCP 00181 #if defined(__WIN32__) || defined(_WIN32) 00182 // Windoze doesn't properly handle SO_REUSEPORT 00183 #else 00184 #ifdef SO_REUSEPORT 00185 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, 00186 (const char*)&reuseFlag, sizeof reuseFlag) < 0) { 00187 socketErr(env, "setsockopt(SO_REUSEPORT) error: "); 00188 closeSocket(newSocket); 00189 return -1; 00190 } 00191 #endif 00192 #endif 00193 #endif 00194 00195 // Note: Windoze requires binding, even if the port number is 0 00196 #if defined(__WIN32__) || defined(_WIN32) 00197 #else 00198 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { 00199 #endif 00200 MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num()); 00201 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { 00202 char tmpBuffer[100]; 00203 sprintf(tmpBuffer, "bind() error (port number: %d): ", 00204 ntohs(port.num())); 00205 socketErr(env, tmpBuffer); 00206 closeSocket(newSocket); 00207 return -1; 00208 } 00209 #if defined(__WIN32__) || defined(_WIN32) 00210 #else 00211 } 00212 #endif 00213 00214 if (makeNonBlocking) { 00215 if (!makeSocketNonBlocking(newSocket)) { 00216 socketErr(env, "failed to make non-blocking: "); 00217 closeSocket(newSocket); 00218 return -1; 00219 } 00220 } 00221 00222 return newSocket; 00223 }
| static void socketErr | ( | UsageEnvironment & | env, | |
| char const * | errorMsg | |||
| ) | [static] |
Definition at line 38 of file GroupsockHelper.cpp.
References env, and UsageEnvironment::setResultErrMsg().
Referenced by getBufferSize(), getSourcePort(), readSocket(), setupDatagramSocket(), setupStreamSocket(), socketJoinGroup(), socketJoinGroupSSM(), and writeSocket().
00038 { 00039 env.setResultErrMsg(errorMsg); 00040 }
| Boolean socketJoinGroup | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| netAddressBits | groupAddress | |||
| ) |
Definition at line 359 of file GroupsockHelper.cpp.
References env, False, UsageEnvironment::getErrno(), IsMulticastAddress(), ReceivingInterfaceAddr, socketErr(), and True.
Referenced by Groupsock::changeDestinationParameters(), Groupsock::Groupsock(), and ourIPAddress().
00360 { 00361 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00362 00363 struct ip_mreq imr; 00364 imr.imr_multiaddr.s_addr = groupAddress; 00365 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00366 if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, 00367 (const char*)&imr, sizeof (struct ip_mreq)) < 0) { 00368 #if defined(__WIN32__) || defined(_WIN32) 00369 if (env.getErrno() != 0) { 00370 // That piece-of-shit toy operating system (Windows) sometimes lies 00371 // about setsockopt() failing! 00372 #endif 00373 socketErr(env, "setsockopt(IP_ADD_MEMBERSHIP) error: "); 00374 return False; 00375 #if defined(__WIN32__) || defined(_WIN32) 00376 } 00377 #endif 00378 } 00379 00380 return True; 00381 }
| Boolean socketJoinGroupSSM | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| netAddressBits | groupAddress, | |||
| netAddressBits | sourceFilterAddr | |||
| ) |
Definition at line 421 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().
00423 { 00424 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00425 00426 struct ip_mreq_source imr; 00427 imr.imr_multiaddr.s_addr = groupAddress; 00428 imr.imr_sourceaddr.s_addr = sourceFilterAddr; 00429 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00430 if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, 00431 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { 00432 socketErr(env, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP) error: "); 00433 return False; 00434 } 00435 00436 return True; 00437 }
| Boolean socketLeaveGroup | ( | UsageEnvironment & | , | |
| int | socket, | |||
| netAddressBits | groupAddress | |||
| ) |
Definition at line 383 of file GroupsockHelper.cpp.
References False, IsMulticastAddress(), ReceivingInterfaceAddr, and True.
Referenced by Groupsock::changeDestinationParameters(), Groupsock::multicastSendOnly(), ourIPAddress(), and Groupsock::~Groupsock().
00384 { 00385 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00386 00387 struct ip_mreq imr; 00388 imr.imr_multiaddr.s_addr = groupAddress; 00389 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00390 if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, 00391 (const char*)&imr, sizeof (struct ip_mreq)) < 0) { 00392 return False; 00393 } 00394 00395 return True; 00396 }
| Boolean socketLeaveGroupSSM | ( | UsageEnvironment & | , | |
| int | socket, | |||
| netAddressBits | groupAddress, | |||
| netAddressBits | sourceFilterAddr | |||
| ) |
Definition at line 439 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().
00441 { 00442 if (!IsMulticastAddress(groupAddress)) return True; // ignore this case 00443 00444 struct ip_mreq_source imr; 00445 imr.imr_multiaddr.s_addr = groupAddress; 00446 imr.imr_sourceaddr.s_addr = sourceFilterAddr; 00447 imr.imr_interface.s_addr = ReceivingInterfaceAddr; 00448 if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, 00449 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { 00450 return False; 00451 } 00452 00453 return True; 00454 }
| char const* timestampString | ( | ) |
Definition at line 629 of file GroupsockHelper.cpp.
References NULL.
Referenced by operator<<().
00629 { 00630 struct timeval tvNow; 00631 gettimeofday(&tvNow, NULL); 00632 00633 #if !defined(_WIN32_WCE) 00634 static char timeString[9]; // holds hh:mm:ss plus trailing '\0' 00635 char const* ctimeResult = ctime((time_t*)&tvNow.tv_sec); 00636 char const* from = &ctimeResult[11]; 00637 int i; 00638 for (i = 0; i < 8; ++i) { 00639 timeString[i] = from[i]; 00640 } 00641 timeString[i] = '\0'; 00642 #else 00643 // WinCE apparently doesn't have "ctime()", so instead, construct 00644 // a timestamp string just using the integer and fractional parts 00645 // of "tvNow": 00646 static char timeString[50]; 00647 sprintf(timeString, "%lu.%06ld", tvNow.tv_sec, tvNow.tv_usec); 00648 #endif 00649 00650 return (char const*)&timeString; 00651 }
| Boolean writeSocket | ( | UsageEnvironment & | env, | |
| int | socket, | |||
| struct in_addr | address, | |||
| Port | port, | |||
| u_int8_t | ttlArg, | |||
| unsigned char * | buffer, | |||
| unsigned | bufferSize | |||
| ) |
Definition at line 258 of file GroupsockHelper.cpp.
References env, False, MAKE_SOCKADDR_IN, Port::num(), socketErr(), True, and TTL_TYPE.
Referenced by ourIPAddress(), and OutputSocket::write().
00261 { 00262 do { 00263 if (ttlArg != 0) { 00264 // Before sending, set the socket's TTL: 00265 #if defined(__WIN32__) || defined(_WIN32) 00266 #define TTL_TYPE int 00267 #else 00268 #define TTL_TYPE u_int8_t 00269 #endif 00270 TTL_TYPE ttl = (TTL_TYPE)ttlArg; 00271 if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, 00272 (const char*)&ttl, sizeof ttl) < 0) { 00273 socketErr(env, "setsockopt(IP_MULTICAST_TTL) error: "); 00274 break; 00275 } 00276 } 00277 00278 MAKE_SOCKADDR_IN(dest, address.s_addr, port.num()); 00279 int bytesSent = sendto(socket, (char*)buffer, bufferSize, 0, 00280 (struct sockaddr*)&dest, sizeof dest); 00281 if (bytesSent != (int)bufferSize) { 00282 char tmpBuf[100]; 00283 sprintf(tmpBuf, "writeSocket(%d), sendTo() error: wrote %d bytes instead of %u: ", socket, bytesSent, bufferSize); 00284 socketErr(env, tmpBuf); 00285 break; 00286 } 00287 00288 return True; 00289 } while (0); 00290 00291 return False; 00292 }
| Boolean loopbackWorks = 1 |
| netAddressBits ReceivingInterfaceAddr = INADDR_ANY |
Definition at line 36 of file GroupsockHelper.cpp.
Referenced by main(), RTSPServer::rtspURLPrefix(), setupDatagramSocket(), setupStreamSocket(), socketJoinGroup(), socketJoinGroupSSM(), socketLeaveGroup(), and socketLeaveGroupSSM().
int reuseFlag = 1 [static] |
Definition at line 42 of file GroupsockHelper.cpp.
Referenced by NoReuse::NoReuse(), setupDatagramSocket(), setupStreamSocket(), and NoReuse::~NoReuse().
| netAddressBits SendingInterfaceAddr = INADDR_ANY |
1.5.2