Esempio n. 1
0
Boolean Groupsock::wasLoopedBackFromUs(UsageEnvironment& env,
                                       struct sockaddr_in& fromAddress) {
    if (fromAddress.sin_addr.s_addr
            == ourIPAddress(env)) {
        if (fromAddress.sin_port == sourcePortNum()) {
#ifdef DEBUG_LOOPBACK_CHECKING
            if (DebugLevel >= 3) {
                env() << *this << ": got looped-back packet\n";
            }
#endif
            return True;
        }
    }

    return False;
}
Esempio n. 2
0
Boolean Groupsock::output(UsageEnvironment& env, u_int8_t ttlToSend,
			  unsigned char* buffer, unsigned bufferSize,
			  DirectedNetInterface* interfaceNotToFwdBackTo) {
  do {
		// First, do the datagram send, to each destination:
	Boolean writeSuccess = True;
	for (destRecord* dests = fDests; dests != NULL; dests = dests->fNext) {
		if (!write(dests->fGroupEId.groupAddress().s_addr, dests->fPort, ttlToSend,
			buffer, bufferSize)) {
			writeSuccess = False;
			break;
		}
	}
	  if (!writeSuccess) break;
 #if 0	//optm
	  statsOutgoing.countPacket(bufferSize);
	  statsGroupOutgoing.countPacket(bufferSize);
#endif
		// Then, forward to our members:
	  int numMembers = 0;
	  if (!members().IsEmpty()) {
		  numMembers =
	outputToAllMembersExcept(interfaceNotToFwdBackTo,
				 ttlToSend, buffer, bufferSize,
				 ourIPAddress(env));
		  if (numMembers < 0) break;
		}

	  if (DebugLevel >= 3) {
		  env << *this << ": wrote " << bufferSize << " bytes, ttl "
		<< (unsigned)ttlToSend;
		  if (numMembers > 0) {
	env << "; relayed to " << numMembers << " members";
			}
		  env << "\n";
		}
	  return True;
	} while (0);

  if (DebugLevel >= 0) { // this is a fatal error
	  env.setResultMsg("Groupsock write failed: ", env.getResultMsg());
	}
  return False;
}
Esempio n. 3
0
// Constructor for a source-independent multicast group
Groupsock::Groupsock(UsageEnvironment& env, struct in_addr const& groupAddr,
		     Port port, u_int8_t ttl)
  : OutputSocket(env, port),
    deleteIfNoMembers(False), isSlave(False),
    fIncomingGroupEId(groupAddr, port.num(), ttl), fDests(NULL), fTTL(ttl) {
  addDestination(groupAddr, port);

  if (!socketJoinGroup(env, socketNum(), groupAddr.s_addr)) {
    if (DebugLevel >= 1) {
      env << *this << ": failed to join group: "
	  << env.getResultMsg() << "\n";
    }
  }

  // Make sure we can get our source address:
  if (ourIPAddress(env) == 0) {
    if (DebugLevel >= 0) { // this is a fatal error
      env << "Unable to determine our source address: "
	  << env.getResultMsg() << "\n";
    }
  }

  if (DebugLevel >= 2) env << *this << ": created\n";
}
Esempio n. 4
0
char* RTSPServer::rtspURLPrefix(int clientSocket) const {
  struct sockaddr_in ourAddress;
  if (clientSocket < 0) {
		// Use our default IP address in the URL:
	  ourAddress.sin_addr.s_addr = ReceivingInterfaceAddr != 0
			? ReceivingInterfaceAddr
			: ourIPAddress(envir()); // hack
	} else {
	  SOCKLEN_T namelen = sizeof ourAddress;
	  getsockname(clientSocket, (struct sockaddr*)&ourAddress, &namelen);
	}

  char urlBuffer[100]; // more than big enough for "rtsp://<ip-address>:<port>/"

  portNumBits portNumHostOrder = ntohs(fServerPort.num());
  if (portNumHostOrder == 554 /* the default port number */) {
	  sprintf(urlBuffer, "rtsp://%s/", our_inet_ntoa(ourAddress.sin_addr));
	} else {
	  sprintf(urlBuffer, "rtsp://%s:%hu/",
		  our_inet_ntoa(ourAddress.sin_addr), portNumHostOrder);
	}

  return strDup(urlBuffer);
}
char *ServerMediaSession::generateSDPDescription()
{
    struct in_addr ipAddress;
    ipAddress.s_addr = ourIPAddress(envir());
    char *const ipAddressStr = strDup(our_inet_ntoa(ipAddress));
    unsigned ipAddressStrSize = strlen(ipAddressStr);

    // For a SSM sessions, we need a "a=source-filter: incl ..." line also:
    char *sourceFilterLine;
    if (fIsSSM)
    {
        char const *const sourceFilterFmt =
            "a=source-filter: incl IN IP4 * %s\r\n"
            "a=rtcp-unicast: reflection\r\n";
        unsigned const sourceFilterFmtSize = strlen(sourceFilterFmt) + ipAddressStrSize + 1;

        sourceFilterLine = new char[sourceFilterFmtSize];
        sprintf(sourceFilterLine, sourceFilterFmt, ipAddressStr);
    }
    else
    {
        sourceFilterLine = strDup("");
    }

    char *rangeLine = NULL; // for now
    char *sdp = NULL; // for now

    do
    {
        // Count the lengths of each subsession's media-level SDP lines.
        // (We do this first, because the call to "subsession->sdpLines()"
        // causes correct subsession 'duration()'s to be calculated later.)
        unsigned sdpLength = 0;
        ServerMediaSubsession *subsession;
        for (subsession = fSubsessionsHead; subsession != NULL;
                subsession = subsession->fNext)
        {
            char const *sdpLines = subsession->sdpLines();
            if (sdpLines == NULL) break; // the media's not available
            sdpLength += strlen(sdpLines);
        }
        if (subsession != NULL) break; // an error occurred

        // Unless subsessions have differing durations, we also have a "a=range:" line:
        float dur = duration();
        if (dur == 0.0)
        {
            rangeLine = strDup("a=range:npt=0-\r\n");
        }
        else if (dur > 0.0)
        {
            char buf[100];
            sprintf(buf, "a=range:npt=0-%.3f\r\n", dur);
            rangeLine = strDup(buf);
        }
        else     // subsessions have differing durations, so "a=range:" lines go there
        {
            rangeLine = strDup("");
        }

        char const *const sdpPrefixFmt =
            "v=0\r\n"
            "o=- %ld%06ld %d IN IP4 %s\r\n"
            "s=%s\r\n"
            "i=%s\r\n"
            "t=0 0\r\n"
            "a=tool:%s%s\r\n"
            "a=type:broadcast\r\n"
            "a=control:*\r\n"
            "%s"
            "%s"
            "a=x-qt-text-nam:%s\r\n"
            "a=x-qt-text-inf:%s\r\n"
            "%s";
        sdpLength += strlen(sdpPrefixFmt)
                     + 20 + 6 + 20 + ipAddressStrSize
                     + strlen(fDescriptionSDPString)
                     + strlen(fInfoSDPString)
                     + strlen(libNameStr) + strlen(libVersionStr)
                     + strlen(sourceFilterLine)
                     + strlen(rangeLine)
                     + strlen(fDescriptionSDPString)
                     + strlen(fInfoSDPString)
                     + strlen(fMiscSDPLines);
        sdp = new char[sdpLength];
        if (sdp == NULL) break;

        // Generate the SDP prefix (session-level lines):
        sprintf(sdp, sdpPrefixFmt,
                fCreationTime.tv_sec, fCreationTime.tv_usec, // o= <session id>
                1, // o= <version> // (needs to change if params are modified)
                ipAddressStr, // o= <address>
                fDescriptionSDPString, // s= <description>
                fInfoSDPString, // i= <info>
                libNameStr, libVersionStr, // a=tool:
                sourceFilterLine, // a=source-filter: incl (if a SSM session)
                rangeLine, // a=range: line
                fDescriptionSDPString, // a=x-qt-text-nam: line
                fInfoSDPString, // a=x-qt-text-inf: line
                fMiscSDPLines); // miscellaneous session SDP lines (if any)

        // Then, add the (media-level) lines for each subsession:
        char *mediaSDP = sdp;
        for (subsession = fSubsessionsHead; subsession != NULL;
                subsession = subsession->fNext)
        {
            mediaSDP += strlen(mediaSDP);
            sprintf(mediaSDP, "%s", subsession->sdpLines());
        }
    }
    while (0);

    delete[] rangeLine;
    delete[] sourceFilterLine;
    delete[] ipAddressStr;
    return sdp;
}
Esempio n. 6
0
SIPClient::SIPClient(UsageEnvironment& env,
		     unsigned char desiredAudioRTPPayloadFormat,
		     char const* mimeSubtype,
		     int verbosityLevel, char const* applicationName)
  : Medium(env),
    fT1(500000 /* 500 ms */),
    fDesiredAudioRTPPayloadFormat(desiredAudioRTPPayloadFormat),
    fVerbosityLevel(verbosityLevel), fCSeq(0),
    fUserAgentHeaderStr(NULL), fUserAgentHeaderStrLen(0),
    fURL(NULL), fURLSize(0),
    fToTagStr(NULL), fToTagStrSize(0),
    fUserName(NULL), fUserNameSize(0),
    fInviteSDPDescription(NULL), fInviteSDPDescriptionReturned(NULL),
    fInviteCmd(NULL), fInviteCmdSize(0) {
  if (mimeSubtype == NULL) mimeSubtype = "";
  fMIMESubtype = strDup(mimeSubtype);
  fMIMESubtypeSize = strlen(fMIMESubtype);

  if (applicationName == NULL) applicationName = "";
  fApplicationName = strDup(applicationName);
  fApplicationNameSize = strlen(fApplicationName);

  struct in_addr ourAddress;
  ourAddress.s_addr = ourIPAddress(env); // hack
  fOurAddressStr = strDup(AddressString(ourAddress).val());
  fOurAddressStrSize = strlen(fOurAddressStr);

  fOurSocket = new Groupsock(env, ourAddress, 0, 255);
  if (fOurSocket == NULL) {
    env << "ERROR: Failed to create socket for addr "
	<< fOurAddressStr << ": "
	<< env.getResultMsg() << "\n";
  }

  // Now, find out our source port number.  Hack: Do this by first trying to
  // send a 0-length packet, so that the "getSourcePort()" call will work.
  fOurSocket->output(envir(), (unsigned char*)"", 0);
  Port srcPort(0);
  getSourcePort(env, fOurSocket->socketNum(), srcPort);
  if (srcPort.num() != 0) {
    fOurPortNum = ntohs(srcPort.num());
  } else {
    // No luck.  Try again using a default port number:
    fOurPortNum = 5060;
    delete fOurSocket;
    fOurSocket = new Groupsock(env, ourAddress, fOurPortNum, 255);
    if (fOurSocket == NULL) {
      env << "ERROR: Failed to create socket for addr "
	  << fOurAddressStr << ", port "
	  << fOurPortNum << ": "
	  << env.getResultMsg() << "\n";
    }
  }

  // Set the "User-Agent:" header to use in each request:
  char const* const libName = "LIVE555 Streaming Media v";
  char const* const libVersionStr = LIVEMEDIA_LIBRARY_VERSION_STRING;
  char const* libPrefix; char const* libSuffix;
  if (applicationName == NULL || applicationName[0] == '\0') {
    applicationName = libPrefix = libSuffix = "";
  } else {
    libPrefix = " (";
    libSuffix = ")";
  }
  unsigned userAgentNameSize
    = fApplicationNameSize + strlen(libPrefix) + strlen(libName) + strlen(libVersionStr) + strlen(libSuffix) + 1;
  char* userAgentName = new char[userAgentNameSize];
  sprintf(userAgentName, "%s%s%s%s%s",
	  applicationName, libPrefix, libName, libVersionStr, libSuffix);
  setUserAgentString(userAgentName);
  delete[] userAgentName;

  reset();
}