1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- // Original author: ekr@rtfm.com
- #include <algorithm>
- #include <deque>
- #include <iostream>
- #include <limits>
- #include <map>
- #include <string>
- #include <vector>
- #include "sigslot.h"
- #include "logging.h"
- #include "nspr.h"
- #include "nss.h"
- #include "ssl.h"
- #include "mozilla/Preferences.h"
- #include "nsThreadUtils.h"
- #include "nsXPCOM.h"
- #include "nricectxhandler.h"
- #include "nricemediastream.h"
- #include "nriceresolverfake.h"
- #include "nriceresolver.h"
- #include "nrinterfaceprioritizer.h"
- #include "gtest_ringbuffer_dumper.h"
- #include "rlogconnector.h"
- #include "runnable_utils.h"
- #include "stunserver.h"
- #include "nr_socket_prsock.h"
- #include "test_nr_socket.h"
- #include "ice_ctx.h"
- #include "stun_socket_filter.h"
- #include "mozilla/net/DNS.h"
- #include "ice_ctx.h"
- #include "ice_peer_ctx.h"
- #include "ice_media_stream.h"
- extern "C" {
- #include "async_timer.h"
- #include "r_data.h"
- #include "util.h"
- #include "r_time.h"
- }
- #define GTEST_HAS_RTTI 0
- #include "gtest/gtest.h"
- #include "gtest_utils.h"
- using namespace mozilla;
- static unsigned int kDefaultTimeout = 7000;
- //TODO(nils@mozilla.com): This should get replaced with some non-external
- //solution like discussed in bug 860775.
- const std::string kDefaultStunServerHostname(
- (char *)"global.stun.twilio.com");
- const std::string kBogusStunServerHostname(
- (char *)"stun-server-nonexistent.invalid");
- const uint16_t kDefaultStunServerPort=3478;
- const std::string kBogusIceCandidate(
- (char *)"candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ");
- const std::string kUnreachableHostIceCandidate(
- (char *)"candidate:0 1 UDP 2113601790 192.168.178.20 50769 typ host");
- namespace {
- // DNS resolution helper code
- static std::string
- Resolve(const std::string& fqdn, int address_family)
- {
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = address_family;
- hints.ai_protocol = IPPROTO_UDP;
- struct addrinfo *res;
- int err = getaddrinfo(fqdn.c_str(), nullptr, &hints, &res);
- if (err) {
- std::cerr << "Error in getaddrinfo: " << err << std::endl;
- return "";
- }
- char str_addr[64] = {0};
- switch (res->ai_family) {
- case AF_INET:
- inet_ntop(
- AF_INET,
- &reinterpret_cast<struct sockaddr_in*>(res->ai_addr)->sin_addr,
- str_addr,
- sizeof(str_addr));
- break;
- case AF_INET6:
- inet_ntop(
- AF_INET6,
- &reinterpret_cast<struct sockaddr_in6*>(res->ai_addr)->sin6_addr,
- str_addr,
- sizeof(str_addr));
- break;
- default:
- std::cerr << "Got unexpected address family in DNS lookup: "
- << res->ai_family << std::endl;
- freeaddrinfo(res);
- return "";
- }
- if (!strlen(str_addr)) {
- std::cerr << "inet_ntop failed" << std::endl;
- }
- freeaddrinfo(res);
- return str_addr;
- }
- class StunTest : public MtransportTest {
- public:
- StunTest() : MtransportTest() {
- stun_server_hostname_ = kDefaultStunServerHostname;
- }
- void SetUp() override {
- MtransportTest::SetUp();
- // If only a STUN server FQDN was provided, look up its IP address for the
- // address-only tests.
- if (stun_server_address_.empty() && !stun_server_hostname_.empty()) {
- stun_server_address_ = Resolve(stun_server_hostname_, AF_INET);
- }
- // Make sure NrIceCtx is in a testable state.
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&NrIceCtx::internal_DeinitializeGlobal),
- NS_DISPATCH_SYNC);
- // NB: NrIceCtx::internal_DeinitializeGlobal destroys the RLogConnector
- // singleton.
- RLogConnector::CreateInstance();
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunServer::GetInstance, AF_INET),
- NS_DISPATCH_SYNC);
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunServer::GetInstance, AF_INET6),
- NS_DISPATCH_SYNC);
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
- NS_DISPATCH_SYNC);
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
- NS_DISPATCH_SYNC);
- }
- void TearDown() override {
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&NrIceCtx::internal_DeinitializeGlobal),
- NS_DISPATCH_SYNC);
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunServer::ShutdownInstance), NS_DISPATCH_SYNC);
- test_utils_->sts_target()->Dispatch(
- WrapRunnableNM(&TestStunTcpServer::ShutdownInstance), NS_DISPATCH_SYNC);
- RLogConnector::DestroyInstance();
- MtransportTest::TearDown();
- }
- };
- enum TrickleMode { TRICKLE_NONE, TRICKLE_SIMULATE, TRICKLE_REAL };
- enum ConsentStatus { CONSENT_FRESH, CONSENT_STALE, CONSENT_EXPIRED};
- const unsigned int ICE_TEST_PEER_OFFERER = (1 << 0);
- const unsigned int ICE_TEST_PEER_ALLOW_LOOPBACK = (1 << 1);
- const unsigned int ICE_TEST_PEER_ENABLED_TCP = (1 << 2);
- const unsigned int ICE_TEST_PEER_ALLOW_LINK_LOCAL = (1 << 3);
- typedef std::string (*CandidateFilter)(const std::string& candidate);
- std::vector<std::string> split(const std::string &s, char delim) {
- std::vector<std::string> elems;
- std::stringstream ss(s);
- std::string item;
- while (std::getline(ss, item, delim)) {
- elems.push_back(item);
- }
- return elems;
- }
- static std::string IsSrflxCandidate(const std::string& candidate) {
- std::vector<std::string> tokens = split(candidate, ' ');
- if ((tokens.at(6) == "typ") && (tokens.at(7) == "srflx")) {
- return candidate;
- }
- return std::string();
- }
- static std::string IsRelayCandidate(const std::string& candidate) {
- if (candidate.find("typ relay") != std::string::npos) {
- return candidate;
- }
- return std::string();
- }
- static std::string IsTcpCandidate(const std::string& candidate) {
- if (candidate.find("TCP") != std::string::npos) {
- return candidate;
- }
- return std::string();
- }
- static std::string IsTcpSoCandidate(const std::string& candidate) {
- if (candidate.find("tcptype so") != std::string::npos) {
- return candidate;
- }
- return std::string();
- }
- static std::string IsLoopbackCandidate(const std::string& candidate) {
- if (candidate.find("127.0.0.") != std::string::npos) {
- return candidate;
- }
- return std::string();
- }
- static std::string IsIpv4Candidate(const std::string& candidate) {
- std::vector<std::string> tokens = split(candidate, ' ');
- if (tokens.at(4).find(":") == std::string::npos) {
- return candidate;
- }
- return std::string();
- }
- static std::string SabotageHostCandidateAndDropReflexive(
- const std::string& candidate) {
- if (candidate.find("typ srflx") != std::string::npos) {
- return std::string();
- }
- if (candidate.find("typ host") != std::string::npos) {
- return kUnreachableHostIceCandidate;
- }
- return candidate;
- }
- bool ContainsSucceededPair(const std::vector<NrIceCandidatePair>& pairs) {
- for (size_t i = 0; i < pairs.size(); ++i) {
- if (pairs[i].state == NrIceCandidatePair::STATE_SUCCEEDED) {
- return true;
- }
- }
- return false;
- }
- // Note: Does not correspond to any notion of prioritization; this is just
- // so we can use stl containers/algorithms that need a comparator
- bool operator<(const NrIceCandidate& lhs,
- const NrIceCandidate& rhs) {
- if (lhs.cand_addr.host == rhs.cand_addr.host) {
- if (lhs.cand_addr.port == rhs.cand_addr.port) {
- if (lhs.cand_addr.transport == rhs.cand_addr.transport) {
- if (lhs.type == rhs.type) {
- return lhs.tcp_type < rhs.tcp_type;
- }
- return lhs.type < rhs.type;
- }
- return lhs.cand_addr.transport < rhs.cand_addr.transport;
- }
- return lhs.cand_addr.port < rhs.cand_addr.port;
- }
- return lhs.cand_addr.host < rhs.cand_addr.host;
- }
- bool operator==(const NrIceCandidate& lhs,
- const NrIceCandidate& rhs) {
- return !((lhs < rhs) || (rhs < lhs));
- }
- class IceCandidatePairCompare {
- public:
- bool operator()(const NrIceCandidatePair& lhs,
- const NrIceCandidatePair& rhs) const {
- if (lhs.priority == rhs.priority) {
- if (lhs.local == rhs.local) {
- if (lhs.remote == rhs.remote) {
- return lhs.codeword < rhs.codeword;
- }
- return lhs.remote < rhs.remote;
- }
- return lhs.local < rhs.local;
- }
- return lhs.priority < rhs.priority;
- }
- };
- class IceTestPeer;
- class SchedulableTrickleCandidate {
- public:
- SchedulableTrickleCandidate(IceTestPeer *peer,
- size_t stream,
- const std::string &candidate,
- MtransportTestUtils* utils) :
- peer_(peer),
- stream_(stream),
- candidate_(candidate),
- timer_handle_(nullptr),
- test_utils_(utils) {
- }
- ~SchedulableTrickleCandidate() {
- if (timer_handle_)
- NR_async_timer_cancel(timer_handle_);
- }
- void Schedule(unsigned int ms) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &SchedulableTrickleCandidate::Schedule_s, ms),
- NS_DISPATCH_SYNC);
- }
- void Schedule_s(unsigned int ms) {
- MOZ_ASSERT(!timer_handle_);
- NR_ASYNC_TIMER_SET(ms, Trickle_cb, this, &timer_handle_);
- }
- static void Trickle_cb(NR_SOCKET s, int how, void *cb_arg) {
- static_cast<SchedulableTrickleCandidate*>(cb_arg)->Trickle();
- }
- void Trickle();
- std::string& Candidate() {
- return candidate_;
- }
- const std::string& Candidate() const {
- return candidate_;
- }
- size_t Stream() const {
- return stream_;
- }
- bool IsHost() const {
- return candidate_.find("typ host") != std::string::npos;
- }
- bool IsReflexive() const {
- return candidate_.find("typ srflx") != std::string::npos;
- }
- bool IsRelay() const {
- return candidate_.find("typ relay") != std::string::npos;
- }
- private:
- IceTestPeer *peer_;
- size_t stream_;
- std::string candidate_;
- void *timer_handle_;
- MtransportTestUtils* test_utils_;
- DISALLOW_COPY_ASSIGN(SchedulableTrickleCandidate);
- };
- class IceTestPeer : public sigslot::has_slots<> {
- public:
- // TODO(ekr@rtfm.com): Convert to flags when NrIceCtx::Create() does.
- // Bug 1193437.
- IceTestPeer(const std::string& name, MtransportTestUtils* utils,
- bool offerer,
- bool allow_loopback = false, bool enable_tcp = true,
- bool allow_link_local = false,
- NrIceCtx::Policy ice_policy = NrIceCtx::ICE_POLICY_ALL) :
- name_(name),
- ice_ctx_(NrIceCtxHandler::Create(name, offerer, allow_loopback,
- enable_tcp, allow_link_local,
- ice_policy)),
- candidates_(),
- shutting_down_(false),
- gathering_complete_(false),
- ready_ct_(0),
- ice_connected_(false),
- ice_failed_(false),
- ice_reached_checking_(false),
- received_(0),
- sent_(0),
- fake_resolver_(),
- dns_resolver_(new NrIceResolver()),
- remote_(nullptr),
- candidate_filter_(nullptr),
- expected_local_type_(NrIceCandidate::ICE_HOST),
- expected_local_transport_(kNrIceTransportUdp),
- expected_remote_type_(NrIceCandidate::ICE_HOST),
- trickle_mode_(TRICKLE_NONE),
- trickled_(0),
- simulate_ice_lite_(false),
- nat_(new TestNat),
- test_utils_(utils) {
- ice_ctx_->ctx()->SignalGatheringStateChange.connect(
- this,
- &IceTestPeer::GatheringStateChange);
- ice_ctx_->ctx()->SignalConnectionStateChange.connect(
- this,
- &IceTestPeer::ConnectionStateChange);
- consent_timestamp_.tv_sec = 0;
- consent_timestamp_.tv_usec = 0;
- int r = ice_ctx_->ctx()->SetNat(nat_);
- (void)r;
- MOZ_ASSERT(!r);
- }
- ~IceTestPeer() {
- test_utils_->sts_target()->Dispatch(WrapRunnable(this,
- &IceTestPeer::Shutdown),
- NS_DISPATCH_SYNC);
- // Give the ICE destruction callback time to fire before
- // we destroy the resolver.
- PR_Sleep(1000);
- }
- void AddStream_s(int components) {
- char name[100];
- snprintf(name, sizeof(name), "%s:stream%d", name_.c_str(),
- (int)ice_ctx_->ctx()->GetStreamCount());
- RefPtr<NrIceMediaStream> stream =
- ice_ctx_->CreateStream(static_cast<char *>(name), components);
- ice_ctx_->ctx()->SetStream(ice_ctx_->ctx()->GetStreamCount(), stream);
- ASSERT_TRUE(stream);
- stream->SignalCandidate.connect(this, &IceTestPeer::CandidateInitialized);
- stream->SignalReady.connect(this, &IceTestPeer::StreamReady);
- stream->SignalFailed.connect(this, &IceTestPeer::StreamFailed);
- stream->SignalPacketReceived.connect(this, &IceTestPeer::PacketReceived);
- }
- void AddStream(int components)
- {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &IceTestPeer::AddStream_s, components),
- NS_DISPATCH_SYNC);
- }
- void RemoveStream_s(size_t index) {
- ice_ctx_->ctx()->SetStream(index, nullptr);
- }
- void RemoveStream(size_t index) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &IceTestPeer::RemoveStream_s, index),
- NS_DISPATCH_SYNC);
- }
- void SetStunServer(const std::string addr, uint16_t port,
- const char* transport = kNrIceTransportUdp) {
- if (addr.empty()) {
- // Happens when MOZ_DISABLE_NONLOCAL_CONNECTIONS is set
- return;
- }
- std::vector<NrIceStunServer> stun_servers;
- UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
- addr, port, transport));
- stun_servers.push_back(*server);
- SetStunServers(stun_servers);
- }
- void SetStunServers(const std::vector<NrIceStunServer> &servers) {
- ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetStunServers(servers)));
- }
- void UseTestStunServer() {
- SetStunServer(TestStunServer::GetInstance(AF_INET)->addr(),
- TestStunServer::GetInstance(AF_INET)->port());
- }
- void SetTurnServer(const std::string addr, uint16_t port,
- const std::string username,
- const std::string password,
- const char* transport) {
- std::vector<unsigned char> password_vec(password.begin(), password.end());
- SetTurnServer(addr, port, username, password_vec, transport);
- }
- void SetTurnServer(const std::string addr, uint16_t port,
- const std::string username,
- const std::vector<unsigned char> password,
- const char* transport) {
- std::vector<NrIceTurnServer> turn_servers;
- UniquePtr<NrIceTurnServer> server(NrIceTurnServer::Create(
- addr, port, username, password, transport));
- turn_servers.push_back(*server);
- ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetTurnServers(turn_servers)));
- }
- void SetTurnServers(const std::vector<NrIceTurnServer> servers) {
- ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetTurnServers(servers)));
- }
- void SetFakeResolver(const std::string& ip,
- const std::string& fqdn) {
- ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
- if (!ip.empty() && !fqdn.empty()) {
- PRNetAddr addr;
- PRStatus status = PR_StringToNetAddr(ip.c_str(), &addr);
- addr.inet.port = kDefaultStunServerPort;
- ASSERT_EQ(PR_SUCCESS, status);
- fake_resolver_.SetAddr(fqdn, addr);
- }
- ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetResolver(
- fake_resolver_.AllocateResolver())));
- }
- void SetDNSResolver() {
- ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
- ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetResolver(
- dns_resolver_->AllocateResolver())));
- }
- void Gather(bool default_route_only = false) {
- nsresult res;
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&res,
- ice_ctx_->ctx(),
- &NrIceCtx::StartGathering,
- default_route_only,
- false),
- NS_DISPATCH_SYNC);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- void UseNat() {
- nat_->enabled_ = true;
- }
- void SetTimerDivider(int div) {
- ice_ctx_->ctx()->internal_SetTimerAccelarator(div);
- }
- void SetStunResponseDelay(uint32_t delay) {
- nat_->delay_stun_resp_ms_ = delay;
- }
- void SetFilteringType(TestNat::NatBehavior type) {
- MOZ_ASSERT(!nat_->has_port_mappings());
- nat_->filtering_type_ = type;
- }
- void SetMappingType(TestNat::NatBehavior type) {
- MOZ_ASSERT(!nat_->has_port_mappings());
- nat_->mapping_type_ = type;
- }
- void SetBlockUdp(bool block) {
- MOZ_ASSERT(!nat_->has_port_mappings());
- nat_->block_udp_ = block;
- }
- void SetBlockStun(bool block) {
- nat_->block_stun_ = block;
- }
- // Get various pieces of state
- std::vector<std::string> GetGlobalAttributes() {
- std::vector<std::string> attrs(ice_ctx_->ctx()->GetGlobalAttributes());
- if (simulate_ice_lite_) {
- attrs.push_back("ice-lite");
- }
- return attrs;
- }
- std::vector<std::string> GetCandidates(size_t stream) {
- std::vector<std::string> v;
- RUN_ON_THREAD(
- test_utils_->sts_target(),
- WrapRunnableRet(&v, this, &IceTestPeer::GetCandidates_s, stream));
- return v;
- }
- std::string FilterCandidate(const std::string& candidate) {
- if (candidate_filter_) {
- return candidate_filter_(candidate);
- }
- return candidate;
- }
- std::vector<std::string> GetCandidates_s(size_t stream) {
- std::vector<std::string> candidates;
- if (stream >= ice_ctx_->ctx()->GetStreamCount() ||
- !ice_ctx_->ctx()->GetStream(stream)) {
- EXPECT_TRUE(false) << "No such stream " << stream;
- return candidates;
- }
- std::vector<std::string> candidates_in =
- ice_ctx_->ctx()->GetStream(stream)->GetCandidates();
- for (size_t i=0; i < candidates_in.size(); i++) {
- std::string candidate(FilterCandidate(candidates_in[i]));
- if (!candidate.empty()) {
- std::cerr << name_ << " Returning candidate: "
- << candidate << std::endl;
- candidates.push_back(candidate);
- }
- }
- return candidates;
- }
- void SetExpectedTypes(NrIceCandidate::Type local,
- NrIceCandidate::Type remote,
- std::string local_transport = kNrIceTransportUdp) {
- expected_local_type_ = local;
- expected_local_transport_ = local_transport;
- expected_remote_type_ = remote;
- }
- void SetExpectedRemoteCandidateAddr(const std::string& addr) {
- expected_remote_addr_ = addr;
- }
- int GetCandidatesPrivateIpv4Range(size_t stream) {
- std::vector<std::string> candidates = GetCandidates(stream);
- int host_net = 0;
- for (auto c : candidates) {
- if (c.find("typ host") != std::string::npos) {
- nr_transport_addr addr;
- std::vector<std::string> tokens = split(c, ' ');
- int r = nr_str_port_to_transport_addr(tokens.at(4).c_str(), 0, IPPROTO_UDP, &addr);
- MOZ_ASSERT(!r);
- if (!r && (addr.ip_version == NR_IPV4)) {
- int n = nr_transport_addr_get_private_addr_range(&addr);
- if (n) {
- if (host_net) {
- // TODO: add support for multiple private interfaces
- std::cerr << "This test doesn't support multiple private interfaces";
- return -1;
- }
- host_net = n;
- }
- }
- }
- }
- return host_net;
- }
- bool gathering_complete() { return gathering_complete_; }
- int ready_ct() { return ready_ct_; }
- bool is_ready_s(size_t stream) {
- RefPtr<NrIceMediaStream> media_stream = ice_ctx_->ctx()->GetStream(stream);
- if (!media_stream) {
- EXPECT_TRUE(false) << "No such stream " << stream;
- return false;
- }
- return media_stream->state() == NrIceMediaStream::ICE_OPEN;
- }
- bool is_ready(size_t stream)
- {
- bool result;
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&result, this, &IceTestPeer::is_ready_s, stream),
- NS_DISPATCH_SYNC);
- return result;
- }
- bool ice_connected() { return ice_connected_; }
- bool ice_failed() { return ice_failed_; }
- bool ice_reached_checking() { return ice_reached_checking_; }
- size_t received() { return received_; }
- size_t sent() { return sent_; }
- void RestartIce() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this,
- &IceTestPeer::RestartIce_s,
- ice_ctx_->CreateCtx()),
- NS_DISPATCH_SYNC);
- }
- void RestartIce_s(RefPtr<NrIceCtx> new_ctx) {
- ice_ctx_->BeginIceRestart(new_ctx);
- // set signals for the newly restarted ctx
- ice_ctx_->ctx()->SignalGatheringStateChange.connect(
- this,
- &IceTestPeer::GatheringStateChange);
- ice_ctx_->ctx()->SignalConnectionStateChange.connect(
- this,
- &IceTestPeer::ConnectionStateChange);
- // take care of some local bookkeeping
- ready_ct_ = 0;
- gathering_complete_ = false;
- ice_connected_ = false;
- ice_failed_ = false;
- ice_reached_checking_ = false;
- remote_ = nullptr;
- }
- void FinalizeIceRestart() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &IceTestPeer::FinalizeIceRestart_s),
- NS_DISPATCH_SYNC);
- }
- void FinalizeIceRestart_s() {
- ice_ctx_->FinalizeIceRestart();
- }
- void RollbackIceRestart() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &IceTestPeer::RollbackIceRestart_s),
- NS_DISPATCH_SYNC);
- }
- void RollbackIceRestart_s() {
- ice_ctx_->RollbackIceRestart();
- }
- // Start connecting to another peer
- void Connect_s(IceTestPeer *remote, TrickleMode trickle_mode,
- bool start = true) {
- nsresult res;
- remote_ = remote;
- trickle_mode_ = trickle_mode;
- ice_connected_ = false;
- ice_failed_ = false;
- ice_reached_checking_ = false;
- res = ice_ctx_->ctx()->ParseGlobalAttributes(remote->GetGlobalAttributes());
- ASSERT_TRUE(NS_SUCCEEDED(res));
- if (trickle_mode == TRICKLE_NONE ||
- trickle_mode == TRICKLE_REAL) {
- for (size_t i=0; i<ice_ctx_->ctx()->GetStreamCount(); ++i) {
- RefPtr<NrIceMediaStream> aStream = ice_ctx_->ctx()->GetStream(i);
- if (!aStream || aStream->HasParsedAttributes()) {
- continue;
- }
- std::vector<std::string> candidates =
- remote->GetCandidates(i);
- for (size_t j=0; j<candidates.size(); ++j) {
- std::cerr << name_ << " Adding remote candidate: " + candidates[j] << std::endl;
- }
- res = aStream->ParseAttributes(candidates);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- } else {
- // Parse empty attributes and then trickle them out later
- for (size_t i=0; i<ice_ctx_->ctx()->GetStreamCount(); ++i) {
- RefPtr<NrIceMediaStream> aStream = ice_ctx_->ctx()->GetStream(i);
- if (!aStream || aStream->HasParsedAttributes()) {
- continue;
- }
- std::vector<std::string> empty_attrs;
- std::cout << "Calling ParseAttributes on stream " << i << std::endl;
- res = aStream->ParseAttributes(empty_attrs);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- }
- if (start) {
- // Now start checks
- res = ice_ctx_->ctx()->StartChecks();
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- }
- void Connect(IceTestPeer *remote, TrickleMode trickle_mode,
- bool start = true) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(
- this, &IceTestPeer::Connect_s, remote, trickle_mode, start),
- NS_DISPATCH_SYNC);
- }
- void SimulateTrickle(size_t stream) {
- std::cerr << name_ << " Doing trickle for stream " << stream << std::endl;
- // If we are in trickle deferred mode, now trickle in the candidates
- // for |stream|
- // We should be safe here since stream changes happen on STS thread.
- ASSERT_GT(remote_->ice_ctx_->ctx()->GetStreamCount(), stream);
- ASSERT_TRUE(remote_->ice_ctx_->ctx()->GetStream(stream).get());
- std::vector<SchedulableTrickleCandidate*>& candidates =
- ControlTrickle(stream);
- for (auto i = candidates.begin(); i != candidates.end(); ++i) {
- (*i)->Schedule(0);
- }
- }
- // Allows test case to completely control when/if candidates are trickled
- // (test could also do things like insert extra trickle candidates, or
- // change existing ones, or insert duplicates, really anything is fair game)
- std::vector<SchedulableTrickleCandidate*>& ControlTrickle(size_t stream) {
- std::cerr << "Doing controlled trickle for stream " << stream << std::endl;
- std::vector<std::string> candidates =
- remote_->GetCandidates(stream);
- for (size_t j=0; j<candidates.size(); j++) {
- controlled_trickle_candidates_[stream].push_back(
- new SchedulableTrickleCandidate(
- this, stream, candidates[j], test_utils_));
- }
- return controlled_trickle_candidates_[stream];
- }
- nsresult TrickleCandidate_s(const std::string &candidate, size_t stream) {
- if (!ice_ctx_->ctx()->GetStream(stream)) {
- // stream might have gone away before the trickle timer popped
- return NS_OK;
- }
- return ice_ctx_->ctx()->GetStream(stream)->ParseTrickleCandidate(candidate);
- }
- void DumpCandidate(std::string which, const NrIceCandidate& cand) {
- std::string type;
- std::string tcp_type;
- std::string addr;
- int port;
- if (which.find("Remote") != std::string::npos) {
- addr = cand.cand_addr.host;
- port = cand.cand_addr.port;
- }
- else {
- addr = cand.local_addr.host;
- port = cand.local_addr.port;
- }
- switch(cand.type) {
- case NrIceCandidate::ICE_HOST:
- type = "host";
- break;
- case NrIceCandidate::ICE_SERVER_REFLEXIVE:
- type = "srflx";
- break;
- case NrIceCandidate::ICE_PEER_REFLEXIVE:
- type = "prflx";
- break;
- case NrIceCandidate::ICE_RELAYED:
- type = "relay";
- if (which.find("Local") != std::string::npos) {
- type += "(" + cand.local_addr.transport + ")";
- }
- break;
- default:
- FAIL();
- };
- switch(cand.tcp_type) {
- case NrIceCandidate::ICE_NONE:
- break;
- case NrIceCandidate::ICE_ACTIVE:
- tcp_type = " tcptype=active";
- break;
- case NrIceCandidate::ICE_PASSIVE:
- tcp_type = " tcptype=passive";
- break;
- case NrIceCandidate::ICE_SO:
- tcp_type = " tcptype=so";
- break;
- default:
- FAIL();
- };
- std::cerr << which
- << " --> "
- << type
- << " "
- << addr
- << ":"
- << port
- << "/"
- << cand.cand_addr.transport
- << tcp_type
- << " codeword="
- << cand.codeword
- << std::endl;
- }
- void DumpAndCheckActiveCandidates_s() {
- std::cerr << name_ << " Active candidates:" << std::endl;
- for (size_t i=0; i < ice_ctx_->ctx()->GetStreamCount(); ++i) {
- if (!ice_ctx_->ctx()->GetStream(i)) {
- continue;
- }
- for (size_t j=0; j < ice_ctx_->ctx()->GetStream(i)->components(); ++j) {
- std::cerr << name_ << " Stream " << i
- << " component " << j+1 << std::endl;
- UniquePtr<NrIceCandidate> local;
- UniquePtr<NrIceCandidate> remote;
- nsresult res = ice_ctx_->ctx()->GetStream(i)->GetActivePair(j+1,
- &local,
- &remote);
- if (res == NS_ERROR_NOT_AVAILABLE) {
- std::cerr << "Component unpaired or disabled." << std::endl;
- } else {
- ASSERT_TRUE(NS_SUCCEEDED(res));
- DumpCandidate("Local ", *local);
- /* Depending on timing, and the whims of the network
- * stack/configuration we're running on top of, prflx is always a
- * possibility. */
- if (expected_local_type_ == NrIceCandidate::ICE_HOST) {
- ASSERT_NE(NrIceCandidate::ICE_SERVER_REFLEXIVE, local->type);
- ASSERT_NE(NrIceCandidate::ICE_RELAYED, local->type);
- } else {
- ASSERT_EQ(expected_local_type_, local->type);
- }
- ASSERT_EQ(expected_local_transport_, local->local_addr.transport);
- DumpCandidate("Remote ", *remote);
- /* Depending on timing, and the whims of the network
- * stack/configuration we're running on top of, prflx is always a
- * possibility. */
- if (expected_remote_type_ == NrIceCandidate::ICE_HOST) {
- ASSERT_NE(NrIceCandidate::ICE_SERVER_REFLEXIVE, remote->type);
- ASSERT_NE(NrIceCandidate::ICE_RELAYED, remote->type);
- } else {
- ASSERT_EQ(expected_remote_type_, remote->type);
- }
- if (!expected_remote_addr_.empty()) {
- ASSERT_EQ(expected_remote_addr_, remote->cand_addr.host);
- }
- }
- }
- }
- }
- void DumpAndCheckActiveCandidates() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this, &IceTestPeer::DumpAndCheckActiveCandidates_s),
- NS_DISPATCH_SYNC);
- }
- void Close() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(ice_ctx_->ctx(), &NrIceCtx::destroy_peer_ctx),
- NS_DISPATCH_SYNC);
- }
- void Shutdown() {
- std::cerr << name_ << " Shutdown" << std::endl;
- shutting_down_ = true;
- for (auto s = controlled_trickle_candidates_.begin();
- s != controlled_trickle_candidates_.end();
- ++s) {
- for (auto cand = s->second.begin(); cand != s->second.end(); ++cand) {
- delete *cand;
- }
- }
- ice_ctx_ = nullptr;
- if (remote_) {
- remote_->UnsetRemote();
- remote_ = nullptr;
- }
- }
- void UnsetRemote()
- {
- remote_ = nullptr;
- }
- void StartChecks() {
- nsresult res;
- // Now start checks
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&res, ice_ctx_->ctx(), &NrIceCtx::StartChecks),
- NS_DISPATCH_SYNC);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- // Handle events
- void GatheringStateChange(NrIceCtx* ctx,
- NrIceCtx::GatheringState state) {
- if (shutting_down_) {
- return;
- }
- if (state != NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
- return;
- }
- std::cerr << name_ << " Gathering complete" << std::endl;
- gathering_complete_ = true;
- std::cerr << name_ << " CANDIDATES:" << std::endl;
- for (size_t i=0; i<ice_ctx_->ctx()->GetStreamCount(); ++i) {
- std::cerr << "Stream " << name_ << std::endl;
- if (!ice_ctx_->ctx()->GetStream(i)) {
- std::cerr << "DISABLED" << std::endl;
- continue;
- }
- std::vector<std::string> candidates =
- ice_ctx_->ctx()->GetStream(i)->GetCandidates();
- for(size_t j=0; j<candidates.size(); ++j) {
- std::cerr << candidates[j] << std::endl;
- }
- }
- std::cerr << std::endl;
- }
- void CandidateInitialized(NrIceMediaStream *stream, const std::string &raw_candidate) {
- std::string candidate(FilterCandidate(raw_candidate));
- if (candidate.empty()) {
- return;
- }
- std::cerr << "Candidate for stream " << stream->name() << " initialized: "
- << candidate << std::endl;
- candidates_[stream->name()].push_back(candidate);
- // If we are connected, then try to trickle to the other side.
- if (remote_ && remote_->remote_ && (trickle_mode_ != TRICKLE_SIMULATE)) {
- // first, find the index of the stream we've been given so
- // we can get the corresponding stream on the remote side
- for (size_t i=0; i<ice_ctx_->ctx()->GetStreamCount(); ++i) {
- if (ice_ctx_->ctx()->GetStream(i) == stream) {
- RefPtr<NrIceCtx> ctx = remote_->ice_ctx_->ctx();
- ASSERT_GT(ctx->GetStreamCount(), i);
- nsresult res = ctx->GetStream(i)->ParseTrickleCandidate(candidate);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- ++trickled_;
- return;
- }
- }
- ADD_FAILURE() << "No matching stream found for " << stream;
- }
- }
- nsresult GetCandidatePairs_s(size_t stream_index,
- std::vector<NrIceCandidatePair>* pairs)
- {
- MOZ_ASSERT(pairs);
- if (stream_index >= ice_ctx_->ctx()->GetStreamCount() ||
- !ice_ctx_->ctx()->GetStream(stream_index)) {
- // Is there a better error for "no such index"?
- ADD_FAILURE() << "No such media stream index: " << stream_index;
- return NS_ERROR_INVALID_ARG;
- }
- return ice_ctx_->ctx()->GetStream(stream_index)->GetCandidatePairs(pairs);
- }
- nsresult GetCandidatePairs(size_t stream_index,
- std::vector<NrIceCandidatePair>* pairs) {
- nsresult v;
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&v, this,
- &IceTestPeer::GetCandidatePairs_s,
- stream_index,
- pairs),
- NS_DISPATCH_SYNC);
- return v;
- }
- void DumpCandidatePair(const NrIceCandidatePair& pair) {
- std::cerr << std::endl;
- DumpCandidate("Local", pair.local);
- DumpCandidate("Remote", pair.remote);
- std::cerr << "state = " << pair.state
- << " priority = " << pair.priority
- << " nominated = " << pair.nominated
- << " selected = " << pair.selected
- << " codeword = " << pair.codeword << std::endl;
- }
- void DumpCandidatePairs_s(NrIceMediaStream *stream) {
- std::vector<NrIceCandidatePair> pairs;
- nsresult res = stream->GetCandidatePairs(&pairs);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- std::cerr << "Begin list of candidate pairs [" << std::endl;
- for (std::vector<NrIceCandidatePair>::iterator p = pairs.begin();
- p != pairs.end(); ++p) {
- DumpCandidatePair(*p);
- }
- std::cerr << "]" << std::endl;
- }
- void DumpCandidatePairs_s() {
- std::cerr << "Dumping candidate pairs for all streams [" << std::endl;
- for (size_t s = 0; s < ice_ctx_->ctx()->GetStreamCount(); ++s) {
- if (!ice_ctx_->ctx()->GetStream(s)) {
- continue;
- }
- DumpCandidatePairs_s(ice_ctx_->ctx()->GetStream(s).get());
- }
- std::cerr << "]" << std::endl;
- }
- bool CandidatePairsPriorityDescending(const std::vector<NrIceCandidatePair>&
- pairs) {
- // Verify that priority is descending
- uint64_t priority = std::numeric_limits<uint64_t>::max();
- for (size_t p = 0; p < pairs.size(); ++p) {
- if (priority < pairs[p].priority) {
- std::cerr << "Priority increased in subsequent pairs:" << std::endl;
- DumpCandidatePair(pairs[p-1]);
- DumpCandidatePair(pairs[p]);
- return false;
- } else if (priority == pairs[p].priority) {
- if (!IceCandidatePairCompare()(pairs[p], pairs[p-1]) &&
- !IceCandidatePairCompare()(pairs[p-1], pairs[p])) {
- std::cerr << "Ignoring identical pair from trigger check" << std::endl;
- } else {
- std::cerr << "Duplicate priority in subseqent pairs:" << std::endl;
- DumpCandidatePair(pairs[p-1]);
- DumpCandidatePair(pairs[p]);
- return false;
- }
- }
- priority = pairs[p].priority;
- }
- return true;
- }
- void UpdateAndValidateCandidatePairs(size_t stream_index,
- std::vector<NrIceCandidatePair>*
- new_pairs) {
- std::vector<NrIceCandidatePair> old_pairs = *new_pairs;
- GetCandidatePairs(stream_index, new_pairs);
- ASSERT_TRUE(CandidatePairsPriorityDescending(*new_pairs)) << "New list of "
- "candidate pairs is either not sorted in priority order, or has "
- "duplicate priorities.";
- ASSERT_TRUE(CandidatePairsPriorityDescending(old_pairs)) << "Old list of "
- "candidate pairs is either not sorted in priority order, or has "
- "duplicate priorities. This indicates some bug in the test case.";
- std::vector<NrIceCandidatePair> added_pairs;
- std::vector<NrIceCandidatePair> removed_pairs;
- // set_difference computes the set of elements that are present in the
- // first set, but not the second
- // NrIceCandidatePair::operator< compares based on the priority, local
- // candidate, and remote candidate in that order. This means this will
- // catch cases where the priority has remained the same, but one of the
- // candidates has changed.
- std::set_difference((*new_pairs).begin(),
- (*new_pairs).end(),
- old_pairs.begin(),
- old_pairs.end(),
- std::inserter(added_pairs, added_pairs.begin()),
- IceCandidatePairCompare());
- std::set_difference(old_pairs.begin(),
- old_pairs.end(),
- (*new_pairs).begin(),
- (*new_pairs).end(),
- std::inserter(removed_pairs, removed_pairs.begin()),
- IceCandidatePairCompare());
- for (std::vector<NrIceCandidatePair>::iterator a = added_pairs.begin();
- a != added_pairs.end(); ++a) {
- std::cerr << "Found new candidate pair." << std::endl;
- DumpCandidatePair(*a);
- }
- for (std::vector<NrIceCandidatePair>::iterator r = removed_pairs.begin();
- r != removed_pairs.end(); ++r) {
- std::cerr << "Pre-existing candidate pair is now missing:" << std::endl;
- DumpCandidatePair(*r);
- }
- ASSERT_TRUE(removed_pairs.empty()) << "At least one candidate pair has "
- "gone missing.";
- }
- void StreamReady(NrIceMediaStream *stream) {
- ++ready_ct_;
- std::cerr << name_ << " Stream ready for " << stream->name()
- << " ct=" << ready_ct_ << std::endl;
- DumpCandidatePairs_s(stream);
- }
- void StreamFailed(NrIceMediaStream *stream) {
- std::cerr << name_ << " Stream failed for " << stream->name()
- << " ct=" << ready_ct_ << std::endl;
- DumpCandidatePairs_s(stream);
- }
- void ConnectionStateChange(NrIceCtx* ctx,
- NrIceCtx::ConnectionState state) {
- (void)ctx;
- switch (state) {
- case NrIceCtx::ICE_CTX_INIT:
- break;
- case NrIceCtx::ICE_CTX_CHECKING:
- std::cerr << name_ << " ICE reached checking" << std::endl;
- ice_reached_checking_ = true;
- break;
- case NrIceCtx::ICE_CTX_CONNECTED:
- std::cerr << name_ << " ICE connected" << std::endl;
- ice_connected_ = true;
- break;
- case NrIceCtx::ICE_CTX_COMPLETED:
- std::cerr << name_ << " ICE completed" << std::endl;
- break;
- case NrIceCtx::ICE_CTX_FAILED:
- std::cerr << name_ << " ICE failed" << std::endl;
- ice_failed_ = true;
- break;
- case NrIceCtx::ICE_CTX_DISCONNECTED:
- std::cerr << name_ << " ICE disconnected" << std::endl;
- ice_connected_ = false;
- break;
- default:
- MOZ_CRASH();
- }
- }
- void PacketReceived(NrIceMediaStream *stream, int component, const unsigned char *data,
- int len) {
- std::cerr << name_ << ": received " << len << " bytes" << std::endl;
- ++received_;
- }
- void SendPacket(int stream, int component, const unsigned char *data,
- int len) {
- RefPtr<NrIceMediaStream> media_stream = ice_ctx_->ctx()->GetStream(stream);
- if (!media_stream) {
- ADD_FAILURE() << "No such stream " << stream;
- return;
- }
- ASSERT_TRUE(NS_SUCCEEDED(media_stream->SendPacket(component, data, len)));
- ++sent_;
- std::cerr << name_ << ": sent " << len << " bytes" << std::endl;
- }
- void SendFailure(int stream, int component) {
- RefPtr<NrIceMediaStream> media_stream = ice_ctx_->ctx()->GetStream(stream);
- if (!media_stream) {
- ADD_FAILURE() << "No such stream " << stream;
- return;
- }
- const std::string d("FAIL");
- ASSERT_TRUE(NS_FAILED(media_stream->SendPacket(component,
- reinterpret_cast<const unsigned char *>(d.c_str()), d.length())));
- std::cerr << name_ << ": send failed as expected" << std::endl;
- }
- void SetCandidateFilter(CandidateFilter filter) {
- candidate_filter_ = filter;
- }
- void ParseCandidate_s(size_t i, const std::string& candidate) {
- ASSERT_TRUE(ice_ctx_->ctx()->GetStream(i).get()) << "No such stream " << i;
- std::vector<std::string> attributes;
- attributes.push_back(candidate);
- ice_ctx_->ctx()->GetStream(i)->ParseAttributes(attributes);
- }
- void ParseCandidate(size_t i, const std::string& candidate)
- {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this,
- &IceTestPeer::ParseCandidate_s,
- i,
- candidate),
- NS_DISPATCH_SYNC);
- }
- void DisableComponent_s(size_t stream, int component_id) {
- ASSERT_LT(stream, ice_ctx_->ctx()->GetStreamCount());
- ASSERT_TRUE(ice_ctx_->ctx()->GetStream(stream).get()) << "No such stream "
- << stream;
- nsresult res =
- ice_ctx_->ctx()->GetStream(stream)->DisableComponent(component_id);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- void DisableComponent(size_t stream, int component_id)
- {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this,
- &IceTestPeer::DisableComponent_s,
- stream,
- component_id),
- NS_DISPATCH_SYNC);
- }
- void AssertConsentRefresh_s(size_t stream, int component_id, ConsentStatus status) {
- ASSERT_LT(stream, ice_ctx_->ctx()->GetStreamCount());
- ASSERT_TRUE(ice_ctx_->ctx()->GetStream(stream).get()) << "No such stream "
- << stream;
- bool can_send;
- struct timeval timestamp;
- nsresult res = ice_ctx_->ctx()->GetStream(stream)->
- GetConsentStatus(component_id, &can_send, ×tamp);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- if (status == CONSENT_EXPIRED) {
- ASSERT_EQ(can_send, 0);
- } else {
- ASSERT_EQ(can_send, 1);
- }
- if (consent_timestamp_.tv_sec) {
- if (status == CONSENT_FRESH) {
- ASSERT_EQ(r_timeval_cmp(×tamp, &consent_timestamp_), 1);
- } else {
- ASSERT_EQ(r_timeval_cmp(×tamp, &consent_timestamp_), 0);
- }
- }
- consent_timestamp_.tv_sec = timestamp.tv_sec;
- consent_timestamp_.tv_usec = timestamp.tv_usec;
- std::cerr << name_ << ": new consent timestamp = " <<
- consent_timestamp_.tv_sec << "." << consent_timestamp_.tv_usec <<
- std::endl;
- }
- void AssertConsentRefresh(ConsentStatus status) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this,
- &IceTestPeer::AssertConsentRefresh_s,
- 0,
- 1,
- status),
- NS_DISPATCH_SYNC);
- }
- int trickled() { return trickled_; }
- void SetControlling(NrIceCtx::Controlling controlling) {
- nsresult res;
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&res, ice_ctx_->ctx(),
- &NrIceCtx::SetControlling,
- controlling),
- NS_DISPATCH_SYNC);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- NrIceCtx::Controlling GetControlling() {
- return ice_ctx_->ctx()->GetControlling();
- }
- void SetTiebreaker(uint64_t tiebreaker) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(this,
- &IceTestPeer::SetTiebreaker_s,
- tiebreaker),
- NS_DISPATCH_SYNC);
- }
- void SetTiebreaker_s(uint64_t tiebreaker) {
- ice_ctx_->ctx()->peer()->tiebreaker = tiebreaker;
- }
- void SimulateIceLite() {
- simulate_ice_lite_ = true;
- SetControlling(NrIceCtx::ICE_CONTROLLED);
- }
- nsresult GetDefaultCandidate(unsigned int stream, NrIceCandidate* cand) {
- nsresult rv;
- test_utils_->sts_target()->Dispatch(
- WrapRunnableRet(&rv, this,
- &IceTestPeer::GetDefaultCandidate_s,
- stream, cand),
- NS_DISPATCH_SYNC);
- return rv;
- }
- nsresult GetDefaultCandidate_s(unsigned int stream, NrIceCandidate* cand) {
- return ice_ctx_->ctx()->GetStream(stream)->GetDefaultCandidate(1, cand);
- }
- private:
- std::string name_;
- RefPtr<NrIceCtxHandler> ice_ctx_;
- std::map<std::string, std::vector<std::string> > candidates_;
- // Maps from stream id to list of remote trickle candidates
- std::map<size_t, std::vector<SchedulableTrickleCandidate*> >
- controlled_trickle_candidates_;
- bool shutting_down_;
- bool gathering_complete_;
- int ready_ct_;
- bool ice_connected_;
- bool ice_failed_;
- bool ice_reached_checking_;
- size_t received_;
- size_t sent_;
- struct timeval consent_timestamp_;
- NrIceResolverFake fake_resolver_;
- RefPtr<NrIceResolver> dns_resolver_;
- IceTestPeer *remote_;
- CandidateFilter candidate_filter_;
- NrIceCandidate::Type expected_local_type_;
- std::string expected_local_transport_;
- NrIceCandidate::Type expected_remote_type_;
- std::string expected_remote_addr_;
- TrickleMode trickle_mode_;
- int trickled_;
- bool simulate_ice_lite_;
- RefPtr<mozilla::TestNat> nat_;
- MtransportTestUtils* test_utils_;
- };
- void SchedulableTrickleCandidate::Trickle() {
- timer_handle_ = nullptr;
- nsresult res = peer_->TrickleCandidate_s(candidate_, stream_);
- ASSERT_TRUE(NS_SUCCEEDED(res));
- }
- class WebRtcIceGatherTest : public StunTest {
- public:
- void SetUp() override {
- StunTest::SetUp();
- Preferences::SetInt("media.peerconnection.ice.tcp_so_sock_count", 3);
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(TestStunServer::GetInstance(AF_INET),
- &TestStunServer::Reset),
- NS_DISPATCH_SYNC);
- if (TestStunServer::GetInstance(AF_INET6)) {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(TestStunServer::GetInstance(AF_INET6),
- &TestStunServer::Reset),
- NS_DISPATCH_SYNC);
- }
- }
- void TearDown() override {
- peer_ = nullptr;
- StunTest::TearDown();
- }
- void EnsurePeer(const unsigned int flags = ICE_TEST_PEER_OFFERER) {
- if (!peer_) {
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_,
- flags & ICE_TEST_PEER_OFFERER,
- flags & ICE_TEST_PEER_ALLOW_LOOPBACK,
- flags & ICE_TEST_PEER_ENABLED_TCP,
- flags & ICE_TEST_PEER_ALLOW_LINK_LOCAL);
- peer_->AddStream(1);
- }
- }
- void Gather(unsigned int waitTime = kDefaultTimeout) {
- EnsurePeer();
- peer_->Gather();
- if (waitTime) {
- WaitForGather(waitTime);
- }
- }
- void WaitForGather(unsigned int waitTime = kDefaultTimeout) {
- ASSERT_TRUE_WAIT(peer_->gathering_complete(), waitTime);
- }
- void AddStunServerWithResponse(
- const std::string& fake_addr,
- uint16_t fake_port,
- const std::string& fqdn,
- const std::string& proto,
- std::vector<NrIceStunServer>* stun_servers) {
- int family;
- if (fake_addr.find(':') != std::string::npos) {
- family = AF_INET6;
- } else {
- family = AF_INET;
- }
- std::string stun_addr;
- uint16_t stun_port;
- if (proto == kNrIceTransportUdp) {
- TestStunServer::GetInstance(family)->SetResponseAddr(fake_addr,
- fake_port);
- stun_addr = TestStunServer::GetInstance(family)->addr();
- stun_port = TestStunServer::GetInstance(family)->port();
- } else if (proto == kNrIceTransportTcp) {
- TestStunTcpServer::GetInstance(family)->SetResponseAddr(fake_addr,
- fake_port);
- stun_addr = TestStunTcpServer::GetInstance(family)->addr();
- stun_port = TestStunTcpServer::GetInstance(family)->port();
- } else {
- MOZ_CRASH();
- }
- if (!fqdn.empty()) {
- peer_->SetFakeResolver(stun_addr, fqdn);
- stun_addr = fqdn;
- }
- stun_servers->push_back(*NrIceStunServer::Create(stun_addr,
- stun_port,
- proto.c_str()));
- }
- void UseFakeStunUdpServerWithResponse(
- const std::string& fake_addr,
- uint16_t fake_port,
- const std::string& fqdn = std::string()) {
- EnsurePeer();
- std::vector<NrIceStunServer> stun_servers;
- AddStunServerWithResponse(fake_addr, fake_port, fqdn, "udp", &stun_servers);
- peer_->SetStunServers(stun_servers);
- }
- void UseFakeStunTcpServerWithResponse(
- const std::string& fake_addr,
- uint16_t fake_port,
- const std::string& fqdn = std::string()) {
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- std::vector<NrIceStunServer> stun_servers;
- AddStunServerWithResponse(fake_addr, fake_port, fqdn, "tcp", &stun_servers);
- peer_->SetStunServers(stun_servers);
- }
- void UseFakeStunUdpTcpServersWithResponse(
- const std::string& fake_udp_addr,
- uint16_t fake_udp_port,
- const std::string& fake_tcp_addr,
- uint16_t fake_tcp_port) {
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- std::vector<NrIceStunServer> stun_servers;
- AddStunServerWithResponse(fake_udp_addr,
- fake_udp_port,
- "", // no fqdn
- "udp",
- &stun_servers);
- AddStunServerWithResponse(fake_tcp_addr,
- fake_tcp_port,
- "", // no fqdn
- "tcp",
- &stun_servers);
- peer_->SetStunServers(stun_servers);
- }
- void UseTestStunServer() {
- TestStunServer::GetInstance(AF_INET)->Reset();
- peer_->SetStunServer(TestStunServer::GetInstance(AF_INET)->addr(),
- TestStunServer::GetInstance(AF_INET)->port());
- }
- // NB: Only does substring matching, watch out for stuff like "1.2.3.4"
- // matching "21.2.3.47". " 1.2.3.4 " should not have false positives.
- bool StreamHasMatchingCandidate(unsigned int stream,
- const std::string& match,
- const std::string& match2 = "") {
- std::vector<std::string> candidates = peer_->GetCandidates(stream);
- for (size_t c = 0; c < candidates.size(); ++c) {
- if (std::string::npos != candidates[c].find(match)) {
- if (!match2.length() ||
- std::string::npos != candidates[c].find(match2)) {
- return true;
- }
- }
- }
- return false;
- }
- void DumpCandidates(unsigned int stream) {
- std::vector<std::string> candidates = peer_->GetCandidates(stream);
- std::cerr << "Candidates for stream " << stream << "->"
- << candidates.size() << std::endl;
- for (auto c : candidates) {
- std::cerr << "Candidate: " << c << std::endl;
- }
- }
- protected:
- mozilla::UniquePtr<IceTestPeer> peer_;
- };
- class WebRtcIceConnectTest : public StunTest {
- public:
- WebRtcIceConnectTest() :
- initted_(false),
- test_stun_server_inited_(false),
- use_nat_(false),
- filtering_type_(TestNat::ENDPOINT_INDEPENDENT),
- mapping_type_(TestNat::ENDPOINT_INDEPENDENT),
- block_udp_(false) {}
- void SetUp() override {
- StunTest::SetUp();
- nsresult rv;
- target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
- ASSERT_TRUE(NS_SUCCEEDED(rv));
- }
- void TearDown() override {
- p1_ = nullptr;
- p2_ = nullptr;
- StunTest::TearDown();
- }
- void AddStream(int components) {
- Init(false, false);
- p1_->AddStream(components);
- p2_->AddStream(components);
- }
- void RemoveStream(size_t index) {
- p1_->RemoveStream(index);
- p2_->RemoveStream(index);
- }
- void Init(bool allow_loopback,
- bool enable_tcp,
- bool setup_stun_servers = true,
- NrIceCtx::Policy ice_policy = NrIceCtx::ICE_POLICY_ALL) {
- if (initted_) {
- return;
- }
- p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, allow_loopback,
- enable_tcp, false, ice_policy);
- p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, allow_loopback,
- enable_tcp, false, ice_policy);
- InitPeer(p1_.get(), setup_stun_servers);
- InitPeer(p2_.get(), setup_stun_servers);
- initted_ = true;
- }
- void InitPeer(IceTestPeer* peer, bool setup_stun_servers = true) {
- if (use_nat_) {
- // If we enable nat simulation, but still use a real STUN server somewhere
- // on the internet, we will see failures if there is a real NAT in
- // addition to our simulated one, particularly if it disallows
- // hairpinning.
- if (setup_stun_servers) {
- InitTestStunServer();
- peer->UseTestStunServer();
- }
- peer->UseNat();
- peer->SetFilteringType(filtering_type_);
- peer->SetMappingType(mapping_type_);
- peer->SetBlockUdp(block_udp_);
- } else if (setup_stun_servers) {
- std::vector<NrIceStunServer> stun_servers;
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
- kDefaultStunServerPort, kNrIceTransportUdp));
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
- kDefaultStunServerPort, kNrIceTransportTcp));
- peer->SetStunServers(stun_servers);
- }
- }
- bool Gather(unsigned int waitTime = kDefaultTimeout,
- bool default_route_only = false) {
- Init(false, false);
- return GatherCallerAndCallee(p1_.get(),
- p2_.get(),
- waitTime,
- default_route_only);
- }
- bool GatherCallerAndCallee(IceTestPeer* caller,
- IceTestPeer* callee,
- unsigned int waitTime = kDefaultTimeout,
- bool default_route_only = false) {
- caller->Gather(default_route_only);
- callee->Gather(default_route_only);
- if (waitTime) {
- EXPECT_TRUE_WAIT(caller->gathering_complete(), waitTime);
- if (!caller->gathering_complete())
- return false;
- EXPECT_TRUE_WAIT(callee->gathering_complete(), waitTime);
- if (!callee->gathering_complete())
- return false;
- }
- return true;
- }
- void UseNat() {
- // to be useful, this method should be called before Init
- ASSERT_FALSE(initted_);
- use_nat_ = true;
- }
- void SetFilteringType(TestNat::NatBehavior type) {
- // to be useful, this method should be called before Init
- ASSERT_FALSE(initted_);
- filtering_type_ = type;
- }
- void SetMappingType(TestNat::NatBehavior type) {
- // to be useful, this method should be called before Init
- ASSERT_FALSE(initted_);
- mapping_type_ = type;
- }
- void BlockUdp() {
- // note: |block_udp_| is used only in InitPeer.
- // Use IceTestPeer::SetBlockUdp to act on the peer directly.
- block_udp_ = true;
- }
- void SetupAndCheckConsent() {
- p1_->SetTimerDivider(10);
- p2_->SetTimerDivider(10);
- ASSERT_TRUE(Gather());
- Connect();
- p1_->AssertConsentRefresh(CONSENT_FRESH);
- p2_->AssertConsentRefresh(CONSENT_FRESH);
- SendReceive();
- }
- void AssertConsentRefresh(ConsentStatus status = CONSENT_FRESH) {
- p1_->AssertConsentRefresh(status);
- p2_->AssertConsentRefresh(status);
- }
- void InitTestStunServer() {
- if (test_stun_server_inited_) {
- return;
- }
- std::cerr << "Resetting TestStunServer" << std::endl;
- TestStunServer::GetInstance(AF_INET)->Reset();
- test_stun_server_inited_ = true;
- }
- void UseTestStunServer() {
- InitTestStunServer();
- p1_->UseTestStunServer();
- p2_->UseTestStunServer();
- }
- void SetTurnServer(const std::string addr, uint16_t port,
- const std::string username,
- const std::string password,
- const char* transport = kNrIceTransportUdp) {
- p1_->SetTurnServer(addr, port, username, password, transport);
- p2_->SetTurnServer(addr, port, username, password, transport);
- }
- void SetTurnServers(const std::vector<NrIceTurnServer>& servers) {
- p1_->SetTurnServers(servers);
- p2_->SetTurnServers(servers);
- }
- void SetCandidateFilter(CandidateFilter filter, bool both=true) {
- p1_->SetCandidateFilter(filter);
- if (both) {
- p2_->SetCandidateFilter(filter);
- }
- }
- void Connect() {
- ConnectCallerAndCallee(p1_.get(), p2_.get());
- }
- void ConnectCallerAndCallee(IceTestPeer* caller, IceTestPeer* callee) {
- ASSERT_TRUE(caller->ready_ct() == 0);
- ASSERT_TRUE(caller->ice_connected() == 0);
- ASSERT_TRUE(caller->ice_reached_checking() == 0);
- ASSERT_TRUE(callee->ready_ct() == 0);
- ASSERT_TRUE(callee->ice_connected() == 0);
- ASSERT_TRUE(callee->ice_reached_checking() == 0);
- // IceTestPeer::Connect grabs attributes from the first arg, and
- // gives them to |this|, meaning that callee->Connect(caller, ...)
- // simulates caller sending an offer to callee. Order matters here
- // because it determines which peer is controlling.
- callee->Connect(caller, TRICKLE_NONE);
- caller->Connect(callee, TRICKLE_NONE);
- ASSERT_TRUE_WAIT(caller->ready_ct() == 1 && callee->ready_ct() == 1,
- kDefaultTimeout);
- ASSERT_TRUE_WAIT(caller->ice_connected() && callee->ice_connected(),
- kDefaultTimeout);
- ASSERT_TRUE(caller->ice_reached_checking());
- ASSERT_TRUE(callee->ice_reached_checking());
- caller->DumpAndCheckActiveCandidates();
- callee->DumpAndCheckActiveCandidates();
- }
- void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote,
- std::string transport = kNrIceTransportUdp) {
- p1_->SetExpectedTypes(local, remote, transport);
- p2_->SetExpectedTypes(local, remote, transport);
- }
- void SetExpectedTypes(NrIceCandidate::Type local1, NrIceCandidate::Type remote1,
- NrIceCandidate::Type local2, NrIceCandidate::Type remote2) {
- p1_->SetExpectedTypes(local1, remote1);
- p2_->SetExpectedTypes(local2, remote2);
- }
- void SetExpectedRemoteCandidateAddr(const std::string& addr) {
- p1_->SetExpectedRemoteCandidateAddr(addr);
- p2_->SetExpectedRemoteCandidateAddr(addr);
- }
- void ConnectP1(TrickleMode mode = TRICKLE_NONE) {
- p1_->Connect(p2_.get(), mode);
- }
- void ConnectP2(TrickleMode mode = TRICKLE_NONE) {
- p2_->Connect(p1_.get(), mode);
- }
- void WaitForConnectedStreams(int expected_streams = 1) {
- ASSERT_TRUE_WAIT(p1_->ready_ct() == expected_streams &&
- p2_->ready_ct() == expected_streams, kDefaultTimeout);
- ASSERT_TRUE_WAIT(p1_->ice_connected() && p2_->ice_connected(),
- kDefaultTimeout);
- }
- void AssertCheckingReached() {
- ASSERT_TRUE(p1_->ice_reached_checking());
- ASSERT_TRUE(p2_->ice_reached_checking());
- }
- void WaitForConnected(unsigned int timeout = kDefaultTimeout) {
- ASSERT_TRUE_WAIT(p1_->ice_connected(), timeout);
- ASSERT_TRUE_WAIT(p2_->ice_connected(), timeout);
- }
- void WaitForGather() {
- ASSERT_TRUE_WAIT(p1_->gathering_complete(), kDefaultTimeout);
- ASSERT_TRUE_WAIT(p2_->gathering_complete(), kDefaultTimeout);
- }
- void WaitForDisconnected(unsigned int timeout = kDefaultTimeout) {
- ASSERT_TRUE(p1_->ice_connected());
- ASSERT_TRUE(p2_->ice_connected());
- ASSERT_TRUE_WAIT(p1_->ice_connected() == 0 &&
- p2_->ice_connected() == 0,
- timeout);
- }
- void WaitForFailed(unsigned int timeout = kDefaultTimeout) {
- ASSERT_TRUE_WAIT(p1_->ice_failed() &&
- p2_->ice_failed(),
- timeout);
- }
- void ConnectTrickle(TrickleMode trickle = TRICKLE_SIMULATE) {
- p2_->Connect(p1_.get(), trickle);
- p1_->Connect(p2_.get(), trickle);
- }
- void SimulateTrickle(size_t stream) {
- p1_->SimulateTrickle(stream);
- p2_->SimulateTrickle(stream);
- ASSERT_TRUE_WAIT(p1_->is_ready(stream), kDefaultTimeout);
- ASSERT_TRUE_WAIT(p2_->is_ready(stream), kDefaultTimeout);
- }
- void SimulateTrickleP1(size_t stream) {
- p1_->SimulateTrickle(stream);
- }
- void SimulateTrickleP2(size_t stream) {
- p2_->SimulateTrickle(stream);
- }
- void CloseP1() {
- p1_->Close();
- }
- void ConnectThenDelete() {
- p2_->Connect(p1_.get(), TRICKLE_NONE, false);
- p1_->Connect(p2_.get(), TRICKLE_NONE, true);
- test_utils_->sts_target()->Dispatch(WrapRunnable(this,
- &WebRtcIceConnectTest::CloseP1),
- NS_DISPATCH_SYNC);
- p2_->StartChecks();
- // Wait to see if we crash
- PR_Sleep(PR_MillisecondsToInterval(kDefaultTimeout));
- }
- // default is p1_ sending to p2_
- void SendReceive() {
- SendReceive(p1_.get(), p2_.get());
- }
- void SendReceive(IceTestPeer *p1, IceTestPeer *p2,
- bool expect_tx_failure = false,
- bool expect_rx_failure = false) {
- size_t previousSent = p1->sent();
- size_t previousReceived = p2->received();
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(p1,
- &IceTestPeer::SendPacket, 0, 1,
- reinterpret_cast<const unsigned char *>("TEST"), 4),
- NS_DISPATCH_SYNC);
- if (expect_tx_failure) {
- ASSERT_EQ(previousSent, p1->sent());
- } else {
- ASSERT_EQ(previousSent+1, p1->sent());
- }
- if (expect_rx_failure) {
- usleep(1000);
- ASSERT_EQ(previousReceived, p2->received());
- } else {
- ASSERT_TRUE_WAIT(p2->received() == previousReceived+1, 1000);
- }
- }
- void SendFailure() {
- test_utils_->sts_target()->Dispatch(
- WrapRunnable(p1_.get(),
- &IceTestPeer::SendFailure, 0, 1),
- NS_DISPATCH_SYNC);
- }
- protected:
- bool initted_;
- bool test_stun_server_inited_;
- nsCOMPtr<nsIEventTarget> target_;
- mozilla::UniquePtr<IceTestPeer> p1_;
- mozilla::UniquePtr<IceTestPeer> p2_;
- bool use_nat_;
- TestNat::NatBehavior filtering_type_;
- TestNat::NatBehavior mapping_type_;
- bool block_udp_;
- };
- class WebRtcIcePrioritizerTest : public StunTest {
- public:
- WebRtcIcePrioritizerTest():
- prioritizer_(nullptr) {}
- ~WebRtcIcePrioritizerTest() {
- if (prioritizer_) {
- nr_interface_prioritizer_destroy(&prioritizer_);
- }
- }
- void SetPriorizer(nr_interface_prioritizer *prioritizer) {
- prioritizer_ = prioritizer;
- }
- void AddInterface(const std::string& num, int type, int estimated_speed) {
- std::string str_addr = "10.0.0." + num;
- std::string ifname = "eth" + num;
- nr_local_addr local_addr;
- local_addr.interface.type = type;
- local_addr.interface.estimated_speed = estimated_speed;
- int r = nr_str_port_to_transport_addr(str_addr.c_str(), 0,
- IPPROTO_UDP, &(local_addr.addr));
- ASSERT_EQ(0, r);
- strncpy(local_addr.addr.ifname, ifname.c_str(), MAXIFNAME);
- r = nr_interface_prioritizer_add_interface(prioritizer_, &local_addr);
- ASSERT_EQ(0, r);
- r = nr_interface_prioritizer_sort_preference(prioritizer_);
- ASSERT_EQ(0, r);
- }
- void HasLowerPreference(const std::string& num1, const std::string& num2) {
- std::string key1 = "eth" + num1 + ":10.0.0." + num1;
- std::string key2 = "eth" + num2 + ":10.0.0." + num2;
- UCHAR pref1, pref2;
- int r = nr_interface_prioritizer_get_priority(prioritizer_, key1.c_str(), &pref1);
- ASSERT_EQ(0, r);
- r = nr_interface_prioritizer_get_priority(prioritizer_, key2.c_str(), &pref2);
- ASSERT_EQ(0, r);
- ASSERT_LE(pref1, pref2);
- }
- private:
- nr_interface_prioritizer *prioritizer_;
- };
- class WebRtcIcePacketFilterTest : public StunTest {
- public:
- WebRtcIcePacketFilterTest(): udp_filter_(nullptr),
- tcp_filter_(nullptr) {}
- void SetUp() {
- StunTest::SetUp();
- // Set up enough of the ICE ctx to allow the packet filter to work
- ice_ctx_ = NrIceCtxHandler::Create("test", true);
- nsCOMPtr<nsISocketFilterHandler> udp_handler =
- do_GetService(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID);
- ASSERT_TRUE(udp_handler);
- udp_handler->NewFilter(getter_AddRefs(udp_filter_));
- nsCOMPtr<nsISocketFilterHandler> tcp_handler =
- do_GetService(NS_STUN_TCP_SOCKET_FILTER_HANDLER_CONTRACTID);
- ASSERT_TRUE(tcp_handler);
- tcp_handler->NewFilter(getter_AddRefs(tcp_filter_));
- }
- void TearDown() {
- test_utils_->sts_target()->Dispatch(WrapRunnable(this,
- &WebRtcIcePacketFilterTest::TearDown_s),
- NS_DISPATCH_SYNC);
- StunTest::TearDown();
- }
- void TearDown_s() {
- ice_ctx_ = nullptr;
- }
- void TestIncoming(const uint8_t* data, uint32_t len,
- uint8_t from_addr, int from_port,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- MakeNetAddr(&addr, from_addr, from_port);
- bool result;
- nsresult rv = udp_filter_->FilterPacket(&addr, data, len,
- nsISocketFilter::SF_INCOMING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- }
- void TestIncomingTcp(const uint8_t* data, uint32_t len,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- bool result;
- nsresult rv = tcp_filter_->FilterPacket(&addr, data, len,
- nsISocketFilter::SF_INCOMING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- }
- void TestIncomingTcpFramed(const uint8_t* data, uint32_t len,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- bool result;
- uint8_t* framed_data = new uint8_t[len+2];
- framed_data[0] = htons(len);
- memcpy(&framed_data[2], data, len);
- nsresult rv = tcp_filter_->FilterPacket(&addr, framed_data, len+2,
- nsISocketFilter::SF_INCOMING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- delete[] framed_data;
- }
- void TestOutgoing(const uint8_t* data, uint32_t len,
- uint8_t to_addr, int to_port,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- MakeNetAddr(&addr, to_addr, to_port);
- bool result;
- nsresult rv = udp_filter_->FilterPacket(&addr, data, len,
- nsISocketFilter::SF_OUTGOING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- }
- void TestOutgoingTcp(const uint8_t* data, uint32_t len,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- bool result;
- nsresult rv = tcp_filter_->FilterPacket(&addr, data, len,
- nsISocketFilter::SF_OUTGOING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- }
- void TestOutgoingTcpFramed(const uint8_t* data, uint32_t len,
- bool expected_result) {
- mozilla::net::NetAddr addr;
- bool result;
- uint8_t* framed_data = new uint8_t[len+2];
- framed_data[0] = htons(len);
- memcpy(&framed_data[2], data, len);
- nsresult rv = tcp_filter_->FilterPacket(&addr, framed_data, len+2,
- nsISocketFilter::SF_OUTGOING,
- &result);
- ASSERT_EQ(NS_OK, rv);
- ASSERT_EQ(expected_result, result);
- delete[] framed_data;
- }
- private:
- void MakeNetAddr(mozilla::net::NetAddr* net_addr,
- uint8_t last_digit, uint16_t port) {
- net_addr->inet.family = AF_INET;
- net_addr->inet.ip = 192 << 24 | 168 << 16 | 1 << 8 | last_digit;
- net_addr->inet.port = port;
- }
- nsCOMPtr<nsISocketFilter> udp_filter_;
- nsCOMPtr<nsISocketFilter> tcp_filter_;
- RefPtr<NrIceCtxHandler> ice_ctx_;
- };
- } // end namespace
- TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
- kNrIceTransportTcp);
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerIpAddress) {
- if (stun_server_address_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
- peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherStunServerIpAddressNoHost) {
- if (stun_server_address_.empty()) {
- return;
- }
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- peer_->AddStream(1);
- peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
- peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
- Gather();
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " host "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostname) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
- peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherFakeStunBogusHostname) {
- EnsurePeer();
- peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
- peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddress) {
- if (stun_server_address_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
- if (stun_server_address_.empty()) {
- return;
- }
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort,
- kNrIceTransportTcp);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostname) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameTcp) {
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
- kNrIceTransportTcp);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- std::vector<NrIceStunServer> stun_servers;
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_hostname_,
- kDefaultStunServerPort, kNrIceTransportUdp));
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_hostname_,
- kDefaultStunServerPort, kNrIceTransportTcp));
- peer_->SetStunServers(stun_servers);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
- if (stun_server_address_.empty()) {
- return;
- }
- std::vector<NrIceStunServer> stun_servers;
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
- kDefaultStunServerPort, kNrIceTransportUdp));
- stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
- kDefaultStunServerPort, kNrIceTransportTcp));
- peer_->SetStunServers(stun_servers);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostname) {
- EnsurePeer();
- peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostnameTcp) {
- EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
- peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort,
- kNrIceTransportTcp);
- peer_->SetDNSResolver();
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
- }
- TEST_F(WebRtcIceGatherTest, TestDefaultCandidate) {
- EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
- Gather();
- NrIceCandidate default_candidate;
- ASSERT_TRUE(NS_SUCCEEDED(peer_->GetDefaultCandidate(0, &default_candidate)));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherTurn) {
- EnsurePeer();
- if (turn_server_.empty())
- return;
- peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_, kNrIceTransportUdp);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherTurnTcp) {
- EnsurePeer();
- if (turn_server_.empty())
- return;
- peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_, kNrIceTransportTcp);
- Gather();
- }
- TEST_F(WebRtcIceGatherTest, TestGatherDisableComponent) {
- if (stun_server_hostname_.empty()) {
- return;
- }
- EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
- peer_->AddStream(2);
- peer_->DisableComponent(1, 2);
- Gather();
- std::vector<std::string> candidates =
- peer_->GetCandidates(1);
- for (size_t i=0; i<candidates.size(); ++i) {
- size_t sp1 = candidates[i].find(' ');
- ASSERT_EQ(0, candidates[i].compare(sp1+1, 1, "1", 1));
- }
- }
- TEST_F(WebRtcIceGatherTest, TestGatherVerifyNoLoopback) {
- Gather();
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "127.0.0.1"));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherAllowLoopback) {
- // Set up peer with loopback allowed.
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, true);
- peer_->AddStream(1);
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "127.0.0.1"));
- }
- TEST_F(WebRtcIceGatherTest, TestGatherTcpDisabled) {
- // Set up peer with tcp disabled.
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false);
- peer_->AddStream(1);
- Gather();
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " TCP "));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
- }
- // Verify that a bogus candidate doesn't cause crashes on the
- // main thread. See bug 856433.
- TEST_F(WebRtcIceGatherTest, TestBogusCandidate) {
- Gather();
- peer_->ParseCandidate(0, kBogusIceCandidate);
- }
- TEST_F(WebRtcIceGatherTest, VerifyTestStunServer) {
- UseFakeStunUdpServerWithResponse("192.0.2.133", 3333);
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
- }
- TEST_F(WebRtcIceGatherTest, VerifyTestStunTcpServer) {
- UseFakeStunTcpServerWithResponse("192.0.2.233", 3333);
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.233 3333 typ srflx",
- " tcptype "));
- }
- TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6) {
- if (!TestStunServer::GetInstance(AF_INET6)) {
- // No V6 addresses
- return;
- }
- UseFakeStunUdpServerWithResponse("beef::", 3333);
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
- }
- TEST_F(WebRtcIceGatherTest, VerifyTestStunServerFQDN) {
- UseFakeStunUdpServerWithResponse("192.0.2.133", 3333, "stun.example.com");
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
- }
- TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6FQDN) {
- if (!TestStunServer::GetInstance(AF_INET6)) {
- // No V6 addresses
- return;
- }
- UseFakeStunUdpServerWithResponse("beef::", 3333, "stun.example.com");
- Gather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddr) {
- UseFakeStunUdpServerWithResponse("0.0.0.0", 3333);
- Gather(kDefaultTimeout * 3);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " 0.0.0.0 "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddrV6) {
- if (!TestStunServer::GetInstance(AF_INET6)) {
- // No V6 addresses
- return;
- }
- UseFakeStunUdpServerWithResponse("::", 3333);
- Gather(kDefaultTimeout * 3);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " :: "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerReturnsPort0) {
- UseFakeStunUdpServerWithResponse("192.0.2.133", 0);
- Gather(kDefaultTimeout * 3);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.2.133 0 "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddr) {
- UseFakeStunUdpServerWithResponse("127.0.0.133", 3333);
- Gather(kDefaultTimeout * 3);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " 127.0.0.133 "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
- if (!TestStunServer::GetInstance(AF_INET6)) {
- // No V6 addresses
- return;
- }
- UseFakeStunUdpServerWithResponse("::1", 3333);
- Gather(kDefaultTimeout * 3);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " ::1 "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunServerTrickle) {
- UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
- TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
- Gather(0);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1"));
- WaitForGather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1"));
- }
- // Test no host with our fake STUN server and apparently NATted.
- TEST_F(WebRtcIceGatherTest, TestFakeStunServerNatedNoHost) {
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- peer_->AddStream(1);
- UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
- Gather(0);
- WaitForGather();
- DumpCandidates(0);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
- NrIceCandidate default_candidate;
- nsresult rv = peer_->GetDefaultCandidate(0, &default_candidate);
- if (NS_SUCCEEDED(rv)) {
- ASSERT_NE(NrIceCandidate::ICE_HOST, default_candidate.type);
- }
- }
- // Test no host with our fake STUN server and apparently non-NATted.
- TEST_F(WebRtcIceGatherTest, TestFakeStunServerNoNatNoHost) {
- peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- peer_->AddStream(1);
- UseTestStunServer();
- Gather(0);
- WaitForGather();
- DumpCandidates(0);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
- }
- TEST_F(WebRtcIceGatherTest, TestStunTcpServerTrickle) {
- UseFakeStunTcpServerWithResponse("192.0.3.1", 3333);
- TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
- Gather(0);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
- WaitForGather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
- }
- TEST_F(WebRtcIceGatherTest, TestStunTcpAndUdpServerTrickle) {
- UseFakeStunUdpTcpServersWithResponse("192.0.2.1", 3333, "192.0.3.1", 3333);
- TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
- TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
- Gather(0);
- ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
- ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
- WaitForGather();
- ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
- ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
- }
- TEST_F(WebRtcIceGatherTest, TestSetIceControlling) {
- EnsurePeer();
- peer_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- NrIceCtx::Controlling controlling = peer_->GetControlling();
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, controlling);
- // SetControlling should only allow setting this once
- peer_->SetControlling(NrIceCtx::ICE_CONTROLLED);
- controlling = peer_->GetControlling();
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, controlling);
- }
- TEST_F(WebRtcIceGatherTest, TestSetIceControlled) {
- EnsurePeer();
- peer_->SetControlling(NrIceCtx::ICE_CONTROLLED);
- NrIceCtx::Controlling controlling = peer_->GetControlling();
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, controlling);
- // SetControlling should only allow setting this once
- peer_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- controlling = peer_->GetControlling();
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, controlling);
- }
- TEST_F(WebRtcIceConnectTest, TestGather) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestGatherTcp) {
- Init(false, true);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestGatherAutoPrioritize) {
- Init(false, false);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestConnect) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectRestartIce) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- SendReceive(p1_.get(), p2_.get());
- p2_->RestartIce();
- ASSERT_FALSE(p2_->gathering_complete());
- // verify p1 and p2 streams are still connected after restarting ice on p2
- SendReceive(p1_.get(), p2_.get());
- mozilla::UniquePtr<IceTestPeer> p3_;
- p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
- InitPeer(p3_.get());
- p3_->AddStream(1);
- p2_->AddStream(1);
- ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
- std::cout << "-------------------------------------------------" << std::endl;
- ConnectCallerAndCallee(p3_.get(), p2_.get());
- SendReceive(p1_.get(), p2_.get()); // p1 and p2 still connected
- SendReceive(p3_.get(), p2_.get()); // p3 and p2 are now connected
- p2_->FinalizeIceRestart();
- SendReceive(p3_.get(), p2_.get()); // p3 and p2 are still connected
- SendReceive(p1_.get(), p2_.get(), false, true); // p1 and p2 not connected
- p3_ = nullptr;
- }
- TEST_F(WebRtcIceConnectTest, TestConnectRestartIceThenAbort) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- SendReceive(p1_.get(), p2_.get());
- p2_->RestartIce();
- ASSERT_FALSE(p2_->gathering_complete());
- // verify p1 and p2 streams are still connected after restarting ice on p2
- SendReceive(p1_.get(), p2_.get());
- mozilla::UniquePtr<IceTestPeer> p3_;
- p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
- InitPeer(p3_.get());
- p3_->AddStream(1);
- p2_->AddStream(1);
- ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
- std::cout << "-------------------------------------------------" << std::endl;
- ConnectCallerAndCallee(p3_.get(), p2_.get());
- SendReceive(p1_.get(), p2_.get()); // p1 and p2 still connected
- SendReceive(p3_.get(), p2_.get()); // p3 and p2 are now connected
- p2_->RollbackIceRestart();
- SendReceive(p1_.get(), p2_.get()); // p1 and p2 are still connected
- SendReceive(p3_.get(), p2_.get(), false, true); // p3 and p2 not connected
- p3_ = nullptr;
- }
- TEST_F(WebRtcIceConnectTest, TestConnectSetControllingAfterIceRestart) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- // Just for fun lets do this with switched rolls
- p1_->SetControlling(NrIceCtx::ICE_CONTROLLED);
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- Connect();
- SendReceive(p1_.get(), p2_.get());
- // Set rolls should not switch by connecting
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p1_->GetControlling());
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p2_->GetControlling());
- p2_->RestartIce();
- ASSERT_FALSE(p2_->gathering_complete());
- // ICE restart should allow us to set control role again
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLED);
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
- // But still only allowed to set control role once
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
- mozilla::UniquePtr<IceTestPeer> p3_;
- p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
- InitPeer(p3_.get());
- p3_->AddStream(1);
- // Set control role for p3 accordingly (w/o role conflict)
- p3_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
- p2_->AddStream(1);
- ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
- std::cout << "-------------------------------------------------" << std::endl;
- ConnectCallerAndCallee(p3_.get(), p2_.get());
- // Again connecting should not result in role switch
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
- p2_->FinalizeIceRestart();
- // And again we are not allowed to switch roles at this point any more
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
- p3_->SetControlling(NrIceCtx::ICE_CONTROLLED);
- ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
- p3_ = nullptr;
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTcp) {
- Init(false, true);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsTcpCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
- Connect();
- }
- //TCP SO tests works on localhost only with delay applied:
- // tc qdisc add dev lo root netem delay 10ms
- TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectTcpSo) {
- Init(false, true);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsTcpSoCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
- Connect();
- }
- // Disabled because this breaks with hairpinning.
- TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectNoHost) {
- Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE, kNrIceTransportTcp);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestLoopbackOnlySortOf) {
- Init(true, false, false);
- AddStream(1);
- SetCandidateFilter(IsLoopbackCandidate);
- ASSERT_TRUE(Gather());
- SetExpectedRemoteCandidateAddr("127.0.0.1");
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP1Wins) {
- AddStream(1);
- p1_->SetTiebreaker(1);
- p2_->SetTiebreaker(0);
- ASSERT_TRUE(Gather());
- p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP2Wins) {
- AddStream(1);
- p1_->SetTiebreaker(0);
- p2_->SetTiebreaker(1);
- ASSERT_TRUE(Gather());
- p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectIceLiteOfferer) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- p1_->SimulateIceLite();
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP1Wins) {
- AddStream(1);
- p1_->SetTiebreaker(1);
- p2_->SetTiebreaker(0);
- ASSERT_TRUE(Gather());
- p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- ConnectTrickle();
- SimulateTrickle(0);
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP2Wins) {
- AddStream(1);
- p1_->SetTiebreaker(0);
- p2_->SetTiebreaker(1);
- ASSERT_TRUE(Gather());
- p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
- ConnectTrickle();
- SimulateTrickle(0);
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestTrickleIceLiteOfferer) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- p1_->SimulateIceLite();
- ConnectTrickle();
- SimulateTrickle(0);
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestGatherFullCone) {
- UseNat();
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestGatherFullConeAutoPrioritize) {
- UseNat();
- Init(true, false);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestConnectFullCone) {
- UseNat();
- AddStream(1);
- SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectNoNatNoHost) {
- Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- AddStream(1);
- UseTestStunServer();
- // Because we are connecting from our host candidate to the
- // other side's apparent srflx (which is also their host)
- // we see a host/srflx pair.
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectFullConeNoHost) {
- UseNat();
- Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
- AddStream(1);
- UseTestStunServer();
- SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestGatherAddressRestrictedCone) {
- UseNat();
- SetFilteringType(TestNat::ADDRESS_DEPENDENT);
- SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestConnectAddressRestrictedCone) {
- UseNat();
- SetFilteringType(TestNat::ADDRESS_DEPENDENT);
- SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
- AddStream(1);
- SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestGatherPortRestrictedCone) {
- UseNat();
- SetFilteringType(TestNat::PORT_DEPENDENT);
- SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestConnectPortRestrictedCone) {
- UseNat();
- SetFilteringType(TestNat::PORT_DEPENDENT);
- SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
- AddStream(1);
- SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
- NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestGatherSymmetricNat) {
- UseNat();
- SetFilteringType(TestNat::PORT_DEPENDENT);
- SetMappingType(TestNat::PORT_DEPENDENT);
- AddStream(1);
- ASSERT_TRUE(Gather());
- }
- TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNat) {
- if (turn_server_.empty())
- return;
- UseNat();
- SetFilteringType(TestNat::PORT_DEPENDENT);
- SetMappingType(TestNat::PORT_DEPENDENT);
- AddStream(1);
- p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED);
- p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNatAndNoNat) {
- p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false);
- p1_->UseNat();
- p1_->SetFilteringType(TestNat::PORT_DEPENDENT);
- p1_->SetMappingType(TestNat::PORT_DEPENDENT);
- p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, false, false);
- initted_ = true;
- AddStream(1);
- p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_PEER_REFLEXIVE,
- NrIceCandidate::Type::ICE_HOST);
- p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_PEER_REFLEXIVE);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestGatherNatBlocksUDP) {
- if (turn_server_.empty())
- return;
- UseNat();
- BlockUdp();
- AddStream(1);
- std::vector<NrIceTurnServer> turn_servers;
- std::vector<unsigned char> password_vec(turn_password_.begin(),
- turn_password_.end());
- turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportTcp));
- turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportUdp));
- SetTurnServers(turn_servers);
- // We have to wait for the UDP-based stuff to time out.
- ASSERT_TRUE(Gather(kDefaultTimeout * 3));
- }
- TEST_F(WebRtcIceConnectTest, TestConnectNatBlocksUDP) {
- if (turn_server_.empty())
- return;
- UseNat();
- BlockUdp();
- AddStream(1);
- std::vector<NrIceTurnServer> turn_servers;
- std::vector<unsigned char> password_vec(turn_password_.begin(),
- turn_password_.end());
- turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportTcp));
- turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportUdp));
- SetTurnServers(turn_servers);
- p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED,
- kNrIceTransportTcp);
- p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED,
- kNrIceTransportTcp);
- ASSERT_TRUE(Gather(kDefaultTimeout * 3));
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTwoComponents) {
- AddStream(2);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTwoComponentsDisableSecond) {
- AddStream(2);
- ASSERT_TRUE(Gather());
- p1_->DisableComponent(0, 2);
- p2_->DisableComponent(0, 2);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectP2();
- PR_Sleep(1000);
- ConnectP1();
- WaitForConnectedStreams();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1Trickle) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectP2();
- PR_Sleep(1000);
- ConnectP1(TRICKLE_SIMULATE);
- SimulateTrickleP1(0);
- WaitForConnectedStreams();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1TrickleTwoComponents) {
- AddStream(1);
- AddStream(2);
- ASSERT_TRUE(Gather());
- ConnectP2();
- PR_Sleep(1000);
- ConnectP1(TRICKLE_SIMULATE);
- SimulateTrickleP1(0);
- std::cerr << "Sleeping between trickle streams" << std::endl;
- PR_Sleep(1000); // Give this some time to settle but not complete
- // all of ICE.
- SimulateTrickleP1(1);
- WaitForConnectedStreams(2);
- }
- TEST_F(WebRtcIceConnectTest, TestConnectAutoPrioritize) {
- Init(false, false);
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTrickleOneStreamOneComponent) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- SimulateTrickle(0);
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTrickleTwoStreamsOneComponent) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- SimulateTrickle(0);
- SimulateTrickle(1);
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- void RealisticTrickleDelay(
- std::vector<SchedulableTrickleCandidate*>& candidates) {
- for (size_t i = 0; i < candidates.size(); ++i) {
- SchedulableTrickleCandidate* cand = candidates[i];
- if (cand->IsHost()) {
- cand->Schedule(i*10);
- } else if (cand->IsReflexive()) {
- cand->Schedule(i*10 + 100);
- } else if (cand->IsRelay()) {
- cand->Schedule(i*10 + 200);
- }
- }
- }
- void DelayRelayCandidates(
- std::vector<SchedulableTrickleCandidate*>& candidates,
- unsigned int ms) {
- for (auto i = candidates.begin(); i != candidates.end(); ++i) {
- if ((*i)->IsRelay()) {
- (*i)->Schedule(ms);
- } else {
- (*i)->Schedule(0);
- }
- }
- }
- void AddNonPairableCandidates(
- std::vector<SchedulableTrickleCandidate*>& candidates,
- IceTestPeer *peer, size_t stream, int net_type,
- MtransportTestUtils* test_utils_) {
- for (int i=1; i<5; i++) {
- if (net_type == i)
- continue;
- switch (i) {
- case 1:
- candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
- "candidate:0 1 UDP 2113601790 10.0.0.1 12345 typ host",
- test_utils_));
- break;
- case 2:
- candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
- "candidate:0 1 UDP 2113601791 172.16.1.1 12345 typ host",
- test_utils_));
- break;
- case 3:
- candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
- "candidate:0 1 UDP 2113601792 192.168.0.1 12345 typ host",
- test_utils_));
- break;
- case 4:
- candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
- "candidate:0 1 UDP 2113601793 100.64.1.1 12345 typ host",
- test_utils_));
- break;
- default:
- UNIMPLEMENTED;
- }
- }
- for (auto i = candidates.rbegin(); i != candidates.rend(); ++i) {
- std::cerr << "Scheduling candidate: " << (*i)->Candidate().c_str() << std::endl;
- (*i)->Schedule(0);
- }
- }
- void DropTrickleCandidates(
- std::vector<SchedulableTrickleCandidate*>& candidates) {
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamDuringICE) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- AddStream(1);
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamAfterICE) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- WaitForConnected(1000);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, RemoveStream) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- RemoveStream(0);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- }
- TEST_F(WebRtcIceConnectTest, P1NoTrickle) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- DropTrickleCandidates(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, P2NoTrickle) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- DropTrickleCandidates(p2_->ControlTrickle(0));
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, RemoveAndAddStream) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- RemoveStream(0);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(2));
- RealisticTrickleDelay(p2_->ControlTrickle(2));
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, RemoveStreamBeforeGather) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather(0));
- RemoveStream(0);
- WaitForGather();
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, RemoveStreamDuringGather) {
- AddStream(1);
- AddStream(1);
- RemoveStream(0);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, RemoveStreamDuringConnect) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- RealisticTrickleDelay(p1_->ControlTrickle(1));
- RealisticTrickleDelay(p2_->ControlTrickle(1));
- RemoveStream(0);
- WaitForConnected(1000);
- }
- TEST_F(WebRtcIceConnectTest, TestConnectRealTrickleOneStreamOneComponent) {
- AddStream(1);
- AddStream(1);
- ASSERT_TRUE(Gather(0));
- ConnectTrickle(TRICKLE_REAL);
- WaitForConnected();
- WaitForGather(); // ICE can complete before we finish gathering.
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestSendReceive) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestSendReceiveTcp) {
- Init(false, true);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsTcpCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
- Connect();
- SendReceive();
- }
- //TCP SO tests works on localhost only with delay applied:
- // tc qdisc add dev lo root netem delay 10ms
- TEST_F(WebRtcIceConnectTest, DISABLED_TestSendReceiveTcpSo) {
- Init(false, true);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsTcpSoCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
- Connect();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestConsent) {
- AddStream(1);
- SetupAndCheckConsent();
- PR_Sleep(1500);
- AssertConsentRefresh();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestConsentTcp) {
- Init(false, true);
- AddStream(1);
- SetCandidateFilter(IsTcpCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
- NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
- SetupAndCheckConsent();
- PR_Sleep(1500);
- AssertConsentRefresh();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestConsentIntermittent) {
- AddStream(1);
- SetupAndCheckConsent();
- p1_->SetBlockStun(true);
- p2_->SetBlockStun(true);
- WaitForDisconnected();
- AssertConsentRefresh(CONSENT_STALE);
- SendReceive();
- p1_->SetBlockStun(false);
- p2_->SetBlockStun(false);
- WaitForConnected();
- AssertConsentRefresh();
- SendReceive();
- p1_->SetBlockStun(true);
- p2_->SetBlockStun(true);
- WaitForDisconnected();
- AssertConsentRefresh(CONSENT_STALE);
- SendReceive();
- p1_->SetBlockStun(false);
- p2_->SetBlockStun(false);
- WaitForConnected();
- AssertConsentRefresh();
- }
- TEST_F(WebRtcIceConnectTest, TestConsentTimeout) {
- AddStream(1);
- SetupAndCheckConsent();
- p1_->SetBlockStun(true);
- p2_->SetBlockStun(true);
- WaitForDisconnected();
- AssertConsentRefresh(CONSENT_STALE);
- SendReceive();
- WaitForFailed();
- AssertConsentRefresh(CONSENT_EXPIRED);
- SendFailure();
- }
- TEST_F(WebRtcIceConnectTest, TestConsentDelayed) {
- AddStream(1);
- SetupAndCheckConsent();
- /* Note: We don't have a list of STUN transaction IDs of the previously timed
- out consent requests. Thus responses after sending the next consent
- request are ignored. */
- p1_->SetStunResponseDelay(300);
- p2_->SetStunResponseDelay(300);
- PR_Sleep(1000);
- AssertConsentRefresh();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurn) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnWithDelay) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
- p1_->Gather();
- PR_Sleep(500);
- p2_->Gather();
- ConnectTrickle(TRICKLE_REAL);
- WaitForGather();
- WaitForConnectedStreams();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- RealisticTrickleDelay(p2_->ControlTrickle(0));
- WaitForConnected();
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- RealisticTrickleDelay(p1_->ControlTrickle(0));
- p2_->SimulateTrickle(0);
- WaitForConnected();
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
- ASSERT_TRUE(Gather());
- ConnectTrickle();
- // Trickle host candidates immediately, but delay relay candidates
- DelayRelayCandidates(p1_->ControlTrickle(0), 3700);
- DelayRelayCandidates(p2_->ControlTrickle(0), 3700);
- WaitForConnected();
- AssertCheckingReached();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnTcp) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_, kNrIceTransportTcp);
- ASSERT_TRUE(Gather());
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnOnly) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsRelayCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectTurnTcpOnly) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_, kNrIceTransportTcp);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsRelayCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED,
- kNrIceTransportTcp);
- Connect();
- }
- TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnOnly) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsRelayCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED);
- Connect();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnTcpOnly) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
- turn_user_, turn_password_, kNrIceTransportTcp);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsRelayCandidate);
- SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED,
- kNrIceTransportTcp);
- Connect();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnBothOnly) {
- if (turn_server_.empty())
- return;
- AddStream(1);
- std::vector<NrIceTurnServer> turn_servers;
- std::vector<unsigned char> password_vec(turn_password_.begin(),
- turn_password_.end());
- turn_servers.push_back(*NrIceTurnServer::Create(
- turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportTcp));
- turn_servers.push_back(*NrIceTurnServer::Create(
- turn_server_, kDefaultStunServerPort,
- turn_user_, password_vec, kNrIceTransportUdp));
- SetTurnServers(turn_servers);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsRelayCandidate);
- // UDP is preferred.
- SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
- NrIceCandidate::Type::ICE_RELAYED,
- kNrIceTransportUdp);
- Connect();
- SendReceive();
- }
- TEST_F(WebRtcIceConnectTest, TestConnectShutdownOneSide) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- ConnectThenDelete();
- }
- TEST_F(WebRtcIceConnectTest, TestPollCandPairsBeforeConnect) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- std::vector<NrIceCandidatePair> pairs;
- nsresult res = p1_->GetCandidatePairs(0, &pairs);
- // There should be no candidate pairs prior to calling Connect()
- ASSERT_EQ(NS_OK, res);
- ASSERT_EQ(0U, pairs.size());
- res = p2_->GetCandidatePairs(0, &pairs);
- ASSERT_EQ(NS_OK, res);
- ASSERT_EQ(0U, pairs.size());
- }
- TEST_F(WebRtcIceConnectTest, TestPollCandPairsAfterConnect) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- Connect();
- std::vector<NrIceCandidatePair> pairs;
- nsresult r = p1_->GetCandidatePairs(0, &pairs);
- ASSERT_EQ(NS_OK, r);
- // How detailed of a check do we want to do here? If the turn server is
- // functioning, we'll get at least two pairs, but this is probably not
- // something we should assume.
- ASSERT_NE(0U, pairs.size());
- ASSERT_TRUE(p1_->CandidatePairsPriorityDescending(pairs));
- ASSERT_TRUE(ContainsSucceededPair(pairs));
- pairs.clear();
- r = p2_->GetCandidatePairs(0, &pairs);
- ASSERT_EQ(NS_OK, r);
- ASSERT_NE(0U, pairs.size());
- ASSERT_TRUE(p2_->CandidatePairsPriorityDescending(pairs));
- ASSERT_TRUE(ContainsSucceededPair(pairs));
- }
- // TODO Bug 1259842 - disabled until we find a better way to handle two
- // candidates from different RFC1918 ranges
- TEST_F(WebRtcIceConnectTest, DISABLED_TestHostCandPairingFilter) {
- Init(false, false, false);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsIpv4Candidate);
- int host_net = p1_->GetCandidatesPrivateIpv4Range(0);
- if (host_net <= 0) {
- // TODO bug 1226838: make this work with multiple private IPs
- FAIL() << "This test needs exactly one private IPv4 host candidate to work" << std::endl;
- }
- ConnectTrickle();
- AddNonPairableCandidates(p1_->ControlTrickle(0), p1_.get(), 0, host_net, test_utils_);
- AddNonPairableCandidates(p2_->ControlTrickle(0), p2_.get(), 0, host_net, test_utils_);
- std::vector<NrIceCandidatePair> pairs;
- p1_->GetCandidatePairs(0, &pairs);
- for (auto p : pairs) {
- std::cerr << "Verifying pair:" << std::endl;
- p1_->DumpCandidatePair(p);
- nr_transport_addr addr;
- nr_str_port_to_transport_addr(p.local.local_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == host_net);
- nr_str_port_to_transport_addr(p.remote.cand_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == host_net);
- }
- }
- // TODO Bug 1226838 - See Comment 2 - this test can't work as written
- TEST_F(WebRtcIceConnectTest, DISABLED_TestSrflxCandPairingFilter) {
- if (stun_server_address_.empty()) {
- return;
- }
- Init(false, false, false);
- AddStream(1);
- ASSERT_TRUE(Gather());
- SetCandidateFilter(IsSrflxCandidate);
- if (p1_->GetCandidatesPrivateIpv4Range(0) <= 0) {
- // TODO bug 1226838: make this work with public IP addresses
- std::cerr << "Don't run this test at IETF meetings!" << std::endl;
- FAIL() << "This test needs one private IPv4 host candidate to work" << std::endl;
- }
- ConnectTrickle();
- SimulateTrickleP1(0);
- SimulateTrickleP2(0);
- std::vector<NrIceCandidatePair> pairs;
- p1_->GetCandidatePairs(0, &pairs);
- for (auto p : pairs) {
- std::cerr << "Verifying P1 pair:" << std::endl;
- p1_->DumpCandidatePair(p);
- nr_transport_addr addr;
- nr_str_port_to_transport_addr(p.local.local_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) != 0);
- nr_str_port_to_transport_addr(p.remote.cand_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == 0);
- }
- p2_->GetCandidatePairs(0, &pairs);
- for (auto p : pairs) {
- std::cerr << "Verifying P2 pair:" << std::endl;
- p2_->DumpCandidatePair(p);
- nr_transport_addr addr;
- nr_str_port_to_transport_addr(p.local.local_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) != 0);
- nr_str_port_to_transport_addr(p.remote.cand_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
- ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == 0);
- }
- }
- TEST_F(WebRtcIceConnectTest, TestPollCandPairsDuringConnect) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- p2_->Connect(p1_.get(), TRICKLE_NONE, false);
- p1_->Connect(p2_.get(), TRICKLE_NONE, false);
- std::vector<NrIceCandidatePair> pairs1;
- std::vector<NrIceCandidatePair> pairs2;
- p1_->StartChecks();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- p2_->StartChecks();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- WaitForConnectedStreams();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- ASSERT_TRUE(ContainsSucceededPair(pairs1));
- ASSERT_TRUE(ContainsSucceededPair(pairs2));
- }
- TEST_F(WebRtcIceConnectTest, TestRLogConnector) {
- AddStream(1);
- ASSERT_TRUE(Gather());
- p2_->Connect(p1_.get(), TRICKLE_NONE, false);
- p1_->Connect(p2_.get(), TRICKLE_NONE, false);
- std::vector<NrIceCandidatePair> pairs1;
- std::vector<NrIceCandidatePair> pairs2;
- p1_->StartChecks();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- p2_->StartChecks();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- WaitForConnectedStreams();
- p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
- p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
- ASSERT_TRUE(ContainsSucceededPair(pairs1));
- ASSERT_TRUE(ContainsSucceededPair(pairs2));
- for (auto p = pairs1.begin(); p != pairs1.end(); ++p) {
- std::deque<std::string> logs;
- std::string substring("CAND-PAIR(");
- substring += p->codeword;
- RLogConnector::GetInstance()->Filter(substring, 0, &logs);
- ASSERT_NE(0U, logs.size());
- }
- for (auto p = pairs2.begin(); p != pairs2.end(); ++p) {
- std::deque<std::string> logs;
- std::string substring("CAND-PAIR(");
- substring += p->codeword;
- RLogConnector::GetInstance()->Filter(substring, 0, &logs);
- ASSERT_NE(0U, logs.size());
- }
- }
- TEST_F(WebRtcIcePrioritizerTest, TestPrioritizer) {
- SetPriorizer(::mozilla::CreateInterfacePrioritizer());
- AddInterface("0", NR_INTERFACE_TYPE_VPN, 100); // unknown vpn
- AddInterface("1", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIRED, 100); // wired vpn
- AddInterface("2", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIFI, 100); // wifi vpn
- AddInterface("3", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_MOBILE, 100); // wifi vpn
- AddInterface("4", NR_INTERFACE_TYPE_WIRED, 1000); // wired, high speed
- AddInterface("5", NR_INTERFACE_TYPE_WIRED, 10); // wired, low speed
- AddInterface("6", NR_INTERFACE_TYPE_WIFI, 10); // wifi, low speed
- AddInterface("7", NR_INTERFACE_TYPE_WIFI, 1000); // wifi, high speed
- AddInterface("8", NR_INTERFACE_TYPE_MOBILE, 10); // mobile, low speed
- AddInterface("9", NR_INTERFACE_TYPE_MOBILE, 1000); // mobile, high speed
- AddInterface("10", NR_INTERFACE_TYPE_UNKNOWN, 10); // unknown, low speed
- AddInterface("11", NR_INTERFACE_TYPE_UNKNOWN, 1000); // unknown, high speed
- // expected preference "4" > "5" > "1" > "7" > "6" > "2" > "9" > "8" > "3" > "11" > "10" > "0"
- HasLowerPreference("0", "10");
- HasLowerPreference("10", "11");
- HasLowerPreference("11", "3");
- HasLowerPreference("3", "8");
- HasLowerPreference("8", "9");
- HasLowerPreference("9", "2");
- HasLowerPreference("2", "6");
- HasLowerPreference("6", "7");
- HasLowerPreference("7", "1");
- HasLowerPreference("1", "5");
- HasLowerPreference("5", "4");
- }
- TEST_F(WebRtcIcePacketFilterTest, TestSendNonStunPacket) {
- const unsigned char data[] = "12345abcde";
- TestOutgoing(data, sizeof(data), 123, 45, false);
- TestOutgoingTcp(data, sizeof(data), false);
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvNonStunPacket) {
- const unsigned char data[] = "12345abcde";
- TestIncoming(data, sizeof(data), 123, 45, false);
- TestIncomingTcp(data, sizeof(data), true);
- }
- TEST_F(WebRtcIcePacketFilterTest, TestSendStunPacket) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- TestOutgoingTcpFramed(msg->buffer, msg->length, true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithoutAPendingId) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.id.octet[0] = 1;
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- msg->header.id.octet[0] = 0;
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncoming(msg->buffer, msg->length, 123, 45, true);
- TestIncomingTcp(msg->buffer, msg->length, true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithoutAPendingIdTcpFramed) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.id.octet[0] = 1;
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoingTcpFramed(msg->buffer, msg->length, true);
- msg->header.id.octet[0] = 0;
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncomingTcpFramed(msg->buffer, msg->length, true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithoutAPendingAddress) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- // nothing to test here for the TCP filter
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncoming(msg->buffer, msg->length, 123, 46, false);
- TestIncoming(msg->buffer, msg->length, 124, 45, false);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithPendingIdAndAddress) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncoming(msg->buffer, msg->length, 123, 45, true);
- TestIncomingTcp(msg->buffer, msg->length, true);
- // Test whitelist by filtering non-stun packets.
- const unsigned char data[] = "12345abcde";
- // 123:45 is white-listed.
- TestOutgoing(data, sizeof(data), 123, 45, true);
- TestOutgoingTcp(data, sizeof(data), true);
- TestIncoming(data, sizeof(data), 123, 45, true);
- TestIncomingTcp(data, sizeof(data), true);
- // Indications pass as well.
- msg->header.type = NR_STUN_MSG_BINDING_INDICATION;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- TestIncoming(msg->buffer, msg->length, 123, 45, true);
- TestIncomingTcp(msg->buffer, msg->length, true);
- // Packets from and to other address are still disallowed.
- // Note: this doesn't apply for TCP connections
- TestOutgoing(data, sizeof(data), 123, 46, false);
- TestIncoming(data, sizeof(data), 123, 46, false);
- TestOutgoing(data, sizeof(data), 124, 45, false);
- TestIncoming(data, sizeof(data), 124, 45, false);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithPendingIdTcpFramed) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoingTcpFramed(msg->buffer, msg->length, true);
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncomingTcpFramed(msg->buffer, msg->length, true);
- // Test whitelist by filtering non-stun packets.
- const unsigned char data[] = "12345abcde";
- TestOutgoingTcpFramed(data, sizeof(data), true);
- TestIncomingTcpFramed(data, sizeof(data), true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestSendNonRequestStunPacket) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, false);
- TestOutgoingTcp(msg->buffer, msg->length, false);
- // Send a packet so we allow the incoming request.
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- // This packet makes us able to send a response.
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestIncoming(msg->buffer, msg->length, 123, 45, true);
- TestIncomingTcp(msg->buffer, msg->length, true);
- msg->header.type = NR_STUN_MSG_BINDING_RESPONSE;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST_F(WebRtcIcePacketFilterTest, TestRecvDataPacketWithAPendingAddress) {
- nr_stun_message *msg;
- ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
- msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
- ASSERT_EQ(0, nr_stun_encode_message(msg));
- TestOutgoing(msg->buffer, msg->length, 123, 45, true);
- TestOutgoingTcp(msg->buffer, msg->length, true);
- const unsigned char data[] = "12345abcde";
- TestIncoming(data, sizeof(data), 123, 45, true);
- TestIncomingTcp(data, sizeof(data), true);
- ASSERT_EQ(0, nr_stun_message_destroy(&msg));
- }
- TEST(WebRtcIceInternalsTest, TestAddBogusAttribute) {
- nr_stun_message *req;
- ASSERT_EQ(0, nr_stun_message_create(&req));
- Data *data;
- ASSERT_EQ(0, r_data_alloc(&data, 3000));
- memset(data->data, 'A', data->len);
- ASSERT_TRUE(nr_stun_message_add_message_integrity_attribute(req, data));
- ASSERT_EQ(0, r_data_destroy(&data));
- ASSERT_EQ(0, nr_stun_message_destroy(&req));
- }
|