ACE_QoS_Session * TAO_AV_UDP_QoS_Session_Helper::open_qos_session (TAO_AV_UDP_QoS_Flow_Handler *handler, ACE_INET_Addr &addr) { ACE_QoS_Params qos_params; ACE_QoS* ace_qos = 0; FillQoSParams (qos_params, 0, ace_qos); // Create a QoS Session Factory. ACE_QoS_Session_Factory session_factory; // Ask the factory to create a QoS session. ACE_QoS_Session *qos_session = session_factory.create_session (); // Create a destination address for the QoS session. The same // address should be used for the subscribe call later. A copy // is made below only to distinguish the two usages of the dest // address. ACE_INET_Addr dest_addr (addr); // A QoS session is defined by the 3-tuple [DestAddr, DestPort, // Protocol]. Initialize the QoS session. if (qos_session->open (dest_addr, IPPROTO_UDP) == -1) ORBSVCS_ERROR_RETURN ((LM_ERROR, "Error in opening the QoS session\n"), 0); else ORBSVCS_DEBUG ((LM_DEBUG, "QoS session opened successfully\n")); if (handler->flowspec_entry ()->role () == TAO_FlowSpec_Entry::TAO_AV_PRODUCER) { // This is a sender qos_session->flags (ACE_QoS_Session::ACE_QOS_SENDER); } else if (handler->flowspec_entry ()->role () == TAO_FlowSpec_Entry::TAO_AV_CONSUMER) { // This is a receiver qos_session->flags (ACE_QoS_Session::ACE_QOS_RECEIVER); } return qos_session; }
address generate_atomic_xchg() { StubCodeMark mark(this, "StubRoutines", "atomic_xchg"); address start = __ pc(); __ pushl(edx); Address exchange(esp, 2 * wordSize); Address dest_addr(esp, 3 * wordSize); __ movl(eax, exchange); __ movl(edx, dest_addr); __ xchg(eax, Address(edx, 0)); __ popl(edx); __ ret(0); return start; }
ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz) : _options_size(), reach_time(0), retrans_timer(0) { if(total_sz < sizeof(_header)) throw malformed_packet(); std::memcpy(&_header, buffer, sizeof(_header)); buffer += sizeof(_header); total_sz -= sizeof(_header); if(has_target_addr()) { if(total_sz < ipaddress_type::address_size) throw malformed_packet(); target_addr(buffer); buffer += ipaddress_type::address_size; total_sz -= ipaddress_type::address_size; } if(has_dest_addr()) { if(total_sz < ipaddress_type::address_size) throw malformed_packet(); dest_addr(buffer); buffer += ipaddress_type::address_size; total_sz -= ipaddress_type::address_size; } if(type() == ROUTER_ADVERT) { if(total_sz < sizeof(uint32_t) * 2) throw malformed_packet(); const uint32_t *ptr_32 = (const uint32_t*)buffer; reach_time = *ptr_32++; retrans_timer = *ptr_32++; buffer += sizeof(uint32_t) * 2; total_sz -= sizeof(uint32_t) * 2; } if(has_options()) parse_options(buffer, total_sz); if(total_sz > 0) inner_pdu(new RawPDU(buffer, total_sz)); }
int ACE_TMAIN (int argc, ACE_TCHAR * argv[]) { QoS_Util qos_util(argc, argv); if (qos_util.parse_args () == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error in parsing args\n"), -1); // This is a multicast application. if (qos_util.multicast_flag ()) { Fill_ACE_QoS fill_ace_qos; // The application adds the flow specs that it wants into the // Fill_ACE_QoS. The Fill_ACE_QoS indexes the flow specs by the // flow spec names. Here the new flowspec being added is g_711. ACE_CString g_711 ("g_711"); switch (fill_ace_qos.map ().bind (g_711, new ACE_Flow_Spec (9200, 708, 18400, 0, 0, ACE_SERVICETYPE_CONTROLLEDLOAD, 368, 368, 25, 1))) { case 1 : ACE_ERROR_RETURN ((LM_ERROR, "Unable to bind the new flow spec\n" "The Flow Spec name already exists\n"), -1); break; case -1 : ACE_ERROR_RETURN ((LM_ERROR, "Unable to bind the new flow spec\n"), -1); break; } ACE_DEBUG ((LM_DEBUG, "g_711 Flow Spec bound successfully\n")); // This is a receiver. So we fill in the receiving QoS parameters. ACE_QoS ace_qos_receiver; if (fill_ace_qos.fill_simplex_receiver_qos (ace_qos_receiver, g_711) !=0) ACE_ERROR_RETURN ((LM_ERROR, "Unable to fill simplex receiver qos\n"), -1); else ACE_DEBUG ((LM_DEBUG, "Filled up the Receiver QoS parameters\n")); // Opening a new Multicast Datagram. ACE_SOCK_Dgram_Mcast_QoS dgram_mcast_qos; // Multicast Session Address specified by user at command line. // If this address is not specified, // <localhost:ACE_DEFAULT_MULTICAST_PORT> is assumed. ACE_INET_Addr mult_addr (*(qos_util.mult_session_addr ())); // Fill the ACE_QoS_Params to be passed to the <ACE_OS::join_leaf> // through subscribe. ACE_QoS_Params qos_params; FillQoSParams (qos_params, 0, &ace_qos_receiver); // Create a QoS Session Factory. ACE_QoS_Session_Factory session_factory; // Ask the factory to create a QoS session. ACE_QoS_Session *qos_session = session_factory.create_session (); // Create a destination address for the QoS session. The same // address should be used for the subscribe call later. A copy // is made below only to distinguish the two usages of the dest // address. ACE_INET_Addr dest_addr (mult_addr); // A QoS session is defined by the 3-tuple [DestAddr, DestPort, // Protocol]. Initialize the QoS session. if (qos_session->open (mult_addr, IPPROTO_UDP) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error in opening the QoS session\n"), -1); else ACE_DEBUG ((LM_DEBUG, "QoS session opened successfully\n")); // The following call opens the Dgram_Mcast and calls the // <ACE_OS::join_leaf> with the qos_params supplied here. Note // the QoS session object is passed into this call. This // subscribes the underlying socket to the passed in QoS // session. For joining multiple multicast sessions, the // following subscribe call should be made with different // multicast addresses and a new QoS session object should be // passed in for each such call. The QoS session objects can be // created only through the session factory. Care should be // taken that the mult_addr for the subscribe() call matches the // dest_addr of the QoS session object. If this is not done, the // subscribe call will fail. A more abstract version of // subscribe will be added that constrains the various features // of GQoS like different flags etc. if (dgram_mcast_qos.subscribe (mult_addr, qos_params, 1, 0, AF_INET, // ACE_FROM_PROTOCOL_INFO, 0, 0, // ACE_Protocol_Info, 0, ACE_OVERLAPPED_SOCKET_FLAG | ACE_FLAG_MULTIPOINT_C_LEAF | ACE_FLAG_MULTIPOINT_D_LEAF, qos_session) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error in subscribe\n"), -1); else ACE_DEBUG ((LM_DEBUG, "Dgram_Mcast subscribe succeeds\n")); int nIP_TTL = 25; char achInBuf [BUFSIZ]; u_long dwBytes; // Should this be abstracted into QoS objects ?? Doesnt seem to have // to do anything directly with QoS. if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket. ACE_SIO_MULTICAST_SCOPE, // IO control code. &nIP_TTL, // In buffer. sizeof (nIP_TTL), // Length of in buffer. achInBuf, // Out buffer. BUFSIZ, // Length of Out buffer. &dwBytes, // bytes returned. 0, // Overlapped. 0) == -1) // Func. ACE_ERROR ((LM_ERROR, "Error in Multicast scope ACE_OS::ioctl()\n")); else ACE_DEBUG ((LM_DEBUG, "Setting TTL with Multicast scope ACE_OS::ioctl call succeeds\n")); int bFlag = 0; // Should this be abstracted into QoS objects ?? Doesnt seem to have // to do anything directly with QoS. if (ACE_OS::ioctl (dgram_mcast_qos.get_handle (), // Socket. ACE_SIO_MULTIPOINT_LOOPBACK, // IO control code. &bFlag, // In buffer. sizeof (bFlag), // Length of in buffer. achInBuf, // Out buffer. BUFSIZ, // Length of Out buffer. &dwBytes, // bytes returned. 0, // Overlapped. 0) == -1) // Func. ACE_ERROR ((LM_ERROR, "Error in Loopback ACE_OS::ioctl()\n")); else ACE_DEBUG ((LM_DEBUG, "Disable Loopback with ACE_OS::ioctl call succeeds\n")); // This is a receiver. qos_session->flags (ACE_QoS_Session::ACE_QOS_RECEIVER); ACE_QoS_Manager qos_manager = dgram_mcast_qos.qos_manager (); // Set the QoS for the session. Replaces the ioctl () call that // was being made previously. if (qos_session->qos (&dgram_mcast_qos, &qos_manager, ace_qos_receiver) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Unable to set QoS\n"), -1); else ACE_DEBUG ((LM_DEBUG, "Setting QOS succeeds.\n")); // Register a signal handler that helps to gracefully close the // open QoS sessions. QoS_Signal_Handler qos_signal_handler (qos_session); // Register the usual SIGINT signal handler with the Reactor for // the application to gracefully release the QoS session and // shutdown. if (ACE_Reactor::instance ()->register_handler (SIGINT, &qos_signal_handler) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error in registering the Signal Handler.\n"), -1); // Handler to process QoS and Data events for the reciever. Receiver_QoS_Event_Handler qos_event_handler (dgram_mcast_qos, qos_session); // Decorate the above handler with QoS functionality. ACE_QoS_Decorator qos_decorator (&qos_event_handler, qos_session); // Initialize the Decorator. if (qos_decorator.init () != 0) ACE_ERROR_RETURN ((LM_ERROR, "QoS Decorator init () failed.\n"), -1); // Register the decorated Event Handler with the Reactor. if (ACE_Reactor::instance ()->register_handler (&qos_decorator, ACE_Event_Handler::QOS_MASK | ACE_Event_Handler::READ_MASK) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error in registering the Decorator with the Reactor\n"), -1); // // Register the RAPI Event Handler with the Reactor. This // // handles the QoS events. // if (ACE_Reactor::instance ()->register_handler // (&rapi_event_handler, // ACE_Event_Handler::QOS_MASK | ACE_Event_Handler::READ_MASK) == -1) // ACE_ERROR_RETURN ((LM_ERROR, // "Error in registering the RAPI Event Handler\n"), // -1); // // The following event handler handles the data. // ACE_QoS_Event_Handler data_event_handler (dgram_mcast_qos, // qos_session); // // Register the Data Event Handler with the Reactor. // if (ACE_Reactor::instance ()->register_handler // (&data_event_handler,ACE_Event_Handler::READ_MASK) == -1) // ACE_ERROR_RETURN ((LM_ERROR, // "Error in registering Data Event Handler\n"), // -1); // Start the event loop. ACE_DEBUG ((LM_DEBUG, "Running the Event Loop ...\n")); ACE_Reactor::instance ()->run_event_loop (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); } else ACE_DEBUG ((LM_DEBUG, "Specify a -m option for multicast application\n")); return 0; }
void IPTVStreamHandler::run(void) { RunProlog(); LOG(VB_GENERAL, LOG_INFO, LOC + "run()"); SetRunning(true, false, false); // TODO Error handling.. // Setup CetonRTSP *rtsp = NULL; IPTVTuningData tuning = m_tuning; if (m_tuning.GetURL(0).scheme().toLower() == "rtsp") { rtsp = new CetonRTSP(m_tuning.GetURL(0)); // Check RTSP capabilities QStringList options; if (!(rtsp->GetOptions(options) && options.contains("OPTIONS") && options.contains("DESCRIBE") && options.contains("SETUP") && options.contains("PLAY") && options.contains("TEARDOWN"))) { LOG(VB_RECORD, LOG_ERR, LOC + "RTSP interface did not support the necessary options"); delete rtsp; SetRunning(false, false, false); RunEpilog(); return; } if (!rtsp->Describe()) { LOG(VB_RECORD, LOG_ERR, LOC + "RTSP Describe command failed"); delete rtsp; SetRunning(false, false, false); RunEpilog(); return; } tuning = IPTVTuningData( QString("rtp://%1@%2:0") .arg(m_tuning.GetURL(0).host()) .arg(QHostAddress(QHostAddress::Any).toString()), 0, IPTVTuningData::kNone, QString("rtp://%1@%2:0") .arg(m_tuning.GetURL(0).host()) .arg(QHostAddress(QHostAddress::Any).toString()), 0, "", 0); } for (uint i = 0; i < IPTV_SOCKET_COUNT; i++) { QUrl url = tuning.GetURL(i); if (url.port() < 0) continue; m_sockets[i] = new QUdpSocket(); m_read_helpers[i] = new IPTVStreamHandlerReadHelper( this, m_sockets[i], i); // we need to open the descriptor ourselves so we // can set some socket options int fd = socket(AF_INET, SOCK_DGRAM, 0); // create IPv4 socket if (fd < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create socket " + ENO); continue; } int buf_size = 2 * 1024 * max(tuning.GetBitrate(i)/1000, 500U); if (!tuning.GetBitrate(i)) buf_size = 2 * 1024 * 1024; int ok = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)); if (ok) { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Increasing buffer size to %1 failed") .arg(buf_size) + ENO); } /* int broadcast = 1; ok = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); if (ok) { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Enabling broadcast failed") + ENO); } */ m_sockets[i]->setSocketDescriptor( fd, QAbstractSocket::UnconnectedState, QIODevice::ReadOnly); m_sockets[i]->bind(QHostAddress::Any, url.port()); QHostAddress dest_addr(tuning.GetURL(i).host()); if (dest_addr != QHostAddress::Any) { //m_sockets[i]->joinMulticastGroup(dest_addr); // needs Qt 4.8 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Joining %1") .arg(dest_addr.toString())); struct ip_mreq imr; memset(&imr, 0, sizeof(struct ip_mreq)); imr.imr_multiaddr.s_addr = inet_addr( dest_addr.toString().toLatin1().constData()); imr.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "setsockopt - IP_ADD_MEMBERSHIP " + ENO); } } if (!url.userInfo().isEmpty()) m_sender[i] = QHostAddress(url.userInfo()); } if (m_use_rtp_streaming) m_buffer = new RTPPacketBuffer(tuning.GetBitrate(0)); else m_buffer = new UDPPacketBuffer(tuning.GetBitrate(0)); m_write_helper = new IPTVStreamHandlerWriteHelper(this); m_write_helper->Start(); bool error = false; if (rtsp) { // Start Streaming if (!rtsp->Setup(m_sockets[0]->localPort(), m_sockets[1]->localPort()) || !rtsp->Play()) { LOG(VB_RECORD, LOG_ERR, LOC + "Starting recording (RTP initialization failed). Aborting."); error = true; } } if (!error) { // Enter event loop exec(); } // Clean up for (uint i = 0; i < IPTV_SOCKET_COUNT; i++) { if (m_sockets[i]) { delete m_sockets[i]; m_sockets[i] = NULL; delete m_read_helpers[i]; m_read_helpers[i] = NULL; } } delete m_buffer; m_buffer = NULL; delete m_write_helper; m_write_helper = NULL; if (rtsp) { rtsp->Teardown(); delete rtsp; } SetRunning(false, false, false); RunEpilog(); }
void IPTVStreamHandler::run(void) { RunProlog(); LOG(VB_GENERAL, LOG_INFO, LOC + "run()"); SetRunning(true, false, false); // TODO Error handling.. // Setup CetonRTSP *rtsp = nullptr; IPTVTuningData tuning = m_tuning; if(m_tuning.IsRTSP()) { rtsp = new CetonRTSP(m_tuning.GetURL(0)); // Check RTSP capabilities QStringList options; if (!(rtsp->GetOptions(options) && options.contains("DESCRIBE") && options.contains("SETUP") && options.contains("PLAY") && options.contains("TEARDOWN"))) { LOG(VB_RECORD, LOG_ERR, LOC + "RTSP interface did not support the necessary options"); delete rtsp; SetRunning(false, false, false); RunEpilog(); return; } if (!rtsp->Describe()) { LOG(VB_RECORD, LOG_ERR, LOC + "RTSP Describe command failed"); delete rtsp; SetRunning(false, false, false); RunEpilog(); return; } m_use_rtp_streaming = true; QUrl urltuned = m_tuning.GetURL(0); urltuned.setScheme("rtp"); urltuned.setPort(0); tuning = IPTVTuningData(urltuned.toString(), 0, IPTVTuningData::kNone, urltuned.toString(), 0, "", 0); } bool error = false; int start_port = 0; for (uint i = 0; i < IPTV_SOCKET_COUNT; i++) { QUrl url = tuning.GetURL(i); if (url.port() < 0) continue; LOG(VB_RECORD, LOG_DEBUG, LOC + QString("setting up url[%1]:%2").arg(i).arg(url.toString())); // always ensure we use consecutive port numbers int port = start_port ? start_port + 1 : url.port(); QString host = url.host(); QHostAddress dest_addr(host); if (!host.isEmpty() && dest_addr.isNull()) { // address is a hostname, attempts to resolve it QHostInfo info = QHostInfo::fromName(host); QList<QHostAddress> list = info.addresses(); if (list.isEmpty()) { LOG(VB_RECORD, LOG_ERR, LOC + QString("Can't resolve hostname:'%1'").arg(host)); } else { for (int j=0; j < list.size(); j++) { dest_addr = list[j]; if (list[j].protocol() == QAbstractSocket::IPv6Protocol) { // We prefer first IPv4 break; } } LOG(VB_RECORD, LOG_DEBUG, LOC + QString("resolved %1 as %2").arg(host).arg(dest_addr.toString())); } } bool ipv6 = dest_addr.protocol() == QAbstractSocket::IPv6Protocol; bool is_multicast = ipv6 ? dest_addr.isInSubnet(QHostAddress::parseSubnet("ff00::/8")) : (dest_addr.toIPv4Address() & 0xf0000000) == 0xe0000000; m_sockets[i] = new QUdpSocket(); if (!is_multicast) { // this allow to filter incoming traffic, and make sure it's from // the requested server m_sender[i] = dest_addr; } m_read_helpers[i] = new IPTVStreamHandlerReadHelper( this, m_sockets[i], i); // we need to open the descriptor ourselves so we // can set some socket options int fd = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_DGRAM, 0); // create IPv4 socket if (fd < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create socket " + ENO); continue; } int buf_size = 2 * 1024 * max(tuning.GetBitrate(i)/1000, 500U); if (!tuning.GetBitrate(i)) buf_size = 2 * 1024 * 1024; int err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)); if (err) { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Increasing buffer size to %1 failed") .arg(buf_size) + ENO); } m_sockets[i]->setSocketDescriptor( fd, QAbstractSocket::UnconnectedState, QIODevice::ReadOnly); // we bind to destination address if it's a multicast address, or // the local ones otherwise if (!m_sockets[i]->bind(is_multicast ? dest_addr : (ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any), port)) { LOG(VB_GENERAL, LOG_ERR, LOC + "Binding to port failed."); error = true; } else { start_port = m_sockets[i]->localPort(); } if (is_multicast) { m_sockets[i]->joinMulticastGroup(dest_addr); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Joining %1") .arg(dest_addr.toString())); } if (!is_multicast && rtsp && i == 1) { m_rtcp_dest = dest_addr; } } if (!error) { if (m_tuning.IsRTP() || m_tuning.IsRTSP()) m_buffer = new RTPPacketBuffer(tuning.GetBitrate(0)); else m_buffer = new UDPPacketBuffer(tuning.GetBitrate(0)); m_write_helper = new IPTVStreamHandlerWriteHelper(this); m_write_helper->Start(); } if (!error && rtsp) { // Start Streaming if (!rtsp->Setup(m_sockets[0]->localPort(), m_sockets[1]->localPort(), m_rtsp_rtp_port, m_rtsp_rtcp_port, m_rtsp_ssrc) || !rtsp->Play()) { LOG(VB_RECORD, LOG_ERR, LOC + "Starting recording (RTP initialization failed). Aborting."); error = true; } if (m_rtsp_rtcp_port > 0) { m_write_helper->SendRTCPReport(); m_write_helper->StartRTCPRR(); } } if (!error) { // Enter event loop exec(); } // Clean up for (uint i = 0; i < IPTV_SOCKET_COUNT; i++) { if (m_sockets[i]) { delete m_sockets[i]; m_sockets[i] = nullptr; delete m_read_helpers[i]; m_read_helpers[i] = nullptr; } } delete m_buffer; m_buffer = nullptr; delete m_write_helper; m_write_helper = nullptr; if (rtsp) { rtsp->Teardown(); delete rtsp; } SetRunning(false, false, false); RunEpilog(); }