quic_chromium_client_session.cc 137 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/quic/quic_chromium_client_session.h"
  5. #include <memory>
  6. #include <set>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/containers/contains.h"
  10. #include "base/feature_list.h"
  11. #include "base/location.h"
  12. #include "base/memory/ptr_util.h"
  13. #include "base/metrics/histogram_functions.h"
  14. #include "base/metrics/histogram_macros.h"
  15. #include "base/metrics/sparse_histogram.h"
  16. #include "base/no_destructor.h"
  17. #include "base/observer_list.h"
  18. #include "base/strings/string_number_conversions.h"
  19. #include "base/strings/stringprintf.h"
  20. #include "base/task/single_thread_task_runner.h"
  21. #include "base/threading/thread_task_runner_handle.h"
  22. #include "base/time/tick_clock.h"
  23. #include "base/trace_event/memory_usage_estimator.h"
  24. #include "base/values.h"
  25. #include "net/base/features.h"
  26. #include "net/base/io_buffer.h"
  27. #include "net/base/net_errors.h"
  28. #include "net/base/network_activity_monitor.h"
  29. #include "net/base/network_isolation_key.h"
  30. #include "net/base/privacy_mode.h"
  31. #include "net/base/url_util.h"
  32. #include "net/cert/signed_certificate_timestamp_and_status.h"
  33. #include "net/http/transport_security_state.h"
  34. #include "net/log/net_log_event_type.h"
  35. #include "net/log/net_log_source_type.h"
  36. #include "net/quic/address_utils.h"
  37. #include "net/quic/crypto/proof_verifier_chromium.h"
  38. #include "net/quic/quic_chromium_connection_helper.h"
  39. #include "net/quic/quic_chromium_packet_writer.h"
  40. #include "net/quic/quic_crypto_client_stream_factory.h"
  41. #include "net/quic/quic_server_info.h"
  42. #include "net/quic/quic_stream_factory.h"
  43. #include "net/socket/datagram_client_socket.h"
  44. #include "net/spdy/spdy_http_utils.h"
  45. #include "net/spdy/spdy_log_util.h"
  46. #include "net/spdy/spdy_session.h"
  47. #include "net/ssl/ssl_connection_status_flags.h"
  48. #include "net/ssl/ssl_info.h"
  49. #include "net/third_party/quiche/src/quiche/quic/core/http/quic_client_promised_info.h"
  50. #include "net/third_party/quiche/src/quiche/quic/core/http/spdy_server_push_utils.h"
  51. #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
  52. #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
  53. #include "net/traffic_annotation/network_traffic_annotation.h"
  54. #include "third_party/boringssl/src/include/openssl/ssl.h"
  55. #include "url/origin.h"
  56. #include "url/scheme_host_port.h"
  57. namespace net {
  58. namespace {
  59. // IPv6 packets have an additional 20 bytes of overhead than IPv4 packets.
  60. const size_t kAdditionalOverheadForIPv6 = 20;
  61. // Maximum number of Readers that are created for any session due to
  62. // connection migration. A new Reader is created every time this endpoint's
  63. // IP address changes.
  64. const size_t kMaxReadersPerQuicSession = 5;
  65. // Time to wait (in seconds) when no networks are available and
  66. // migrating sessions need to wait for a new network to connect.
  67. const size_t kWaitTimeForNewNetworkSecs = 10;
  68. const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
  69. // These values are persisted to logs. Entries should not be renumbered,
  70. // and numeric values should never be reused.
  71. enum class AcceptChEntries {
  72. kNoEntries = 0,
  73. kOnlyValidEntries = 1,
  74. kOnlyInvalidEntries = 2,
  75. kBothValidAndInvalidEntries = 3,
  76. kMaxValue = kBothValidAndInvalidEntries,
  77. };
  78. void LogAcceptChFrameReceivedHistogram(bool has_valid_entry,
  79. bool has_invalid_entry) {
  80. AcceptChEntries value;
  81. if (has_valid_entry) {
  82. if (has_invalid_entry) {
  83. value = AcceptChEntries::kBothValidAndInvalidEntries;
  84. } else {
  85. value = AcceptChEntries::kOnlyValidEntries;
  86. }
  87. } else {
  88. if (has_invalid_entry) {
  89. value = AcceptChEntries::kOnlyInvalidEntries;
  90. } else {
  91. value = AcceptChEntries::kNoEntries;
  92. }
  93. }
  94. base::UmaHistogramEnumeration("Net.QuicSession.AcceptChFrameReceivedViaAlps",
  95. value);
  96. }
  97. void LogAcceptChForOriginHistogram(bool value) {
  98. base::UmaHistogramBoolean("Net.QuicSession.AcceptChForOrigin", value);
  99. }
  100. void RecordConnectionCloseErrorCodeImpl(const std::string& histogram,
  101. uint64_t error,
  102. bool is_google_host,
  103. bool handshake_confirmed) {
  104. base::UmaHistogramSparse(histogram, error);
  105. if (handshake_confirmed) {
  106. base::UmaHistogramSparse(histogram + ".HandshakeConfirmed", error);
  107. } else {
  108. base::UmaHistogramSparse(histogram + ".HandshakeNotConfirmed", error);
  109. }
  110. if (is_google_host) {
  111. base::UmaHistogramSparse(histogram + "Google", error);
  112. if (handshake_confirmed) {
  113. base::UmaHistogramSparse(histogram + "Google.HandshakeConfirmed", error);
  114. } else {
  115. base::UmaHistogramSparse(histogram + "Google.HandshakeNotConfirmed",
  116. error);
  117. }
  118. }
  119. }
  120. void LogMigrateToSocketStatus(bool success) {
  121. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.MigrateToSocketSuccess", success);
  122. }
  123. void RecordConnectionCloseErrorCode(const quic::QuicConnectionCloseFrame& frame,
  124. quic::ConnectionCloseSource source,
  125. const std::string& hostname,
  126. bool handshake_confirmed) {
  127. bool is_google_host = IsGoogleHost(hostname);
  128. std::string histogram = "Net.QuicSession.ConnectionCloseErrorCode";
  129. if (source == quic::ConnectionCloseSource::FROM_SELF) {
  130. // When sending a CONNECTION_CLOSE frame, it is sufficient to record
  131. // |quic_error_code|.
  132. histogram += "Client";
  133. RecordConnectionCloseErrorCodeImpl(histogram, frame.quic_error_code,
  134. is_google_host, handshake_confirmed);
  135. return;
  136. }
  137. histogram += "Server";
  138. // Record |quic_error_code|. Note that when using IETF QUIC, this is
  139. // extracted from the CONNECTION_CLOSE frame reason phrase, and might be
  140. // QUIC_IETF_GQUIC_ERROR_MISSING.
  141. RecordConnectionCloseErrorCodeImpl(histogram, frame.quic_error_code,
  142. is_google_host, handshake_confirmed);
  143. // For IETF QUIC frames, also record the error code received on the wire.
  144. if (frame.close_type == quic::IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
  145. histogram += "IetfTransport";
  146. RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
  147. is_google_host, handshake_confirmed);
  148. if (frame.quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) {
  149. histogram += "GQuicErrorMissing";
  150. RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
  151. is_google_host, handshake_confirmed);
  152. }
  153. } else if (frame.close_type == quic::IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
  154. histogram += "IetfApplication";
  155. RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
  156. is_google_host, handshake_confirmed);
  157. if (frame.quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) {
  158. histogram += "GQuicErrorMissing";
  159. RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
  160. is_google_host, handshake_confirmed);
  161. }
  162. }
  163. }
  164. base::Value NetLogQuicMigrationFailureParams(
  165. quic::QuicConnectionId connection_id,
  166. base::StringPiece reason) {
  167. base::Value::Dict dict;
  168. dict.Set("connection_id", connection_id.ToString());
  169. dict.Set("reason", reason);
  170. return base::Value(std::move(dict));
  171. }
  172. base::Value NetLogQuicMigrationSuccessParams(
  173. quic::QuicConnectionId connection_id) {
  174. base::Value::Dict dict;
  175. dict.Set("connection_id", connection_id.ToString());
  176. return base::Value(std::move(dict));
  177. }
  178. base::Value NetLogProbingResultParams(
  179. handles::NetworkHandle network,
  180. const quic::QuicSocketAddress* peer_address,
  181. bool is_success) {
  182. base::Value::Dict dict;
  183. dict.Set("network", base::NumberToString(network));
  184. dict.Set("peer address", peer_address->ToString());
  185. dict.Set("is_success", is_success);
  186. return base::Value(std::move(dict));
  187. }
  188. base::Value NetLogAcceptChFrameReceivedParams(
  189. spdy::AcceptChOriginValuePair entry) {
  190. base::Value::Dict dict;
  191. dict.Set("origin", entry.origin);
  192. dict.Set("accept_ch", entry.value);
  193. return base::Value(std::move(dict));
  194. }
  195. // Histogram for recording the different reasons that a QUIC session is unable
  196. // to complete the handshake.
  197. enum HandshakeFailureReason {
  198. HANDSHAKE_FAILURE_UNKNOWN = 0,
  199. HANDSHAKE_FAILURE_BLACK_HOLE = 1,
  200. HANDSHAKE_FAILURE_PUBLIC_RESET = 2,
  201. NUM_HANDSHAKE_FAILURE_REASONS = 3,
  202. };
  203. void RecordHandshakeFailureReason(HandshakeFailureReason reason) {
  204. UMA_HISTOGRAM_ENUMERATION(
  205. "Net.QuicSession.ConnectionClose.HandshakeNotConfirmed.Reason", reason,
  206. NUM_HANDSHAKE_FAILURE_REASONS);
  207. }
  208. // Note: these values must be kept in sync with the corresponding values in:
  209. // tools/metrics/histograms/histograms.xml
  210. enum HandshakeState {
  211. STATE_STARTED = 0,
  212. STATE_ENCRYPTION_ESTABLISHED = 1,
  213. STATE_HANDSHAKE_CONFIRMED = 2,
  214. STATE_FAILED = 3,
  215. NUM_HANDSHAKE_STATES = 4
  216. };
  217. enum class ZeroRttState {
  218. kAttemptedAndSucceeded = 0,
  219. kAttemptedAndRejected = 1,
  220. kNotAttempted = 2,
  221. kMaxValue = kNotAttempted,
  222. };
  223. void RecordHandshakeState(HandshakeState state) {
  224. UMA_HISTOGRAM_ENUMERATION("Net.QuicHandshakeState", state,
  225. NUM_HANDSHAKE_STATES);
  226. }
  227. std::string MigrationCauseToString(MigrationCause cause) {
  228. switch (cause) {
  229. case UNKNOWN_CAUSE:
  230. return "Unknown";
  231. case ON_NETWORK_CONNECTED:
  232. return "OnNetworkConnected";
  233. case ON_NETWORK_DISCONNECTED:
  234. return "OnNetworkDisconnected";
  235. case ON_WRITE_ERROR:
  236. return "OnWriteError";
  237. case ON_NETWORK_MADE_DEFAULT:
  238. return "OnNetworkMadeDefault";
  239. case ON_MIGRATE_BACK_TO_DEFAULT_NETWORK:
  240. return "OnMigrateBackToDefaultNetwork";
  241. case CHANGE_NETWORK_ON_PATH_DEGRADING:
  242. return "OnPathDegrading";
  243. case CHANGE_PORT_ON_PATH_DEGRADING:
  244. return "ChangePortOnPathDegrading";
  245. case NEW_NETWORK_CONNECTED_POST_PATH_DEGRADING:
  246. return "NewNetworkConnectedPostPathDegrading";
  247. default:
  248. QUICHE_NOTREACHED();
  249. break;
  250. }
  251. return "InvalidCause";
  252. }
  253. base::Value NetLogQuicClientSessionParams(
  254. const QuicSessionKey* session_key,
  255. const quic::QuicConnectionId& connection_id,
  256. const quic::QuicConnectionId& client_connection_id,
  257. const quic::ParsedQuicVersionVector& supported_versions,
  258. int cert_verify_flags,
  259. bool require_confirmation) {
  260. base::Value::Dict dict;
  261. dict.Set("host", session_key->server_id().host());
  262. dict.Set("port", session_key->server_id().port());
  263. dict.Set("privacy_mode",
  264. PrivacyModeToDebugString(session_key->privacy_mode()));
  265. dict.Set("network_isolation_key",
  266. session_key->network_isolation_key().ToDebugString());
  267. dict.Set("require_confirmation", require_confirmation);
  268. dict.Set("cert_verify_flags", cert_verify_flags);
  269. dict.Set("connection_id", connection_id.ToString());
  270. if (!client_connection_id.IsEmpty()) {
  271. dict.Set("client_connection_id", client_connection_id.ToString());
  272. }
  273. dict.Set("versions", ParsedQuicVersionVectorToString(supported_versions));
  274. return base::Value(std::move(dict));
  275. }
  276. base::Value NetLogQuicPushPromiseReceivedParams(
  277. const spdy::Http2HeaderBlock* headers,
  278. spdy::SpdyStreamId stream_id,
  279. spdy::SpdyStreamId promised_stream_id,
  280. NetLogCaptureMode capture_mode) {
  281. base::Value::Dict dict;
  282. dict.Set("headers", ElideHttp2HeaderBlockForNetLog(*headers, capture_mode));
  283. dict.Set("id", static_cast<int>(stream_id));
  284. dict.Set("promised_stream_id", static_cast<int>(promised_stream_id));
  285. return base::Value(std::move(dict));
  286. }
  287. // TODO(fayang): Remove this when necessary data is collected.
  288. void LogProbeResultToHistogram(MigrationCause cause, bool success) {
  289. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.PathValidationSuccess", success);
  290. const std::string histogram_name =
  291. "Net.QuicSession.PathValidationSuccess." + MigrationCauseToString(cause);
  292. STATIC_HISTOGRAM_POINTER_GROUP(
  293. histogram_name, cause, MIGRATION_CAUSE_MAX, AddBoolean(success),
  294. base::BooleanHistogram::FactoryGet(
  295. histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag));
  296. }
  297. class QuicServerPushHelper : public ServerPushDelegate::ServerPushHelper {
  298. public:
  299. explicit QuicServerPushHelper(
  300. base::WeakPtr<QuicChromiumClientSession> session,
  301. const GURL& url)
  302. : session_(session), request_url_(url) {}
  303. void Cancel() override {
  304. if (session_) {
  305. session_->CancelPush(request_url_);
  306. }
  307. }
  308. const GURL& GetURL() const override { return request_url_; }
  309. NetworkIsolationKey GetNetworkIsolationKey() const override {
  310. if (session_) {
  311. return session_->quic_session_key().network_isolation_key();
  312. }
  313. return NetworkIsolationKey();
  314. }
  315. private:
  316. base::WeakPtr<QuicChromiumClientSession> session_;
  317. const GURL request_url_;
  318. };
  319. } // namespace
  320. QuicChromiumClientSession::Handle::Handle(
  321. const base::WeakPtr<QuicChromiumClientSession>& session,
  322. url::SchemeHostPort destination)
  323. : MultiplexedSessionHandle(session),
  324. session_(session),
  325. destination_(std::move(destination)),
  326. net_log_(session_->net_log()),
  327. was_handshake_confirmed_(session->OneRttKeysAvailable()),
  328. server_id_(session_->server_id()),
  329. quic_version_(session->connection()->version()) {
  330. DCHECK(session_);
  331. session_->AddHandle(this);
  332. }
  333. QuicChromiumClientSession::Handle::~Handle() {
  334. if (push_handle_) {
  335. auto* push_handle = push_handle_;
  336. push_handle_ = nullptr;
  337. push_handle->Cancel();
  338. }
  339. if (session_)
  340. session_->RemoveHandle(this);
  341. }
  342. void QuicChromiumClientSession::Handle::OnCryptoHandshakeConfirmed() {
  343. was_handshake_confirmed_ = true;
  344. }
  345. void QuicChromiumClientSession::Handle::OnSessionClosed(
  346. quic::ParsedQuicVersion quic_version,
  347. int net_error,
  348. quic::QuicErrorCode quic_error,
  349. bool port_migration_detected,
  350. bool quic_connection_migration_attempted,
  351. bool quic_connection_migration_successful,
  352. LoadTimingInfo::ConnectTiming connect_timing,
  353. bool was_ever_used) {
  354. session_ = nullptr;
  355. port_migration_detected_ = port_migration_detected;
  356. quic_connection_migration_attempted_ = quic_connection_migration_attempted;
  357. quic_connection_migration_successful_ = quic_connection_migration_successful;
  358. net_error_ = net_error;
  359. quic_error_ = quic_error;
  360. quic_version_ = quic_version;
  361. connect_timing_ = connect_timing;
  362. push_handle_ = nullptr;
  363. was_ever_used_ = was_ever_used;
  364. }
  365. bool QuicChromiumClientSession::Handle::IsConnected() const {
  366. return session_ != nullptr;
  367. }
  368. bool QuicChromiumClientSession::Handle::OneRttKeysAvailable() const {
  369. return was_handshake_confirmed_;
  370. }
  371. const LoadTimingInfo::ConnectTiming&
  372. QuicChromiumClientSession::Handle::GetConnectTiming() {
  373. if (!session_)
  374. return connect_timing_;
  375. return session_->GetConnectTiming();
  376. }
  377. void QuicChromiumClientSession::Handle::PopulateNetErrorDetails(
  378. NetErrorDetails* details) const {
  379. if (session_) {
  380. session_->PopulateNetErrorDetails(details);
  381. } else {
  382. details->quic_port_migration_detected = port_migration_detected_;
  383. details->quic_connection_error = quic_error_;
  384. details->quic_connection_migration_attempted =
  385. quic_connection_migration_attempted_;
  386. details->quic_connection_migration_successful =
  387. quic_connection_migration_successful_;
  388. }
  389. }
  390. quic::ParsedQuicVersion QuicChromiumClientSession::Handle::GetQuicVersion()
  391. const {
  392. if (!session_)
  393. return quic_version_;
  394. return session_->GetQuicVersion();
  395. }
  396. void QuicChromiumClientSession::Handle::ResetPromised(
  397. quic::QuicStreamId id,
  398. quic::QuicRstStreamErrorCode error_code) {
  399. if (session_)
  400. session_->ResetPromised(id, error_code);
  401. }
  402. std::unique_ptr<quic::QuicConnection::ScopedPacketFlusher>
  403. QuicChromiumClientSession::Handle::CreatePacketBundler() {
  404. if (!session_)
  405. return nullptr;
  406. return std::make_unique<quic::QuicConnection::ScopedPacketFlusher>(
  407. session_->connection());
  408. }
  409. bool QuicChromiumClientSession::Handle::SharesSameSession(
  410. const Handle& other) const {
  411. return session_.get() == other.session_.get();
  412. }
  413. int QuicChromiumClientSession::Handle::RendezvousWithPromised(
  414. const spdy::Http2HeaderBlock& headers,
  415. CompletionOnceCallback callback) {
  416. if (!session_)
  417. return ERR_CONNECTION_CLOSED;
  418. quic::QuicAsyncStatus push_status =
  419. session_->push_promise_index()->Try(headers, this, &push_handle_);
  420. switch (push_status) {
  421. case quic::QUIC_FAILURE:
  422. return ERR_FAILED;
  423. case quic::QUIC_SUCCESS:
  424. return OK;
  425. case quic::QUIC_PENDING:
  426. push_callback_ = std::move(callback);
  427. return ERR_IO_PENDING;
  428. }
  429. NOTREACHED();
  430. return ERR_UNEXPECTED;
  431. }
  432. int QuicChromiumClientSession::Handle::RequestStream(
  433. bool requires_confirmation,
  434. CompletionOnceCallback callback,
  435. const NetworkTrafficAnnotationTag& traffic_annotation) {
  436. DCHECK(!stream_request_);
  437. if (!session_)
  438. return ERR_CONNECTION_CLOSED;
  439. requires_confirmation |= session_->gquic_zero_rtt_disabled();
  440. // std::make_unique does not work because the StreamRequest constructor
  441. // is private.
  442. stream_request_ = base::WrapUnique(
  443. new StreamRequest(this, requires_confirmation, traffic_annotation));
  444. return stream_request_->StartRequest(std::move(callback));
  445. }
  446. std::unique_ptr<QuicChromiumClientStream::Handle>
  447. QuicChromiumClientSession::Handle::ReleaseStream() {
  448. DCHECK(stream_request_);
  449. auto handle = stream_request_->ReleaseStream();
  450. stream_request_.reset();
  451. return handle;
  452. }
  453. std::unique_ptr<QuicChromiumClientStream::Handle>
  454. QuicChromiumClientSession::Handle::ReleasePromisedStream() {
  455. DCHECK(push_stream_);
  456. return std::move(push_stream_);
  457. }
  458. int QuicChromiumClientSession::Handle::WaitForHandshakeConfirmation(
  459. CompletionOnceCallback callback) {
  460. if (!session_)
  461. return ERR_CONNECTION_CLOSED;
  462. return session_->WaitForHandshakeConfirmation(std::move(callback));
  463. }
  464. void QuicChromiumClientSession::Handle::CancelRequest(StreamRequest* request) {
  465. if (session_)
  466. session_->CancelRequest(request);
  467. }
  468. int QuicChromiumClientSession::Handle::TryCreateStream(StreamRequest* request) {
  469. if (!session_)
  470. return ERR_CONNECTION_CLOSED;
  471. return session_->TryCreateStream(request);
  472. }
  473. quic::QuicClientPushPromiseIndex*
  474. QuicChromiumClientSession::Handle::GetPushPromiseIndex() {
  475. if (!session_)
  476. return push_promise_index_;
  477. return session_->push_promise_index();
  478. }
  479. int QuicChromiumClientSession::Handle::GetPeerAddress(
  480. IPEndPoint* address) const {
  481. if (!session_)
  482. return ERR_CONNECTION_CLOSED;
  483. *address = ToIPEndPoint(session_->peer_address());
  484. return OK;
  485. }
  486. int QuicChromiumClientSession::Handle::GetSelfAddress(
  487. IPEndPoint* address) const {
  488. if (!session_)
  489. return ERR_CONNECTION_CLOSED;
  490. *address = ToIPEndPoint(session_->self_address());
  491. return OK;
  492. }
  493. bool QuicChromiumClientSession::Handle::WasEverUsed() const {
  494. if (!session_)
  495. return was_ever_used_;
  496. return session_->WasConnectionEverUsed();
  497. }
  498. const std::set<std::string>&
  499. QuicChromiumClientSession::Handle::GetDnsAliasesForSessionKey(
  500. const QuicSessionKey& key) const {
  501. static const base::NoDestructor<std::set<std::string>> emptyset_result;
  502. return session_ ? session_->GetDnsAliasesForSessionKey(key)
  503. : *emptyset_result;
  504. }
  505. bool QuicChromiumClientSession::Handle::CheckVary(
  506. const spdy::Http2HeaderBlock& client_request,
  507. const spdy::Http2HeaderBlock& promise_request,
  508. const spdy::Http2HeaderBlock& promise_response) {
  509. HttpRequestInfo promise_request_info;
  510. ConvertHeaderBlockToHttpRequestHeaders(promise_request,
  511. &promise_request_info.extra_headers);
  512. HttpRequestInfo client_request_info;
  513. ConvertHeaderBlockToHttpRequestHeaders(client_request,
  514. &client_request_info.extra_headers);
  515. HttpResponseInfo promise_response_info;
  516. if (SpdyHeadersToHttpResponse(promise_response, &promise_response_info) !=
  517. OK) {
  518. DLOG(WARNING) << "Invalid headers";
  519. return false;
  520. }
  521. HttpVaryData vary_data;
  522. if (!vary_data.Init(promise_request_info,
  523. *promise_response_info.headers.get())) {
  524. // Promise didn't contain valid vary info, so URL match was sufficient.
  525. return true;
  526. }
  527. // Now compare the client request for matching.
  528. return vary_data.MatchesRequest(client_request_info,
  529. *promise_response_info.headers.get());
  530. }
  531. void QuicChromiumClientSession::Handle::OnRendezvousResult(
  532. quic::QuicSpdyStream* stream) {
  533. DCHECK(!push_stream_);
  534. int rv = ERR_FAILED;
  535. if (stream) {
  536. rv = OK;
  537. push_stream_ =
  538. static_cast<QuicChromiumClientStream*>(stream)->CreateHandle();
  539. }
  540. if (push_callback_) {
  541. DCHECK(push_handle_);
  542. push_handle_ = nullptr;
  543. std::move(push_callback_).Run(rv);
  544. }
  545. }
  546. QuicChromiumClientSession::StreamRequest::StreamRequest(
  547. QuicChromiumClientSession::Handle* session,
  548. bool requires_confirmation,
  549. const NetworkTrafficAnnotationTag& traffic_annotation)
  550. : session_(session),
  551. requires_confirmation_(requires_confirmation),
  552. traffic_annotation_(traffic_annotation) {}
  553. QuicChromiumClientSession::StreamRequest::~StreamRequest() {
  554. if (stream_)
  555. stream_->Reset(quic::QUIC_STREAM_CANCELLED);
  556. if (session_)
  557. session_->CancelRequest(this);
  558. }
  559. int QuicChromiumClientSession::StreamRequest::StartRequest(
  560. CompletionOnceCallback callback) {
  561. if (!session_->IsConnected())
  562. return ERR_CONNECTION_CLOSED;
  563. next_state_ = STATE_WAIT_FOR_CONFIRMATION;
  564. int rv = DoLoop(OK);
  565. if (rv == ERR_IO_PENDING)
  566. callback_ = std::move(callback);
  567. return rv;
  568. }
  569. std::unique_ptr<QuicChromiumClientStream::Handle>
  570. QuicChromiumClientSession::StreamRequest::ReleaseStream() {
  571. DCHECK(stream_);
  572. return std::move(stream_);
  573. }
  574. void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess(
  575. std::unique_ptr<QuicChromiumClientStream::Handle> stream) {
  576. DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
  577. stream_ = std::move(stream);
  578. // This method is called even when the request completes synchronously.
  579. if (callback_)
  580. DoCallback(OK);
  581. }
  582. void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure(
  583. int rv) {
  584. DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
  585. // This method is called even when the request completes synchronously.
  586. if (callback_) {
  587. // Avoid re-entrancy if the callback calls into the session.
  588. base::ThreadTaskRunnerHandle::Get()->PostTask(
  589. FROM_HERE,
  590. base::BindOnce(&QuicChromiumClientSession::StreamRequest::DoCallback,
  591. weak_factory_.GetWeakPtr(), rv));
  592. }
  593. }
  594. void QuicChromiumClientSession::StreamRequest::OnIOComplete(int rv) {
  595. rv = DoLoop(rv);
  596. if (rv != ERR_IO_PENDING && !callback_.is_null()) {
  597. DoCallback(rv);
  598. }
  599. }
  600. void QuicChromiumClientSession::StreamRequest::DoCallback(int rv) {
  601. CHECK_NE(rv, ERR_IO_PENDING);
  602. CHECK(!callback_.is_null());
  603. // The client callback can do anything, including destroying this class,
  604. // so any pending callback must be issued after everything else is done.
  605. std::move(callback_).Run(rv);
  606. }
  607. int QuicChromiumClientSession::StreamRequest::DoLoop(int rv) {
  608. do {
  609. State state = next_state_;
  610. next_state_ = STATE_NONE;
  611. switch (state) {
  612. case STATE_WAIT_FOR_CONFIRMATION:
  613. CHECK_EQ(OK, rv);
  614. rv = DoWaitForConfirmation();
  615. break;
  616. case STATE_WAIT_FOR_CONFIRMATION_COMPLETE:
  617. rv = DoWaitForConfirmationComplete(rv);
  618. break;
  619. case STATE_REQUEST_STREAM:
  620. CHECK_EQ(OK, rv);
  621. rv = DoRequestStream();
  622. break;
  623. case STATE_REQUEST_STREAM_COMPLETE:
  624. rv = DoRequestStreamComplete(rv);
  625. break;
  626. default:
  627. NOTREACHED() << "next_state_: " << next_state_;
  628. break;
  629. }
  630. } while (next_state_ != STATE_NONE && next_state_ && rv != ERR_IO_PENDING);
  631. return rv;
  632. }
  633. int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmation() {
  634. next_state_ = STATE_WAIT_FOR_CONFIRMATION_COMPLETE;
  635. if (requires_confirmation_) {
  636. return session_->WaitForHandshakeConfirmation(
  637. base::BindOnce(&QuicChromiumClientSession::StreamRequest::OnIOComplete,
  638. weak_factory_.GetWeakPtr()));
  639. }
  640. return OK;
  641. }
  642. int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmationComplete(
  643. int rv) {
  644. DCHECK_NE(ERR_IO_PENDING, rv);
  645. if (rv < 0)
  646. return rv;
  647. next_state_ = STATE_REQUEST_STREAM;
  648. return OK;
  649. }
  650. int QuicChromiumClientSession::StreamRequest::DoRequestStream() {
  651. next_state_ = STATE_REQUEST_STREAM_COMPLETE;
  652. return session_->TryCreateStream(this);
  653. }
  654. int QuicChromiumClientSession::StreamRequest::DoRequestStreamComplete(int rv) {
  655. DCHECK(rv == OK || !stream_);
  656. return rv;
  657. }
  658. QuicChromiumClientSession::QuicChromiumPathValidationContext::
  659. QuicChromiumPathValidationContext(
  660. const quic::QuicSocketAddress& self_address,
  661. const quic::QuicSocketAddress& peer_address,
  662. handles::NetworkHandle network,
  663. std::unique_ptr<DatagramClientSocket> socket,
  664. std::unique_ptr<QuicChromiumPacketWriter> writer,
  665. std::unique_ptr<QuicChromiumPacketReader> reader)
  666. : QuicPathValidationContext(self_address, peer_address),
  667. network_handle_(network),
  668. socket_(std::move(socket)),
  669. writer_(std::move(writer)),
  670. reader_(std::move(reader)) {}
  671. QuicChromiumClientSession::QuicChromiumPathValidationContext::
  672. ~QuicChromiumPathValidationContext() = default;
  673. handles::NetworkHandle
  674. QuicChromiumClientSession::QuicChromiumPathValidationContext::network() {
  675. return network_handle_;
  676. }
  677. quic::QuicPacketWriter*
  678. QuicChromiumClientSession::QuicChromiumPathValidationContext::WriterToUse() {
  679. return writer_.get();
  680. }
  681. std::unique_ptr<QuicChromiumPacketWriter>
  682. QuicChromiumClientSession::QuicChromiumPathValidationContext::ReleaseWriter() {
  683. return std::move(writer_);
  684. }
  685. std::unique_ptr<DatagramClientSocket>
  686. QuicChromiumClientSession::QuicChromiumPathValidationContext::ReleaseSocket() {
  687. return std::move(socket_);
  688. }
  689. std::unique_ptr<QuicChromiumPacketReader>
  690. QuicChromiumClientSession::QuicChromiumPathValidationContext::ReleaseReader() {
  691. return std::move(reader_);
  692. }
  693. QuicChromiumClientSession::ConnectionMigrationValidationResultDelegate::
  694. ConnectionMigrationValidationResultDelegate(
  695. QuicChromiumClientSession* session)
  696. : session_(session) {}
  697. void QuicChromiumClientSession::ConnectionMigrationValidationResultDelegate::
  698. OnPathValidationSuccess(
  699. std::unique_ptr<quic::QuicPathValidationContext> context,
  700. quic::QuicTime start_time) {
  701. auto* chrome_context =
  702. static_cast<QuicChromiumPathValidationContext*>(context.get());
  703. session_->OnConnectionMigrationProbeSucceeded(
  704. chrome_context->network(), chrome_context->peer_address(),
  705. chrome_context->self_address(), chrome_context->ReleaseSocket(),
  706. chrome_context->ReleaseWriter(), chrome_context->ReleaseReader());
  707. }
  708. void QuicChromiumClientSession::ConnectionMigrationValidationResultDelegate::
  709. OnPathValidationFailure(
  710. std::unique_ptr<quic::QuicPathValidationContext> context) {
  711. session_->connection()->OnPathValidationFailureAtClient();
  712. // Note that socket, packet writer, and packet reader in |context| will be
  713. // discarded.
  714. auto* chrome_context =
  715. static_cast<QuicChromiumPathValidationContext*>(context.get());
  716. session_->OnProbeFailed(chrome_context->network(),
  717. chrome_context->peer_address());
  718. }
  719. QuicChromiumClientSession::PortMigrationValidationResultDelegate::
  720. PortMigrationValidationResultDelegate(QuicChromiumClientSession* session)
  721. : session_(session) {}
  722. void QuicChromiumClientSession::PortMigrationValidationResultDelegate::
  723. OnPathValidationSuccess(
  724. std::unique_ptr<quic::QuicPathValidationContext> context,
  725. quic::QuicTime start_time) {
  726. auto* chrome_context =
  727. static_cast<QuicChromiumPathValidationContext*>(context.get());
  728. session_->OnPortMigrationProbeSucceeded(
  729. chrome_context->network(), chrome_context->peer_address(),
  730. chrome_context->self_address(), chrome_context->ReleaseSocket(),
  731. chrome_context->ReleaseWriter(), chrome_context->ReleaseReader());
  732. }
  733. void QuicChromiumClientSession::PortMigrationValidationResultDelegate::
  734. OnPathValidationFailure(
  735. std::unique_ptr<quic::QuicPathValidationContext> context) {
  736. session_->connection()->OnPathValidationFailureAtClient();
  737. // Note that socket, packet writer, and packet reader in |context| will be
  738. // discarded.
  739. auto* chrome_context =
  740. static_cast<QuicChromiumPathValidationContext*>(context.get());
  741. session_->OnProbeFailed(chrome_context->network(),
  742. chrome_context->peer_address());
  743. }
  744. QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  745. QuicChromiumPathValidationWriterDelegate(
  746. QuicChromiumClientSession* session,
  747. base::SequencedTaskRunner* task_runner)
  748. : session_(session),
  749. task_runner_(task_runner),
  750. network_(handles::kInvalidNetworkHandle) {}
  751. QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  752. ~QuicChromiumPathValidationWriterDelegate() = default;
  753. int QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  754. HandleWriteError(
  755. int error_code,
  756. scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> last_packet) {
  757. // Write error on the probing network is not recoverable.
  758. DVLOG(1) << "Probing packet encounters write error " << error_code;
  759. // Post a task to notify |session_| that this probe failed and cancel
  760. // undergoing probing, which will delete the packet writer.
  761. task_runner_->PostTask(
  762. FROM_HERE,
  763. base::BindOnce(
  764. &QuicChromiumPathValidationWriterDelegate::NotifySessionProbeFailed,
  765. weak_factory_.GetWeakPtr(), network_));
  766. return error_code;
  767. }
  768. void QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  769. OnWriteError(int error_code) {
  770. NotifySessionProbeFailed(network_);
  771. }
  772. void QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  773. OnWriteUnblocked() {}
  774. void QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  775. NotifySessionProbeFailed(handles::NetworkHandle network) {
  776. session_->OnProbeFailed(network, peer_address_);
  777. }
  778. void QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  779. set_peer_address(const quic::QuicSocketAddress& peer_address) {
  780. peer_address_ = peer_address;
  781. }
  782. void QuicChromiumClientSession::QuicChromiumPathValidationWriterDelegate::
  783. set_network(handles::NetworkHandle network) {
  784. network_ = network;
  785. }
  786. QuicChromiumClientSession::QuicChromiumClientSession(
  787. quic::QuicConnection* connection,
  788. std::unique_ptr<DatagramClientSocket> socket,
  789. QuicStreamFactory* stream_factory,
  790. QuicCryptoClientStreamFactory* crypto_client_stream_factory,
  791. const quic::QuicClock* clock,
  792. TransportSecurityState* transport_security_state,
  793. SSLConfigService* ssl_config_service,
  794. std::unique_ptr<QuicServerInfo> server_info,
  795. const QuicSessionKey& session_key,
  796. bool require_confirmation,
  797. bool migrate_session_early_v2,
  798. bool migrate_sessions_on_network_change_v2,
  799. handles::NetworkHandle default_network,
  800. quic::QuicTime::Delta retransmittable_on_wire_timeout,
  801. bool migrate_idle_session,
  802. bool allow_port_migration,
  803. base::TimeDelta idle_migration_period,
  804. base::TimeDelta max_time_on_non_default_network,
  805. int max_migrations_to_non_default_network_on_write_error,
  806. int max_migrations_to_non_default_network_on_path_degrading,
  807. int yield_after_packets,
  808. quic::QuicTime::Delta yield_after_duration,
  809. bool headers_include_h2_stream_dependency,
  810. int cert_verify_flags,
  811. const quic::QuicConfig& config,
  812. std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config,
  813. const char* const connection_description,
  814. base::TimeTicks dns_resolution_start_time,
  815. base::TimeTicks dns_resolution_end_time,
  816. std::unique_ptr<quic::QuicClientPushPromiseIndex> push_promise_index,
  817. ServerPushDelegate* push_delegate,
  818. const base::TickClock* tick_clock,
  819. base::SequencedTaskRunner* task_runner,
  820. std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
  821. NetLog* net_log)
  822. : quic::QuicSpdyClientSessionBase(connection,
  823. push_promise_index.get(),
  824. config,
  825. connection->supported_versions()),
  826. session_key_(session_key),
  827. require_confirmation_(require_confirmation),
  828. migrate_session_early_v2_(migrate_session_early_v2),
  829. migrate_session_on_network_change_v2_(
  830. migrate_sessions_on_network_change_v2),
  831. migrate_idle_session_(migrate_idle_session),
  832. allow_port_migration_(allow_port_migration),
  833. idle_migration_period_(idle_migration_period),
  834. max_time_on_non_default_network_(max_time_on_non_default_network),
  835. max_migrations_to_non_default_network_on_write_error_(
  836. max_migrations_to_non_default_network_on_write_error),
  837. max_migrations_to_non_default_network_on_path_degrading_(
  838. max_migrations_to_non_default_network_on_path_degrading),
  839. clock_(clock),
  840. yield_after_packets_(yield_after_packets),
  841. yield_after_duration_(yield_after_duration),
  842. most_recent_path_degrading_timestamp_(base::TimeTicks()),
  843. most_recent_network_disconnected_timestamp_(base::TimeTicks()),
  844. tick_clock_(tick_clock),
  845. most_recent_stream_close_time_(tick_clock_->NowTicks()),
  846. most_recent_write_error_timestamp_(base::TimeTicks()),
  847. crypto_config_(std::move(crypto_config)),
  848. stream_factory_(stream_factory),
  849. transport_security_state_(transport_security_state),
  850. ssl_config_service_(ssl_config_service),
  851. server_info_(std::move(server_info)),
  852. task_runner_(task_runner),
  853. net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::QUIC_SESSION)),
  854. logger_(std::make_unique<QuicConnectionLogger>(
  855. this,
  856. connection_description,
  857. std::move(socket_performance_watcher),
  858. net_log_)),
  859. http3_logger_(VersionUsesHttp3(connection->transport_version())
  860. ? std::make_unique<QuicHttp3Logger>(net_log_)
  861. : nullptr),
  862. push_delegate_(push_delegate),
  863. headers_include_h2_stream_dependency_(
  864. headers_include_h2_stream_dependency),
  865. push_promise_index_(std::move(push_promise_index)),
  866. path_validation_writer_delegate_(this, task_runner_) {
  867. default_network_ = default_network;
  868. auto* socket_raw = socket.get();
  869. sockets_.push_back(std::move(socket));
  870. packet_readers_.push_back(std::make_unique<QuicChromiumPacketReader>(
  871. sockets_.back().get(), clock, this, yield_after_packets,
  872. yield_after_duration, net_log_));
  873. CHECK_EQ(packet_readers_.size(), sockets_.size());
  874. crypto_stream_ = crypto_client_stream_factory->CreateQuicCryptoClientStream(
  875. session_key.server_id(), this,
  876. std::make_unique<ProofVerifyContextChromium>(cert_verify_flags, net_log_),
  877. crypto_config_->GetConfig());
  878. if (VersionUsesHttp3(transport_version()))
  879. set_debug_visitor(http3_logger_.get());
  880. connection->set_debug_visitor(logger_.get());
  881. connection->set_creator_debug_delegate(logger_.get());
  882. migrate_back_to_default_timer_.SetTaskRunner(task_runner_.get());
  883. net_log_.BeginEvent(NetLogEventType::QUIC_SESSION, [&] {
  884. return NetLogQuicClientSessionParams(
  885. &session_key, connection_id(), connection->client_connection_id(),
  886. supported_versions(), cert_verify_flags, require_confirmation_);
  887. });
  888. IPEndPoint address;
  889. if (socket_raw && socket_raw->GetLocalAddress(&address) == OK &&
  890. address.GetFamily() == ADDRESS_FAMILY_IPV6) {
  891. connection->SetMaxPacketLength(connection->max_packet_length() -
  892. kAdditionalOverheadForIPv6);
  893. }
  894. connect_timing_.dns_start = dns_resolution_start_time;
  895. connect_timing_.dns_end = dns_resolution_end_time;
  896. if (!retransmittable_on_wire_timeout.IsZero()) {
  897. connection->set_initial_retransmittable_on_wire_timeout(
  898. retransmittable_on_wire_timeout);
  899. }
  900. }
  901. QuicChromiumClientSession::~QuicChromiumClientSession() {
  902. // This is referenced by the parent class's destructor, so have to delete it
  903. // asynchronously, unfortunately. Don't use DeleteSoon, since that leaks if
  904. // the task is not run, which is often the case in tests.
  905. base::ThreadTaskRunnerHandle::Get()->PostTask(
  906. FROM_HERE,
  907. base::BindOnce([](std::unique_ptr<quic::QuicClientPushPromiseIndex>
  908. push_promise_index) {},
  909. std::move(push_promise_index_)));
  910. DCHECK(callback_.is_null());
  911. for (auto& observer : connectivity_observer_list_)
  912. observer.OnSessionRemoved(this);
  913. net_log_.EndEvent(NetLogEventType::QUIC_SESSION);
  914. DCHECK(waiting_for_confirmation_callbacks_.empty());
  915. DCHECK(!HasActiveRequestStreams());
  916. DCHECK(handles_.empty());
  917. if (!stream_requests_.empty()) {
  918. // The session must be closed before it is destroyed.
  919. CancelAllRequests(ERR_UNEXPECTED);
  920. }
  921. connection()->set_debug_visitor(nullptr);
  922. if (connection()->connected()) {
  923. // Ensure that the connection is closed by the time the session is
  924. // destroyed.
  925. connection()->CloseConnection(quic::QUIC_PEER_GOING_AWAY,
  926. "session torn down",
  927. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  928. }
  929. if (IsEncryptionEstablished())
  930. RecordHandshakeState(STATE_ENCRYPTION_ESTABLISHED);
  931. if (OneRttKeysAvailable())
  932. RecordHandshakeState(STATE_HANDSHAKE_CONFIRMED);
  933. else
  934. RecordHandshakeState(STATE_FAILED);
  935. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.NumTotalStreams",
  936. num_total_streams_);
  937. UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumSentClientHellos",
  938. crypto_stream_->num_sent_client_hellos());
  939. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.Pushed", streams_pushed_count_);
  940. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedAndClaimed",
  941. streams_pushed_and_claimed_count_);
  942. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedBytes", bytes_pushed_count_);
  943. DCHECK_LE(bytes_pushed_and_unclaimed_count_, bytes_pushed_count_);
  944. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedAndUnclaimedBytes",
  945. bytes_pushed_and_unclaimed_count_);
  946. if (!OneRttKeysAvailable())
  947. return;
  948. // Sending one client_hello means we had zero handshake-round-trips.
  949. int round_trip_handshakes = crypto_stream_->num_sent_client_hellos() - 1;
  950. SSLInfo ssl_info;
  951. // QUIC supports only secure urls.
  952. if (GetSSLInfo(&ssl_info) && ssl_info.cert.get()) {
  953. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectRandomPortForHTTPS",
  954. round_trip_handshakes, 1, 3, 4);
  955. if (require_confirmation_) {
  956. UMA_HISTOGRAM_CUSTOM_COUNTS(
  957. "Net.QuicSession.ConnectRandomPortRequiringConfirmationForHTTPS",
  958. round_trip_handshakes, 1, 3, 4);
  959. }
  960. }
  961. const quic::QuicConnectionStats stats = connection()->GetStats();
  962. // The MTU used by QUIC is limited to a fairly small set of predefined values
  963. // (initial values and MTU discovery values), but does not fare well when
  964. // bucketed. Because of that, a sparse histogram is used here.
  965. base::UmaHistogramSparse("Net.QuicSession.ClientSideMtu", stats.egress_mtu);
  966. base::UmaHistogramSparse("Net.QuicSession.ServerSideMtu", stats.ingress_mtu);
  967. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.MtuProbesSent",
  968. connection()->mtu_probe_count());
  969. if (stats.packets_sent >= 100) {
  970. // Used to monitor for regressions that effect large uploads.
  971. UMA_HISTOGRAM_COUNTS_1000(
  972. "Net.QuicSession.PacketRetransmitsPerMille",
  973. 1000 * stats.packets_retransmitted / stats.packets_sent);
  974. }
  975. if (stats.max_sequence_reordering == 0)
  976. return;
  977. const base::HistogramBase::Sample kMaxReordering = 100;
  978. base::HistogramBase::Sample reordering = kMaxReordering;
  979. if (stats.min_rtt_us > 0) {
  980. reordering = static_cast<base::HistogramBase::Sample>(
  981. 100 * stats.max_time_reordering_us / stats.min_rtt_us);
  982. }
  983. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.MaxReorderingTime", reordering,
  984. 1, kMaxReordering, 50);
  985. if (stats.min_rtt_us > 100 * 1000) {
  986. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.MaxReorderingTimeLongRtt",
  987. reordering, 1, kMaxReordering, 50);
  988. }
  989. UMA_HISTOGRAM_COUNTS_1M(
  990. "Net.QuicSession.MaxReordering",
  991. static_cast<base::HistogramBase::Sample>(stats.max_sequence_reordering));
  992. }
  993. void QuicChromiumClientSession::Initialize() {
  994. set_max_inbound_header_list_size(kQuicMaxHeaderListSize);
  995. if (config()->HasClientRequestedIndependentOption(
  996. quic::kQLVE, quic::Perspective::IS_CLIENT)) {
  997. connection()->EnableLegacyVersionEncapsulation(session_key_.host());
  998. }
  999. quic::QuicSpdyClientSessionBase::Initialize();
  1000. }
  1001. size_t QuicChromiumClientSession::WriteHeadersOnHeadersStream(
  1002. quic::QuicStreamId id,
  1003. spdy::Http2HeaderBlock headers,
  1004. bool fin,
  1005. const spdy::SpdyStreamPrecedence& precedence,
  1006. quiche::QuicheReferenceCountedPointer<quic::QuicAckListenerInterface>
  1007. ack_listener) {
  1008. spdy::SpdyStreamId parent_stream_id = 0;
  1009. int weight = 0;
  1010. bool exclusive = false;
  1011. if (headers_include_h2_stream_dependency_) {
  1012. priority_dependency_state_.OnStreamCreation(id, precedence.spdy3_priority(),
  1013. &parent_stream_id, &weight,
  1014. &exclusive);
  1015. } else {
  1016. weight = spdy::Spdy3PriorityToHttp2Weight(precedence.spdy3_priority());
  1017. }
  1018. return WriteHeadersOnHeadersStreamImpl(id, std::move(headers), fin,
  1019. parent_stream_id, weight, exclusive,
  1020. std::move(ack_listener));
  1021. }
  1022. void QuicChromiumClientSession::UnregisterStreamPriority(quic::QuicStreamId id,
  1023. bool is_static) {
  1024. if (headers_include_h2_stream_dependency_ && !is_static) {
  1025. priority_dependency_state_.OnStreamDestruction(id);
  1026. }
  1027. quic::QuicSpdySession::UnregisterStreamPriority(id, is_static);
  1028. }
  1029. void QuicChromiumClientSession::UpdateStreamPriority(
  1030. quic::QuicStreamId id,
  1031. const spdy::SpdyStreamPrecedence& new_precedence) {
  1032. if (headers_include_h2_stream_dependency_ ||
  1033. VersionUsesHttp3(connection()->transport_version())) {
  1034. auto updates = priority_dependency_state_.OnStreamUpdate(
  1035. id, new_precedence.spdy3_priority());
  1036. for (auto update : updates) {
  1037. if (!VersionUsesHttp3(connection()->transport_version())) {
  1038. WritePriority(update.id, update.parent_stream_id, update.weight,
  1039. update.exclusive);
  1040. }
  1041. }
  1042. }
  1043. quic::QuicSpdySession::UpdateStreamPriority(id, new_precedence);
  1044. }
  1045. void QuicChromiumClientSession::OnHttp3GoAway(uint64_t id) {
  1046. quic::QuicSpdySession::OnHttp3GoAway(id);
  1047. NotifyFactoryOfSessionGoingAway();
  1048. PerformActionOnActiveStreams([id](quic::QuicStream* stream) {
  1049. if (stream->id() >= id) {
  1050. static_cast<QuicChromiumClientStream*>(stream)->OnError(
  1051. ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED);
  1052. }
  1053. return true;
  1054. });
  1055. }
  1056. void QuicChromiumClientSession::OnAcceptChFrameReceivedViaAlps(
  1057. const quic::AcceptChFrame& frame) {
  1058. bool has_valid_entry = false;
  1059. bool has_invalid_entry = false;
  1060. for (const auto& entry : frame.entries) {
  1061. const url::SchemeHostPort scheme_host_port(GURL(entry.origin));
  1062. // |entry.origin| must be a valid SchemeHostPort.
  1063. std::string serialized = scheme_host_port.Serialize();
  1064. if (serialized.empty() || entry.origin != serialized) {
  1065. has_invalid_entry = true;
  1066. continue;
  1067. }
  1068. has_valid_entry = true;
  1069. accept_ch_entries_received_via_alps_.insert(
  1070. std::make_pair(std::move(scheme_host_port), entry.value));
  1071. net_log_.AddEvent(NetLogEventType::QUIC_ACCEPT_CH_FRAME_RECEIVED,
  1072. [&] { return NetLogAcceptChFrameReceivedParams(entry); });
  1073. }
  1074. LogAcceptChFrameReceivedHistogram(has_valid_entry, has_invalid_entry);
  1075. }
  1076. void QuicChromiumClientSession::AddHandle(Handle* handle) {
  1077. if (going_away_) {
  1078. handle->OnSessionClosed(connection()->version(), ERR_UNEXPECTED, error(),
  1079. port_migration_detected_,
  1080. quic_connection_migration_attempted_,
  1081. quic_connection_migration_successful_,
  1082. GetConnectTiming(), WasConnectionEverUsed());
  1083. return;
  1084. }
  1085. DCHECK(!base::Contains(handles_, handle));
  1086. handles_.insert(handle);
  1087. }
  1088. void QuicChromiumClientSession::RemoveHandle(Handle* handle) {
  1089. DCHECK(base::Contains(handles_, handle));
  1090. handles_.erase(handle);
  1091. }
  1092. void QuicChromiumClientSession::AddConnectivityObserver(
  1093. ConnectivityObserver* observer) {
  1094. connectivity_observer_list_.AddObserver(observer);
  1095. observer->OnSessionRegistered(this, GetCurrentNetwork());
  1096. }
  1097. void QuicChromiumClientSession::RemoveConnectivityObserver(
  1098. ConnectivityObserver* observer) {
  1099. connectivity_observer_list_.RemoveObserver(observer);
  1100. }
  1101. // TODO(zhongyi): replace migration_session_* booleans with
  1102. // ConnectionMigrationMode.
  1103. ConnectionMigrationMode QuicChromiumClientSession::connection_migration_mode()
  1104. const {
  1105. if (migrate_session_early_v2_)
  1106. return ConnectionMigrationMode::FULL_MIGRATION_V2;
  1107. if (migrate_session_on_network_change_v2_)
  1108. return ConnectionMigrationMode::NO_MIGRATION_ON_PATH_DEGRADING_V2;
  1109. return ConnectionMigrationMode::NO_MIGRATION;
  1110. }
  1111. int QuicChromiumClientSession::WaitForHandshakeConfirmation(
  1112. CompletionOnceCallback callback) {
  1113. if (!connection()->connected())
  1114. return ERR_CONNECTION_CLOSED;
  1115. if (OneRttKeysAvailable())
  1116. return OK;
  1117. waiting_for_confirmation_callbacks_.push_back(std::move(callback));
  1118. return ERR_IO_PENDING;
  1119. }
  1120. int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) {
  1121. if (goaway_received()) {
  1122. DVLOG(1) << "Going away.";
  1123. return ERR_CONNECTION_CLOSED;
  1124. }
  1125. if (!connection()->connected()) {
  1126. DVLOG(1) << "Already closed.";
  1127. return ERR_CONNECTION_CLOSED;
  1128. }
  1129. if (going_away_) {
  1130. return ERR_CONNECTION_CLOSED;
  1131. }
  1132. bool can_open_next = CanOpenNextOutgoingBidirectionalStream();
  1133. if (can_open_next) {
  1134. request->stream_ =
  1135. CreateOutgoingReliableStreamImpl(request->traffic_annotation())
  1136. ->CreateHandle();
  1137. return OK;
  1138. }
  1139. request->pending_start_time_ = tick_clock_->NowTicks();
  1140. stream_requests_.push_back(request);
  1141. UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.NumPendingStreamRequests",
  1142. stream_requests_.size());
  1143. return ERR_IO_PENDING;
  1144. }
  1145. void QuicChromiumClientSession::CancelRequest(StreamRequest* request) {
  1146. // Remove |request| from the queue while preserving the order of the
  1147. // other elements.
  1148. auto it =
  1149. std::find(stream_requests_.begin(), stream_requests_.end(), request);
  1150. if (it != stream_requests_.end()) {
  1151. it = stream_requests_.erase(it);
  1152. }
  1153. }
  1154. bool QuicChromiumClientSession::ShouldCreateOutgoingBidirectionalStream() {
  1155. if (!crypto_stream_->encryption_established()) {
  1156. DVLOG(1) << "Encryption not active so no outgoing stream created.";
  1157. return false;
  1158. }
  1159. if (!CanOpenNextOutgoingBidirectionalStream()) {
  1160. DVLOG(1) << "Failed to create a new outgoing stream. "
  1161. << "Already " << GetNumActiveStreams() << " open.";
  1162. return false;
  1163. }
  1164. if (goaway_received()) {
  1165. DVLOG(1) << "Failed to create a new outgoing stream. "
  1166. << "Already received goaway.";
  1167. return false;
  1168. }
  1169. if (going_away_) {
  1170. return false;
  1171. }
  1172. return true;
  1173. }
  1174. bool QuicChromiumClientSession::ShouldCreateOutgoingUnidirectionalStream() {
  1175. NOTREACHED() << "Try to create outgoing unidirectional streams";
  1176. return false;
  1177. }
  1178. bool QuicChromiumClientSession::WasConnectionEverUsed() {
  1179. const quic::QuicConnectionStats& stats = connection()->GetStats();
  1180. return stats.bytes_sent > 0 || stats.bytes_received > 0;
  1181. }
  1182. QuicChromiumClientStream*
  1183. QuicChromiumClientSession::CreateOutgoingBidirectionalStream() {
  1184. NOTREACHED() << "CreateOutgoingReliableStreamImpl should be called directly";
  1185. return nullptr;
  1186. }
  1187. QuicChromiumClientStream*
  1188. QuicChromiumClientSession::CreateOutgoingUnidirectionalStream() {
  1189. NOTREACHED() << "Try to create outgoing unidirectional stream";
  1190. return nullptr;
  1191. }
  1192. QuicChromiumClientStream*
  1193. QuicChromiumClientSession::CreateOutgoingReliableStreamImpl(
  1194. const NetworkTrafficAnnotationTag& traffic_annotation) {
  1195. DCHECK(connection()->connected());
  1196. QuicChromiumClientStream* stream = new QuicChromiumClientStream(
  1197. GetNextOutgoingBidirectionalStreamId(), this, quic::BIDIRECTIONAL,
  1198. net_log_, traffic_annotation);
  1199. ActivateStream(base::WrapUnique(stream));
  1200. ++num_total_streams_;
  1201. UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.NumOpenStreams",
  1202. GetNumActiveStreams());
  1203. // The previous histogram puts 100 in a bucket betweeen 86-113 which does
  1204. // not shed light on if chrome ever things it has more than 100 streams open.
  1205. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.TooManyOpenStreams",
  1206. GetNumActiveStreams() > 100);
  1207. return stream;
  1208. }
  1209. quic::QuicCryptoClientStream*
  1210. QuicChromiumClientSession::GetMutableCryptoStream() {
  1211. return crypto_stream_.get();
  1212. }
  1213. const quic::QuicCryptoClientStream* QuicChromiumClientSession::GetCryptoStream()
  1214. const {
  1215. return crypto_stream_.get();
  1216. }
  1217. int QuicChromiumClientSession::GetRemoteEndpoint(IPEndPoint* endpoint) {
  1218. *endpoint = ToIPEndPoint(peer_address());
  1219. return OK;
  1220. }
  1221. // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways
  1222. // we learn about SSL info (sync vs async vs cached).
  1223. bool QuicChromiumClientSession::GetSSLInfo(SSLInfo* ssl_info) const {
  1224. ssl_info->Reset();
  1225. if (!cert_verify_result_) {
  1226. return false;
  1227. }
  1228. ssl_info->cert_status = cert_verify_result_->cert_status;
  1229. ssl_info->cert = cert_verify_result_->verified_cert;
  1230. ssl_info->public_key_hashes = cert_verify_result_->public_key_hashes;
  1231. ssl_info->is_issued_by_known_root =
  1232. cert_verify_result_->is_issued_by_known_root;
  1233. ssl_info->pkp_bypassed = pkp_bypassed_;
  1234. ssl_info->client_cert_sent = false;
  1235. ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL;
  1236. ssl_info->pinning_failure_log = pinning_failure_log_;
  1237. ssl_info->is_fatal_cert_error = is_fatal_cert_error_;
  1238. ssl_info->signed_certificate_timestamps = cert_verify_result_->scts;
  1239. ssl_info->ct_policy_compliance = cert_verify_result_->policy_compliance;
  1240. const auto& crypto_params = crypto_stream_->crypto_negotiated_params();
  1241. uint16_t cipher_suite;
  1242. if (connection()->version().UsesTls()) {
  1243. cipher_suite = crypto_params.cipher_suite;
  1244. } else {
  1245. // Map QUIC AEADs to the corresponding TLS 1.3 cipher. OpenSSL's cipher
  1246. // suite numbers begin with a stray 0x03, so mask them off.
  1247. quic::QuicTag aead = crypto_params.aead;
  1248. switch (aead) {
  1249. case quic::kAESG:
  1250. cipher_suite = TLS1_CK_AES_128_GCM_SHA256 & 0xffff;
  1251. break;
  1252. case quic::kCC20:
  1253. cipher_suite = TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff;
  1254. break;
  1255. default:
  1256. NOTREACHED();
  1257. return false;
  1258. }
  1259. }
  1260. int ssl_connection_status = 0;
  1261. SSLConnectionStatusSetCipherSuite(cipher_suite, &ssl_connection_status);
  1262. SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_QUIC,
  1263. &ssl_connection_status);
  1264. ssl_info->connection_status = ssl_connection_status;
  1265. if (connection()->version().UsesTls()) {
  1266. ssl_info->key_exchange_group = crypto_params.key_exchange_group;
  1267. ssl_info->peer_signature_algorithm = crypto_params.peer_signature_algorithm;
  1268. return true;
  1269. }
  1270. // Report the QUIC key exchange as the corresponding TLS curve.
  1271. switch (crypto_stream_->crypto_negotiated_params().key_exchange) {
  1272. case quic::kP256:
  1273. ssl_info->key_exchange_group = SSL_CURVE_SECP256R1;
  1274. break;
  1275. case quic::kC255:
  1276. ssl_info->key_exchange_group = SSL_CURVE_X25519;
  1277. break;
  1278. default:
  1279. NOTREACHED();
  1280. return false;
  1281. }
  1282. // QUIC-Crypto always uses RSA-PSS or ECDSA with SHA-256.
  1283. size_t unused;
  1284. X509Certificate::PublicKeyType key_type;
  1285. X509Certificate::GetPublicKeyInfo(ssl_info->cert->cert_buffer(), &unused,
  1286. &key_type);
  1287. switch (key_type) {
  1288. case X509Certificate::kPublicKeyTypeRSA:
  1289. ssl_info->peer_signature_algorithm = SSL_SIGN_RSA_PSS_RSAE_SHA256;
  1290. break;
  1291. case X509Certificate::kPublicKeyTypeECDSA:
  1292. ssl_info->peer_signature_algorithm = SSL_SIGN_ECDSA_SECP256R1_SHA256;
  1293. break;
  1294. default:
  1295. NOTREACHED();
  1296. return false;
  1297. }
  1298. return true;
  1299. }
  1300. base::StringPiece QuicChromiumClientSession::GetAcceptChViaAlps(
  1301. const url::SchemeHostPort& scheme_host_port) const {
  1302. auto it = accept_ch_entries_received_via_alps_.find(scheme_host_port);
  1303. if (it == accept_ch_entries_received_via_alps_.end()) {
  1304. LogAcceptChForOriginHistogram(false);
  1305. return {};
  1306. } else {
  1307. LogAcceptChForOriginHistogram(true);
  1308. return it->second;
  1309. }
  1310. }
  1311. int QuicChromiumClientSession::CryptoConnect(CompletionOnceCallback callback) {
  1312. connect_timing_.connect_start = tick_clock_->NowTicks();
  1313. RecordHandshakeState(STATE_STARTED);
  1314. DCHECK(flow_controller());
  1315. if (!crypto_stream_->CryptoConnect())
  1316. return ERR_QUIC_HANDSHAKE_FAILED;
  1317. if (OneRttKeysAvailable()) {
  1318. connect_timing_.connect_end = tick_clock_->NowTicks();
  1319. return OK;
  1320. }
  1321. // Unless we require handshake confirmation, activate the session if
  1322. // we have established initial encryption.
  1323. if (!require_confirmation_ && IsEncryptionEstablished())
  1324. return OK;
  1325. callback_ = std::move(callback);
  1326. return ERR_IO_PENDING;
  1327. }
  1328. int QuicChromiumClientSession::GetNumSentClientHellos() const {
  1329. return crypto_stream_->num_sent_client_hellos();
  1330. }
  1331. bool QuicChromiumClientSession::CanPool(
  1332. const std::string& hostname,
  1333. const QuicSessionKey& other_session_key) const {
  1334. DCHECK(connection()->connected());
  1335. if (!session_key_.CanUseForAliasing(other_session_key))
  1336. return false;
  1337. SSLInfo ssl_info;
  1338. if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) {
  1339. NOTREACHED() << "QUIC should always have certificates.";
  1340. return false;
  1341. }
  1342. return SpdySession::CanPool(transport_security_state_, ssl_info,
  1343. *ssl_config_service_, session_key_.host(),
  1344. hostname, session_key_.network_isolation_key());
  1345. }
  1346. bool QuicChromiumClientSession::ShouldCreateIncomingStream(
  1347. quic::QuicStreamId id) {
  1348. if (!connection()->connected()) {
  1349. LOG(DFATAL) << "ShouldCreateIncomingStream called when disconnected";
  1350. return false;
  1351. }
  1352. if (goaway_received()) {
  1353. DVLOG(1) << "Cannot create a new outgoing stream. "
  1354. << "Already received goaway.";
  1355. return false;
  1356. }
  1357. if (going_away_) {
  1358. return false;
  1359. }
  1360. if (quic::QuicUtils::IsClientInitiatedStreamId(
  1361. connection()->transport_version(), id) ||
  1362. (connection()->version().HasIetfQuicFrames() &&
  1363. quic::QuicUtils::IsBidirectionalStreamId(id, connection()->version()))) {
  1364. LOG(WARNING) << "Received invalid push stream id " << id;
  1365. connection()->CloseConnection(
  1366. quic::QUIC_INVALID_STREAM_ID,
  1367. "Server created non write unidirectional stream",
  1368. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
  1369. return false;
  1370. }
  1371. return true;
  1372. }
  1373. QuicChromiumClientStream* QuicChromiumClientSession::CreateIncomingStream(
  1374. quic::QuicStreamId id) {
  1375. if (!ShouldCreateIncomingStream(id)) {
  1376. return nullptr;
  1377. }
  1378. net::NetworkTrafficAnnotationTag traffic_annotation =
  1379. net::DefineNetworkTrafficAnnotation("quic_chromium_incoming_session", R"(
  1380. semantics {
  1381. sender: "Quic Chromium Client Session"
  1382. description:
  1383. "When a web server needs to push a response to a client, an incoming "
  1384. "stream is created to reply the client with pushed message instead "
  1385. "of a message from the network."
  1386. trigger:
  1387. "A request by a server to push a response to the client."
  1388. data: "None."
  1389. destination: OTHER
  1390. destination_other:
  1391. "This stream is not used for sending data."
  1392. }
  1393. policy {
  1394. cookies_allowed: NO
  1395. setting: "This feature cannot be disabled in settings."
  1396. policy_exception_justification:
  1397. "Essential for network access."
  1398. }
  1399. )");
  1400. return CreateIncomingReliableStreamImpl(id, traffic_annotation);
  1401. }
  1402. QuicChromiumClientStream* QuicChromiumClientSession::CreateIncomingStream(
  1403. quic::PendingStream* pending) {
  1404. net::NetworkTrafficAnnotationTag traffic_annotation =
  1405. net::DefineNetworkTrafficAnnotation(
  1406. "quic_chromium_incoming_pending_session", R"(
  1407. semantics {
  1408. sender: "Quic Chromium Client Session Pending Stream"
  1409. description:
  1410. "When a web server needs to push a response to a client, an incoming "
  1411. "stream is created to reply to the client with pushed message instead "
  1412. "of a message from the network."
  1413. trigger:
  1414. "A request by a server to push a response to the client."
  1415. data: "This stream is only used to receive data from the server."
  1416. destination: OTHER
  1417. destination_other:
  1418. "The web server pushing the response."
  1419. }
  1420. policy {
  1421. cookies_allowed: NO
  1422. setting: "This feature cannot be disabled in settings."
  1423. policy_exception_justification:
  1424. "Essential for network access."
  1425. }
  1426. )");
  1427. return CreateIncomingReliableStreamImpl(pending, traffic_annotation);
  1428. }
  1429. QuicChromiumClientStream*
  1430. QuicChromiumClientSession::CreateIncomingReliableStreamImpl(
  1431. quic::QuicStreamId id,
  1432. const NetworkTrafficAnnotationTag& traffic_annotation) {
  1433. DCHECK(connection()->connected());
  1434. QuicChromiumClientStream* stream = new QuicChromiumClientStream(
  1435. id, this, quic::READ_UNIDIRECTIONAL, net_log_, traffic_annotation);
  1436. ActivateStream(base::WrapUnique(stream));
  1437. ++num_total_streams_;
  1438. return stream;
  1439. }
  1440. QuicChromiumClientStream*
  1441. QuicChromiumClientSession::CreateIncomingReliableStreamImpl(
  1442. quic::PendingStream* pending,
  1443. const NetworkTrafficAnnotationTag& traffic_annotation) {
  1444. DCHECK(connection()->connected());
  1445. QuicChromiumClientStream* stream =
  1446. new QuicChromiumClientStream(pending, this, net_log_, traffic_annotation);
  1447. ActivateStream(base::WrapUnique(stream));
  1448. ++num_total_streams_;
  1449. return stream;
  1450. }
  1451. void QuicChromiumClientSession::OnStreamClosed(quic::QuicStreamId stream_id) {
  1452. most_recent_stream_close_time_ = tick_clock_->NowTicks();
  1453. quic::QuicStream* stream = GetActiveStream(stream_id);
  1454. if (stream != nullptr) {
  1455. logger_->UpdateReceivedFrameCounts(stream_id, stream->num_frames_received(),
  1456. stream->num_duplicate_frames_received());
  1457. if (quic::QuicUtils::IsServerInitiatedStreamId(
  1458. connection()->transport_version(), stream_id)) {
  1459. bytes_pushed_count_ += stream->stream_bytes_read();
  1460. }
  1461. }
  1462. quic::QuicSpdyClientSessionBase::OnStreamClosed(stream_id);
  1463. }
  1464. void QuicChromiumClientSession::OnCanCreateNewOutgoingStream(
  1465. bool unidirectional) {
  1466. while (CanOpenNextOutgoingBidirectionalStream() &&
  1467. !stream_requests_.empty() &&
  1468. crypto_stream_->encryption_established() && !goaway_received() &&
  1469. !going_away_ && connection()->connected()) {
  1470. StreamRequest* request = stream_requests_.front();
  1471. // TODO(ckrasic) - analyze data and then add logic to mark QUIC
  1472. // broken if wait times are excessive.
  1473. UMA_HISTOGRAM_TIMES("Net.QuicSession.PendingStreamsWaitTime",
  1474. tick_clock_->NowTicks() - request->pending_start_time_);
  1475. stream_requests_.pop_front();
  1476. request->OnRequestCompleteSuccess(
  1477. CreateOutgoingReliableStreamImpl(request->traffic_annotation())
  1478. ->CreateHandle());
  1479. }
  1480. }
  1481. void QuicChromiumClientSession::OnConfigNegotiated() {
  1482. quic::QuicSpdyClientSessionBase::OnConfigNegotiated();
  1483. if (!stream_factory_ || !stream_factory_->allow_server_migration()) {
  1484. if (connection()->connection_migration_use_new_cid()) {
  1485. if (!config()->HasReceivedPreferredAddressConnectionIdAndToken()) {
  1486. return;
  1487. }
  1488. } else {
  1489. if (!config()->HasReceivedIPv6AlternateServerAddress() &&
  1490. !config()->HasReceivedIPv4AlternateServerAddress()) {
  1491. return;
  1492. }
  1493. }
  1494. }
  1495. // Server has sent an alternate address to connect to.
  1496. IPEndPoint old_address;
  1497. GetDefaultSocket()->GetPeerAddress(&old_address);
  1498. // Migrate only if address families match.
  1499. IPEndPoint new_address;
  1500. if (old_address.GetFamily() == ADDRESS_FAMILY_IPV6) {
  1501. if (!config()->HasReceivedIPv6AlternateServerAddress()) {
  1502. return;
  1503. }
  1504. new_address = ToIPEndPoint(config()->ReceivedIPv6AlternateServerAddress());
  1505. } else if (old_address.GetFamily() == ADDRESS_FAMILY_IPV4) {
  1506. if (!config()->HasReceivedIPv4AlternateServerAddress()) {
  1507. return;
  1508. }
  1509. new_address = ToIPEndPoint(config()->ReceivedIPv4AlternateServerAddress());
  1510. }
  1511. DCHECK_EQ(new_address.GetFamily(), old_address.GetFamily());
  1512. // Specifying handles::kInvalidNetworkHandle for the |network| parameter
  1513. // causes the session to use the default network for the new socket.
  1514. Migrate(handles::kInvalidNetworkHandle, new_address,
  1515. /*close_session_on_error=*/true);
  1516. }
  1517. void QuicChromiumClientSession::SetDefaultEncryptionLevel(
  1518. quic::EncryptionLevel level) {
  1519. if (!callback_.is_null() &&
  1520. (!require_confirmation_ || level == quic::ENCRYPTION_FORWARD_SECURE ||
  1521. level == quic::ENCRYPTION_ZERO_RTT)) {
  1522. // Currently for all CryptoHandshakeEvent events, callback_
  1523. // could be called because there are no error events in CryptoHandshakeEvent
  1524. // enum. If error events are added to CryptoHandshakeEvent, then the
  1525. // following code needs to changed.
  1526. std::move(callback_).Run(OK);
  1527. }
  1528. if (level == quic::ENCRYPTION_FORWARD_SECURE) {
  1529. OnCryptoHandshakeComplete();
  1530. LogZeroRttStats();
  1531. }
  1532. if (level == quic::ENCRYPTION_ZERO_RTT)
  1533. attempted_zero_rtt_ = true;
  1534. quic::QuicSpdySession::SetDefaultEncryptionLevel(level);
  1535. }
  1536. void QuicChromiumClientSession::OnTlsHandshakeComplete() {
  1537. if (!callback_.is_null()) {
  1538. // Currently for all CryptoHandshakeEvent events, callback_
  1539. // could be called because there are no error events in CryptoHandshakeEvent
  1540. // enum. If error events are added to CryptoHandshakeEvent, then the
  1541. // following code needs to changed.
  1542. std::move(callback_).Run(OK);
  1543. }
  1544. OnCryptoHandshakeComplete();
  1545. LogZeroRttStats();
  1546. quic::QuicSpdySession::OnTlsHandshakeComplete();
  1547. }
  1548. void QuicChromiumClientSession::OnNewEncryptionKeyAvailable(
  1549. quic::EncryptionLevel level,
  1550. std::unique_ptr<quic::QuicEncrypter> encrypter) {
  1551. if (!attempted_zero_rtt_ && (level == quic::ENCRYPTION_ZERO_RTT ||
  1552. level == quic::ENCRYPTION_FORWARD_SECURE)) {
  1553. base::TimeTicks now = tick_clock_->NowTicks();
  1554. DCHECK_LE(connect_timing_.connect_start, now);
  1555. UMA_HISTOGRAM_TIMES("Net.QuicSession.EncryptionEstablishedTime",
  1556. now - connect_timing_.connect_start);
  1557. }
  1558. if (level == quic::ENCRYPTION_ZERO_RTT)
  1559. attempted_zero_rtt_ = true;
  1560. QuicSpdySession::OnNewEncryptionKeyAvailable(level, std::move(encrypter));
  1561. if (!callback_.is_null() &&
  1562. (!require_confirmation_ && level == quic::ENCRYPTION_ZERO_RTT)) {
  1563. // Currently for all CryptoHandshakeEvent events, callback_
  1564. // could be called because there are no error events in CryptoHandshakeEvent
  1565. // enum. If error events are added to CryptoHandshakeEvent, then the
  1566. // following code needs to changed.
  1567. std::move(callback_).Run(OK);
  1568. }
  1569. }
  1570. void QuicChromiumClientSession::LogZeroRttStats() {
  1571. DCHECK(OneRttKeysAvailable());
  1572. ZeroRttState state;
  1573. ssl_early_data_reason_t early_data_reason = crypto_stream_->EarlyDataReason();
  1574. if (early_data_reason == ssl_early_data_accepted) {
  1575. state = ZeroRttState::kAttemptedAndSucceeded;
  1576. } else if (early_data_reason == ssl_early_data_peer_declined ||
  1577. early_data_reason == ssl_early_data_session_not_resumed ||
  1578. early_data_reason == ssl_early_data_hello_retry_request) {
  1579. state = ZeroRttState::kAttemptedAndRejected;
  1580. } else {
  1581. state = ZeroRttState::kNotAttempted;
  1582. }
  1583. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ZeroRttState", state);
  1584. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ZeroRttReason", early_data_reason,
  1585. ssl_early_data_reason_max_value + 1);
  1586. if (IsGoogleHost(session_key_.host())) {
  1587. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ZeroRttReasonGoogle",
  1588. early_data_reason,
  1589. ssl_early_data_reason_max_value + 1);
  1590. } else {
  1591. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ZeroRttReasonNonGoogle",
  1592. early_data_reason,
  1593. ssl_early_data_reason_max_value + 1);
  1594. }
  1595. }
  1596. void QuicChromiumClientSession::OnCryptoHandshakeMessageSent(
  1597. const quic::CryptoHandshakeMessage& message) {
  1598. logger_->OnCryptoHandshakeMessageSent(message);
  1599. }
  1600. void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived(
  1601. const quic::CryptoHandshakeMessage& message) {
  1602. logger_->OnCryptoHandshakeMessageReceived(message);
  1603. if (message.tag() == quic::kREJ) {
  1604. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.RejectLength",
  1605. message.GetSerialized().length(), 1000, 10000,
  1606. 50);
  1607. absl::string_view proof;
  1608. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.RejectHasProof",
  1609. message.GetStringPiece(quic::kPROF, &proof));
  1610. }
  1611. }
  1612. void QuicChromiumClientSession::OnGoAway(const quic::QuicGoAwayFrame& frame) {
  1613. quic::QuicSession::OnGoAway(frame);
  1614. NotifyFactoryOfSessionGoingAway();
  1615. port_migration_detected_ =
  1616. frame.error_code == quic::QUIC_ERROR_MIGRATING_PORT;
  1617. }
  1618. void QuicChromiumClientSession::OnConnectionClosed(
  1619. const quic::QuicConnectionCloseFrame& frame,
  1620. quic::ConnectionCloseSource source) {
  1621. DCHECK(!connection()->connected());
  1622. logger_->OnConnectionClosed(frame, source);
  1623. RecordConnectionCloseErrorCode(frame, source, session_key_.host(),
  1624. OneRttKeysAvailable());
  1625. if (OneRttKeysAvailable()) {
  1626. handles::NetworkHandle current_network = GetCurrentNetwork();
  1627. for (auto& observer : connectivity_observer_list_)
  1628. observer.OnSessionClosedAfterHandshake(this, current_network, source,
  1629. frame.quic_error_code);
  1630. }
  1631. const quic::QuicErrorCode error = frame.quic_error_code;
  1632. const std::string& error_details = frame.error_details;
  1633. if (source == quic::ConnectionCloseSource::FROM_SELF &&
  1634. error == quic::QUIC_NETWORK_IDLE_TIMEOUT && ShouldKeepConnectionAlive()) {
  1635. quic::QuicStreamCount streams_waiting_to_write = 0;
  1636. PerformActionOnActiveStreams(
  1637. [&streams_waiting_to_write](quic::QuicStream* stream) {
  1638. if (stream->HasBufferedData())
  1639. ++streams_waiting_to_write;
  1640. return true;
  1641. });
  1642. UMA_HISTOGRAM_COUNTS_100(
  1643. "Net.QuicSession.NumStreamsWaitingToWriteOnIdleTimeout",
  1644. streams_waiting_to_write);
  1645. UMA_HISTOGRAM_COUNTS_100("Net.QuicSession.NumActiveStreamsOnIdleTimeout",
  1646. GetNumActiveStreams());
  1647. }
  1648. if (source == quic::ConnectionCloseSource::FROM_PEER) {
  1649. if (error == quic::QUIC_PUBLIC_RESET) {
  1650. // is_from_google_server will be true if the received EPID is
  1651. // kEPIDGoogleFrontEnd or kEPIDGoogleFrontEnd0.
  1652. const bool is_from_google_server =
  1653. error_details.find(base::StringPrintf(
  1654. "From %s", quic::kEPIDGoogleFrontEnd)) != std::string::npos;
  1655. if (OneRttKeysAvailable()) {
  1656. UMA_HISTOGRAM_BOOLEAN(
  1657. "Net.QuicSession.ClosedByPublicReset.HandshakeConfirmed",
  1658. is_from_google_server);
  1659. } else {
  1660. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedByPublicReset",
  1661. is_from_google_server);
  1662. }
  1663. if (is_from_google_server) {
  1664. UMA_HISTOGRAM_COUNTS_100(
  1665. "Net.QuicSession.NumMigrationsExercisedBeforePublicReset",
  1666. sockets_.size() - 1);
  1667. }
  1668. base::UmaHistogramSparse(
  1669. "Net.QuicSession.LastSentPacketContentBeforePublicReset",
  1670. connection()
  1671. ->sent_packet_manager()
  1672. .unacked_packets()
  1673. .GetLastPacketContent());
  1674. const quic::QuicTime last_in_flight_packet_sent_time =
  1675. connection()
  1676. ->sent_packet_manager()
  1677. .unacked_packets()
  1678. .GetLastInFlightPacketSentTime();
  1679. const quic::QuicTime handshake_completion_time =
  1680. connection()->GetStats().handshake_completion_time;
  1681. if (last_in_flight_packet_sent_time.IsInitialized() &&
  1682. handshake_completion_time.IsInitialized() &&
  1683. last_in_flight_packet_sent_time >= handshake_completion_time) {
  1684. const quic::QuicTime::Delta delay =
  1685. last_in_flight_packet_sent_time - handshake_completion_time;
  1686. UMA_HISTOGRAM_LONG_TIMES_100(
  1687. "Net.QuicSession."
  1688. "LastInFlightPacketSentTimeFromHandshakeCompletionWithPublicReset",
  1689. base::Milliseconds(delay.ToMilliseconds()));
  1690. }
  1691. UMA_HISTOGRAM_LONG_TIMES_100(
  1692. "Net.QuicSession.ConnectionDurationWithPublicReset",
  1693. tick_clock_->NowTicks() - connect_timing_.connect_end);
  1694. }
  1695. if (OneRttKeysAvailable()) {
  1696. base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
  1697. "Net.QuicSession.StreamCloseErrorCodeServer.HandshakeConfirmed",
  1698. base::HistogramBase::kUmaTargetedHistogramFlag);
  1699. size_t num_streams = GetNumActiveStreams();
  1700. if (num_streams > 0)
  1701. histogram->AddCount(error, num_streams);
  1702. }
  1703. } else {
  1704. if (OneRttKeysAvailable()) {
  1705. base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
  1706. "Net.QuicSession.StreamCloseErrorCodeClient.HandshakeConfirmed",
  1707. base::HistogramBase::kUmaTargetedHistogramFlag);
  1708. size_t num_streams = GetNumActiveStreams();
  1709. if (num_streams > 0)
  1710. histogram->AddCount(error, num_streams);
  1711. } else {
  1712. if (error == quic::QUIC_HANDSHAKE_TIMEOUT) {
  1713. UMA_HISTOGRAM_BOOLEAN(
  1714. "Net.QuicSession.HandshakeTimeout.PathDegradingDetected",
  1715. connection()->IsPathDegrading());
  1716. }
  1717. }
  1718. if (error == quic::QUIC_TOO_MANY_RTOS) {
  1719. UMA_HISTOGRAM_COUNTS_1000(
  1720. "Net.QuicSession.ClosedByRtoAtClient.ReceivedPacketCount",
  1721. connection()->GetStats().packets_received);
  1722. UMA_HISTOGRAM_COUNTS_1000(
  1723. "Net.QuicSession.ClosedByRtoAtClient.SentPacketCount",
  1724. connection()->GetStats().packets_sent);
  1725. UMA_HISTOGRAM_COUNTS_100(
  1726. "Net.QuicSession."
  1727. "MaxConsecutiveRtoWithForwardProgressAndBlackholeDetected",
  1728. connection()->GetStats().max_consecutive_rto_with_forward_progress);
  1729. }
  1730. }
  1731. if (error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
  1732. UMA_HISTOGRAM_COUNTS_1M(
  1733. "Net.QuicSession.ConnectionClose.NumOpenStreams.TimedOut",
  1734. GetNumActiveStreams());
  1735. if (OneRttKeysAvailable()) {
  1736. if (GetNumActiveStreams() > 0) {
  1737. UMA_HISTOGRAM_BOOLEAN(
  1738. "Net.QuicSession.TimedOutWithOpenStreams.HasUnackedPackets",
  1739. connection()->sent_packet_manager().HasInFlightPackets());
  1740. UMA_HISTOGRAM_COUNTS_1M(
  1741. "Net.QuicSession.TimedOutWithOpenStreams.ConsecutivePTOCount",
  1742. connection()->sent_packet_manager().GetConsecutivePtoCount());
  1743. base::UmaHistogramSparse(
  1744. "Net.QuicSession.TimedOutWithOpenStreams.LocalPort",
  1745. connection()->self_address().port());
  1746. }
  1747. } else {
  1748. UMA_HISTOGRAM_COUNTS_1M(
  1749. "Net.QuicSession.ConnectionClose.NumOpenStreams.HandshakeTimedOut",
  1750. GetNumActiveStreams());
  1751. UMA_HISTOGRAM_COUNTS_1M(
  1752. "Net.QuicSession.ConnectionClose.NumTotalStreams.HandshakeTimedOut",
  1753. num_total_streams_);
  1754. }
  1755. }
  1756. if (OneRttKeysAvailable()) {
  1757. // QUIC connections should not timeout while there are open streams,
  1758. // since PING frames are sent to prevent timeouts. If, however, the
  1759. // connection timed out with open streams then QUIC traffic has become
  1760. // blackholed. Alternatively, if too many retransmission timeouts occur
  1761. // then QUIC traffic has become blackholed.
  1762. if (stream_factory_ && (error == quic::QUIC_TOO_MANY_RTOS ||
  1763. (error == quic::QUIC_NETWORK_IDLE_TIMEOUT &&
  1764. GetNumActiveStreams() > 0))) {
  1765. stream_factory_->OnBlackholeAfterHandshakeConfirmed(this);
  1766. }
  1767. UMA_HISTOGRAM_COUNTS_100(
  1768. "Net.QuicSession.CryptoRetransmitCount.HandshakeConfirmed",
  1769. connection()->GetStats().crypto_retransmit_count);
  1770. UMA_HISTOGRAM_COUNTS_100(
  1771. "Net.QuicSession.MaxConsecutiveRtoWithForwardProgress",
  1772. connection()->GetStats().max_consecutive_rto_with_forward_progress);
  1773. UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.NumPingsSent",
  1774. connection()->GetStats().ping_frames_sent);
  1775. UMA_HISTOGRAM_LONG_TIMES_100(
  1776. "Net.QuicSession.ConnectionDuration",
  1777. tick_clock_->NowTicks() - connect_timing_.connect_end);
  1778. UMA_HISTOGRAM_COUNTS_100("Net.QuicSession.NumMigrations", num_migrations_);
  1779. if (connection()->version().UsesTls()) {
  1780. base::UmaHistogramCounts100("Net.QuicSession.KeyUpdate.PerConnection2",
  1781. connection()->GetStats().key_update_count);
  1782. base::UmaHistogramCounts100(
  1783. "Net.QuicSession.KeyUpdate.PotentialPeerKeyUpdateAttemptCount",
  1784. connection()->PotentialPeerKeyUpdateAttemptCount());
  1785. if (last_key_update_reason_ != quic::KeyUpdateReason::kInvalid) {
  1786. std::string suffix =
  1787. last_key_update_reason_ == quic::KeyUpdateReason::kRemote ? "Remote"
  1788. : "Local";
  1789. // These values are persisted to logs. Entries should not be renumbered
  1790. // and numeric values should never be reused.
  1791. enum class KeyUpdateSuccess {
  1792. kInvalid = 0,
  1793. kSuccess = 1,
  1794. kFailedInitial = 2,
  1795. kFailedNonInitial = 3,
  1796. kMaxValue = kFailedNonInitial,
  1797. };
  1798. KeyUpdateSuccess value = KeyUpdateSuccess::kInvalid;
  1799. if (connection()->HaveSentPacketsInCurrentKeyPhaseButNoneAcked()) {
  1800. if (connection()->GetStats().key_update_count >= 2) {
  1801. value = KeyUpdateSuccess::kFailedNonInitial;
  1802. } else {
  1803. value = KeyUpdateSuccess::kFailedInitial;
  1804. }
  1805. } else {
  1806. value = KeyUpdateSuccess::kSuccess;
  1807. }
  1808. base::UmaHistogramEnumeration(
  1809. "Net.QuicSession.KeyUpdate.Success." + suffix, value);
  1810. }
  1811. }
  1812. } else {
  1813. if (error == quic::QUIC_PUBLIC_RESET) {
  1814. RecordHandshakeFailureReason(HANDSHAKE_FAILURE_PUBLIC_RESET);
  1815. } else if (connection()->GetStats().packets_received == 0) {
  1816. RecordHandshakeFailureReason(HANDSHAKE_FAILURE_BLACK_HOLE);
  1817. base::UmaHistogramSparse(
  1818. "Net.QuicSession.ConnectionClose.HandshakeFailureBlackHole.QuicError",
  1819. error);
  1820. } else {
  1821. RecordHandshakeFailureReason(HANDSHAKE_FAILURE_UNKNOWN);
  1822. base::UmaHistogramSparse(
  1823. "Net.QuicSession.ConnectionClose.HandshakeFailureUnknown.QuicError",
  1824. error);
  1825. }
  1826. UMA_HISTOGRAM_COUNTS_100(
  1827. "Net.QuicSession.CryptoRetransmitCount.HandshakeNotConfirmed",
  1828. connection()->GetStats().crypto_retransmit_count);
  1829. }
  1830. base::UmaHistogramCounts1M(
  1831. "Net.QuicSession.UndecryptablePacketsReceivedWithDecrypter",
  1832. connection()->GetStats().num_failed_authentication_packets_received);
  1833. base::UmaHistogramSparse("Net.QuicSession.QuicVersion",
  1834. connection()->transport_version());
  1835. NotifyFactoryOfSessionGoingAway();
  1836. quic::QuicSession::OnConnectionClosed(frame, source);
  1837. if (!callback_.is_null()) {
  1838. std::move(callback_).Run(ERR_QUIC_PROTOCOL_ERROR);
  1839. }
  1840. CHECK_EQ(sockets_.size(), packet_readers_.size());
  1841. for (auto& socket : sockets_) {
  1842. socket->Close();
  1843. }
  1844. DCHECK(!HasActiveRequestStreams());
  1845. CloseAllHandles(ERR_UNEXPECTED);
  1846. CancelAllRequests(ERR_CONNECTION_CLOSED);
  1847. NotifyRequestsOfConfirmation(ERR_CONNECTION_CLOSED);
  1848. NotifyFactoryOfSessionClosedLater();
  1849. }
  1850. void QuicChromiumClientSession::OnSuccessfulVersionNegotiation(
  1851. const quic::ParsedQuicVersion& version) {
  1852. logger_->OnSuccessfulVersionNegotiation(version);
  1853. quic::QuicSpdySession::OnSuccessfulVersionNegotiation(version);
  1854. }
  1855. int QuicChromiumClientSession::HandleWriteError(
  1856. int error_code,
  1857. scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> packet) {
  1858. current_migration_cause_ = ON_WRITE_ERROR;
  1859. LogHandshakeStatusOnMigrationSignal();
  1860. base::UmaHistogramSparse("Net.QuicSession.WriteError", -error_code);
  1861. if (OneRttKeysAvailable()) {
  1862. base::UmaHistogramSparse("Net.QuicSession.WriteError.HandshakeConfirmed",
  1863. -error_code);
  1864. }
  1865. // For now, skip reporting if there are multiple packet writers and
  1866. // connection migration is enabled.
  1867. if (sockets_.size() == 1u || !migrate_session_early_v2_) {
  1868. handles::NetworkHandle current_network = GetCurrentNetwork();
  1869. for (auto& observer : connectivity_observer_list_) {
  1870. observer.OnSessionEncounteringWriteError(this, current_network,
  1871. error_code);
  1872. }
  1873. }
  1874. if (error_code == ERR_MSG_TOO_BIG || stream_factory_ == nullptr ||
  1875. !migrate_session_on_network_change_v2_ || !OneRttKeysAvailable() ||
  1876. !version().UsesHttp3()) {
  1877. return error_code;
  1878. }
  1879. handles::NetworkHandle current_network = GetCurrentNetwork();
  1880. net_log_.AddEventWithInt64Params(
  1881. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_WRITE_ERROR, "network",
  1882. current_network);
  1883. DCHECK(packet != nullptr);
  1884. DCHECK_NE(ERR_IO_PENDING, error_code);
  1885. DCHECK_GT(0, error_code);
  1886. DCHECK(packet_ == nullptr);
  1887. // Post a task to migrate the session onto a new network.
  1888. task_runner_->PostTask(
  1889. FROM_HERE,
  1890. base::BindOnce(&QuicChromiumClientSession::MigrateSessionOnWriteError,
  1891. weak_factory_.GetWeakPtr(), error_code,
  1892. connection()->writer()));
  1893. // Only save packet from the old path for retransmission on the new path when
  1894. // the connection ID does not change.
  1895. if (!connection()->connection_migration_use_new_cid()) {
  1896. // Store packet in the session since the actual migration and packet rewrite
  1897. // can happen via this posted task or via an async network notification.
  1898. packet_ = std::move(packet);
  1899. }
  1900. ignore_read_error_ = true;
  1901. // Cause the packet writer to return ERR_IO_PENDING and block so
  1902. // that the actual migration happens from the message loop instead
  1903. // of under the call stack of quic::QuicConnection::WritePacket.
  1904. return ERR_IO_PENDING;
  1905. }
  1906. void QuicChromiumClientSession::MigrateSessionOnWriteError(
  1907. int error_code,
  1908. quic::QuicPacketWriter* writer) {
  1909. DCHECK(migrate_session_on_network_change_v2_);
  1910. // If |writer| is no longer actively in use, abort this migration attempt.
  1911. if (writer != connection()->writer())
  1912. return;
  1913. most_recent_write_error_timestamp_ = tick_clock_->NowTicks();
  1914. most_recent_write_error_ = error_code;
  1915. if (stream_factory_ == nullptr) {
  1916. // Close the connection if migration failed. Do not cause a
  1917. // connection close packet to be sent since socket may be borked.
  1918. connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
  1919. "Write error with nulled stream factory",
  1920. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  1921. return;
  1922. }
  1923. current_migration_cause_ = ON_WRITE_ERROR;
  1924. if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
  1925. return;
  1926. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  1927. // connection close packet to be sent since socket may be borked.
  1928. connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
  1929. "Write error for non-migratable session",
  1930. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  1931. return;
  1932. }
  1933. // Do not migrate if connection migration is disabled.
  1934. if (config()->DisableConnectionMigration()) {
  1935. HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
  1936. connection_id(),
  1937. "Migration disabled by config");
  1938. // Close the connection since migration was disabled. Do not cause a
  1939. // connection close packet to be sent since socket may be borked.
  1940. connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
  1941. "Write error for non-migratable session",
  1942. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  1943. return;
  1944. }
  1945. handles::NetworkHandle new_network =
  1946. stream_factory_->FindAlternateNetwork(GetCurrentNetwork());
  1947. if (new_network == handles::kInvalidNetworkHandle) {
  1948. // No alternate network found.
  1949. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
  1950. connection_id(),
  1951. "No alternate network found");
  1952. OnNoNewNetwork();
  1953. return;
  1954. }
  1955. if (GetCurrentNetwork() == default_network_ &&
  1956. current_migrations_to_non_default_network_on_write_error_ >=
  1957. max_migrations_to_non_default_network_on_write_error_) {
  1958. HistogramAndLogMigrationFailure(
  1959. MIGRATION_STATUS_ON_WRITE_ERROR_DISABLED, connection_id(),
  1960. "Exceeds maximum number of migrations on write error");
  1961. connection()->CloseConnection(
  1962. quic::QUIC_PACKET_WRITE_ERROR,
  1963. "Too many migrations for write error for the same network",
  1964. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  1965. return;
  1966. }
  1967. current_migrations_to_non_default_network_on_write_error_++;
  1968. net_log_.BeginEventWithStringParams(
  1969. NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
  1970. "WriteError");
  1971. MigrationResult result =
  1972. Migrate(new_network, ToIPEndPoint(connection()->peer_address()),
  1973. /*close_session_on_error=*/false);
  1974. net_log_.EndEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
  1975. if (result == MigrationResult::FAILURE) {
  1976. // Close the connection if migration failed. Do not cause a
  1977. // connection close packet to be sent since socket may be borked.
  1978. connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
  1979. "Write and subsequent migration failed",
  1980. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  1981. return;
  1982. }
  1983. if (new_network != default_network_) {
  1984. StartMigrateBackToDefaultNetworkTimer(
  1985. base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
  1986. } else {
  1987. CancelMigrateBackToDefaultNetworkTimer();
  1988. }
  1989. }
  1990. void QuicChromiumClientSession::OnNoNewNetwork() {
  1991. DCHECK(OneRttKeysAvailable());
  1992. wait_for_new_network_ = true;
  1993. DVLOG(1) << "Force blocking the packet writer";
  1994. // Force blocking the packet writer to avoid any writes since there is no
  1995. // alternate network available.
  1996. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  1997. ->set_force_write_blocked(true);
  1998. // Post a task to maybe close the session if the alarm fires.
  1999. task_runner_->PostDelayedTask(
  2000. FROM_HERE,
  2001. base::BindOnce(&QuicChromiumClientSession::OnMigrationTimeout,
  2002. weak_factory_.GetWeakPtr(), sockets_.size()),
  2003. base::Seconds(kWaitTimeForNewNetworkSecs));
  2004. }
  2005. void QuicChromiumClientSession::WriteToNewSocket() {
  2006. // Set |send_packet_after_migration_| to true so that a packet will be
  2007. // sent when the writer becomes unblocked.
  2008. send_packet_after_migration_ = true;
  2009. DVLOG(1) << "Cancel force blocking the packet writer";
  2010. // Notify writer that it is no longer forced blocked, which may call
  2011. // OnWriteUnblocked() if the writer has no write in progress.
  2012. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  2013. ->set_force_write_blocked(false);
  2014. }
  2015. void QuicChromiumClientSession::OnMigrationTimeout(size_t num_sockets) {
  2016. // If number of sockets has changed, this migration task is stale.
  2017. if (num_sockets != sockets_.size())
  2018. return;
  2019. int net_error = current_migration_cause_ == ON_NETWORK_DISCONNECTED
  2020. ? ERR_INTERNET_DISCONNECTED
  2021. : ERR_NETWORK_CHANGED;
  2022. // |current_migration_cause_| will be reset after logging.
  2023. LogMigrationResultToHistogram(MIGRATION_STATUS_TIMEOUT);
  2024. CloseSessionOnError(net_error, quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK,
  2025. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2026. }
  2027. void QuicChromiumClientSession::OnPortMigrationProbeSucceeded(
  2028. handles::NetworkHandle network,
  2029. const quic::QuicSocketAddress& peer_address,
  2030. const quic::QuicSocketAddress& self_address,
  2031. std::unique_ptr<DatagramClientSocket> socket,
  2032. std::unique_ptr<QuicChromiumPacketWriter> writer,
  2033. std::unique_ptr<QuicChromiumPacketReader> reader) {
  2034. DCHECK(socket);
  2035. DCHECK(writer);
  2036. DCHECK(reader);
  2037. net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED,
  2038. [&] {
  2039. return NetLogProbingResultParams(network, &peer_address,
  2040. /*is_success=*/true);
  2041. });
  2042. LogProbeResultToHistogram(current_migration_cause_, true);
  2043. // Remove |this| as the old packet writer's delegate. Write error on old
  2044. // writers will be ignored.
  2045. // Set |this| to listen on socket write events on the packet writer
  2046. // that was used for probing.
  2047. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  2048. ->set_delegate(nullptr);
  2049. writer->set_delegate(this);
  2050. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  2051. // If idle sessions won't be migrated, close the connection.
  2052. CloseSessionOnErrorLater(
  2053. ERR_NETWORK_CHANGED,
  2054. quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
  2055. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
  2056. return;
  2057. }
  2058. if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
  2059. return;
  2060. // Migrate to the probed socket immediately: socket, writer and reader will
  2061. // be acquired by connection and used as default on success.
  2062. if (!MigrateToSocket(self_address, peer_address, std::move(socket),
  2063. std::move(reader), std::move(writer))) {
  2064. LogMigrateToSocketStatus(false);
  2065. net_log_.AddEvent(
  2066. NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE_AFTER_PROBING);
  2067. return;
  2068. }
  2069. LogMigrateToSocketStatus(true);
  2070. num_migrations_++;
  2071. HistogramAndLogMigrationSuccess(connection_id());
  2072. }
  2073. void QuicChromiumClientSession::OnConnectionMigrationProbeSucceeded(
  2074. handles::NetworkHandle network,
  2075. const quic::QuicSocketAddress& peer_address,
  2076. const quic::QuicSocketAddress& self_address,
  2077. std::unique_ptr<DatagramClientSocket> socket,
  2078. std::unique_ptr<QuicChromiumPacketWriter> writer,
  2079. std::unique_ptr<QuicChromiumPacketReader> reader) {
  2080. DCHECK(socket);
  2081. DCHECK(writer);
  2082. DCHECK(reader);
  2083. net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED,
  2084. [&] {
  2085. return NetLogProbingResultParams(network, &peer_address,
  2086. /*is_success=*/true);
  2087. });
  2088. if (network == handles::kInvalidNetworkHandle)
  2089. return;
  2090. LogProbeResultToHistogram(current_migration_cause_, true);
  2091. // Remove |this| as the old packet writer's delegate. Write error on old
  2092. // writers will be ignored.
  2093. // Set |this| to listen on socket write events on the packet writer
  2094. // that was used for probing.
  2095. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  2096. ->set_delegate(nullptr);
  2097. writer->set_delegate(this);
  2098. // Close streams that are not migratable to the probed |network|.
  2099. ResetNonMigratableStreams();
  2100. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  2101. // If idle sessions won't be migrated, close the connection.
  2102. CloseSessionOnErrorLater(
  2103. ERR_NETWORK_CHANGED,
  2104. quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
  2105. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
  2106. return;
  2107. }
  2108. if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
  2109. return;
  2110. // Migrate to the probed socket immediately: socket, writer and reader will
  2111. // be acquired by connection and used as default on success.
  2112. if (!MigrateToSocket(self_address, peer_address, std::move(socket),
  2113. std::move(reader), std::move(writer))) {
  2114. LogMigrateToSocketStatus(false);
  2115. net_log_.AddEvent(
  2116. NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE_AFTER_PROBING);
  2117. return;
  2118. }
  2119. LogMigrateToSocketStatus(true);
  2120. net_log_.AddEventWithInt64Params(
  2121. NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING,
  2122. "migrate_to_network", network);
  2123. num_migrations_++;
  2124. HistogramAndLogMigrationSuccess(connection_id());
  2125. if (network == default_network_) {
  2126. DVLOG(1) << "Client successfully migrated to default network: "
  2127. << default_network_;
  2128. CancelMigrateBackToDefaultNetworkTimer();
  2129. return;
  2130. }
  2131. DVLOG(1) << "Client successfully got off default network after "
  2132. << "successful probing network: " << network << ".";
  2133. current_migrations_to_non_default_network_on_path_degrading_++;
  2134. if (!migrate_back_to_default_timer_.IsRunning()) {
  2135. current_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
  2136. // Session gets off the |default_network|, stay on |network| for now but
  2137. // try to migrate back to default network after 1 second.
  2138. StartMigrateBackToDefaultNetworkTimer(
  2139. base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
  2140. }
  2141. }
  2142. void QuicChromiumClientSession::OnProbeFailed(
  2143. handles::NetworkHandle network,
  2144. const quic::QuicSocketAddress& peer_address) {
  2145. DCHECK(connection()->connection_migration_use_new_cid());
  2146. net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED,
  2147. [&] {
  2148. return NetLogProbingResultParams(network, &peer_address,
  2149. /*is_success=*/false);
  2150. });
  2151. LogProbeResultToHistogram(current_migration_cause_, false);
  2152. auto* context = static_cast<QuicChromiumPathValidationContext*>(
  2153. connection()->GetPathValidationContext());
  2154. if (!context)
  2155. return;
  2156. if (context->network() == network &&
  2157. context->peer_address() == peer_address) {
  2158. connection()->CancelPathValidation();
  2159. }
  2160. if (network != handles::kInvalidNetworkHandle) {
  2161. // Probing failure can be ignored.
  2162. DVLOG(1) << "Connectivity probing failed on <network: " << network
  2163. << ", peer_address: " << peer_address.ToString() << ">.";
  2164. DVLOG_IF(1, network == default_network_ &&
  2165. GetCurrentNetwork() != default_network_)
  2166. << "Client probing failed on the default network, still using "
  2167. "non-default network.";
  2168. }
  2169. }
  2170. void QuicChromiumClientSession::OnNetworkConnected(
  2171. handles::NetworkHandle network) {
  2172. if (connection()->IsPathDegrading()) {
  2173. base::TimeDelta duration =
  2174. tick_clock_->NowTicks() - most_recent_path_degrading_timestamp_;
  2175. UMA_HISTOGRAM_CUSTOM_TIMES("Net.QuicNetworkDegradingDurationTillConnected",
  2176. duration, base::Milliseconds(1),
  2177. base::Minutes(10), 50);
  2178. }
  2179. if (!migrate_session_on_network_change_v2_ || !version().UsesHttp3())
  2180. return;
  2181. net_log_.AddEventWithInt64Params(
  2182. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_CONNECTED,
  2183. "connected_network", network);
  2184. // If there was no migration waiting for new network and the path is not
  2185. // degrading, ignore this signal.
  2186. if (!wait_for_new_network_ && !connection()->IsPathDegrading())
  2187. return;
  2188. if (connection()->IsPathDegrading())
  2189. current_migration_cause_ = NEW_NETWORK_CONNECTED_POST_PATH_DEGRADING;
  2190. if (wait_for_new_network_) {
  2191. wait_for_new_network_ = false;
  2192. if (current_migration_cause_ == ON_WRITE_ERROR)
  2193. current_migrations_to_non_default_network_on_write_error_++;
  2194. // |wait_for_new_network_| is true, there was no working network previously.
  2195. // |network| is now the only possible candidate, migrate immediately.
  2196. MigrateNetworkImmediately(network);
  2197. } else {
  2198. // The connection is path degrading.
  2199. DCHECK(connection()->IsPathDegrading());
  2200. MaybeMigrateToAlternateNetworkOnPathDegrading();
  2201. }
  2202. }
  2203. void QuicChromiumClientSession::OnNetworkDisconnectedV2(
  2204. handles::NetworkHandle disconnected_network) {
  2205. LogMetricsOnNetworkDisconnected();
  2206. if (!migrate_session_on_network_change_v2_ || !version().UsesHttp3())
  2207. return;
  2208. net_log_.AddEventWithInt64Params(
  2209. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_DISCONNECTED,
  2210. "disconnected_network", disconnected_network);
  2211. // Stop probing the disconnected network if there is one.
  2212. if (connection()->connection_migration_use_new_cid()) {
  2213. auto* context = static_cast<QuicChromiumPathValidationContext*>(
  2214. connection()->GetPathValidationContext());
  2215. if (context && context->network() == disconnected_network &&
  2216. context->peer_address() == peer_address()) {
  2217. connection()->CancelPathValidation();
  2218. }
  2219. }
  2220. if (disconnected_network == default_network_) {
  2221. DVLOG(1) << "Default network: " << default_network_ << " is disconnected.";
  2222. default_network_ = handles::kInvalidNetworkHandle;
  2223. current_migrations_to_non_default_network_on_write_error_ = 0;
  2224. }
  2225. // Ignore the signal if the current active network is not affected.
  2226. if (GetCurrentNetwork() != disconnected_network) {
  2227. DVLOG(1) << "Client's current default network is not affected by the "
  2228. << "disconnected one.";
  2229. return;
  2230. }
  2231. current_migration_cause_ = ON_NETWORK_DISCONNECTED;
  2232. LogHandshakeStatusOnMigrationSignal();
  2233. if (!OneRttKeysAvailable()) {
  2234. // Close the connection if handshake is not confirmed. Migration before
  2235. // handshake is not allowed.
  2236. CloseSessionOnErrorLater(
  2237. ERR_NETWORK_CHANGED,
  2238. quic::QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED,
  2239. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2240. return;
  2241. }
  2242. // Attempt to find alternative network.
  2243. handles::NetworkHandle new_network =
  2244. stream_factory_->FindAlternateNetwork(disconnected_network);
  2245. if (new_network == handles::kInvalidNetworkHandle) {
  2246. OnNoNewNetwork();
  2247. return;
  2248. }
  2249. // Current network is being disconnected, migrate immediately to the
  2250. // alternative network.
  2251. MigrateNetworkImmediately(new_network);
  2252. }
  2253. void QuicChromiumClientSession::OnNetworkMadeDefault(
  2254. handles::NetworkHandle new_network) {
  2255. LogMetricsOnNetworkMadeDefault();
  2256. if (!migrate_session_on_network_change_v2_ || !version().UsesHttp3())
  2257. return;
  2258. DCHECK_NE(handles::kInvalidNetworkHandle, new_network);
  2259. net_log_.AddEventWithInt64Params(
  2260. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_MADE_DEFAULT,
  2261. "new_default_network", new_network);
  2262. default_network_ = new_network;
  2263. DVLOG(1) << "Network: " << new_network
  2264. << " becomes default, old default: " << default_network_;
  2265. current_migration_cause_ = ON_NETWORK_MADE_DEFAULT;
  2266. current_migrations_to_non_default_network_on_write_error_ = 0;
  2267. current_migrations_to_non_default_network_on_path_degrading_ = 0;
  2268. // Simply cancel the timer to migrate back to the default network if session
  2269. // is already on the default network.
  2270. if (GetCurrentNetwork() == new_network) {
  2271. CancelMigrateBackToDefaultNetworkTimer();
  2272. HistogramAndLogMigrationFailure(MIGRATION_STATUS_ALREADY_MIGRATED,
  2273. connection_id(),
  2274. "Already migrated on the new network");
  2275. return;
  2276. }
  2277. LogHandshakeStatusOnMigrationSignal();
  2278. // Stay on the current network. Try to migrate back to default network
  2279. // without any delay, which will start probing the new default network and
  2280. // migrate to the new network immediately on success.
  2281. StartMigrateBackToDefaultNetworkTimer(base::TimeDelta());
  2282. }
  2283. void QuicChromiumClientSession::MigrateNetworkImmediately(
  2284. handles::NetworkHandle network) {
  2285. // There is no choice but to migrate to |network|. If any error encountered,
  2286. // close the session. When migration succeeds:
  2287. // - if no longer on the default network, start timer to migrate back;
  2288. // - otherwise, it's brought to default network, cancel the running timer to
  2289. // migrate back.
  2290. DCHECK(migrate_session_on_network_change_v2_ && version().UsesHttp3());
  2291. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  2292. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
  2293. connection_id(), "No active streams");
  2294. CloseSessionOnErrorLater(
  2295. ERR_NETWORK_CHANGED,
  2296. quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
  2297. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2298. return;
  2299. }
  2300. if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
  2301. return;
  2302. // Do not migrate if connection migration is disabled.
  2303. if (config()->DisableConnectionMigration()) {
  2304. HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
  2305. connection_id(),
  2306. "Migration disabled by config");
  2307. CloseSessionOnErrorLater(ERR_NETWORK_CHANGED,
  2308. quic::QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG,
  2309. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2310. return;
  2311. }
  2312. if (network == GetCurrentNetwork()) {
  2313. HistogramAndLogMigrationFailure(MIGRATION_STATUS_ALREADY_MIGRATED,
  2314. connection_id(),
  2315. "Already bound to new network");
  2316. return;
  2317. }
  2318. // Cancel probing on |network| if there is any.
  2319. if (connection()->connection_migration_use_new_cid()) {
  2320. auto* context = static_cast<QuicChromiumPathValidationContext*>(
  2321. connection()->GetPathValidationContext());
  2322. if (context && context->network() == network &&
  2323. context->peer_address() == peer_address()) {
  2324. connection()->CancelPathValidation();
  2325. }
  2326. }
  2327. MigrationResult result =
  2328. Migrate(network, ToIPEndPoint(connection()->peer_address()),
  2329. /*close_session_on_error=*/true);
  2330. if (result == MigrationResult::FAILURE)
  2331. return;
  2332. if (network == default_network_) {
  2333. CancelMigrateBackToDefaultNetworkTimer();
  2334. return;
  2335. }
  2336. // TODO(zhongyi): reconsider this, maybe we just want to hear back
  2337. // We are forced to migrate to |network|, probably |default_network_| is
  2338. // not working, start to migrate back to default network after 1 secs.
  2339. StartMigrateBackToDefaultNetworkTimer(
  2340. base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
  2341. }
  2342. void QuicChromiumClientSession::OnWriteError(int error_code) {
  2343. DCHECK_NE(ERR_IO_PENDING, error_code);
  2344. DCHECK_GT(0, error_code);
  2345. connection()->OnWriteError(error_code);
  2346. }
  2347. void QuicChromiumClientSession::OnWriteUnblocked() {
  2348. DCHECK(!connection()->writer()->IsWriteBlocked());
  2349. // A new packet will be written after migration completes, unignore read
  2350. // errors.
  2351. if (ignore_read_error_)
  2352. ignore_read_error_ = false;
  2353. if (packet_) {
  2354. DCHECK(send_packet_after_migration_);
  2355. send_packet_after_migration_ = false;
  2356. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  2357. ->WritePacketToSocket(std::move(packet_));
  2358. return;
  2359. }
  2360. // Unblock the connection, which may send queued packets.
  2361. connection()->OnCanWrite();
  2362. if (send_packet_after_migration_) {
  2363. send_packet_after_migration_ = false;
  2364. if (!connection()->writer()->IsWriteBlocked()) {
  2365. connection()->SendPing();
  2366. }
  2367. }
  2368. }
  2369. void QuicChromiumClientSession::OnPathDegrading() {
  2370. if (most_recent_path_degrading_timestamp_ == base::TimeTicks())
  2371. most_recent_path_degrading_timestamp_ = tick_clock_->NowTicks();
  2372. handles::NetworkHandle current_network = GetCurrentNetwork();
  2373. for (auto& observer : connectivity_observer_list_)
  2374. observer.OnSessionPathDegrading(this, current_network);
  2375. if (!stream_factory_)
  2376. return;
  2377. if (allow_port_migration_ && !migrate_session_early_v2_) {
  2378. MaybeMigrateToDifferentPortOnPathDegrading();
  2379. return;
  2380. }
  2381. MaybeMigrateToAlternateNetworkOnPathDegrading();
  2382. }
  2383. void QuicChromiumClientSession::OnForwardProgressMadeAfterPathDegrading() {
  2384. handles::NetworkHandle current_network = GetCurrentNetwork();
  2385. for (auto& observer : connectivity_observer_list_)
  2386. observer.OnSessionResumedPostPathDegrading(this, current_network);
  2387. }
  2388. void QuicChromiumClientSession::OnKeyUpdate(quic::KeyUpdateReason reason) {
  2389. net_log_.AddEventWithStringParams(NetLogEventType::QUIC_SESSION_KEY_UPDATE,
  2390. "reason",
  2391. quic::KeyUpdateReasonString(reason));
  2392. base::UmaHistogramEnumeration("Net.QuicSession.KeyUpdate.Reason", reason);
  2393. last_key_update_reason_ = reason;
  2394. }
  2395. void QuicChromiumClientSession::OnProofValid(
  2396. const quic::QuicCryptoClientConfig::CachedState& cached) {
  2397. DCHECK(cached.proof_valid());
  2398. if (!server_info_) {
  2399. return;
  2400. }
  2401. QuicServerInfo::State* state = server_info_->mutable_state();
  2402. state->server_config = cached.server_config();
  2403. state->source_address_token = cached.source_address_token();
  2404. state->cert_sct = cached.cert_sct();
  2405. state->chlo_hash = cached.chlo_hash();
  2406. state->server_config_sig = cached.signature();
  2407. state->certs = cached.certs();
  2408. server_info_->Persist();
  2409. }
  2410. void QuicChromiumClientSession::OnProofVerifyDetailsAvailable(
  2411. const quic::ProofVerifyDetails& verify_details) {
  2412. const ProofVerifyDetailsChromium* verify_details_chromium =
  2413. reinterpret_cast<const ProofVerifyDetailsChromium*>(&verify_details);
  2414. cert_verify_result_ = std::make_unique<CertVerifyResult>(
  2415. verify_details_chromium->cert_verify_result);
  2416. pinning_failure_log_ = verify_details_chromium->pinning_failure_log;
  2417. logger_->OnCertificateVerified(*cert_verify_result_);
  2418. pkp_bypassed_ = verify_details_chromium->pkp_bypassed;
  2419. is_fatal_cert_error_ = verify_details_chromium->is_fatal_cert_error;
  2420. }
  2421. void QuicChromiumClientSession::StartReading() {
  2422. for (auto& packet_reader : packet_readers_) {
  2423. packet_reader->StartReading();
  2424. }
  2425. }
  2426. void QuicChromiumClientSession::CloseSessionOnError(
  2427. int net_error,
  2428. quic::QuicErrorCode quic_error,
  2429. quic::ConnectionCloseBehavior behavior) {
  2430. base::UmaHistogramSparse("Net.QuicSession.CloseSessionOnError", -net_error);
  2431. if (!callback_.is_null()) {
  2432. std::move(callback_).Run(net_error);
  2433. }
  2434. NotifyAllStreamsOfError(net_error);
  2435. net_log_.AddEventWithIntParams(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
  2436. "net_error", net_error);
  2437. if (connection()->connected())
  2438. connection()->CloseConnection(quic_error, "net error", behavior);
  2439. DCHECK(!connection()->connected());
  2440. CloseAllHandles(net_error);
  2441. NotifyFactoryOfSessionClosed();
  2442. }
  2443. void QuicChromiumClientSession::CloseSessionOnErrorLater(
  2444. int net_error,
  2445. quic::QuicErrorCode quic_error,
  2446. quic::ConnectionCloseBehavior behavior) {
  2447. base::UmaHistogramSparse("Net.QuicSession.CloseSessionOnError", -net_error);
  2448. if (!callback_.is_null()) {
  2449. std::move(callback_).Run(net_error);
  2450. }
  2451. NotifyAllStreamsOfError(net_error);
  2452. CloseAllHandles(net_error);
  2453. net_log_.AddEventWithIntParams(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
  2454. "net_error", net_error);
  2455. if (connection()->connected())
  2456. connection()->CloseConnection(quic_error, "net error", behavior);
  2457. DCHECK(!connection()->connected());
  2458. NotifyFactoryOfSessionClosedLater();
  2459. }
  2460. void QuicChromiumClientSession::NotifyAllStreamsOfError(int net_error) {
  2461. PerformActionOnActiveStreams([net_error](quic::QuicStream* stream) {
  2462. static_cast<QuicChromiumClientStream*>(stream)->OnError(net_error);
  2463. return true;
  2464. });
  2465. }
  2466. void QuicChromiumClientSession::CloseAllHandles(int net_error) {
  2467. while (!handles_.empty()) {
  2468. Handle* handle = *handles_.begin();
  2469. handles_.erase(handle);
  2470. handle->OnSessionClosed(connection()->version(), net_error, error(),
  2471. port_migration_detected_,
  2472. quic_connection_migration_attempted_,
  2473. quic_connection_migration_successful_,
  2474. GetConnectTiming(), WasConnectionEverUsed());
  2475. }
  2476. }
  2477. void QuicChromiumClientSession::CancelAllRequests(int net_error) {
  2478. UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.AbortedPendingStreamRequests",
  2479. stream_requests_.size());
  2480. while (!stream_requests_.empty()) {
  2481. StreamRequest* request = stream_requests_.front();
  2482. stream_requests_.pop_front();
  2483. request->OnRequestCompleteFailure(net_error);
  2484. }
  2485. }
  2486. void QuicChromiumClientSession::NotifyRequestsOfConfirmation(int net_error) {
  2487. // Post tasks to avoid reentrancy.
  2488. for (auto& callback : waiting_for_confirmation_callbacks_)
  2489. task_runner_->PostTask(FROM_HERE,
  2490. base::BindOnce(std::move(callback), net_error));
  2491. waiting_for_confirmation_callbacks_.clear();
  2492. }
  2493. void QuicChromiumClientSession::MaybeMigrateToDifferentPortOnPathDegrading() {
  2494. DCHECK(allow_port_migration_ && !migrate_session_early_v2_);
  2495. current_migration_cause_ = CHANGE_PORT_ON_PATH_DEGRADING;
  2496. if (!version().UsesHttp3())
  2497. return;
  2498. // Migration before handshake confirmed is not allowed.
  2499. if (!connection()->IsHandshakeConfirmed()) {
  2500. HistogramAndLogMigrationFailure(
  2501. MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
  2502. connection_id(), "Path degrading before handshake confirmed");
  2503. return;
  2504. }
  2505. if (config()->DisableConnectionMigration()) {
  2506. HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
  2507. connection_id(),
  2508. "Migration disabled by config");
  2509. return;
  2510. }
  2511. net_log_.BeginEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
  2512. if (!stream_factory_)
  2513. return;
  2514. // Probe a different port, session will migrate to the probed port on success.
  2515. StartProbing(default_network_, peer_address());
  2516. net_log_.EndEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
  2517. }
  2518. void QuicChromiumClientSession::
  2519. MaybeMigrateToAlternateNetworkOnPathDegrading() {
  2520. net_log_.AddEvent(
  2521. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_PATH_DEGRADING);
  2522. current_migration_cause_ = CHANGE_NETWORK_ON_PATH_DEGRADING;
  2523. if (!migrate_session_early_v2_ || !version().UsesHttp3()) {
  2524. HistogramAndLogMigrationFailure(MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED,
  2525. connection_id(),
  2526. "Migration on path degrading not enabled");
  2527. return;
  2528. }
  2529. if (GetCurrentNetwork() == default_network_ &&
  2530. current_migrations_to_non_default_network_on_path_degrading_ >=
  2531. max_migrations_to_non_default_network_on_path_degrading_) {
  2532. HistogramAndLogMigrationFailure(
  2533. MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED, connection_id(),
  2534. "Exceeds maximum number of migrations on path degrading");
  2535. return;
  2536. }
  2537. handles::NetworkHandle alternate_network =
  2538. stream_factory_->FindAlternateNetwork(GetCurrentNetwork());
  2539. if (alternate_network == handles::kInvalidNetworkHandle) {
  2540. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
  2541. connection_id(),
  2542. "No alternative network on path degrading");
  2543. return;
  2544. }
  2545. LogHandshakeStatusOnMigrationSignal();
  2546. if (!connection()->IsHandshakeConfirmed()) {
  2547. HistogramAndLogMigrationFailure(
  2548. MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
  2549. connection_id(), "Path degrading before handshake confirmed");
  2550. return;
  2551. }
  2552. net_log_.BeginEventWithStringParams(
  2553. NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
  2554. "PathDegrading");
  2555. // Probe the alternative network, session will migrate to the probed
  2556. // network and decide whether it wants to migrate back to the default
  2557. // network on success.
  2558. MaybeStartProbing(alternate_network, peer_address());
  2559. net_log_.EndEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
  2560. }
  2561. ProbingResult QuicChromiumClientSession::MaybeStartProbing(
  2562. handles::NetworkHandle network,
  2563. const quic::QuicSocketAddress& peer_address) {
  2564. if (!stream_factory_)
  2565. return ProbingResult::FAILURE;
  2566. CHECK_NE(handles::kInvalidNetworkHandle, network);
  2567. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  2568. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
  2569. connection_id(), "No active streams");
  2570. CloseSessionOnErrorLater(
  2571. ERR_NETWORK_CHANGED,
  2572. quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
  2573. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
  2574. return ProbingResult::DISABLED_WITH_IDLE_SESSION;
  2575. }
  2576. if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
  2577. return ProbingResult::DISABLED_WITH_IDLE_SESSION;
  2578. // Abort probing if connection migration is disabled by config.
  2579. if (!connection()->connection_migration_use_new_cid()) {
  2580. DVLOG(1) << "Client IETF connection migration is not enabled.";
  2581. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NOT_ENABLED,
  2582. connection_id(),
  2583. "IETF migration flag is false");
  2584. return ProbingResult::DISABLED_BY_CONFIG;
  2585. }
  2586. if (config()->DisableConnectionMigration()) {
  2587. DVLOG(1) << "Client disables probing network with connection migration "
  2588. << "disabled by config";
  2589. HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
  2590. connection_id(),
  2591. "Migration disabled by config");
  2592. return ProbingResult::DISABLED_BY_CONFIG;
  2593. }
  2594. return StartProbing(network, peer_address);
  2595. }
  2596. ProbingResult QuicChromiumClientSession::StartProbing(
  2597. handles::NetworkHandle network,
  2598. const quic::QuicSocketAddress& peer_address) {
  2599. if (!connection()->connection_migration_use_new_cid()) {
  2600. return ProbingResult::DISABLED_BY_CONFIG;
  2601. }
  2602. // Check if probing manager is probing the same path.
  2603. auto* existing_context = static_cast<QuicChromiumPathValidationContext*>(
  2604. connection()->GetPathValidationContext());
  2605. if (existing_context && existing_context->network() == network &&
  2606. existing_context->peer_address() == peer_address) {
  2607. return ProbingResult::PENDING;
  2608. }
  2609. // Create and configure socket on |network|.
  2610. std::unique_ptr<DatagramClientSocket> probing_socket =
  2611. stream_factory_->CreateSocket(net_log_.net_log(), net_log_.source());
  2612. if (stream_factory_->ConfigureSocket(probing_socket.get(),
  2613. ToIPEndPoint(peer_address), network,
  2614. session_key_.socket_tag()) != OK) {
  2615. HistogramAndLogMigrationFailure(MIGRATION_STATUS_INTERNAL_ERROR,
  2616. connection_id(),
  2617. "Socket configuration failed");
  2618. return ProbingResult::INTERNAL_ERROR;
  2619. }
  2620. // Create new packet writer and reader on the probing socket.
  2621. auto probing_writer = std::make_unique<QuicChromiumPacketWriter>(
  2622. probing_socket.get(), task_runner_);
  2623. auto probing_reader = std::make_unique<QuicChromiumPacketReader>(
  2624. probing_socket.get(), clock_, this, yield_after_packets_,
  2625. yield_after_duration_, net_log_);
  2626. probing_reader->StartReading();
  2627. path_validation_writer_delegate_.set_network(network);
  2628. path_validation_writer_delegate_.set_peer_address(peer_address);
  2629. probing_writer->set_delegate(&path_validation_writer_delegate_);
  2630. IPEndPoint local_address;
  2631. probing_socket->GetLocalAddress(&local_address);
  2632. auto context = std::make_unique<QuicChromiumPathValidationContext>(
  2633. ToQuicSocketAddress(local_address), peer_address, network,
  2634. std::move(probing_socket), std::move(probing_writer),
  2635. std::move(probing_reader));
  2636. if (current_migration_cause_ != CHANGE_PORT_ON_PATH_DEGRADING) {
  2637. ValidatePath(
  2638. std::move(context),
  2639. std::make_unique<ConnectionMigrationValidationResultDelegate>(this));
  2640. return ProbingResult::PENDING;
  2641. }
  2642. ValidatePath(std::move(context),
  2643. std::make_unique<PortMigrationValidationResultDelegate>(this));
  2644. return ProbingResult::PENDING;
  2645. }
  2646. void QuicChromiumClientSession::StartMigrateBackToDefaultNetworkTimer(
  2647. base::TimeDelta delay) {
  2648. if (current_migration_cause_ != ON_NETWORK_MADE_DEFAULT)
  2649. current_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
  2650. CancelMigrateBackToDefaultNetworkTimer();
  2651. // Post a task to try migrate back to default network after |delay|.
  2652. migrate_back_to_default_timer_.Start(
  2653. FROM_HERE, delay,
  2654. base::BindOnce(
  2655. &QuicChromiumClientSession::MaybeRetryMigrateBackToDefaultNetwork,
  2656. weak_factory_.GetWeakPtr()));
  2657. }
  2658. void QuicChromiumClientSession::CancelMigrateBackToDefaultNetworkTimer() {
  2659. retry_migrate_back_count_ = 0;
  2660. migrate_back_to_default_timer_.Stop();
  2661. }
  2662. void QuicChromiumClientSession::TryMigrateBackToDefaultNetwork(
  2663. base::TimeDelta timeout) {
  2664. if (default_network_ == handles::kInvalidNetworkHandle) {
  2665. DVLOG(1) << "Default network is not connected";
  2666. return;
  2667. }
  2668. net_log_.AddEventWithInt64Params(
  2669. NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_MIGRATE_BACK, "retry_count",
  2670. retry_migrate_back_count_);
  2671. // Start probe default network immediately, if manager is probing
  2672. // the same network, this will be a no-op. Otherwise, previous probe
  2673. // will be cancelled and manager starts to probe |default_network_|
  2674. // immediately.
  2675. ProbingResult result = MaybeStartProbing(default_network_, peer_address());
  2676. if (result == ProbingResult::DISABLED_WITH_IDLE_SESSION)
  2677. return;
  2678. if (result != ProbingResult::PENDING) {
  2679. // Session is not allowed to migrate, mark session as going away, cancel
  2680. // migrate back to default timer.
  2681. NotifyFactoryOfSessionGoingAway();
  2682. CancelMigrateBackToDefaultNetworkTimer();
  2683. return;
  2684. }
  2685. retry_migrate_back_count_++;
  2686. migrate_back_to_default_timer_.Start(
  2687. FROM_HERE, timeout,
  2688. base::BindOnce(
  2689. &QuicChromiumClientSession::MaybeRetryMigrateBackToDefaultNetwork,
  2690. weak_factory_.GetWeakPtr()));
  2691. }
  2692. void QuicChromiumClientSession::MaybeRetryMigrateBackToDefaultNetwork() {
  2693. base::TimeDelta retry_migrate_back_timeout =
  2694. base::Seconds(UINT64_C(1) << retry_migrate_back_count_);
  2695. if (default_network_ == GetCurrentNetwork()) {
  2696. // If session has been back on the default already by other direct
  2697. // migration attempt, cancel migrate back now.
  2698. CancelMigrateBackToDefaultNetworkTimer();
  2699. return;
  2700. }
  2701. if (retry_migrate_back_timeout > max_time_on_non_default_network_) {
  2702. // Mark session as going away to accept no more streams.
  2703. NotifyFactoryOfSessionGoingAway();
  2704. return;
  2705. }
  2706. TryMigrateBackToDefaultNetwork(retry_migrate_back_timeout);
  2707. }
  2708. bool QuicChromiumClientSession::CheckIdleTimeExceedsIdleMigrationPeriod() {
  2709. if (!migrate_idle_session_)
  2710. return false;
  2711. if (HasActiveRequestStreams()) {
  2712. return false;
  2713. }
  2714. // There are no active/drainning streams, check the last stream's finish time.
  2715. if (tick_clock_->NowTicks() - most_recent_stream_close_time_ <
  2716. idle_migration_period_) {
  2717. // Still within the idle migration period.
  2718. return false;
  2719. }
  2720. HistogramAndLogMigrationFailure(MIGRATION_STATUS_IDLE_MIGRATION_TIMEOUT,
  2721. connection_id(),
  2722. "Ilde migration period exceeded");
  2723. CloseSessionOnErrorLater(ERR_NETWORK_CHANGED, quic::QUIC_NETWORK_IDLE_TIMEOUT,
  2724. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2725. return true;
  2726. }
  2727. void QuicChromiumClientSession::ResetNonMigratableStreams() {
  2728. // TODO(zhongyi): may close non-migratable draining streams as well to avoid
  2729. // sending additional data on alternate networks.
  2730. PerformActionOnActiveStreams([](quic::QuicStream* stream) {
  2731. QuicChromiumClientStream* chrome_stream =
  2732. static_cast<QuicChromiumClientStream*>(stream);
  2733. if (!chrome_stream->can_migrate_to_cellular_network()) {
  2734. // Close the stream in both direction by resetting the stream.
  2735. // TODO(zhongyi): use a different error code to reset streams for
  2736. // connection migration.
  2737. chrome_stream->Reset(quic::QUIC_STREAM_CANCELLED);
  2738. }
  2739. return true;
  2740. });
  2741. }
  2742. void QuicChromiumClientSession::LogMetricsOnNetworkDisconnected() {
  2743. if (most_recent_path_degrading_timestamp_ != base::TimeTicks()) {
  2744. most_recent_network_disconnected_timestamp_ = tick_clock_->NowTicks();
  2745. base::TimeDelta degrading_duration =
  2746. most_recent_network_disconnected_timestamp_ -
  2747. most_recent_path_degrading_timestamp_;
  2748. UMA_HISTOGRAM_CUSTOM_TIMES(
  2749. "Net.QuicNetworkDegradingDurationTillDisconnected", degrading_duration,
  2750. base::Milliseconds(1), base::Minutes(10), 100);
  2751. }
  2752. if (most_recent_write_error_timestamp_ != base::TimeTicks()) {
  2753. base::TimeDelta write_error_to_disconnection_gap =
  2754. most_recent_network_disconnected_timestamp_ -
  2755. most_recent_write_error_timestamp_;
  2756. UMA_HISTOGRAM_CUSTOM_TIMES(
  2757. "Net.QuicNetworkGapBetweenWriteErrorAndDisconnection",
  2758. write_error_to_disconnection_gap, base::Milliseconds(1),
  2759. base::Minutes(10), 100);
  2760. base::UmaHistogramSparse("Net.QuicSession.WriteError.NetworkDisconnected",
  2761. -most_recent_write_error_);
  2762. most_recent_write_error_ = 0;
  2763. most_recent_write_error_timestamp_ = base::TimeTicks();
  2764. }
  2765. }
  2766. void QuicChromiumClientSession::LogMetricsOnNetworkMadeDefault() {
  2767. if (most_recent_path_degrading_timestamp_ != base::TimeTicks()) {
  2768. if (most_recent_network_disconnected_timestamp_ != base::TimeTicks()) {
  2769. // NetworkDiscconected happens before NetworkMadeDefault, the platform
  2770. // is dropping WiFi.
  2771. base::TimeTicks now = tick_clock_->NowTicks();
  2772. base::TimeDelta disconnection_duration =
  2773. now - most_recent_network_disconnected_timestamp_;
  2774. base::TimeDelta degrading_duration =
  2775. now - most_recent_path_degrading_timestamp_;
  2776. UMA_HISTOGRAM_CUSTOM_TIMES("Net.QuicNetworkDisconnectionDuration",
  2777. disconnection_duration, base::Milliseconds(1),
  2778. base::Minutes(10), 100);
  2779. UMA_HISTOGRAM_CUSTOM_TIMES(
  2780. "Net.QuicNetworkDegradingDurationTillNewNetworkMadeDefault",
  2781. degrading_duration, base::Milliseconds(1), base::Minutes(10), 100);
  2782. most_recent_network_disconnected_timestamp_ = base::TimeTicks();
  2783. }
  2784. most_recent_path_degrading_timestamp_ = base::TimeTicks();
  2785. }
  2786. }
  2787. void QuicChromiumClientSession::LogMigrationResultToHistogram(
  2788. QuicConnectionMigrationStatus status) {
  2789. if (current_migration_cause_ == CHANGE_PORT_ON_PATH_DEGRADING) {
  2790. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.PortMigration", status,
  2791. MIGRATION_STATUS_MAX);
  2792. current_migration_cause_ = UNKNOWN_CAUSE;
  2793. return;
  2794. }
  2795. UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration", status,
  2796. MIGRATION_STATUS_MAX);
  2797. // Log the connection migraiton result to different histograms based on the
  2798. // cause of the connection migration.
  2799. std::string histogram_name = "Net.QuicSession.ConnectionMigration." +
  2800. MigrationCauseToString(current_migration_cause_);
  2801. base::UmaHistogramEnumeration(histogram_name, status, MIGRATION_STATUS_MAX);
  2802. current_migration_cause_ = UNKNOWN_CAUSE;
  2803. }
  2804. void QuicChromiumClientSession::LogHandshakeStatusOnMigrationSignal() const {
  2805. if (current_migration_cause_ == CHANGE_PORT_ON_PATH_DEGRADING) {
  2806. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.HandshakeStatusOnPortMigration",
  2807. OneRttKeysAvailable());
  2808. return;
  2809. }
  2810. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.HandshakeStatusOnConnectionMigration",
  2811. OneRttKeysAvailable());
  2812. const std::string histogram_name =
  2813. "Net.QuicSession.HandshakeStatusOnConnectionMigration." +
  2814. MigrationCauseToString(current_migration_cause_);
  2815. STATIC_HISTOGRAM_POINTER_GROUP(
  2816. histogram_name, current_migration_cause_, MIGRATION_CAUSE_MAX,
  2817. AddBoolean(OneRttKeysAvailable()),
  2818. base::BooleanHistogram::FactoryGet(
  2819. histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag));
  2820. }
  2821. void QuicChromiumClientSession::HistogramAndLogMigrationFailure(
  2822. QuicConnectionMigrationStatus status,
  2823. quic::QuicConnectionId connection_id,
  2824. const char* reason) {
  2825. NetLogEventType event_type =
  2826. current_migration_cause_ == CHANGE_PORT_ON_PATH_DEGRADING
  2827. ? NetLogEventType::QUIC_PORT_MIGRATION_FAILURE
  2828. : NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE;
  2829. net_log_.AddEvent(event_type, [&] {
  2830. return NetLogQuicMigrationFailureParams(connection_id, reason);
  2831. });
  2832. // |current_migration_cause_| will be reset afterwards.
  2833. LogMigrationResultToHistogram(status);
  2834. }
  2835. void QuicChromiumClientSession::HistogramAndLogMigrationSuccess(
  2836. quic::QuicConnectionId connection_id) {
  2837. NetLogEventType event_type =
  2838. current_migration_cause_ == CHANGE_PORT_ON_PATH_DEGRADING
  2839. ? NetLogEventType::QUIC_PORT_MIGRATION_SUCCESS
  2840. : NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS;
  2841. net_log_.AddEvent(event_type, [&] {
  2842. return NetLogQuicMigrationSuccessParams(connection_id);
  2843. });
  2844. // |current_migration_cause_| will be reset afterwards.
  2845. LogMigrationResultToHistogram(MIGRATION_STATUS_SUCCESS);
  2846. }
  2847. base::Value QuicChromiumClientSession::GetInfoAsValue(
  2848. const std::set<HostPortPair>& aliases) {
  2849. base::Value::Dict dict;
  2850. dict.Set("version", ParsedQuicVersionToString(connection()->version()));
  2851. dict.Set("open_streams", static_cast<int>(GetNumActiveStreams()));
  2852. base::Value::List stream_list;
  2853. auto* stream_list_ptr = &stream_list;
  2854. PerformActionOnActiveStreams([stream_list_ptr](quic::QuicStream* stream) {
  2855. stream_list_ptr->Append(base::NumberToString(stream->id()));
  2856. return true;
  2857. });
  2858. dict.Set("active_streams", std::move(stream_list));
  2859. dict.Set("total_streams", static_cast<int>(num_total_streams_));
  2860. dict.Set("peer_address", peer_address().ToString());
  2861. dict.Set("network_isolation_key",
  2862. session_key_.network_isolation_key().ToDebugString());
  2863. dict.Set("connection_id", connection_id().ToString());
  2864. if (!connection()->client_connection_id().IsEmpty()) {
  2865. dict.Set("client_connection_id",
  2866. connection()->client_connection_id().ToString());
  2867. }
  2868. dict.Set("connected", connection()->connected());
  2869. const quic::QuicConnectionStats& stats = connection()->GetStats();
  2870. dict.Set("packets_sent", static_cast<int>(stats.packets_sent));
  2871. dict.Set("packets_received", static_cast<int>(stats.packets_received));
  2872. dict.Set("packets_lost", static_cast<int>(stats.packets_lost));
  2873. SSLInfo ssl_info;
  2874. base::Value::List alias_list;
  2875. for (const auto& alias : aliases) {
  2876. alias_list.Append(alias.ToString());
  2877. }
  2878. dict.Set("aliases", std::move(alias_list));
  2879. return base::Value(std::move(dict));
  2880. }
  2881. bool QuicChromiumClientSession::gquic_zero_rtt_disabled() const {
  2882. if (!stream_factory_)
  2883. return false;
  2884. return stream_factory_->gquic_zero_rtt_disabled();
  2885. }
  2886. std::unique_ptr<QuicChromiumClientSession::Handle>
  2887. QuicChromiumClientSession::CreateHandle(url::SchemeHostPort destination) {
  2888. return std::make_unique<QuicChromiumClientSession::Handle>(
  2889. weak_factory_.GetWeakPtr(), std::move(destination));
  2890. }
  2891. bool QuicChromiumClientSession::OnReadError(
  2892. int result,
  2893. const DatagramClientSocket* socket) {
  2894. DCHECK(socket != nullptr);
  2895. base::UmaHistogramSparse("Net.QuicSession.ReadError.AnyNetwork", -result);
  2896. if (socket != GetDefaultSocket()) {
  2897. DVLOG(1) << "Ignoring read error " << ErrorToString(result)
  2898. << " on old socket";
  2899. base::UmaHistogramSparse("Net.QuicSession.ReadError.OtherNetworks",
  2900. -result);
  2901. // Ignore read errors from sockets that are not affecting the current
  2902. // network, i.e., sockets that are no longer active and probing socket.
  2903. // TODO(jri): Maybe clean up old sockets on error.
  2904. return false;
  2905. }
  2906. if (ignore_read_error_) {
  2907. DVLOG(1) << "Ignoring read error " << ErrorToString(result)
  2908. << " during pending migration";
  2909. // Ignore read errors during pending migration. Connection will be closed if
  2910. // pending migration failed or timed out.
  2911. base::UmaHistogramSparse("Net.QuicSession.ReadError.PendingMigration",
  2912. -result);
  2913. return false;
  2914. }
  2915. base::UmaHistogramSparse("Net.QuicSession.ReadError.CurrentNetwork", -result);
  2916. if (OneRttKeysAvailable()) {
  2917. base::UmaHistogramSparse(
  2918. "Net.QuicSession.ReadError.CurrentNetwork.HandshakeConfirmed", -result);
  2919. }
  2920. DVLOG(1) << "Closing session on read error " << ErrorToString(result);
  2921. connection()->CloseConnection(quic::QUIC_PACKET_READ_ERROR,
  2922. ErrorToString(result),
  2923. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  2924. return false;
  2925. }
  2926. bool QuicChromiumClientSession::OnPacket(
  2927. const quic::QuicReceivedPacket& packet,
  2928. const quic::QuicSocketAddress& local_address,
  2929. const quic::QuicSocketAddress& peer_address) {
  2930. ProcessUdpPacket(local_address, peer_address, packet);
  2931. if (!connection()->connected()) {
  2932. NotifyFactoryOfSessionClosedLater();
  2933. return false;
  2934. }
  2935. return true;
  2936. }
  2937. void QuicChromiumClientSession::NotifyFactoryOfSessionGoingAway() {
  2938. going_away_ = true;
  2939. if (stream_factory_)
  2940. stream_factory_->OnSessionGoingAway(this);
  2941. }
  2942. void QuicChromiumClientSession::NotifyFactoryOfSessionClosedLater() {
  2943. going_away_ = true;
  2944. DCHECK_EQ(0u, GetNumActiveStreams());
  2945. DCHECK(!connection()->connected());
  2946. task_runner_->PostTask(
  2947. FROM_HERE,
  2948. base::BindOnce(&QuicChromiumClientSession::NotifyFactoryOfSessionClosed,
  2949. weak_factory_.GetWeakPtr()));
  2950. }
  2951. void QuicChromiumClientSession::NotifyFactoryOfSessionClosed() {
  2952. going_away_ = true;
  2953. DCHECK_EQ(0u, GetNumActiveStreams());
  2954. // Will delete |this|.
  2955. if (stream_factory_)
  2956. stream_factory_->OnSessionClosed(this);
  2957. }
  2958. void QuicChromiumClientSession::OnCryptoHandshakeComplete() {
  2959. if (stream_factory_)
  2960. stream_factory_->set_is_quic_known_to_work_on_current_network(true);
  2961. // Update |connect_end| only when handshake is confirmed. This should also
  2962. // take care of any failed 0-RTT request.
  2963. connect_timing_.connect_end = tick_clock_->NowTicks();
  2964. DCHECK_LE(connect_timing_.connect_start, connect_timing_.connect_end);
  2965. UMA_HISTOGRAM_TIMES(
  2966. "Net.QuicSession.HandshakeConfirmedTime",
  2967. connect_timing_.connect_end - connect_timing_.connect_start);
  2968. // Track how long it has taken to finish handshake after we have finished
  2969. // DNS host resolution.
  2970. if (!connect_timing_.dns_end.is_null()) {
  2971. UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolution.HandshakeConfirmedTime",
  2972. tick_clock_->NowTicks() - connect_timing_.dns_end);
  2973. }
  2974. auto it = handles_.begin();
  2975. while (it != handles_.end()) {
  2976. Handle* handle = *it;
  2977. ++it;
  2978. handle->OnCryptoHandshakeConfirmed();
  2979. }
  2980. NotifyRequestsOfConfirmation(OK);
  2981. // Attempt to migrate back to the default network after handshake has been
  2982. // confirmed if the session is not created on the default network.
  2983. if (migrate_session_on_network_change_v2_ &&
  2984. default_network_ != handles::kInvalidNetworkHandle &&
  2985. GetCurrentNetwork() != default_network_ && version().UsesHttp3()) {
  2986. current_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
  2987. StartMigrateBackToDefaultNetworkTimer(
  2988. base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
  2989. }
  2990. }
  2991. MigrationResult QuicChromiumClientSession::Migrate(
  2992. handles::NetworkHandle network,
  2993. IPEndPoint peer_address,
  2994. bool close_session_on_error) {
  2995. quic_connection_migration_attempted_ = true;
  2996. quic_connection_migration_successful_ = false;
  2997. if (!stream_factory_)
  2998. return MigrationResult::FAILURE;
  2999. if (network != handles::kInvalidNetworkHandle) {
  3000. // This is a migration attempt from connection migration.
  3001. ResetNonMigratableStreams();
  3002. if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
  3003. // If idle sessions can not be migrated, close the session if needed.
  3004. if (close_session_on_error) {
  3005. CloseSessionOnErrorLater(
  3006. ERR_NETWORK_CHANGED,
  3007. quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
  3008. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  3009. }
  3010. return MigrationResult::FAILURE;
  3011. }
  3012. }
  3013. // Create and configure socket on |network|.
  3014. std::unique_ptr<DatagramClientSocket> socket(
  3015. stream_factory_->CreateSocket(net_log_.net_log(), net_log_.source()));
  3016. if (stream_factory_->ConfigureSocket(socket.get(), peer_address, network,
  3017. session_key_.socket_tag()) != OK) {
  3018. HistogramAndLogMigrationFailure(MIGRATION_STATUS_INTERNAL_ERROR,
  3019. connection_id(),
  3020. "Socket configuration failed");
  3021. if (close_session_on_error) {
  3022. if (migrate_session_on_network_change_v2_) {
  3023. CloseSessionOnErrorLater(ERR_NETWORK_CHANGED,
  3024. quic::QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR,
  3025. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  3026. } else {
  3027. CloseSessionOnError(ERR_NETWORK_CHANGED,
  3028. quic::QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR,
  3029. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  3030. }
  3031. }
  3032. return MigrationResult::FAILURE;
  3033. }
  3034. // Create new packet reader and writer on the new socket.
  3035. auto new_reader = std::make_unique<QuicChromiumPacketReader>(
  3036. socket.get(), clock_, this, yield_after_packets_, yield_after_duration_,
  3037. net_log_);
  3038. new_reader->StartReading();
  3039. auto new_writer =
  3040. std::make_unique<QuicChromiumPacketWriter>(socket.get(), task_runner_);
  3041. static_cast<QuicChromiumPacketWriter*>(connection()->writer())
  3042. ->set_delegate(nullptr);
  3043. new_writer->set_delegate(this);
  3044. IPEndPoint self_address;
  3045. socket->GetLocalAddress(&self_address);
  3046. // Migrate to the new socket.
  3047. if (!MigrateToSocket(ToQuicSocketAddress(self_address),
  3048. ToQuicSocketAddress(peer_address), std::move(socket),
  3049. std::move(new_reader), std::move(new_writer))) {
  3050. if (close_session_on_error) {
  3051. if (migrate_session_on_network_change_v2_) {
  3052. CloseSessionOnErrorLater(
  3053. ERR_NETWORK_CHANGED,
  3054. quic::QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES,
  3055. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  3056. } else {
  3057. CloseSessionOnError(ERR_NETWORK_CHANGED,
  3058. quic::QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES,
  3059. quic::ConnectionCloseBehavior::SILENT_CLOSE);
  3060. }
  3061. }
  3062. return MigrationResult::FAILURE;
  3063. }
  3064. quic_connection_migration_successful_ = true;
  3065. HistogramAndLogMigrationSuccess(connection_id());
  3066. return MigrationResult::SUCCESS;
  3067. }
  3068. bool QuicChromiumClientSession::MigrateToSocket(
  3069. const quic::QuicSocketAddress& self_address,
  3070. const quic::QuicSocketAddress& peer_address,
  3071. std::unique_ptr<DatagramClientSocket> socket,
  3072. std::unique_ptr<QuicChromiumPacketReader> reader,
  3073. std::unique_ptr<QuicChromiumPacketWriter> writer) {
  3074. CHECK_EQ(sockets_.size(), packet_readers_.size());
  3075. // TODO(zhongyi): figure out whether we want to limit the number of
  3076. // connection migrations for v2, which includes migration on platform signals,
  3077. // write error events, and path degrading on original network.
  3078. if (!migrate_session_on_network_change_v2_ &&
  3079. sockets_.size() >= kMaxReadersPerQuicSession) {
  3080. HistogramAndLogMigrationFailure(MIGRATION_STATUS_TOO_MANY_CHANGES,
  3081. connection_id(), "Too many changes");
  3082. return false;
  3083. }
  3084. packet_readers_.push_back(std::move(reader));
  3085. sockets_.push_back(std::move(socket));
  3086. // Froce the writer to be blocked to prevent it being used until
  3087. // WriteToNewSocket completes.
  3088. DVLOG(1) << "Force blocking the packet writer";
  3089. writer->set_force_write_blocked(true);
  3090. if (!MigratePath(self_address, peer_address, writer.release(),
  3091. /*owns_writer=*/true)) {
  3092. HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_UNUSED_CONNECTION_ID,
  3093. connection_id(),
  3094. "No unused server connection ID");
  3095. DVLOG(1) << "MigratePath fails as there is no CID available";
  3096. return false;
  3097. }
  3098. // Post task to write the pending packet or a PING packet to the new
  3099. // socket. This avoids reentrancy issues if there is a write error
  3100. // on the write to the new socket.
  3101. task_runner_->PostTask(
  3102. FROM_HERE, base::BindOnce(&QuicChromiumClientSession::WriteToNewSocket,
  3103. weak_factory_.GetWeakPtr()));
  3104. return true;
  3105. }
  3106. void QuicChromiumClientSession::PopulateNetErrorDetails(
  3107. NetErrorDetails* details) const {
  3108. details->quic_port_migration_detected = port_migration_detected_;
  3109. details->quic_connection_error = error();
  3110. details->quic_connection_migration_attempted =
  3111. quic_connection_migration_attempted_;
  3112. details->quic_connection_migration_successful =
  3113. quic_connection_migration_successful_;
  3114. }
  3115. const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket()
  3116. const {
  3117. DCHECK(sockets_.back().get() != nullptr);
  3118. // The most recently added socket is the currently active one.
  3119. return sockets_.back().get();
  3120. }
  3121. handles::NetworkHandle QuicChromiumClientSession::GetCurrentNetwork() const {
  3122. // If connection migration is enabled, alternate network interface may be
  3123. // used to send packet, it is identified as the bound network of the default
  3124. // socket. Otherwise, always use |default_network_|.
  3125. return migrate_session_on_network_change_v2_
  3126. ? GetDefaultSocket()->GetBoundNetwork()
  3127. : default_network_;
  3128. }
  3129. bool QuicChromiumClientSession::IsAuthorized(const std::string& hostname) {
  3130. bool result = CanPool(hostname, session_key_);
  3131. if (result)
  3132. streams_pushed_count_++;
  3133. return result;
  3134. }
  3135. bool QuicChromiumClientSession::HandlePromised(
  3136. quic::QuicStreamId id,
  3137. quic::QuicStreamId promised_id,
  3138. const spdy::Http2HeaderBlock& headers) {
  3139. bool result =
  3140. quic::QuicSpdyClientSessionBase::HandlePromised(id, promised_id, headers);
  3141. if (result) {
  3142. // The push promise is accepted, notify the push_delegate that a push
  3143. // promise has been received.
  3144. if (push_delegate_) {
  3145. std::string pushed_url =
  3146. quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers);
  3147. push_delegate_->OnPush(std::make_unique<QuicServerPushHelper>(
  3148. weak_factory_.GetWeakPtr(), GURL(pushed_url)),
  3149. net_log_);
  3150. }
  3151. if (headers_include_h2_stream_dependency_ ||
  3152. VersionUsesHttp3(connection()->transport_version())) {
  3153. // Even though the promised stream will not be created until after the
  3154. // push promise headers are received, send a PRIORITY frame for the
  3155. // promised stream ID. Send |kDefaultPriority| since that will be the
  3156. // initial spdy::SpdyPriority of the push promise stream when created.
  3157. const spdy::SpdyPriority priority = quic::QuicStream::kDefaultPriority;
  3158. spdy::SpdyStreamId parent_stream_id = 0;
  3159. int weight = 0;
  3160. bool exclusive = false;
  3161. priority_dependency_state_.OnStreamCreation(
  3162. promised_id, priority, &parent_stream_id, &weight, &exclusive);
  3163. if (!VersionUsesHttp3(connection()->transport_version())) {
  3164. WritePriority(promised_id, parent_stream_id, weight, exclusive);
  3165. }
  3166. }
  3167. }
  3168. net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PUSH_PROMISE_RECEIVED,
  3169. [&](NetLogCaptureMode capture_mode) {
  3170. return NetLogQuicPushPromiseReceivedParams(
  3171. &headers, id, promised_id, capture_mode);
  3172. });
  3173. return result;
  3174. }
  3175. void QuicChromiumClientSession::DeletePromised(
  3176. quic::QuicClientPromisedInfo* promised) {
  3177. if (IsOpenStream(promised->id()))
  3178. streams_pushed_and_claimed_count_++;
  3179. quic::QuicSpdyClientSessionBase::DeletePromised(promised);
  3180. }
  3181. void QuicChromiumClientSession::OnPushStreamTimedOut(
  3182. quic::QuicStreamId stream_id) {
  3183. quic::QuicSpdyStream* stream = GetPromisedStream(stream_id);
  3184. if (stream != nullptr)
  3185. bytes_pushed_and_unclaimed_count_ += stream->stream_bytes_read();
  3186. }
  3187. void QuicChromiumClientSession::CancelPush(const GURL& url) {
  3188. quic::QuicClientPromisedInfo* promised_info =
  3189. quic::QuicSpdyClientSessionBase::GetPromisedByUrl(url.spec());
  3190. if (!promised_info || promised_info->is_validating()) {
  3191. // Push stream has already been claimed or is pending matched to a request.
  3192. return;
  3193. }
  3194. quic::QuicStreamId stream_id = promised_info->id();
  3195. // Collect data on the cancelled push stream.
  3196. quic::QuicSpdyStream* stream = GetPromisedStream(stream_id);
  3197. if (stream != nullptr)
  3198. bytes_pushed_and_unclaimed_count_ += stream->stream_bytes_read();
  3199. // Send the reset and remove the promised info from the promise index.
  3200. quic::QuicSpdyClientSessionBase::ResetPromised(stream_id,
  3201. quic::QUIC_STREAM_CANCELLED);
  3202. DeletePromised(promised_info);
  3203. }
  3204. const LoadTimingInfo::ConnectTiming&
  3205. QuicChromiumClientSession::GetConnectTiming() {
  3206. connect_timing_.ssl_start = connect_timing_.connect_start;
  3207. connect_timing_.ssl_end = connect_timing_.connect_end;
  3208. return connect_timing_;
  3209. }
  3210. quic::ParsedQuicVersion QuicChromiumClientSession::GetQuicVersion() const {
  3211. return connection()->version();
  3212. }
  3213. quic::QuicClientPromisedInfo* QuicChromiumClientSession::GetPromised(
  3214. const GURL& url,
  3215. const QuicSessionKey& session_key) {
  3216. if (!session_key_.CanUseForAliasing(session_key)) {
  3217. return nullptr;
  3218. }
  3219. return push_promise_index_->GetPromised(url.spec());
  3220. }
  3221. const std::set<std::string>&
  3222. QuicChromiumClientSession::GetDnsAliasesForSessionKey(
  3223. const QuicSessionKey& key) const {
  3224. static const base::NoDestructor<std::set<std::string>> emptyset_result;
  3225. return stream_factory_ ? stream_factory_->GetDnsAliasesForSessionKey(key)
  3226. : *emptyset_result;
  3227. }
  3228. } // namespace net