diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index f880e2b9e7b1e..4edfa38747b14 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -78469,6 +78469,99 @@ true mirror : always +# +When +true +origin +A +and +origin +B +will +be +coalesced +if +they +have +an +overlap +# +in +IP +addresses +as +advertized +by +DNS +regardless +if +the +existing +connection +# +to +origin +A +is +not +to +an +IP +present +in +B +' +s +DNS +response +. +# +When +false +an +existing +connection +will +only +be +reused +if +the +# +connection +' +s +remote +IP +is +also +present +in +B +' +s +DNS +response +. +- +name +: +network +. +http +. +http2 +. +aggressive_coalescing +type +: +RelaxedAtomicBool +value +: +false +mirror +: +always - name : diff --git a/netwerk/protocol/http/ConnectionEntry.cpp b/netwerk/protocol/http/ConnectionEntry.cpp index 9b69479c7616e..50f2ef7128517 100644 --- a/netwerk/protocol/http/ConnectionEntry.cpp +++ b/netwerk/protocol/http/ConnectionEntry.cpp @@ -673,6 +673,12 @@ Clear ( ) ; +mAddresses +. +Clear +( +) +; } void ConnectionEntry @@ -729,6 +735,12 @@ Clear ( ) ; +mAddresses +. +Clear +( +) +; } void ConnectionEntry @@ -2357,6 +2369,12 @@ Clear ( ) ; +mAddresses +. +Clear +( +) +; } uint32_t ConnectionEntry @@ -5445,12 +5463,6 @@ return false ; } -nsTArray -< -NetAddr -> -addressSet -; nsresult rv = @@ -5459,7 +5471,7 @@ dnsRecord > GetAddresses ( -addressSet +mAddresses ) ; if @@ -5470,7 +5482,7 @@ rv ) | | -addressSet +mAddresses . IsEmpty ( @@ -5490,7 +5502,7 @@ i ; i < -addressSet +mAddresses . Length ( @@ -5504,7 +5516,7 @@ i if ( ( -addressSet +mAddresses [ i ] @@ -5517,7 +5529,7 @@ family AF_INET & & -addressSet +mAddresses [ i ] @@ -5532,7 +5544,7 @@ ip | | ( -addressSet +mAddresses [ i ] @@ -5545,7 +5557,7 @@ family AF_INET6 & & -addressSet +mAddresses [ i ] @@ -5563,7 +5575,7 @@ u64 0 & & -addressSet +mAddresses [ i ] @@ -5638,7 +5650,7 @@ kIPv6CStrBufSize 26 ) ; -addressSet +mAddresses [ i ] diff --git a/netwerk/protocol/http/ConnectionEntry.h b/netwerk/protocol/http/ConnectionEntry.h index a418e040d20ef..bc5efc7045eba 100644 --- a/netwerk/protocol/http/ConnectionEntry.h +++ b/netwerk/protocol/http/ConnectionEntry.h @@ -472,6 +472,12 @@ nsCString > mCoalescingKeys ; +nsTArray +< +NetAddr +> +mAddresses +; bool mUsingSpdy : diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 49b7e3b5e6267..ee78a3753317d 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -4507,61 +4507,143 @@ aNoHttp2 aNoHttp3 ) ; -if +auto +usableEntry += +[ +& +] ( +HttpConnectionBase +* conn ) { -LOG -( +if ( -" -FindCoalescableConnection +StaticPrefs +: +: +network_http_http2_aggressive_coalescing ( -% -s ) -match +) +{ +return +true +; +} +NetAddr +addr +; +nsresult +rv += conn -% -p -on -dns -key -% -s -\ -n -" -ci - > -HashKey +GetPeerAddr ( +& +addr ) -. -get +; +if +( +NS_FAILED ( +rv ) -conn +) +{ +return +false +; +} +addr +. +inet +. +port += +0 +; +return ent - > -mCoalescingKeys -[ -i -] +mAddresses . -get +Contains +( +addr +) +; +} +; +if +( +conn +) +{ +LOG +( +( +" +Found +connection +with +matching +hash +" +) +) +; +if ( +usableEntry +( +conn ) ) +{ +LOG +( +( +" +> +coalescing +" +) ) ; return conn ; } +else +{ +LOG +( +( +" +> +not +coalescing +as +remote +address +not +present +in +DNS +records +" +) +) +; +} +} } LOG ( diff --git a/netwerk/test/unit/test_connection_coalescing.js b/netwerk/test/unit/test_connection_coalescing.js new file mode 100644 index 0000000000000..311dfb7ad20cd --- /dev/null +++ b/netwerk/test/unit/test_connection_coalescing.js @@ -0,0 +1,1310 @@ +" +use +strict +" +; +const +override += +Cc +[ +" +mozilla +. +org +/ +network +/ +native +- +dns +- +override +; +1 +" +] +. +getService +( +Ci +. +nsINativeDNSResolverOverride +) +; +let +certdb += +Cc +[ +" +mozilla +. +org +/ +security +/ +x509certdb +; +1 +" +] +. +getService +( +Ci +. +nsIX509CertDB +) +; +addCertFromFile +( +certdb +" +http2 +- +ca +. +pem +" +" +CTu +u +u +" +) +; +async +function +createServer +( +) +{ +let +server += +new +NodeHTTP2Server +( +) +; +await +server +. +start +( +) +; +registerCleanupFunction +( +async +( +) += +> +{ +await +server +. +stop +( +) +; +} +) +; +await +server +. +registerPathHandler +( +" +/ +" +( +req +resp +) += +> +{ +let +content += +hello +from +{ +req +. +authority +} +| +{ +req +. +socket +. +remotePort +} +; +resp +. +writeHead +( +200 +{ +" +Content +- +Type +" +: +" +text +/ +plain +" +" +Content +- +Length +" +: +{ +content +. +length +} +} +) +; +resp +. +end +( +content +) +; +} +) +; +return +server +; +} +async +function +openChan +( +uri +) +{ +let +chan += +NetUtil +. +newChannel +( +{ +uri +loadUsingSystemPrincipal +: +true +} +) +. +QueryInterface +( +Ci +. +nsIHttpChannel +) +; +chan +. +loadFlags += +Ci +. +nsIChannel +. +LOAD_INITIAL_DOCUMENT_URI +; +let +{ +req +buffer +} += +await +new +Promise +( +resolve += +> +{ +function +finish +( +r +b +) +{ +resolve +( +{ +req +: +r +buffer +: +b +} +) +; +} +chan +. +asyncOpen +( +new +ChannelListener +( +finish +null +CL_ALLOW_UNKNOWN_CL +) +) +; +} +) +; +return +{ +buffer +port +: +buffer +. +split +( +" +| +" +) +[ +1 +] +addr +: +req +. +QueryInterface +( +Ci +. +nsIHttpChannelInternal +) +. +remoteAddress +status +: +req +. +QueryInterface +( +Ci +. +nsIHttpChannel +) +. +responseStatus +} +; +} +add_task +( +async +function +test_dontCoalesce +( +) +{ +let +server += +await +createServer +( +) +; +Services +. +prefs +. +setBoolPref +( +" +network +. +http +. +http2 +. +aggressive_coalescing +" +false +) +; +override +. +clearOverrides +( +) +; +Services +. +dns +. +clearCache +( +true +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +: +: +1 +" +) +; +override +. +addIPOverride +( +" +alt1 +. +example +. +com +" +" +: +: +1 +" +) +; +let +{ +addr +: +addr1 +} += +await +openChan +( +https +: +/ +/ +foo +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +let +{ +addr +: +addr2 +} += +await +openChan +( +https +: +/ +/ +alt1 +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +Assert +. +notEqual +( +addr1 +addr2 +) +; +await +server +. +stop +( +) +; +} +) +; +add_task +( +async +function +test_doCoalesce +( +) +{ +let +server += +await +createServer +( +) +; +Services +. +prefs +. +setBoolPref +( +" +network +. +http +. +http2 +. +aggressive_coalescing +" +false +) +; +override +. +clearOverrides +( +) +; +Services +. +dns +. +clearCache +( +true +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +: +: +1 +" +) +; +override +. +addIPOverride +( +" +alt2 +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +override +. +addIPOverride +( +" +alt2 +. +example +. +com +" +" +: +: +1 +" +) +; +let +{ +port +: +port1 +addr +: +addr1 +} += +await +openChan +( +https +: +/ +/ +foo +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +let +{ +port +: +port2 +addr +: +addr2 +} += +await +openChan +( +https +: +/ +/ +alt2 +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +Assert +. +equal +( +addr1 +addr2 +) +; +Assert +. +equal +( +port1 +port2 +) +; +await +server +. +stop +( +) +; +} +) +; +add_task +( +async +function +test_doCoalesceAggresive +( +) +{ +let +server += +await +createServer +( +) +; +Services +. +prefs +. +setBoolPref +( +" +network +. +http +. +http2 +. +aggressive_coalescing +" +true +) +; +override +. +clearOverrides +( +) +; +Services +. +dns +. +clearCache +( +true +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +: +: +1 +" +) +; +override +. +addIPOverride +( +" +alt1 +. +example +. +com +" +" +: +: +1 +" +) +; +let +{ +port +: +port1 +addr +: +addr1 +} += +await +openChan +( +https +: +/ +/ +foo +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +let +{ +port +: +port2 +addr +: +addr2 +} += +await +openChan +( +https +: +/ +/ +alt1 +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +Assert +. +equal +( +addr1 +addr2 +) +; +Assert +. +equal +( +port1 +port2 +) +; +await +server +. +stop +( +) +; +} +) +; +add_task +( +async +function +test_doCoalesceAggresive421 +( +) +{ +let +server += +await +createServer +( +) +; +await +server +. +registerPathHandler +( +" +/ +" +( +req +resp +) += +> +{ +let +content += +hello +from +{ +req +. +authority +} +| +{ +req +. +socket +. +remotePort +} +; +if +( +req +. +authority +. +startsWith +( +" +alt1 +. +example +. +com +" +) +& +& +req +. +socket +. +localAddress += += +" +: +: +1 +" +) +{ +resp +. +writeHead +( +421 +{ +" +Content +- +Type +" +: +" +text +/ +plain +" +" +Content +- +Length +" +: +{ +content +. +length +} +} +) +; +resp +. +end +( +content +) +; +return +; +} +resp +. +writeHead +( +200 +{ +" +Content +- +Type +" +: +" +text +/ +plain +" +" +Content +- +Length +" +: +{ +content +. +length +} +} +) +; +resp +. +end +( +content +) +; +} +) +; +Services +. +prefs +. +setBoolPref +( +" +network +. +http +. +http2 +. +aggressive_coalescing +" +true +) +; +override +. +clearOverrides +( +) +; +Services +. +dns +. +clearCache +( +true +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +: +: +1 +" +) +; +override +. +addIPOverride +( +" +foo +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +override +. +addIPOverride +( +" +alt1 +. +example +. +com +" +" +127 +. +0 +. +0 +. +1 +" +) +; +let +{ +addr +: +addr1 +status +: +status1 +} += +await +openChan +( +https +: +/ +/ +foo +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +Assert +. +equal +( +status1 +200 +) +; +Assert +. +equal +( +addr1 +" +: +: +1 +" +) +; +let +{ +addr +: +addr2 +status +: +status2 +} += +await +openChan +( +https +: +/ +/ +alt1 +. +example +. +com +: +{ +server +. +port +( +) +} +/ +) +; +Assert +. +equal +( +status2 +200 +) +; +Assert +. +equal +( +addr2 +" +127 +. +0 +. +0 +. +1 +" +) +; +await +server +. +stop +( +) +; +} +) +; diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml index 931d6334c3ed5..431b505ad5035 100644 --- a/netwerk/test/unit/xpcshell.toml +++ b/netwerk/test/unit/xpcshell.toml @@ -7148,3 +7148,10 @@ test_xmlhttprequest js " ] +[ +" +test_connection_coalescing +. +js +" +]