void RTCPCompoundPacketBuilder::ClearBuildBuffers() { report.Clear(); sdes.Clear(); std::list<Buffer>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) { if ((*it).packetdata) RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); } for (it = apppackets.begin() ; it != apppackets.end() ; it++) { if ((*it).packetdata) RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); } #ifdef RTP_SUPPORT_RTCPUNKNOWN for (it = unknownpackets.begin() ; it != unknownpackets.end() ; it++) { if ((*it).packetdata) RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); } #endif // RTP_SUPPORT_RTCPUNKNOWN byepackets.clear(); apppackets.clear(); #ifdef RTP_SUPPORT_RTCPUNKNOWN unknownpackets.clear(); #endif // RTP_SUPPORT_RTCPUNKNOWN byesize = 0; appsize = 0; #ifdef RTP_SUPPORT_RTCPUNKNOWN unknownsize = 0; #endif // RTP_SUPPORT_RTCPUNKNOWN }
void RTPSession::Destroy() { if (!created) return; #ifdef RTP_SUPPORT_THREAD if (pollthread) RTPDelete(pollthread,GetMemoryManager()); #endif // RTP_SUPPORT_THREAD if (deletetransmitter) RTPDelete(rtptrans,GetMemoryManager()); packetbuilder.Destroy(); rtcpbuilder.Destroy(); rtcpsched.Reset(); collisionlist.Clear(); sources.Clear(); std::list<RTCPCompoundPacket *>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) RTPDelete(*it,GetMemoryManager()); byepackets.clear(); created = false; }
int RTPSession::Create(const RTPSessionParams &sessparams,const RTPTransmissionParams *transparams /* = 0 */, RTPTransmitter::TransmissionProtocol protocol) { int status; if (created) return ERR_RTP_SESSION_ALREADYCREATED; usingpollthread = sessparams.IsUsingPollThread(); useSR_BYEifpossible = sessparams.GetSenderReportForBYE(); sentpackets = false; // Check max packet size if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE) return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL; // Initialize the transmission component rtptrans = 0; switch(protocol) { case RTPTransmitter::IPv4UDPProto: rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv4Transmitter(GetMemoryManager()); break; #ifdef RTP_SUPPORT_IPV6 case RTPTransmitter::IPv6UDPProto: rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv6Transmitter(GetMemoryManager()); break; #endif // RTP_SUPPORT_IPV6 case RTPTransmitter::UserDefinedProto: rtptrans = NewUserDefinedTransmitter(); if (rtptrans == 0) return ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL; break; default: return ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL; } if (rtptrans == 0) return ERR_RTP_OUTOFMEM; if ((status = rtptrans->Init(usingpollthread)) < 0) { RTPDelete(rtptrans,GetMemoryManager()); return status; } if ((status = rtptrans->Create(maxpacksize,transparams)) < 0) { RTPDelete(rtptrans,GetMemoryManager()); return status; } deletetransmitter = true; return InternalCreate(sessparams); }
RTPUDPv6Transmitter::RTPUDPv6Transmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr), destinations(GetMemoryManager(),RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT), multicastgroups(GetMemoryManager(),RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT), acceptignoreinfo(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT) { created = false; init = false; #if (defined(WIN32) || defined(_WIN32_WCE)) timeinit.Dummy(); #endif // WIN32 || _WIN32_WCE }
int RTCPSDESInfo::SetPrivateValue(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen) { std::list<SDESPrivateItem *>::const_iterator it; bool found; found = false; it = privitems.begin(); while (!found && it != privitems.end()) { uint8_t *p; size_t l; p = (*it)->GetPrefix(&l); if (l == prefixlen) { if (l <= 0) found = true; else if (memcmp(prefix,p,l) == 0) found = true; else ++it; } else ++it; } SDESPrivateItem *item; if (found) // replace the value for this entry item = *it; else // no entry for this prefix found... add it { if (privitems.size() >= RTP_MAXPRIVITEMS) // too many items present, just ignore it return ERR_RTP_SDES_MAXPRIVITEMS; int status; item = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESPRIVATEITEM) SDESPrivateItem(GetMemoryManager()); if (item == 0) return ERR_RTP_OUTOFMEM; if ((status = item->SetPrefix(prefix,prefixlen)) < 0) { RTPDelete(item,GetMemoryManager()); return status; } privitems.push_front(item); } return item->SetInfo(value,valuelen); }
int RTPPacketBuilder::SetMaximumPacketSize(size_t max) { uint8_t *newbuf; if (max <= 0) return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; newbuf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t[max]; if (newbuf == 0) return ERR_RTP_OUTOFMEM; RTPDeleteByteArray(buffer,GetMemoryManager()); buffer = newbuf; maxpacksize = max; return 0; }
void RTPPacketBuilder::Destroy() { if (!init) return; RTPDeleteByteArray(buffer,GetMemoryManager()); init = false; }
int RTPPacketBuilder::PrivateBuildPacket(const void *data,size_t len, uint8_t pt,bool mark,uint32_t timestampinc,bool gotextension, uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) { RTPPacket p(pt,data,len,seqnr,timestamp,ssrc,mark,numcsrcs,csrcs,gotextension,hdrextID, (uint16_t)numhdrextwords,hdrextdata,buffer,maxpacksize,GetMemoryManager()); int status = p.GetCreationError(); if (status < 0) return status; packetlength = p.GetPacketLength(); if (numpackets == 0) // first packet { lastwallclocktime = RTPTime::CurrentTime(); lastrtptimestamp = timestamp; prevrtptimestamp = timestamp; } else if (timestamp != prevrtptimestamp) { lastwallclocktime = RTPTime::CurrentTime(); lastrtptimestamp = timestamp; prevrtptimestamp = timestamp; } numpayloadbytes += (uint32_t)p.GetPayloadLength(); numpackets++; timestamp += timestampinc; seqnr++; return 0; }
int RTPCollisionList::UpdateAddress(const RTPAddress *addr,const RTPTime &receivetime,bool *created) { if (addr == 0) return ERR_RTP_COLLISIONLIST_BADADDRESS; std::list<AddressAndTime>::iterator it; for (it = addresslist.begin() ; it != addresslist.end() ; it++) { if (((*it).addr)->IsSameAddress(addr)) { (*it).recvtime = receivetime; *created = false; return 0; } } RTPAddress *newaddr = addr->CreateCopy(GetMemoryManager()); if (newaddr == 0) return ERR_RTP_OUTOFMEM; addresslist.push_back(AddressAndTime(newaddr,receivetime)); *created = true; return 0; }
int RTCPCompoundPacketBuilder::AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq, uint32_t jitter,uint32_t lsr,uint32_t dlsr) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (report.headerlength == 0) return ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED; size_t totalothersize = byesize+appsize+sdes.NeededBytes(); size_t reportsizewithextrablock = report.NeededBytesWithExtraReportBlock(); if ((totalothersize+reportsizewithextrablock) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRECEIVERREPORT) uint8_t[sizeof(RTCPReceiverReport)]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPReceiverReport *rr = (RTCPReceiverReport *)buf; uint32_t *packlost = (uint32_t *)&packetslost; uint32_t packlost2 = (*packlost); rr->ssrc = htonl(ssrc); rr->fractionlost = fractionlost; rr->packetslost[2] = (uint8_t)(packlost2&0xFF); rr->packetslost[1] = (uint8_t)((packlost2>>8)&0xFF); rr->packetslost[0] = (uint8_t)((packlost2>>16)&0xFF); rr->exthighseqnr = htonl(exthighestseq); rr->jitter = htonl(jitter); rr->lsr = htonl(lsr); rr->dlsr = htonl(dlsr); report.reportblocks.push_back(Buffer(buf,sizeof(RTCPReceiverReport))); return 0; }
int RTCPSDESInfo::DeletePrivatePrefix(const uint8_t *prefix,size_t prefixlen) { std::list<SDESPrivateItem *>::iterator it; bool found; found = false; it = privitems.begin(); while (!found && it != privitems.end()) { uint8_t *p; size_t l; p = (*it)->GetPrefix(&l); if (l == prefixlen) { if (l <= 0) found = true; else if (memcmp(prefix,p,l) == 0) found = true; else ++it; } else ++it; } if (!found) return ERR_RTP_SDES_PREFIXNOTFOUND; RTPDelete(*it,GetMemoryManager()); privitems.erase(it); return 0; }
int RTCPCompoundPacketBuilder::AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (sdes.sdessources.empty()) return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; uint8_t itemid; switch(t) { case RTCPSDESPacket::CNAME: itemid = RTCP_SDES_ID_CNAME; break; case RTCPSDESPacket::NAME: itemid = RTCP_SDES_ID_NAME; break; case RTCPSDESPacket::EMAIL: itemid = RTCP_SDES_ID_EMAIL; break; case RTCPSDESPacket::PHONE: itemid = RTCP_SDES_ID_PHONE; break; case RTCPSDESPacket::LOC: itemid = RTCP_SDES_ID_LOCATION; break; case RTCPSDESPacket::TOOL: itemid = RTCP_SDES_ID_TOOL; break; case RTCPSDESPacket::NOTE: itemid = RTCP_SDES_ID_NOTE; break; default: return ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE; } size_t totalotherbytes = byesize+appsize+report.NeededBytes(); size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; size_t len; buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+(size_t)itemlength]; if (buf == 0) return ERR_RTP_OUTOFMEM; len = sizeof(RTCPSDESHeader)+(size_t)itemlength; RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf); sdeshdr->sdesid = itemid; sdeshdr->length = itemlength; if (itemlength != 0) memcpy((buf + sizeof(RTCPSDESHeader)),itemdata,(size_t)itemlength); sdes.AddItem(buf,len); return 0; }
void RTPCollisionList::Clear() { std::list<AddressAndTime>::iterator it; for (it = addresslist.begin() ; it != addresslist.end() ; it++) RTPDelete((*it).addr,GetMemoryManager()); addresslist.clear(); }
void RTCPCompoundPacket::ClearPacketList() { std::list<RTCPPacket *>::const_iterator it; for (it = rtcppacklist.begin() ; it != rtcppacklist.end() ; it++) RTPDelete(*it,GetMemoryManager()); rtcppacklist.clear(); rtcppackit = rtcppacklist.begin(); }
int RTPInternalSourceData::ProcessBYEPacket(const uint8_t *reason,size_t reasonlen,const RTPTime &receivetime) { if (byereason) { RTPDeleteByteArray(byereason,GetMemoryManager()); byereason = 0; byereasonlen = 0; } byetime = receivetime; byereason = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEREASON) uint8_t[reasonlen]; if (byereason == 0) return ERR_RTP_OUTOFMEM; memcpy(byereason,reason,reasonlen); byereasonlen = reasonlen; receivedbye = true; stats.SetLastMessageTime(receivetime); return 0; }
void RTCPSDESInfo::Clear() { #ifdef RTP_SUPPORT_SDESPRIV std::list<SDESPrivateItem *>::const_iterator it; for (it = privitems.begin() ; it != privitems.end() ; ++it) RTPDelete(*it,GetMemoryManager()); privitems.clear(); #endif // RTP_SUPPORT_SDESPRIV }
int RTCPCompoundPacketBuilder::AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (subtype > 31) return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE; if ((appdatalen%4) != 0) return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH; size_t appdatawords = appdatalen/4; if ((appdatawords+2) > 65535) return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2+appdatalen; #ifndef RTP_SUPPORT_RTCPUNKNOWN size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); #else size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes(); #endif // RTP_SUPPORT_RTCPUNKNOWN if ((totalotherbytes + packsize) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPAPPPACKET) uint8_t[packsize]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; hdr->version = 2; hdr->padding = 0; hdr->count = subtype; hdr->length = htons((uint16_t)(appdatawords+2)); hdr->packettype = RTP_RTCPTYPE_APP; uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); *source = htonl(ssrc); buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+0] = name[0]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+1] = name[1]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+2] = name[2]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+3] = name[3]; if (appdatalen > 0) memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2),appdata,appdatalen); apppackets.push_back(Buffer(buf,packsize)); appsize += packsize; return 0; }
void RTCPCompoundPacketBuilder::ClearBuildBuffers() { report.Clear(); sdes.Clear(); std::list<Buffer>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) { if ((*it).packetdata) RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); } for (it = apppackets.begin() ; it != apppackets.end() ; it++) { if ((*it).packetdata) RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); } byepackets.clear(); apppackets.clear(); byesize = 0; appsize = 0; }
int RTPFakeTransmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams) { // struct sockaddr_in addr; // int status; if (!init) return ERR_RTP_FAKETRANS_NOTINIT; MAINMUTEX_LOCK if (created) { MAINMUTEX_UNLOCK return ERR_RTP_FAKETRANS_ALREADYCREATED; } // Obtain transmission parameters if (transparams == 0) params = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) RTPFakeTransmissionParams; else { if (transparams->GetTransmissionProtocol() != RTPTransmitter::UserDefinedProto) return ERR_RTP_FAKETRANS_ILLEGALPARAMETERS; params = (RTPFakeTransmissionParams *)transparams; } // Check if portbase is even //if (params->GetPortbase()%2 != 0) //{ // MAINMUTEX_UNLOCK // return ERR_RTP_FAKETRANS_PORTBASENOTEVEN; //} // Try to obtain local IP addresses localIPs = params->GetLocalIPList(); if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them { int status; if ((status = CreateLocalIPList()) < 0) { MAINMUTEX_UNLOCK return status; }
void RTPCollisionList::Timeout(const RTPTime ¤ttime,const RTPTime &timeoutdelay) { std::list<AddressAndTime>::iterator it; RTPTime checktime = currenttime; checktime -= timeoutdelay; it = addresslist.begin(); while(it != addresslist.end()) { if ((*it).recvtime < checktime) // timeout { RTPDelete((*it).addr,GetMemoryManager()); it = addresslist.erase(it); } else it++; } }
int RTCPCompoundPacketBuilder::AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata, uint8_t valuelength) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (sdes.sdessources.empty()) return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; size_t itemlength = ((size_t)prefixlength)+1+((size_t)valuelength); if (itemlength > 255) return ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG; #ifndef RTP_SUPPORT_RTCPUNKNOWN size_t totalotherbytes = byesize+appsize+report.NeededBytes(); #else size_t totalotherbytes = byesize+appsize+unknownsize+report.NeededBytes(); #endif // RTP_SUPPORT_RTCPUNKNOWN size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; size_t len; buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+itemlength]; if (buf == 0) return ERR_RTP_OUTOFMEM; len = sizeof(RTCPSDESHeader)+(size_t)itemlength; RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf); sdeshdr->sdesid = RTCP_SDES_ID_PRIVATE; sdeshdr->length = itemlength; buf[sizeof(RTCPSDESHeader)] = prefixlength; if (prefixlength != 0) memcpy((buf+sizeof(RTCPSDESHeader)+1),prefixdata,(size_t)prefixlength); if (valuelength != 0) memcpy((buf+sizeof(RTCPSDESHeader)+1+(size_t)prefixlength),valuedata,(size_t)valuelength); sdes.AddItem(buf,len); return 0; }
int RTCPCompoundPacketBuilder::AddUnknownPacket(uint8_t payload_type, uint8_t subtype, uint32_t ssrc, const void *data, size_t len) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; size_t datawords = len/4; if ((datawords+2) > 65535) return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)+len; size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes(); if ((totalotherbytes + packsize) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) uint8_t[packsize]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; hdr->version = 2; hdr->padding = 0; hdr->count = subtype; hdr->length = htons((uint16_t)(datawords+1)); hdr->packettype = payload_type; uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); *source = htonl(ssrc); if (len > 0) memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)),data,len); unknownpackets.push_back(Buffer(buf,packsize)); unknownsize += packsize; return 0; }
int RTPPacketBuilder::Init(size_t max) { if (init) return ERR_RTP_PACKBUILD_ALREADYINIT; if (max <= 0) return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; maxpacksize = max; buffer = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t [max]; if (buffer == 0) return ERR_RTP_OUTOFMEM; packetlength = 0; CreateNewSSRC(); deftsset = false; defptset = false; defmarkset = false; numcsrcs = 0; init = true; return 0; }
void Application::AtExit() { // Remove all references GetMemoryManager().Sweep(); }
void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, std::unique_ptr<MemoryBuffer> O) { assert(O && "Object must not be null"); // This method launches an asynchronous link step that will fulfill our // materialization responsibility. We need to switch R to be heap // allocated before that happens so it can live as long as the asynchronous // link needs it to (i.e. it must be able to outlive this method). auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R)); auto &ES = getExecutionSession(); // Create a MemoryBufferRef backed MemoryBuffer (i.e. shallow) copy of the // the underlying buffer to pass into RuntimeDyld. This allows us to hold // ownership of the real underlying buffer and return it to the user once // the object has been emitted. auto ObjBuffer = MemoryBuffer::getMemBuffer(O->getMemBufferRef(), false); auto Obj = object::ObjectFile::createObjectFile(*ObjBuffer); if (!Obj) { getExecutionSession().reportError(Obj.takeError()); SharedR->failMaterialization(); return; } // Collect the internal symbols from the object file: We will need to // filter these later. auto InternalSymbols = std::make_shared<std::set<StringRef>>(); { for (auto &Sym : (*Obj)->symbols()) { if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) { if (auto SymName = Sym.getName()) InternalSymbols->insert(*SymName); else { ES.reportError(SymName.takeError()); R.failMaterialization(); return; } } } } auto K = R.getVModuleKey(); RuntimeDyld::MemoryManager *MemMgr = nullptr; // Create a record a memory manager for this object. { auto Tmp = GetMemoryManager(); std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); MemMgrs.push_back(std::move(Tmp)); MemMgr = MemMgrs.back().get(); } JITDylibSearchOrderResolver Resolver(*SharedR); // FIXME: Switch to move-capture for the 'O' buffer once we have c++14. MemoryBuffer *UnownedObjBuffer = O.release(); jitLinkForORC( **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections, [this, K, SharedR, &Obj, InternalSymbols]( std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) { return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo), ResolvedSymbols, *InternalSymbols); }, [this, K, SharedR, UnownedObjBuffer](Error Err) { std::unique_ptr<MemoryBuffer> ObjBuffer(UnownedObjBuffer); onObjEmit(K, std::move(ObjBuffer), *SharedR, std::move(Err)); }); }
int RTCPCompoundPacket::ParseData(uint8_t *data, size_t datalen) { bool first; if (datalen < sizeof(RTCPCommonHeader)) return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; first = true; do { RTCPCommonHeader *rtcphdr; size_t length; rtcphdr = (RTCPCommonHeader *)data; if (rtcphdr->version != RTP_VERSION) // check version { ClearPacketList(); return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; } if (first) { // Check if first packet is SR or RR first = false; if ( ! (rtcphdr->packettype == RTP_RTCPTYPE_SR || rtcphdr->packettype == RTP_RTCPTYPE_RR)) { ClearPacketList(); return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; } } length = (size_t)ntohs(rtcphdr->length); length++; length *= sizeof(uint32_t); if (length > datalen) // invalid length field { ClearPacketList(); return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; } if (rtcphdr->padding) { // check if it's the last packet if (length != datalen) { ClearPacketList(); return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; } } RTCPPacket *p; switch (rtcphdr->packettype) { case RTP_RTCPTYPE_SR: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(data,length); break; case RTP_RTCPTYPE_RR: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(data,length); break; case RTP_RTCPTYPE_SDES: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(data,length); break; case RTP_RTCPTYPE_BYE: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(data,length); break; case RTP_RTCPTYPE_APP: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(data,length); break; default: p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) RTCPUnknownPacket(data,length); } if (p == 0) { ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); datalen -= length; data += length; } while (datalen >= (size_t)sizeof(RTCPCommonHeader)); if (datalen != 0) // some remaining bytes { ClearPacketList(); return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; } return 0; }
RTCPCompoundPacket::~RTCPCompoundPacket() { ClearPacketList(); if (compoundpacket && deletepacket) RTPDeleteByteArray(compoundpacket,GetMemoryManager()); }
int RTCPCompoundPacketBuilder::AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength) { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (numssrcs > 31) return ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS; size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*((size_t)numssrcs); size_t zerobytes = 0; if (reasonlength > 0) { packsize += 1; // 1 byte for the length; packsize += (size_t)reasonlength; size_t r = (packsize&0x03); if (r != 0) { zerobytes = 4-r; packsize += zerobytes; } } size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); if ((totalotherbytes + packsize) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; size_t numwords; buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEPACKET) uint8_t[packsize]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; hdr->version = 2; hdr->padding = 0; hdr->count = numssrcs; numwords = packsize/sizeof(uint32_t); hdr->length = htons((uint16_t)(numwords-1)); hdr->packettype = RTP_RTCPTYPE_BYE; uint32_t *sources = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); uint8_t srcindex; for (srcindex = 0 ; srcindex < numssrcs ; srcindex++) sources[srcindex] = htonl(ssrcs[srcindex]); if (reasonlength != 0) { size_t offset = sizeof(RTCPCommonHeader)+((size_t)numssrcs)*sizeof(uint32_t); buf[offset] = reasonlength; memcpy((buf+offset+1),reasondata,(size_t)reasonlength); for (size_t i = 0 ; i < zerobytes ; i++) buf[packsize-1-i] = 0; } byepackets.push_back(Buffer(buf,packsize)); byesize += packsize; return 0; }
// The following function should delete rtppack if necessary int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored) { bool accept,onprobation,applyprobation; double tsunit; *stored = false; if (timestampunit < 0) tsunit = INF_GetEstimatedTimestampUnit(); else tsunit = timestampunit; #ifdef RTP_SUPPORT_PROBATION if (validated) // If the source is our own process, we can already be validated. No applyprobation = false; // probation should be applied in that case. else { if (probationtype == RTPSources::NoProbation) applyprobation = false; else applyprobation = true; } #else applyprobation = false; #endif // RTP_SUPPORT_PROBATION stats.ProcessPacket(rtppack,receivetime,tsunit,ownssrc,&accept,applyprobation,&onprobation); #ifdef RTP_SUPPORT_PROBATION switch (probationtype) { case RTPSources::ProbationStore: if (!(onprobation || accept)) return 0; if (accept) validated = true; break; case RTPSources::ProbationDiscard: case RTPSources::NoProbation: if (!accept) return 0; validated = true; break; default: return ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE; } #else if (!accept) return 0; validated = true; #endif // RTP_SUPPORT_PROBATION; if (validated && !ownssrc) // for own ssrc these variables depend on the outgoing packets, not on the incoming issender = true; // Now, we can place the packet in the queue if (packetlist.empty()) { *stored = true; packetlist.push_back(rtppack); return 0; } if (!validated) // still on probation { // Make sure that we don't buffer too much packets to avoid wasting memory // on a bad source. Delete the packet in the queue with the lowest sequence // number. if (packetlist.size() == RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS) { RTPPacket *p = *(packetlist.begin()); packetlist.pop_front(); RTPDelete(p,GetMemoryManager()); } } // find the right position to insert the packet std::list<RTPPacket*>::iterator it,start; bool done = false; uint32_t newseqnr = rtppack->GetExtendedSequenceNumber(); it = packetlist.end(); --it; start = packetlist.begin(); while (!done) { RTPPacket *p; uint32_t seqnr; p = *it; seqnr = p->GetExtendedSequenceNumber(); if (seqnr > newseqnr) { if (it != start) --it; else // we're at the start of the list { *stored = true; done = true; packetlist.push_front(rtppack); } } else if (seqnr < newseqnr) // insert after this packet { ++it; packetlist.insert(it,rtppack); done = true; *stored = true; } else // they're equal !! Drop packet { done = true; } } return 0; }
int RTCPCompoundPacketBuilder::EndBuild() { if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (report.headerlength == 0) return ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT; uint8_t *buf; size_t len; len = appsize+byesize+report.NeededBytes()+sdes.NeededBytes(); if (!external) { buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPCOMPOUNDPACKET) uint8_t[len]; if (buf == 0) return ERR_RTP_OUTOFMEM; } else buf = buffer; uint8_t *curbuf = buf; RTCPPacket *p; // first, we'll add all report info { bool firstpacket = true; bool done = false; std::list<Buffer>::const_iterator it = report.reportblocks.begin(); do { RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; size_t offset; hdr->version = 2; hdr->padding = 0; if (firstpacket && report.isSR) { hdr->packettype = RTP_RTCPTYPE_SR; memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,report.headerlength); offset = sizeof(RTCPCommonHeader)+report.headerlength; } else { hdr->packettype = RTP_RTCPTYPE_RR; memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,sizeof(uint32_t)); offset = sizeof(RTCPCommonHeader)+sizeof(uint32_t); } firstpacket = false; uint8_t count = 0; while (it != report.reportblocks.end() && count < 31) { memcpy(curbuf+offset,(*it).packetdata,(*it).packetlength); offset += (*it).packetlength; count++; it++; } size_t numwords = offset/sizeof(uint32_t); hdr->length = htons((uint16_t)(numwords-1)); hdr->count = count; // add entry in parent's list if (hdr->packettype == RTP_RTCPTYPE_SR) p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(curbuf,offset); else p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(curbuf,offset); if (p == 0) { if (!external) RTPDeleteByteArray(buf,GetMemoryManager()); ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += offset; if (it == report.reportblocks.end()) done = true; } while (!done); } // then, we'll add the sdes info if (!sdes.sdessources.empty()) { bool done = false; std::list<SDESSource *>::const_iterator sourceit = sdes.sdessources.begin(); do { RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; size_t offset = sizeof(RTCPCommonHeader); hdr->version = 2; hdr->padding = 0; hdr->packettype = RTP_RTCPTYPE_SDES; uint8_t sourcecount = 0; while (sourceit != sdes.sdessources.end() && sourcecount < 31) { uint32_t *ssrc = (uint32_t *)(curbuf+offset); *ssrc = htonl((*sourceit)->ssrc); offset += sizeof(uint32_t); std::list<Buffer>::const_iterator itemit,itemend; itemit = (*sourceit)->items.begin(); itemend = (*sourceit)->items.end(); while (itemit != itemend) { memcpy(curbuf+offset,(*itemit).packetdata,(*itemit).packetlength); offset += (*itemit).packetlength; itemit++; } curbuf[offset] = 0; // end of item list; offset++; size_t r = offset&0x03; if (r != 0) // align to 32 bit boundary { size_t num = 4-r; size_t i; for (i = 0 ; i < num ; i++) curbuf[offset+i] = 0; offset += num; } sourceit++; sourcecount++; } size_t numwords = offset/4; hdr->count = sourcecount; hdr->length = htons((uint16_t)(numwords-1)); p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(curbuf,offset); if (p == 0) { if (!external) RTPDeleteByteArray(buf,GetMemoryManager()); ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += offset; if (sourceit == sdes.sdessources.end()) done = true; } while (!done); } // adding the app data { std::list<Buffer>::const_iterator it; for (it = apppackets.begin() ; it != apppackets.end() ; it++) { memcpy(curbuf,(*it).packetdata,(*it).packetlength); p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(curbuf,(*it).packetlength); if (p == 0) { if (!external) RTPDeleteByteArray(buf,GetMemoryManager()); ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += (*it).packetlength; } } // adding bye packets { std::list<Buffer>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) { memcpy(curbuf,(*it).packetdata,(*it).packetlength); p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(curbuf,(*it).packetlength); if (p == 0) { if (!external) RTPDeleteByteArray(buf,GetMemoryManager()); ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += (*it).packetlength; } } compoundpacket = buf; compoundpacketlength = len; arebuilding = false; ClearBuildBuffers(); return 0; }