//--------------------------------------------------------------------------- // View::reduce //--------------------------------------------------------------------------- void View::reduce(int dim) throw ( cdma::Exception ) { int i = 0; int range = -1; for(yat::uint16 j = 0; j < m_ranges.size(); j++) { if( ! m_ranges[j].reduce() ) { if( i == dim ) { range = i; } i++; } } if( (dim < 0) || (dim >= m_rank) ) { VIEW_ERROR("Illegal reduce dim " + ('0' + dim), "View::reduce" ); } if( m_ranges[range].length() != 1 ) { VIEW_ERROR(std::string("Illegal reduce dim " + ('0' + dim)) + " : reduced dimension must be have length=1", "View::reduce"); } // Reduce proper range m_ranges[range].setReduce(true); m_rank--; m_upToDate = false; }
bool PeerConnector::ConnectUDP(const PEER_ADDRESS& addr, const PeerConnectParam& param) { if (m_LiveInfo.TransferMethod == TRANSFER_TCP) { return ConnectTCP(addr, 0, param); // 用于测试纯tcp的情况 } if ( addr.UdpPort == 0 ) return false; if (CheckConnected(addr, param.IsVIP)) { VIEW_INFO("CPeerManager::ConnectToRemote CheckConnected " << addr << " failed"); return false; } const PEER_ADDRESS& localAddr = m_NetInfo->Address; if (addr.IP == localAddr.IP && addr.UdpPort == localAddr.UdpPort) { //LIVE_ASSERT(false); VIEW_ERROR("ConnectUDP ignore myself " << addr); return false; } return m_UDPConnector->Connect(addr, param); }
//--------------------------------------------------------------------------- // View::setStride //--------------------------------------------------------------------------- void View::setStride(std::vector<int> stride) { if( stride.size() != (unsigned int)m_rank ) { VIEW_ERROR("Origin must have same length as view's rank!", "View::setStride"); } m_upToDate = false; yat::uint16 i = 0; yat::uint16 j = 0; while( i < stride.size() ) { // Only consider not reduced ranges if( ! m_ranges[j].reduce() ) { m_ranges[j].set( m_ranges[j].getName(), (long) m_ranges[j].first(), (long) m_ranges[j].last(), (long) stride[i], m_ranges[j].reduce() ); i++; } j++; } }
//--------------------------------------------------------------------------- // View::setOrigin //--------------------------------------------------------------------------- void View::setOrigin(std::vector<int> origin) { CDMA_FUNCTION_TRACE("View::setOrigin"); if( origin.size() != (unsigned int)m_rank ) { VIEW_ERROR("Origin must have same length as view's rank!", "View::setOrigin"); } yat::uint16 i = 0; yat::uint16 j = 0; while( i < origin.size() ) { // Only consider not reduced ranges if( ! m_ranges[j].reduce() ) { m_ranges[j].set( m_ranges[j].getName(), (long) origin[i] * abs(m_ranges[j].stride()), (long) origin[i] * abs(m_ranges[j].stride()) + (m_ranges[j].length() - 1) * m_ranges[j].stride() , (long) m_ranges[i].stride(), m_ranges[j].reduce() ); i++; } j++; } m_upToDate = false; }
//--------------------------------------------------------------------------- // View::getViewName //--------------------------------------------------------------------------- std::string View::getViewName(int dim) { if( dim >= m_rank || dim < 0 ) { VIEW_ERROR("Requested range is out of rank!", "View::getViewName"); } return m_ranges[dim].getName(); }
//--------------------------------------------------------------------------- // View::setViewName //--------------------------------------------------------------------------- void View::setViewName(int dim, const std::string& viewName) { if( dim >= m_rank || dim < 0 ) { VIEW_ERROR("Requested range is out of rank!", "View::setViewName"); } Range range ( viewName, m_ranges[dim].first(), m_ranges[dim].last(), m_ranges[dim].stride() ); m_ranges[dim] = range; }
LiveAppModuleImpl::LiveAppModuleImpl(const LiveAppModuleCreateParam& param, const TCHAR* tagname, bool tagMutate) : m_CreateParam( param ), m_NormalUDPSender(param.NormalUDPSender), m_TCPProxyUDPSender(param.TCPProxyUDPSender), m_HTTPProxyUDPSender(param.HTTPProxyUDPSender), m_AutoMaxAppPeerCount(20), m_AutoMinAppPeerCount(0), m_BootModule( new BootModule(param.NormalUDPSender) ) { TEST_LOG_OPEN( paths::combine( param.ConfigDirectory, _T("live_test.log") ).c_str() ); m_SysInfo = static_cast<const CSysInfo*>(param.SysInfo); m_PeerInformation.reset(new PeerInformation(param.ChannelGUID, param.SysInfo->PeerGUID, param.AppVersion, param.AppVersionNumber16, CreatePeerNetInfo(*m_SysInfo))); m_PeerInformation->NetInfo->CoreInfo.PeerType = param.PeerType; LIVE_ASSERT(m_SysInfo != NULL); m_PeerCountLimit = m_SysInfo->MaxAppPeerCount; LIMIT_MIN(m_PeerCountLimit, PPL_MIN_PEER_COUNT_LIMIT); // 传入的最大peer个数应该不超过一个最大限制PPL_MAX_PEER_COUNT_LIMIT LIVE_ASSERT(m_PeerCountLimit <= PPL_MAX_PEER_COUNT_LIMIT); LIMIT_MAX(m_PeerCountLimit, PPL_MAX_PEER_COUNT_LIMIT); m_iptable.Load(m_CreateParam.BaseDirectory); boost::shared_ptr<IDGenerator> trackerTransactionID(new IDGenerator()); boost::shared_ptr<IDGenerator> peerTransactionID(new IDGenerator()); m_UDPConnectionlessPacketBuilder.reset(new UDPConnectionlessPacketBuilder(peerTransactionID)); m_TCPConnectionlessPacketBuilder.reset(new TCPConnectionlessPacketBuilder()); m_OldTrackerPacketBuilder.reset(new UDPPacketBuilder(trackerTransactionID)); // 用于tracker报文 m_SecureUDPPacketBuilder.reset( new SecureTrackerRequestPacketBuilder( trackerTransactionID ) ); boost::shared_ptr<UDPConnectionPacketBuilder> udpConnectionPacketBuilder(new UDPConnectionPacketBuilder(peerTransactionID)); boost::shared_ptr<TCPConnectionPacketBuilder> tcpPacketBuilder(new TCPConnectionPacketBuilder()); m_SecureTrackerProxyPacketBuilder.reset( new SecureTrackerProxyPacketBuilder( trackerTransactionID ) ); m_SecureTrackerProxyPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID ); m_OldTrackerPacketBuilder->InitHeadInfo( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID ); m_SecureUDPPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, m_PeerInformation->NetInfo->CoreInfo, m_PeerInformation->AppVersion ); m_UDPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, *m_PeerInformation->NetInfo, m_PeerInformation->AppVersion); m_TCPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, *m_PeerInformation->NetInfo, m_PeerInformation->AppVersion); m_UDPPacketSender.reset(new TrackerPacketSender(m_OldTrackerPacketBuilder, m_SecureUDPPacketBuilder, m_NormalUDPSender, m_TCPProxyUDPSender, m_HTTPProxyUDPSender, m_PeerInformation, m_Statistics.OldUDPFlow.Upload, m_Statistics.TotalFlow.Upload)); m_UDPConnectionlessPacketSender.reset( new UDPConnectionlessPacketSender( m_UDPConnectionlessPacketBuilder, m_NormalUDPSender, m_PeerInformation, m_Statistics.UDPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_UDPConnectionPacketSender.reset( new UDPConnectionPacketSender( udpConnectionPacketBuilder, m_NormalUDPSender, m_Statistics.UDPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_TCPConnectionlessPacketSender.reset( new TCPConnectionlessPacketSender( m_TCPConnectionlessPacketBuilder, m_PeerInformation, m_Statistics.TCPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_TCPConnectionPacketSender.reset( new TCPConnectionPacketSender( tcpPacketBuilder, m_Statistics.TCPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) ); VIEW_ERROR("Create New AppModule! " << this << " ResourceGUID=" << param.ChannelGUID); m_LiveInfo = CreateLiveInfo(m_StatisticsInfo, m_MappingLiveInfo, tagname, m_PeerCountLimit, param, m_PeerInformation->AppVersion, tagMutate); LoadTracker(param.Trackers); InitPeerAuthInfo(*m_PeerInformation->AuthInfo, param); { //#if defined(_PPL_PLATFORM_LINUX) || defined(_PPL_USE_ASIO) // ini_file ini; // this->InitIni(ini); // ini.set_section(_T("media")); // int netWriterMode = ini.get_int(_T("NetWriterMode"), 0); // m_mediaServerListener.reset(CreateMediaServerListener(netWriterMode)); //#elif defined(_PPL_PLATFORM_MSWIN) m_mediaServerListener.reset(CreateMediaServerListener(*m_LiveInfo)); //#endif } /* ----------Removed by Tady, 04142010: Moved into Func. Start(). if ( NORMAL_PEER == param.PeerType ) { // 检查stun type MY_STUN_NAT_TYPE natType = this->LoadNATType(); if ( STUN_TYPE_INVALID == natType ) { // 读取nat类型失败,另起线程检测 m_StunTypeResolver.reset( new StunTypeResolver ); m_StunTypeResolver->Resolve(StunTypeResolver::CallbackType(boost::bind(&LiveAppModuleImpl::OnNATQuerySucceeded, this, _1))); } else { // 保存nat类型到NetInfo对象 m_PeerInformation->NetInfo->SetNATType( natType ); m_LiveInfo->LocalPeerInfo.NetInfo.CoreInfo.NATType = natType; } } */ { std::vector<InetSocketAddress> stunServers; ini_file ini; this->InitConfig(ini); ini.set_section(_T("stun")); tstring serverListStr = ini.get_string(_T("servers"), _T("")); int day = ini.get_int(_T("time"), -1); SYSTEMTIME st; GetLocalTime(&st); if ( false == serverListStr.empty() && ( day > 0 ) && (abs(st.wDay - day) < 3) ) { std::vector<tstring> serverList; strings::split(std::back_inserter(serverList), serverListStr, _T('|')); for ( size_t serverIndex = 0; serverIndex < serverList.size(); ++serverIndex ) { pair<tstring, tstring> ipAndPort = strings::split_pair(serverList[serverIndex], _T(':')); if ( false == ipAndPort.first.empty() && false == ipAndPort.second.empty() ) { UINT ip = ResolveHostName(ipAndPort.first); WORD port = static_cast<WORD>( _ttoi(ipAndPort.second.c_str()) ); if ( ip != 0 && ip != INADDR_NONE && port != 0) { stunServers.push_back(InetSocketAddress(ip, port)); } } } } if ( false == stunServers.empty() ) { this->StartStunModule(stunServers); } else { // 向boot server查询 m_BootModule->QueryNTSList(BootModule::NTSListCallbackType(boost::bind(&LiveAppModuleImpl::OnNTSListOK, this, _1))); } } m_LogClient.reset( new LogClient( m_CreateParam.BaseDirectory, m_CreateParam.ConfigDirectory, m_PeerInformation ) ); m_timer.set_callback(boost::bind(&LiveAppModuleImpl::OnAppTimer, this)); //#ifdef _DEBUG #ifdef _PPL_PLATFORM_MSWIN #pragma message("!!!!!!从params.ini中加载TransferMethod设置") #endif { ini_file ini; this->InitIni(ini); ini.set_section(_T("connector")); int method = ini.get_int(_T("TransferMethod"), 0); VIEW_DEBUG("Load TransferMethod " << method); if (method != TRANSFER_ALL && method != TRANSFER_UDP && method != TRANSFER_TCP && method != TRANSFER_NO_DETECT) { method = TRANSFER_ALL; } m_LiveInfo->TransferMethod = (BYTE)method; } //#endif TEST_LOG_OUT("live start"); TEST_LOG_OUT("channel id " << param.ChannelGUID); TEST_LOG_OUT("peer id " << param.SysInfo->PeerGUID); TEST_LOG_OUT("peer address " << m_PeerInformation->NetInfo->Address); TEST_LOG_FLUSH(); }
bool LiveAppModuleImpl::DispatchUdpPacket(BYTE* data, int size, const InetSocketAddress& remoteSockAddr, UINT proxyType, ExtraProxyEnum extraProxy) { m_Statistics.TotalFlow.Download.Record( size ); const size_t totalDataSize = size; APP_EVENT( "DispatchUdpPacket " << make_buffer_pair(data, size) << " from " << remoteSockAddr );//<< " " << HexEncoding::Encode(string((const char*)data, size)) ); //BYTE* rawData = data; //size_t rawSize = size; this->RecordDownload(size); SimpleSocketAddress sockAddr(remoteSockAddr); if ((size_t) size >= sizeof( OLD_UDP_PACKET_HEAD ) + sizeof( GUID ) ) { #ifndef _PPL_TEMP_DISABLE_TRACKER PacketInputStream is( data, size ); // 可能是老报文,尝试由tracker模块处理 if (m_tracker->TryHandleResponse( is, remoteSockAddr, (BYTE)proxyType )) { m_trackerFlow.Download.Record(size); return true; } #endif } // 解混淆 int len = PacketObfuscator::UnObfuscate( reinterpret_cast<BYTE*>( data ), size ); if ( len <= 0 ) { // 解混淆失败,可能是vod的报文 if ( VODProxy::HandlePacket( data, size, remoteSockAddr, m_BootModule.get(), m_StunModule.get() ) ) { return true; } m_Statistics.TotalInvalidPackets++; if ( size >= 3 ) { VIEW_ERROR( "LiveAppModuleImpl::DispatchUdpPacket unshuffle failed 1 " << make_tuple( size, len ) << sockAddr << " action=" << strings::format( "0x%02X%02X 0x%02X", data[0], data[1], data[2] ) ); } else { VIEW_ERROR( "LiveAppModuleImpl::DispatchUdpPacket unshuffle failed 1 " << make_tuple( size, len ) << sockAddr ); } //LIVE_ASSERT( false ); return false; } if ( size < len ) { m_Statistics.TotalInvalidPackets++; VIEW_ERROR( "LiveAppModuleImpl::DispatchUdpPacket unshuffle failed 2 " << make_tuple( size, len ) << sockAddr ); return false; } // 截去混淆部分的头,取出真正的报文部分 data += len; size -= len; PacketInputStream is( data, size ); NEW_UDP_PACKET_HEAD head; is >> head; if ( !is ) { m_Statistics.TotalInvalidPackets++; VIEW_ERROR( "LiveAppModuleImpl::DispatchUdpPacket invalid 2 " << size << " " << sockAddr ); return false; } if ( head.ProtocolVersion < SYNACAST_VERSION_3 ) { m_Statistics.TotalInvalidPackets++; // 检查版本号与MAGIC APP_ERROR("Invalid protocol version " << head.ProtocolVersion << " " << sockAddr); return false; } UDPT_INFO("LiveAppModuleImpl::DispatchUdp "<<sockAddr << " " << (int)head.Action); // session 处理完 if ( head.Action & PPL_P2P_CONNECTION_ACTION_FLAG ) { UDP_SESSION_INFO sessionInfo; is >> sessionInfo; if ( !is ) { m_Statistics.TotalInvalidPackets++; APP_ERROR("Invalid session size " << size << " " << sockAddr); return false; } bool res = m_Manager->HandleUDPSessionPacket(is, head, sessionInfo, sockAddr); if ( false == res ) { m_Statistics.TotalInvalidPackets++; } else { m_Statistics.UDPConnectionFlow.Download.Record(totalDataSize); } return res; }
void PeerConnector::HandleNoDegree( data_input_stream& is, const PACKET_PEER_INFO& packetPeerInfo, bool isTCP ) { PPRedirectInfo redirectPacket; is >> redirectPacket; if ( !is ) return; VIEW_DEBUG("HandleNoDegree " << make_tuple( packetPeerInfo.Address, packetPeerInfo.OuterAddress ) << " " << redirectPacket.Peers.size() ); m_ipPool.AddConnectFailed(packetPeerInfo.OuterAddress, isTCP); PEER_CORE_INFO coreInfo; coreInfo.Clear(); for (UINT8 index = 0; index < redirectPacket.Peers.size(); ++index) { const REDIRECT_PEER_INFO& peer = redirectPacket.Peers[index]; //VIEW_INFO("Redirect " << peer.Address << " " << peer.Status.UploadBWLeft << " Qos=" << peer.Status.Qos << " DL=" << (int)peer.Status.DegreeLeft << " DO=" << peer.Status.OutDegree << " DI=" << peer.Status.InDegree << " SP=" << peer.Status.SkipPercent ); PEER_ADDRESS targetAddr ; if ( peer.OuterAddress.IP == m_NetInfo->GetOuterIP() ) // 外部IP相同,取内网IP连接,局域网连接 { targetAddr = peer.Address; } else if ( peer.OuterAddress.IsValid() ) // 外网地址可用,取外网地址 { targetAddr = peer.OuterAddress; } else // 没有外网地址可用,只好取内网地址 { targetAddr = peer.Address; } LIVE_ASSERT( targetAddr.IsValid() ); /* if ( false == peer.OuterAddress.IsValid() ) { // 如果OuterAddress无效(可能是还没有获取到外部ip和端口),使用内部地址代替 targetAddr = peer.Address; LIVE_ASSERT( false ); } else if ( peer.OuterAddress.IP == m_NetInfo->OuterAddress.IP ) { // 外部IP和我的外部IP相同,此peer跟我处于同一内网,使用内部地址连接 targetAddr = peer.Address; } else { targetAddr = peer.OuterAddress; } LIVE_ASSERT( 0 != targetAddr.UdpPort || 0 != targetAddr.TcpPort ); */ m_ipPool.AddCandidate(targetAddr, coreInfo, CANDIDATE_FROM_REDIRECT); // 检查剩余度是否不足 if ( m_PeerManager.GetDegreeLeft() < 0 ) return; // 检查出度是否已经过大 if ( m_PeerManager.GetStatistics().Degrees.All.Out + 3 > m_PeerManager.GetMaxLocalPeerCount() ) return; /// 检查pending连接是否已经过多 if ( IsBusy() ) return; PeerItem peerItem; peerItem.Init(); peerItem.CanDetect = true; peerItem.Info.Address = targetAddr; PeerConnectParam param(peerItem, false, m_PeerManager.GetConnectTimeout(), false); if ( targetAddr.TcpPort == 0 && targetAddr.UdpPort == 0 ) // 两个端口都没有,错误 { VIEW_ERROR( "PeerConnector::HandleNoDegree - targetAddr error. inner address: " << peer.Address << " outer address: " << peer.OuterAddress ); } else if ( targetAddr.TcpPort == 0 ) // 没有TCP端口 { this->ConnectUDP( targetAddr, param ); } else if ( targetAddr.UdpPort == 0 ) // 没有UDP端口,只能连接TCP { this->ConnectTCP( targetAddr, 0, param ); } else if (peer.ConnectionType == 0) // 两个端口都存在 { // tcp this->ConnectTCP( targetAddr, 0, param ); } else if ( peer.ConnectionType == 1 ) { // udp this->ConnectUDP( targetAddr, param ); } else { VIEW_ERROR( "PeerConnector::HandleNoDegree invalid peer connection type " << peer.ConnectionType << " " << make_tuple( peer.Address, peer.OuterAddress, targetAddr ) << " " << packetPeerInfo.OuterAddress ); } } }