config.go 160 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038
  1. /*
  2. * Copyright (c) 2015, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package psiphon
  20. import (
  21. "crypto/md5"
  22. "encoding/base64"
  23. "encoding/binary"
  24. "encoding/json"
  25. "fmt"
  26. "io/ioutil"
  27. "net/http"
  28. "os"
  29. "path/filepath"
  30. "reflect"
  31. "regexp"
  32. "strconv"
  33. "strings"
  34. "sync"
  35. "sync/atomic"
  36. "time"
  37. "unicode"
  38. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  39. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  40. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/inproxy"
  41. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/networkid"
  42. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/parameters"
  43. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
  44. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/resolver"
  45. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/transforms"
  46. "golang.org/x/crypto/nacl/secretbox"
  47. )
  48. const (
  49. TUNNEL_POOL_SIZE = 1
  50. MAX_TUNNEL_POOL_SIZE = 32
  51. // Psiphon data directory name, relative to config.DataRootDirectory.
  52. // See config.GetPsiphonDataDirectory().
  53. PsiphonDataDirectoryName = "ca.psiphon.PsiphonTunnel.tunnel-core"
  54. // Filename constants, all relative to config.GetPsiphonDataDirectory().
  55. HomepageFilename = "homepage"
  56. NoticesFilename = "notices"
  57. OldNoticesFilename = "notices.1"
  58. UpgradeDownloadFilename = "upgrade"
  59. )
  60. // Config is the Psiphon configuration specified by the application. This
  61. // configuration controls the behavior of the core tunnel functionality.
  62. //
  63. // To distinguish omitted timeout params from explicit 0 value timeout params,
  64. // corresponding fields are int pointers. nil means no value was supplied and
  65. // to use the default; a non-nil pointer to 0 means no timeout.
  66. type Config struct {
  67. // DataRootDirectory is the directory in which to store persistent files,
  68. // which contain information such as server entries. By default, current
  69. // working directory.
  70. //
  71. // Psiphon will assume full control of files under this directory. They may
  72. // be deleted, moved or overwritten.
  73. DataRootDirectory string
  74. // UseNoticeFiles configures notice files for writing. If set, homepages
  75. // will be written to a file created at config.GetHomePageFilename()
  76. // and notices will be written to a file created at
  77. // config.GetNoticesFilename().
  78. //
  79. // The homepage file may be read after the Tunnels notice with count of 1.
  80. //
  81. // The value of UseNoticeFiles sets the size and frequency at which the
  82. // notices file, config.GetNoticesFilename(), will be rotated. See the
  83. // comment for UseNoticeFiles for more details. One rotated older file,
  84. // config.GetOldNoticesFilename(), is retained.
  85. //
  86. // The notice files may be may be read at any time; and should be opened
  87. // read-only for reading. Diagnostic notices are omitted from the notice
  88. // files.
  89. //
  90. // See comment for setNoticeFiles in notice.go for further details.
  91. UseNoticeFiles *UseNoticeFiles
  92. // PropagationChannelId is a string identifier which indicates how the
  93. // Psiphon client was distributed. This parameter is required. This value
  94. // is supplied by and depends on the Psiphon Network, and is typically
  95. // embedded in the client binary.
  96. PropagationChannelId string
  97. // SponsorId is a string identifier which indicates who is sponsoring this
  98. // Psiphon client. One purpose of this value is to determine the home
  99. // pages for display. This parameter is required. This value is supplied
  100. // by and depends on the Psiphon Network, and is typically embedded in the
  101. // client binary.
  102. SponsorId string
  103. // ClientVersion is the client version number that the client reports to
  104. // the server. The version number refers to the host client application,
  105. // not the core tunnel library. One purpose of this value is to enable
  106. // automatic updates. This value is supplied by and depends on the Psiphon
  107. // Network, and is typically embedded in the client binary.
  108. //
  109. // Note that sending a ClientPlatform string which includes "windows"
  110. // (case insensitive) and a ClientVersion of <= 44 will cause an error in
  111. // processing the response to DoConnectedRequest calls.
  112. ClientVersion string
  113. // ClientPlatform is the client platform ("Windows", "Android", etc.) that
  114. // the client reports to the server.
  115. ClientPlatform string
  116. // ClientFeatures is a list of feature names denoting enabled application
  117. // features. Clients report enabled features to the server for stats
  118. // purposes.
  119. ClientFeatures []string
  120. // EgressRegion is a ISO 3166-1 alpha-2 country code which indicates which
  121. // country to egress from. For the default, "", the best performing server
  122. // in any country is selected.
  123. EgressRegion string
  124. // SplitTunnelOwnRegion enables split tunnel mode for the client's own
  125. // country. When enabled, TCP port forward destinations that resolve to
  126. // the same GeoIP country as the client are connected to directly,
  127. // untunneled.
  128. SplitTunnelOwnRegion bool
  129. // SplitTunnelRegions enables selected split tunnel mode in which the
  130. // client specifies a list of ISO 3166-1 alpha-2 country codes for which
  131. // traffic should be untunneled. TCP port forwards destined to any
  132. // country specified in SplitTunnelRegions will be untunneled, regardless
  133. // of whether SplitTunnelOwnRegion is on or off.
  134. SplitTunnelRegions []string
  135. // ListenInterface specifies which interface to listen on. If no
  136. // interface is provided then listen on 127.0.0.1. If 'any' is provided
  137. // then use 0.0.0.0. If there are multiple IP addresses on an interface
  138. // use the first IPv4 address.
  139. ListenInterface string
  140. // DisableLocalSocksProxy disables running the local SOCKS proxy.
  141. DisableLocalSocksProxy bool
  142. // LocalSocksProxyPort specifies a port number for the local SOCKS proxy
  143. // running at 127.0.0.1. For the default value, 0, the system selects a
  144. // free port (a notice reporting the selected port is emitted).
  145. LocalSocksProxyPort int
  146. // LocalHttpProxyPort specifies a port number for the local HTTP proxy
  147. // running at 127.0.0.1. For the default value, 0, the system selects a
  148. // free port (a notice reporting the selected port is emitted).
  149. LocalHttpProxyPort int
  150. // DisableLocalHTTPProxy disables running the local HTTP proxy.
  151. DisableLocalHTTPProxy bool
  152. // NetworkLatencyMultiplier is a multiplier that is to be applied to
  153. // default network event timeouts. Set this to tune performance for
  154. // slow networks.
  155. // When set, must be >= 1.0.
  156. NetworkLatencyMultiplier float64
  157. // LimitTunnelProtocols indicates which protocols to use. Valid values
  158. // include: "SSH", "OSSH", "TLS-OSSH", "UNFRONTED-MEEK-OSSH",
  159. // "UNFRONTED-MEEK-HTTPS-OSSH", "UNFRONTED-MEEK-SESSION-TICKET-OSSH",
  160. // "FRONTED-MEEK-OSSH", "FRONTED-MEEK-HTTP-OSSH", "QUIC-OSSH",
  161. // "FRONTED-MEEK-QUIC-OSSH", "TAPDANCE-OSSH", "CONJURE-OSSH", and
  162. // "SHADOWSOCKS-OSSH".
  163. // For the default, an empty list, all protocols are used.
  164. LimitTunnelProtocols []string
  165. // InitialLimitTunnelProtocols is an optional initial phase of limited
  166. // protocols for the first InitialLimitTunnelProtocolsCandidateCount
  167. // candidates; after these candidates, LimitTunnelProtocols applies.
  168. //
  169. // For the default, an empty list, InitialLimitTunnelProtocols is off.
  170. InitialLimitTunnelProtocols []string
  171. // InitialLimitTunnelProtocolsCandidateCount is the number of candidates
  172. // to which InitialLimitTunnelProtocols is applied instead of
  173. // LimitTunnelProtocols.
  174. //
  175. // For the default, 0, InitialLimitTunnelProtocols is off.
  176. InitialLimitTunnelProtocolsCandidateCount int
  177. // LimitTLSProfiles indicates which TLS profiles to select from. Valid
  178. // values are listed in protocols.SupportedTLSProfiles.
  179. // For the default, an empty list, all profiles are candidates for
  180. // selection.
  181. LimitTLSProfiles []string
  182. // LimitQUICVersions indicates which QUIC versions to select from. Valid
  183. // values are listed in protocols.SupportedQUICVersions.
  184. // For the default, an empty list, all versions are candidates for
  185. // selection.
  186. LimitQUICVersions []string
  187. // EstablishTunnelTimeoutSeconds specifies a time limit after which to
  188. // halt the core tunnel controller if no tunnel has been established. The
  189. // default is parameters.EstablishTunnelTimeout.
  190. EstablishTunnelTimeoutSeconds *int
  191. // EstablishTunnelPausePeriodSeconds specifies the delay between attempts
  192. // to establish tunnels. Briefly pausing allows for network conditions to
  193. // improve and for asynchronous operations such as fetch remote server
  194. // list to complete. If omitted, a default value is used. This value is
  195. // typical overridden for testing.
  196. EstablishTunnelPausePeriodSeconds *int
  197. // EstablishTunnelPausePeriodSeconds specifies the grace period, or head
  198. // start, provided to the affinity server candidate when establishing. The
  199. // affinity server is the server used for the last established tunnel.
  200. EstablishTunnelServerAffinityGracePeriodMilliseconds *int
  201. // ConnectionWorkerPoolSize specifies how many connection attempts to
  202. // attempt in parallel. If omitted or when 0, a default is used; this is
  203. // recommended.
  204. ConnectionWorkerPoolSize int
  205. // TunnelPoolSize specifies how many tunnels to run in parallel. Port
  206. // forwards are multiplexed over multiple tunnels. If omitted or when 0,
  207. // the default is TUNNEL_POOL_SIZE, which is recommended. Any value over
  208. // MAX_TUNNEL_POOL_SIZE is treated as MAX_TUNNEL_POOL_SIZE.
  209. TunnelPoolSize int
  210. // StaggerConnectionWorkersMilliseconds adds a specified delay before
  211. // making each server candidate available to connection workers. This
  212. // option is enabled when StaggerConnectionWorkersMilliseconds > 0.
  213. StaggerConnectionWorkersMilliseconds int
  214. // LimitIntensiveConnectionWorkers limits the number of concurrent
  215. // connection workers attempting connections with resource intensive
  216. // protocols. This option is enabled when LimitIntensiveConnectionWorkers
  217. // > 0.
  218. LimitIntensiveConnectionWorkers int
  219. // LimitMeekBufferSizes selects smaller buffers for meek protocols.
  220. LimitMeekBufferSizes bool
  221. // LimitCPUThreads minimizes the number of CPU threads -- and associated
  222. // overhead -- the are used.
  223. LimitCPUThreads bool
  224. // LimitRelayBufferSizes selects smaller buffers for port forward relaying.
  225. LimitRelayBufferSizes bool
  226. // IgnoreHandshakeStatsRegexps skips compiling and using stats regexes.
  227. IgnoreHandshakeStatsRegexps bool
  228. // UpstreamProxyURL is a URL specifying an upstream proxy to use for all
  229. // outbound connections. The URL should include proxy type and
  230. // authentication information, as required. See example URLs here:
  231. // https://github.com/Psiphon-Labs/psiphon-tunnel-core/tree/master/psiphon/upstreamproxy
  232. UpstreamProxyURL string
  233. // CustomHeaders is a set of additional arbitrary HTTP headers that are
  234. // added to all plaintext HTTP requests and requests made through an HTTP
  235. // upstream proxy when specified by UpstreamProxyURL.
  236. CustomHeaders http.Header
  237. // MeekAdditionalHeaders is a set of additional arbitrary HTTP headers
  238. // that are added to all meek HTTP requests. An additional header is
  239. // ignored when the header name is already present in a meek request.
  240. MeekAdditionalHeaders http.Header
  241. // NetworkConnectivityChecker is an interface that enables tunnel-core to
  242. // call into the host application to check for network connectivity. See:
  243. // NetworkConnectivityChecker doc.
  244. NetworkConnectivityChecker NetworkConnectivityChecker
  245. // DeviceBinder is an interface that enables tunnel-core to call into the
  246. // host application to bind sockets to specific devices. See: DeviceBinder
  247. // doc.
  248. //
  249. // When DeviceBinder is set, the "VPN" feature name is automatically added
  250. // when reporting ClientFeatures.
  251. DeviceBinder DeviceBinder
  252. // AllowDefaultDNSResolverWithBindToDevice indicates that it's safe to use
  253. // the default resolver when DeviceBinder is configured, as the host OS
  254. // will automatically exclude DNS requests from the VPN.
  255. AllowDefaultDNSResolverWithBindToDevice bool
  256. // IPv6Synthesizer is an interface that allows tunnel-core to call into
  257. // the host application to synthesize IPv6 addresses. See: IPv6Synthesizer
  258. // doc.
  259. IPv6Synthesizer IPv6Synthesizer
  260. // HasIPv6RouteGetter is an interface that allows tunnel-core to call into
  261. // the host application to determine if the host has an IPv6 route. See:
  262. // HasIPv6RouteGetter doc.
  263. HasIPv6RouteGetter HasIPv6RouteGetter
  264. // DNSServerGetter is an interface that enables tunnel-core to call into
  265. // the host application to discover the native network DNS server
  266. // settings. See: DNSServerGetter doc.
  267. DNSServerGetter DNSServerGetter
  268. // NetworkIDGetter in an interface that enables tunnel-core to call into
  269. // the host application to get an identifier for the host's current active
  270. // network. See: NetworkIDGetter doc.
  271. NetworkIDGetter NetworkIDGetter
  272. // NetworkID, when not blank, is used as the identifier for the host's
  273. // current active network.
  274. // NetworkID is ignored when NetworkIDGetter is set, or when
  275. // common/networkid is enabled.
  276. NetworkID string
  277. // DisableTactics disables tactics operations including requests, payload
  278. // handling, and application of parameters.
  279. DisableTactics bool
  280. // DisableReplay causes any persisted dial parameters to be ignored when
  281. // they would otherwise be used for replay.
  282. DisableReplay bool
  283. // TargetServerEntry is an encoded server entry. When specified, this
  284. // server entry is used exclusively and all other known servers are
  285. // ignored; also, when set, ConnectionWorkerPoolSize is ignored and
  286. // the pool size is 1.
  287. TargetServerEntry string
  288. // DisableApi disables Psiphon server API calls including handshake,
  289. // connected, status, etc. This is used for special case temporary tunnels
  290. // (Windows VPN mode).
  291. DisableApi bool
  292. // TargetAPIProtocol specifies whether to force use of "ssh" or "web" API
  293. // protocol. When blank, the default, the optimal API protocol is used.
  294. // Note that this capability check is not applied before the
  295. // "CandidateServers" count is emitted.
  296. //
  297. // This parameter is intended for testing and debugging only. Not all
  298. // parameters are supported in the legacy "web" API protocol, including
  299. // speed test samples.
  300. TargetAPIProtocol string
  301. // TargetAPIProtocol specifies whether to use "json" or "cbor" API
  302. // protocol parameter encodings. When blank, the default is to use "cbor"
  303. // where supported.
  304. TargetAPIEncoding string
  305. // RemoteServerListURLs is list of URLs which specify locations to fetch
  306. // out-of-band server entries. This facility is used when a tunnel cannot
  307. // be established to known servers. This value is supplied by and depends
  308. // on the Psiphon Network, and is typically embedded in the client binary.
  309. // All URLs must point to the same entity with the same ETag. At least one
  310. // TransferURL must have OnlyAfterAttempts = 0.
  311. RemoteServerListURLs parameters.TransferURLs
  312. // RemoteServerListSignaturePublicKey specifies a public key that's used
  313. // to authenticate the remote server list payload. This value is supplied
  314. // by and depends on the Psiphon Network, and is typically embedded in the
  315. // client binary.
  316. RemoteServerListSignaturePublicKey string
  317. // DisableRemoteServerListFetcher disables fetching remote server lists.
  318. // This is used for special case temporary tunnels.
  319. DisableRemoteServerListFetcher bool
  320. // FetchRemoteServerListRetryPeriodMilliseconds specifies the delay before
  321. // resuming a remote server list download after a failure. If omitted, a
  322. // default value is used. This value is typical overridden for testing.
  323. FetchRemoteServerListRetryPeriodMilliseconds *int
  324. // ObfuscatedServerListRootURLs is a list of URLs which specify root
  325. // locations from which to fetch obfuscated server list files. This value
  326. // is supplied by and depends on the Psiphon Network, and is typically
  327. // embedded in the client binary. All URLs must point to the same entity
  328. // with the same ETag. At least one DownloadURL must have
  329. // OnlyAfterAttempts = 0.
  330. ObfuscatedServerListRootURLs parameters.TransferURLs
  331. // EnableUpgradeDownload indicates whether to check for and download
  332. // upgrades. When set, UpgradeDownloadURLs and
  333. // UpgradeDownloadClientVersionHeader must also be set. ClientPlatform
  334. // and ClientVersion should also be set.
  335. EnableUpgradeDownload bool
  336. // UpgradeDownloadURLs is list of URLs which specify locations from which
  337. // to download a host client upgrade file, when one is available. The core
  338. // tunnel controller provides a resumable download facility which
  339. // downloads this resource and emits a notice when complete. This value is
  340. // supplied by and depends on the Psiphon Network, and is typically
  341. // embedded in the client binary. All URLs must point to the same entity
  342. // with the same ETag. At least one DownloadURL must have
  343. // OnlyAfterAttempts = 0.
  344. UpgradeDownloadURLs parameters.TransferURLs
  345. // UpgradeDownloadClientVersionHeader specifies the HTTP header name for
  346. // the entity at UpgradeDownloadURLs which specifies the client version
  347. // (an integer value). A HEAD request may be made to check the version
  348. // number available at UpgradeDownloadURLs.
  349. // UpgradeDownloadClientVersionHeader is required when UpgradeDownloadURLs
  350. // is specified.
  351. UpgradeDownloadClientVersionHeader string
  352. // FetchUpgradeRetryPeriodMilliseconds specifies the delay before resuming
  353. // a client upgrade download after a failure. If omitted, a default value
  354. // is used. This value is typical overridden for testing.
  355. FetchUpgradeRetryPeriodMilliseconds *int
  356. // EnableFeedbackUpload indicates whether to enable uploading feedback
  357. // data. When set, FeedbackUploadURLs and FeedbackEncryptionPublicKey
  358. // must also be set.
  359. EnableFeedbackUpload bool
  360. // FeedbackUploadURLs is a list of SecureTransferURLs which specify
  361. // locations where feedback data can be uploaded, pairing with each
  362. // location a public key with which to encrypt the feedback data. This
  363. // value is supplied by and depends on the Psiphon Network, and is
  364. // typically embedded in the client binary. At least one TransferURL must
  365. // have OnlyAfterAttempts = 0.
  366. FeedbackUploadURLs parameters.TransferURLs
  367. // FeedbackEncryptionPublicKey is a default base64-encoded, RSA public key
  368. // value used to encrypt feedback data. Used when uploading feedback with a
  369. // TransferURL which has no public key value configured, i.e.
  370. // B64EncodedPublicKey = "".
  371. FeedbackEncryptionPublicKey string
  372. // TrustedCACertificatesFilename specifies a file containing trusted CA
  373. // certs. When set, this toggles use of the trusted CA certs, specified in
  374. // TrustedCACertificatesFilename, for tunneled TLS connections that expect
  375. // server certificates signed with public certificate authorities
  376. // (currently, only upgrade downloads). This option is used with stock Go
  377. // TLS in cases where Go may fail to obtain a list of root CAs from the
  378. // operating system.
  379. TrustedCACertificatesFilename string
  380. // DisableSystemRootCAs, when true, disables loading system root CAs when
  381. // verifying TLS certificates for all remote server list downloads, upgrade
  382. // downloads, and feedback uploads. Each of these transfers has additional
  383. // security at the payload level. Verifying TLS certificates is preferred,
  384. // as an additional security and circumvention layer; set
  385. // DisableSystemRootCAs only in cases where system root CAs cannot be
  386. // loaded; for example, if unsupported (iOS < 12) or insufficient memory
  387. // (VPN extension on iOS < 15).
  388. DisableSystemRootCAs bool
  389. // DisablePeriodicSshKeepAlive indicates whether to send an SSH keepalive
  390. // every 1-2 minutes, when the tunnel is idle. If the SSH keepalive times
  391. // out, the tunnel is considered to have failed.
  392. DisablePeriodicSshKeepAlive bool
  393. // DeviceLocation is the optional, reported location the host device is
  394. // running in. This input value should be a string representing location
  395. // geohash. The device location is reported to the server in the connected
  396. // request and recorded for Psiphon stats.
  397. DeviceLocation string
  398. // DeviceRegion is the optional, reported region the host device is
  399. // running in. This input value should be a ISO 3166-1 alpha-2 country
  400. // code. The device region is reported to the server in the connected
  401. // request and recorded for Psiphon stats.
  402. //
  403. // When provided, this value may be used, pre-connection, to select
  404. // performance or circumvention optimization strategies for the given
  405. // region.
  406. DeviceRegion string
  407. // EmitDiagnosticNotices indicates whether to output notices containing
  408. // detailed information about the Psiphon session. As these notices may
  409. // contain sensitive information, they should not be insecurely distributed
  410. // or displayed to users. Default is off.
  411. EmitDiagnosticNotices bool
  412. // EmitDiagnosticNetworkParameters indicates whether to include network
  413. // parameters in diagnostic notices. As these parameters are sensitive
  414. // circumvention network information, they should not be insecurely
  415. // distributed or displayed to users. Default is off.
  416. EmitDiagnosticNetworkParameters bool
  417. // EmitBytesTransferred indicates whether to emit frequent notices showing
  418. // bytes sent and received.
  419. EmitBytesTransferred bool
  420. // EmitSLOKs indicates whether to emit notices for each seeded SLOK. As
  421. // this could reveal user browsing activity, it's intended for debugging
  422. // and testing only.
  423. EmitSLOKs bool
  424. // EmitRefractionNetworkingLogs indicates whether to emit gotapdance log
  425. // messages to stdout. Note that gotapdance log messages do not conform to
  426. // the Notice format standard. Default is off.
  427. EmitRefractionNetworkingLogs bool
  428. // EmitServerAlerts indicates whether to emit notices for server alerts.
  429. EmitServerAlerts bool
  430. // EmitClientAddress indicates whether to emit the client's public network
  431. // address, IP and port, as seen by the server.
  432. EmitClientAddress bool
  433. // RateLimits specify throttling configuration for the tunnel.
  434. RateLimits common.RateLimits
  435. // PacketTunnelTunDeviceFileDescriptor specifies a tun device file
  436. // descriptor to use for running a packet tunnel. When this value is > 0,
  437. // a packet tunnel is established through the server and packets are
  438. // relayed via the tun device file descriptor. The file descriptor is
  439. // duped in NewController. When PacketTunnelTunDeviceFileDescriptor is
  440. // set, TunnelPoolSize must be 1.
  441. PacketTunnelTunFileDescriptor int
  442. // PacketTunnelTransparentDNSIPv4Address is the IPv4 address of the DNS
  443. // server configured by a VPN using a packet tunnel. All DNS packets
  444. // destined to this DNS server are transparently redirected to the
  445. // Psiphon server DNS.
  446. PacketTunnelTransparentDNSIPv4Address string
  447. // PacketTunnelTransparentDNSIPv6Address is the IPv6 address of the DNS
  448. // server configured by a VPN using a packet tunnel. All DNS packets
  449. // destined to this DNS server are transparently redirected to the
  450. // Psiphon server DNS.
  451. PacketTunnelTransparentDNSIPv6Address string
  452. // SessionID specifies a client session ID to use in the Psiphon API. The
  453. // session ID should be a randomly generated value that is used only for a
  454. // single session, which is defined as the period between a user starting
  455. // a Psiphon client and stopping the client.
  456. //
  457. // A session ID must be 32 hex digits (lower case). When blank, a random
  458. // session ID is automatically generated. Supply a session ID when a
  459. // single client session will cross multiple Controller instances.
  460. SessionID string
  461. // Authorizations is a list of encoded, signed access control
  462. // authorizations that the client has obtained and will present to the
  463. // server.
  464. Authorizations []string
  465. // ServerEntrySignaturePublicKey is a base64-encoded, ed25519 public
  466. // key value used to verify individual server entry signatures. This value
  467. // is supplied by and depends on the Psiphon Network, and is typically
  468. // embedded in the client binary.
  469. ServerEntrySignaturePublicKey string
  470. // ExchangeObfuscationKey is a base64-encoded, NaCl secretbox key used to
  471. // obfuscate server info exchanges between clients.
  472. // Required for the exchange functionality.
  473. ExchangeObfuscationKey string
  474. // MigrateHomepageNoticesFilename migrates a homepage file from the path
  475. // previously configured with setNoticeFiles to the new path for homepage
  476. // files under the data root directory. The file specified by this config
  477. // value will be moved to config.GetHomePageFilename().
  478. //
  479. // Note: see comment for config.Commit() for a description of how file
  480. // migrations are performed.
  481. //
  482. // If not set, no migration operation will be performed.
  483. MigrateHomepageNoticesFilename string
  484. // MigrateRotatingNoticesFilename migrates notice files from the path
  485. // previously configured with setNoticeFiles to the new path for notice
  486. // files under the data root directory.
  487. //
  488. // MigrateRotatingNoticesFilename will be moved to
  489. // config.GetNoticesFilename().
  490. //
  491. // MigrateRotatingNoticesFilename.1 will be moved to
  492. // config.GetOldNoticesFilename().
  493. //
  494. // Note: see comment for config.Commit() for a description of how file
  495. // migrations are performed.
  496. //
  497. // If not set, no migration operation will be performed.
  498. MigrateRotatingNoticesFilename string
  499. // MigrateDataStoreDirectory indicates the location of the datastore
  500. // directory, as previously configured with the deprecated
  501. // DataStoreDirectory config field. Datastore files found in the specified
  502. // directory will be moved under the data root directory.
  503. //
  504. // Note: see comment for config.Commit() for a description of how file
  505. // migrations are performed.
  506. MigrateDataStoreDirectory string
  507. // MigrateRemoteServerListDownloadFilename indicates the location of
  508. // remote server list download files. The remote server list files found at
  509. // the specified path will be moved under the data root directory.
  510. //
  511. // Note: see comment for config.Commit() for a description of how file
  512. // migrations are performed.
  513. MigrateRemoteServerListDownloadFilename string
  514. // MigrateObfuscatedServerListDownloadDirectory indicates the location of
  515. // the obfuscated server list downloads directory, as previously configured
  516. // with ObfuscatedServerListDownloadDirectory. Obfuscated server list
  517. // download files found in the specified directory will be moved under the
  518. // data root directory.
  519. //
  520. // Warning: if the directory is empty after obfuscated server
  521. // list files are moved, then it will be deleted.
  522. //
  523. // Note: see comment for config.Commit() for a description of how file
  524. // migrations are performed.
  525. MigrateObfuscatedServerListDownloadDirectory string
  526. // MigrateUpgradeDownloadFilename indicates the location of downloaded
  527. // application upgrade files. Downloaded upgrade files found at the
  528. // specified path will be moved under the data root directory.
  529. //
  530. // Note: see comment for config.Commit() for a description of how file
  531. // migrations are performed.
  532. MigrateUpgradeDownloadFilename string
  533. // DisableTunnels disables establishing a client tunnel. Set
  534. // DisableTunnels when running a stand-alone in-proxy proxy.
  535. DisableTunnels bool
  536. // InproxyEnableProxy enables running an in-proxy proxy.
  537. InproxyEnableProxy bool
  538. // InproxyProxySessionPrivateKey specifies a long-term in-proxy proxy
  539. // private key and corresponding, derived proxy ID to use. If blank, an
  540. // ephemeral key will be generated.
  541. InproxyProxySessionPrivateKey string
  542. // InproxyMaxClients specifies the maximum number of in-proxy clients to
  543. // be proxied concurrently. Must be > 0 when InproxyEnableProxy is set.
  544. InproxyMaxClients int
  545. // InproxyLimitUpstreamBytesPerSecond specifies the upstream byte transfer
  546. // rate limit for each proxied client. When 0, there is no limit.
  547. InproxyLimitUpstreamBytesPerSecond int
  548. // InproxyLimitDownstreamBytesPerSecond specifies the downstream byte
  549. // transfer rate limit for each proxied client. When 0, there is no limit.
  550. InproxyLimitDownstreamBytesPerSecond int
  551. // InproxyProxyPersonalCompartmentID specifies the personal compartment
  552. // ID used by an in-proxy proxy. Personal compartment IDs are
  553. // distributed from proxy operators to client users out-of-band and
  554. // provide a mechanism to allow only certain clients to use a proxy.
  555. InproxyProxyPersonalCompartmentID string
  556. // InproxyClientPersonalCompartmentID specifies the personal compartment
  557. // ID used by an in-proxy client. Personal compartment IDs are
  558. // distributed from proxy operators to client users out-of-band and
  559. // provide a mechanism to ensure a client uses only a certain proxy for
  560. // all tunnels connections.
  561. //
  562. // When an InproxyClientPersonalCompartmentID is set, the client will use
  563. // only in-proxy protocols, ensuring that all connections go through the
  564. // proxy or proxies with the same personal compartment ID.
  565. InproxyClientPersonalCompartmentID string
  566. // InproxyPersonalPairingConnectionWorkerPoolSize specifies the value for
  567. // ConnectionWorkerPoolSize in personal pairing mode. If omitted or when
  568. // 0, a default is used; this is recommended.
  569. InproxyPersonalPairingConnectionWorkerPoolSize int
  570. // EmitInproxyProxyActivity indicates whether to emit frequent notices
  571. // showing proxy connection information and bytes transferred.
  572. EmitInproxyProxyActivity bool
  573. //
  574. // The following parameters are deprecated.
  575. //
  576. // DataStoreDirectory is the directory in which to store the persistent
  577. // database, which contains information such as server entries. By
  578. // default, current working directory.
  579. //
  580. // Deprecated:
  581. // Use MigrateDataStoreDirectory. When MigrateDataStoreDirectory
  582. // is set, this parameter is ignored.
  583. //
  584. // DataStoreDirectory has been subsumed by the new data root directory,
  585. // which is configured with DataRootDirectory. If set, datastore files
  586. // found in the specified directory will be moved under the data root
  587. // directory.
  588. DataStoreDirectory string
  589. // RemoteServerListDownloadFilename specifies a target filename for
  590. // storing the remote server list download. Data is stored in co-located
  591. // files (RemoteServerListDownloadFilename.part*) to allow for resumable
  592. // downloading.
  593. //
  594. // Deprecated:
  595. // Use MigrateRemoteServerListDownloadFilename. When
  596. // MigrateRemoteServerListDownloadFilename is set, this parameter is
  597. // ignored.
  598. //
  599. // If set, remote server list download files found at the specified path
  600. // will be moved under the data root directory.
  601. RemoteServerListDownloadFilename string
  602. // ObfuscatedServerListDownloadDirectory specifies a target directory for
  603. // storing the obfuscated remote server list downloads. Data is stored in
  604. // co-located files (<OSL filename>.part*) to allow for resumable
  605. // downloading.
  606. //
  607. // Deprecated:
  608. // Use MigrateObfuscatedServerListDownloadDirectory. When
  609. // MigrateObfuscatedServerListDownloadDirectory is set, this parameter is
  610. // ignored.
  611. //
  612. // If set, obfuscated server list download files found at the specified path
  613. // will be moved under the data root directory.
  614. ObfuscatedServerListDownloadDirectory string
  615. // UpgradeDownloadFilename is the local target filename for an upgrade
  616. // download. This parameter is required when UpgradeDownloadURLs (or
  617. // UpgradeDownloadUrl) is specified. Data is stored in co-located files
  618. // (UpgradeDownloadFilename.part*) to allow for resumable downloading.
  619. //
  620. // Deprecated:
  621. // Use MigrateUpgradeDownloadFilename. When MigrateUpgradeDownloadFilename
  622. // is set, this parameter is ignored.
  623. //
  624. // If set, upgrade download files found at the specified path will be moved
  625. // under the data root directory.
  626. UpgradeDownloadFilename string
  627. // TunnelProtocol indicates which protocol to use. For the default, "",
  628. // all protocols are used.
  629. //
  630. // Deprecated: Use LimitTunnelProtocols. When LimitTunnelProtocols is not
  631. // nil, this parameter is ignored.
  632. TunnelProtocol string
  633. // Deprecated: Use CustomHeaders. When CustomHeaders is not nil, this
  634. // parameter is ignored.
  635. UpstreamProxyCustomHeaders http.Header
  636. // RemoteServerListUrl is a URL which specifies a location to fetch out-
  637. // of-band server entries. This facility is used when a tunnel cannot be
  638. // established to known servers. This value is supplied by and depends on
  639. // the Psiphon Network, and is typically embedded in the client binary.
  640. //
  641. // Deprecated: Use RemoteServerListURLs. When RemoteServerListURLs is not
  642. // nil, this parameter is ignored.
  643. RemoteServerListUrl string
  644. // ObfuscatedServerListRootURL is a URL which specifies the root location
  645. // from which to fetch obfuscated server list files. This value is
  646. // supplied by and depends on the Psiphon Network, and is typically
  647. // embedded in the client binary.
  648. //
  649. // Deprecated: Use ObfuscatedServerListRootURLs. When
  650. // ObfuscatedServerListRootURLs is not nil, this parameter is ignored.
  651. ObfuscatedServerListRootURL string
  652. // UpgradeDownloadUrl specifies a URL from which to download a host client
  653. // upgrade file, when one is available. The core tunnel controller
  654. // provides a resumable download facility which downloads this resource
  655. // and emits a notice when complete. This value is supplied by and depends
  656. // on the Psiphon Network, and is typically embedded in the client binary.
  657. //
  658. // Deprecated: Use UpgradeDownloadURLs. When UpgradeDownloadURLs is not
  659. // nil, this parameter is ignored.
  660. UpgradeDownloadUrl string
  661. //
  662. // The following parameters are for testing purposes.
  663. //
  664. // TransformHostNameProbability is for testing purposes.
  665. TransformHostNameProbability *float64
  666. // FragmentorProbability and associated Fragmentor fields are for testing
  667. // purposes.
  668. FragmentorProbability *float64
  669. FragmentorLimitProtocols []string
  670. FragmentorMinTotalBytes *int
  671. FragmentorMaxTotalBytes *int
  672. FragmentorMinWriteBytes *int
  673. FragmentorMaxWriteBytes *int
  674. FragmentorMinDelayMicroseconds *int
  675. FragmentorMaxDelayMicroseconds *int
  676. // MeekTrafficShapingProbability and associated fields are for testing
  677. // purposes.
  678. MeekTrafficShapingProbability *float64
  679. MeekTrafficShapingLimitProtocols []string
  680. MeekMinTLSPadding *int
  681. MeekMaxTLSPadding *int
  682. MeekMinLimitRequestPayloadLength *int
  683. MeekMaxLimitRequestPayloadLength *int
  684. MeekRedialTLSProbability *float64
  685. MeekAlternateCookieNameProbability *float64
  686. MeekAlternateContentTypeProbability *float64
  687. // ObfuscatedSSHAlgorithms and associated ObfuscatedSSH fields are for
  688. // testing purposes. If specified, ObfuscatedSSHAlgorithms must have 4 SSH
  689. // KEX elements in order: the kex algorithm, cipher, MAC, and server host
  690. // key algorithm.
  691. ObfuscatedSSHAlgorithms []string
  692. ObfuscatedSSHMinPadding *int
  693. ObfuscatedSSHMaxPadding *int
  694. // LivenessTestMinUpstreamBytes and other LivenessTest fields are for
  695. // testing purposes.
  696. LivenessTestMinUpstreamBytes *int
  697. LivenessTestMaxUpstreamBytes *int
  698. LivenessTestMinDownstreamBytes *int
  699. LivenessTestMaxDownstreamBytes *int
  700. // ReplayCandidateCount and other Replay fields are for testing purposes.
  701. ReplayCandidateCount *int
  702. ReplayDialParametersTTLSeconds *int
  703. ReplayTargetUpstreamBytes *int
  704. ReplayTargetDownstreamBytes *int
  705. ReplayTargetTunnelDurationSeconds *int
  706. ReplayLaterRoundMoveToFrontProbability *float64
  707. ReplayRetainFailedProbability *float64
  708. ReplayIgnoreChangedConfigState *bool
  709. // NetworkLatencyMultiplierMin and other NetworkLatencyMultiplier fields are
  710. // for testing purposes.
  711. NetworkLatencyMultiplierMin float64
  712. NetworkLatencyMultiplierMax float64
  713. NetworkLatencyMultiplierLambda float64
  714. // UseOnlyCustomTLSProfiles and other TLS configuration fields are for
  715. // testing purposes.
  716. UseOnlyCustomTLSProfiles *bool
  717. CustomTLSProfiles protocol.CustomTLSProfiles
  718. SelectRandomizedTLSProfileProbability *float64
  719. NoDefaultTLSSessionIDProbability *float64
  720. DisableFrontingProviderTLSProfiles protocol.LabeledTLSProfiles
  721. // ClientBurstUpstreamTargetBytes and other burst metric fields are for
  722. // testing purposes.
  723. ClientBurstUpstreamTargetBytes *int
  724. ClientBurstUpstreamDeadlineMilliseconds *int
  725. ClientBurstDownstreamTargetBytes *int
  726. ClientBurstDownstreamDeadlineMilliseconds *int
  727. // ApplicationParameters is for testing purposes.
  728. ApplicationParameters parameters.KeyValues
  729. // CustomHostNameRegexes and other custom host name fields are for testing
  730. // purposes.
  731. CustomHostNameRegexes []string
  732. CustomHostNameProbability *float64
  733. CustomHostNameLimitProtocols []string
  734. // ConjureCachedRegistrationTTLSeconds and other Conjure fields are for
  735. // testing purposes.
  736. ConjureCachedRegistrationTTLSeconds *int
  737. ConjureAPIRegistrarBidirectionalURL string
  738. ConjureAPIRegistrarFrontingSpecs parameters.FrontingSpecs
  739. ConjureAPIRegistrarMinDelayMilliseconds *int
  740. ConjureAPIRegistrarMaxDelayMilliseconds *int
  741. ConjureDecoyRegistrarProbability *float64
  742. ConjureDecoyRegistrarWidth *int
  743. ConjureDecoyRegistrarMinDelayMilliseconds *int
  744. ConjureDecoyRegistrarMaxDelayMilliseconds *int
  745. ConjureEnableIPv6Dials *bool
  746. ConjureEnablePortRandomization *bool
  747. ConjureEnableRegistrationOverrides *bool
  748. ConjureLimitTransports protocol.ConjureTransports
  749. ConjureSTUNServerAddresses []string
  750. ConjureDTLSEmptyInitialPacketProbability *float64
  751. // HoldOffTunnelProtocolMinDurationMilliseconds and other
  752. // HoldOffTunnelProtocol fields are for testing purposes.
  753. HoldOffTunnelProtocolMinDurationMilliseconds *int
  754. HoldOffTunnelProtocolMaxDurationMilliseconds *int
  755. HoldOffTunnelProtocolNames []string
  756. HoldOffTunnelProtocolProbability *float64
  757. // HoldOffFrontingTunnelMinDurationMilliseconds and other
  758. // HoldOffFrontingTunnel fields are for testing purposes.
  759. HoldOffFrontingTunnelMinDurationMilliseconds *int
  760. HoldOffFrontingTunnelMaxDurationMilliseconds *int
  761. HoldOffFrontingTunnelProviderIDs []string
  762. HoldOffFrontingTunnelProbability *float64
  763. // RestrictFrontingProviderIDs and other RestrictFrontingProviderIDs fields
  764. // are for testing purposes.
  765. RestrictFrontingProviderIDs []string
  766. RestrictFrontingProviderIDsClientProbability *float64
  767. // HoldOffDirectTunnelMinDurationMilliseconds and other HoldOffDirect
  768. // fields are for testing purposes.
  769. HoldOffDirectTunnelMinDurationMilliseconds *int
  770. HoldOffDirectTunnelMaxDurationMilliseconds *int
  771. HoldOffDirectTunnelProviderRegions map[string][]string
  772. HoldOffDirectTunnelProbability *float64
  773. // RestrictDirectProviderRegions and other RestrictDirect fields are for
  774. // testing purposes.
  775. RestrictDirectProviderRegions map[string][]string
  776. RestrictDirectProviderIDsClientProbability *float64
  777. // HoldOffInproxyTunnelMinDurationMilliseconds and other HoldOffInproxy
  778. // fields are for testing purposes.
  779. HoldOffInproxyTunnelMinDurationMilliseconds *int
  780. HoldOffInproxyTunnelMaxDurationMilliseconds *int
  781. HoldOffInproxyTunnelProviderRegions map[string][]string
  782. HoldOffInproxyTunnelProbability *float64
  783. // RestrictInproxyProviderRegions and other RestrictInproxy fields are for
  784. // testing purposes.
  785. RestrictInproxyProviderRegions map[string][]string
  786. RestrictInproxyProviderIDsClientProbability *float64
  787. // UpstreamProxyAllowAllServerEntrySources is for testing purposes.
  788. UpstreamProxyAllowAllServerEntrySources *bool
  789. // LimitTunnelDialPortNumbers is for testing purposes.
  790. LimitTunnelDialPortNumbers parameters.TunnelProtocolPortLists
  791. // QUICDialEarlyProbability is for testing purposes.
  792. QUICDialEarlyProbability *float64
  793. // QUICObfuscatedPSKProbability is for testing purposes.
  794. QUICObfuscatedPSKProbability *float64
  795. // QUICDisablePathMTUDiscoveryProbability is for testing purposes.
  796. QUICDisablePathMTUDiscoveryProbability *float64
  797. // DNSResolverAttemptsPerServer and other DNSResolver fields are for
  798. // testing purposes.
  799. DNSResolverAttemptsPerServer *int
  800. DNSResolverAttemptsPerPreferredServer *int
  801. DNSResolverRequestTimeoutMilliseconds *int
  802. DNSResolverAwaitTimeoutMilliseconds *int
  803. DNSResolverPreresolvedIPAddressCIDRs parameters.LabeledCIDRs
  804. DNSResolverPreresolvedIPAddressProbability *float64
  805. DNSResolverAlternateServers []string
  806. DNSResolverPreferredAlternateServers []string
  807. DNSResolverPreferAlternateServerProbability *float64
  808. DNSResolverProtocolTransformSpecs transforms.Specs
  809. DNSResolverProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  810. DNSResolverProtocolTransformProbability *float64
  811. DNSResolverQNameRandomizeCasingProbability *float64
  812. DNSResolverQNameMustMatchProbability *float64
  813. DNSResolverIncludeEDNS0Probability *float64
  814. DNSResolverCacheExtensionInitialTTLMilliseconds *int
  815. DNSResolverCacheExtensionVerifiedTTLMilliseconds *int
  816. DirectHTTPProtocolTransformSpecs transforms.Specs
  817. DirectHTTPProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  818. DirectHTTPProtocolTransformProbability *float64
  819. FrontedHTTPProtocolTransformSpecs transforms.Specs
  820. FrontedHTTPProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  821. FrontedHTTPProtocolTransformProbability *float64
  822. OSSHObfuscatorSeedTransformSpecs transforms.Specs
  823. OSSHObfuscatorSeedTransformScopedSpecNames transforms.ScopedSpecNames
  824. OSSHObfuscatorSeedTransformProbability *float64
  825. ObfuscatedQUICNonceTransformSpecs transforms.Specs
  826. ObfuscatedQUICNonceTransformScopedSpecNames transforms.ScopedSpecNames
  827. ObfuscatedQUICNonceTransformProbability *float64
  828. // OSSHPrefix parameters are for testing purposes only.
  829. OSSHPrefixSpecs transforms.Specs
  830. OSSHPrefixScopedSpecNames transforms.ScopedSpecNames
  831. OSSHPrefixProbability *float64
  832. OSSHPrefixSplitMinDelayMilliseconds *int
  833. OSSHPrefixSplitMaxDelayMilliseconds *int
  834. OSSHPrefixEnableFragmentor *bool
  835. // ShadowsocksPrefix parameters are for testing purposes only.
  836. ShadowsocksPrefixSpecs transforms.Specs
  837. ShadowsocksPrefixScopedSpecNames transforms.ScopedSpecNames
  838. ShadowsocksPrefixProbability *float64
  839. // TLSTunnelTrafficShapingProbability and associated fields are for testing.
  840. TLSTunnelObfuscatedPSKProbability *float64
  841. TLSTunnelTrafficShapingProbability *float64
  842. TLSTunnelMinTLSPadding *int
  843. TLSTunnelMaxTLSPadding *int
  844. // TLSFragmentClientHello fields are for testing purposes only.
  845. TLSFragmentClientHelloProbability *float64
  846. TLSFragmentClientHelloLimitProtocols []string
  847. // AdditionalParameters is used for testing.
  848. AdditionalParameters string
  849. // SteeringIP fields are for testing purposes only.
  850. SteeringIPCacheTTLSeconds *int
  851. SteeringIPCacheMaxEntries *int
  852. SteeringIPProbability *float64
  853. // FrontedHTTPClientReplayDialParametersTTL and other FrontedHTTPClient
  854. // fields are for testing purposes only.
  855. FrontedHTTPClientReplayDialParametersTTLSeconds *int
  856. FrontedHTTPClientReplayUpdateFrequencySeconds *int
  857. FrontedHTTPClientReplayDialParametersProbability *float64
  858. FrontedHTTPClientReplayRetainFailedProbability *float64
  859. // The following in-proxy fields are for testing purposes only.
  860. InproxyAllowProxy *bool
  861. InproxyAllowClient *bool
  862. InproxyTunnelProtocolSelectionProbability *float64
  863. InproxyBrokerSpecs parameters.InproxyBrokerSpecsValue
  864. InproxyPersonalPairingBrokerSpecs parameters.InproxyBrokerSpecsValue
  865. InproxyProxyBrokerSpecs parameters.InproxyBrokerSpecsValue
  866. InproxyProxyPersonalPairingBrokerSpecs parameters.InproxyBrokerSpecsValue
  867. InproxyClientBrokerSpecs parameters.InproxyBrokerSpecsValue
  868. InproxyClientPersonalPairingBrokerSpecs parameters.InproxyBrokerSpecsValue
  869. InproxyReplayBrokerDialParametersTTLSeconds *int
  870. InproxyReplayBrokerUpdateFrequencySeconds *int
  871. InproxyReplayBrokerDialParametersProbability *float64
  872. InproxyReplayBrokerRetainFailedProbability *float64
  873. InproxyCommonCompartmentIDs parameters.InproxyCompartmentIDsValue
  874. InproxyMaxCompartmentIDListLength *int
  875. InproxyProxyAnnounceRequestTimeoutMilliseconds *int
  876. InproxyProxyAnnounceDelayMilliseconds *int
  877. InproxyProxyAnnounceMaxBackoffDelayMilliseconds *int
  878. InproxyProxyAnnounceDelayJitter *float64
  879. InproxyProxyAnswerRequestTimeoutMilliseconds *int
  880. InproxyClientOfferRequestTimeoutMilliseconds *int
  881. InproxyClientOfferRequestPersonalTimeoutMilliseconds *int
  882. InproxyClientOfferRetryDelayMilliseconds *int
  883. InproxyClientOfferRetryJitter *float64
  884. InproxyClientRelayedPacketRequestTimeoutMilliseconds *int
  885. InproxyDTLSRandomizationProbability *float64
  886. InproxyWebRTCMediaStreamsProbability *float64
  887. InproxyWebRTCDataChannelTrafficShapingProbability *float64
  888. InproxyWebRTCDataChannelTrafficShapingParameters *parameters.InproxyTrafficShapingParametersValue
  889. InproxyWebRTCMediaStreamsTrafficShapingProbability *float64
  890. InproxyWebRTCMediaStreamsTrafficShapingParameters *parameters.InproxyTrafficShapingParametersValue
  891. InproxySTUNServerAddresses []string
  892. InproxySTUNServerAddressesRFC5780 []string
  893. InproxyProxySTUNServerAddresses []string
  894. InproxyProxySTUNServerAddressesRFC5780 []string
  895. InproxyClientSTUNServerAddresses []string
  896. InproxyClientSTUNServerAddressesRFC5780 []string
  897. InproxyClientDiscoverNATProbability *float64
  898. InproxyDisableSTUN *bool
  899. InproxyDisablePortMapping *bool
  900. InproxyDisableInboundForMobileNetworks *bool
  901. InproxyDisableIPv6ICECandidates *bool
  902. InproxyProxyDisableSTUN *bool
  903. InproxyProxyDisablePortMapping *bool
  904. InproxyProxyDisableInboundForMobileNetworks *bool
  905. InproxyProxyDisableIPv6ICECandidates *bool
  906. InproxyClientDisableSTUN *bool
  907. InproxyClientDisablePortMapping *bool
  908. InproxyClientDisableInboundForMobileNetworks *bool
  909. InproxyClientDisableIPv6ICECandidates *bool
  910. InproxyProxyDiscoverNATTimeoutMilliseconds *int
  911. InproxyClientDiscoverNATTimeoutMilliseconds *int
  912. InproxyWebRTCAnswerTimeoutMilliseconds *int
  913. InproxyProxyWebRTCAwaitReadyToProxyTimeoutMilliseconds *int
  914. InproxyClientWebRTCAwaitReadyToProxyTimeoutMilliseconds *int
  915. InproxyProxyDestinationDialTimeoutMilliseconds *int
  916. InproxyPsiphonAPIRequestTimeoutMilliseconds *int
  917. InproxyProxyTotalActivityNoticePeriodMilliseconds *int
  918. InproxyClientDialRateLimitQuantity *int
  919. InproxyClientDialRateLimitIntervalMilliseconds *int
  920. InproxyClientNoMatchFailoverProbability *float64
  921. InproxyClientNoMatchFailoverPersonalProbability *float64
  922. InproxyFrontingProviderClientMaxRequestTimeouts map[string]string
  923. InproxyProxyOnBrokerClientFailedRetryPeriodMilliseconds *int
  924. InproxyProxyIncompatibleNetworkTypes []string
  925. InproxyClientIncompatibleNetworkTypes []string
  926. InproxySkipAwaitFullyConnected bool
  927. InproxyEnableWebRTCDebugLogging bool
  928. NetworkIDCacheTTLMilliseconds *int
  929. // params is the active parameters.Parameters with defaults, config values,
  930. // and, optionally, tactics applied.
  931. //
  932. // New tactics must be applied by calling Config.SetParameters; calling
  933. // params.Set directly will fail to add config values.
  934. paramsMutex sync.Mutex
  935. params *parameters.Parameters
  936. dialParametersHash []byte
  937. dynamicConfigMutex sync.Mutex
  938. sponsorID string
  939. authorizations []string
  940. deviceBinder DeviceBinder
  941. networkIDGetter *cachingNetworkIDGetter
  942. clientFeatures []string
  943. resolverMutex sync.Mutex
  944. resolver *resolver.Resolver
  945. committed bool
  946. loadTimestamp string
  947. tacticsAppliedReceiversMutex sync.Mutex
  948. tacticsAppliedReceivers []TacticsAppliedReceiver
  949. signalComponentFailure atomic.Value
  950. inproxyMustUpgradePosted int32
  951. }
  952. // TacticsAppliedReceiver specifies the interface for a component that is
  953. // signaled when tactics are applied. TacticsApplied is invoked when any
  954. // tactics are applied after initial start up, and then whenever new tactics
  955. // are received and applied while running.
  956. type TacticsAppliedReceiver interface {
  957. TacticsApplied() error
  958. }
  959. // Config field which specifies if notice files should be used and at which
  960. // frequency and size they should be rotated.
  961. //
  962. // If either RotatingFileSize or RotatingSyncFrequency are <= 0, default values
  963. // are used.
  964. //
  965. // See comment for setNoticeFiles in notice.go for further details.
  966. type UseNoticeFiles struct {
  967. RotatingFileSize int
  968. RotatingSyncFrequency int
  969. }
  970. // LoadConfig parses a JSON format Psiphon config JSON string and returns a
  971. // Config struct populated with config values.
  972. //
  973. // The Config struct may then be programmatically populated with additional
  974. // values, including callbacks such as DeviceBinder.
  975. //
  976. // Before using the Config, Commit must be called, which will perform further
  977. // validation and initialize internal data structures.
  978. func LoadConfig(configJson []byte) (*Config, error) {
  979. var config Config
  980. err := json.Unmarshal(configJson, &config)
  981. if err != nil {
  982. return nil, errors.Trace(err)
  983. }
  984. config.loadTimestamp = common.TruncateTimestampToHour(
  985. common.GetCurrentTimestamp())
  986. config.signalComponentFailure.Store(func() {})
  987. return &config, nil
  988. }
  989. // IsCommitted checks if Commit was called.
  990. func (config *Config) IsCommitted() bool {
  991. return config.committed
  992. }
  993. // Commit validates Config fields finalizes initialization.
  994. //
  995. // Config fields should not be set after calling Config, as any changes may
  996. // not be reflected in internal data structures.
  997. //
  998. // If migrateFromLegacyFields is set to true, then an attempt to migrate from
  999. // legacy fields is made.
  1000. //
  1001. // Migration from legacy fields:
  1002. // Config fields of the naming Migrate* (e.g. MigrateDataStoreDirectory) specify
  1003. // a file migration operation which should be performed. These fields correspond
  1004. // to deprecated fields, which previously could be used to specify where Psiphon
  1005. // stored different sets of persistent files (e.g. MigrateDataStoreDirectory
  1006. // corresponds to the deprecated field DataStoreDirectory).
  1007. //
  1008. // Psiphon now stores all persistent data under the configurable
  1009. // DataRootDirectory (see Config.DataRootDirectory). The deprecated fields, and
  1010. // corresponding Migrate* fields, are now used to specify the file or directory
  1011. // path where, or under which, persistent files and directories created by
  1012. // previous versions of Psiphon exist, so they can be moved under the
  1013. // DataRootDirectory.
  1014. //
  1015. // For each migration operation:
  1016. // - In the case of directories that could have defaulted to the current working
  1017. // directory, persistent files and directories created by Psiphon are
  1018. // precisely targeted to avoid moving files which were not created by Psiphon.
  1019. // - If no file is found at the specified path, or an error is encountered while
  1020. // migrating the file, then an error is logged and execution continues
  1021. // normally.
  1022. //
  1023. // A sentinel file which signals that file migration has been completed, and
  1024. // should not be attempted again, is created under DataRootDirectory after one
  1025. // full pass through Commit(), regardless of whether file migration succeeds or
  1026. // fails. It is better to not endlessly retry file migrations on each Commit()
  1027. // because file system errors are expected to be rare and persistent files will
  1028. // be re-populated over time.
  1029. func (config *Config) Commit(migrateFromLegacyFields bool) error {
  1030. // Apply any additional parameters first
  1031. additionalParametersInfoMsgs, err := config.applyAdditionalParameters()
  1032. if err != nil {
  1033. return errors.TraceMsg(err, "failed to apply additional parameters")
  1034. }
  1035. // Do SetEmitDiagnosticNotices first, to ensure config file errors are
  1036. // emitted.
  1037. if config.EmitDiagnosticNotices {
  1038. SetEmitDiagnosticNotices(
  1039. true, config.EmitDiagnosticNetworkParameters)
  1040. }
  1041. // Migrate and set notice files before any operations that may emit an
  1042. // error. This is to ensure config file errors are written to file when
  1043. // notice files are configured with config.UseNoticeFiles.
  1044. //
  1045. // Note:
  1046. // Errors encountered while configuring the data directory cannot be written
  1047. // to notice files. This is because notices files are created within the
  1048. // data directory.
  1049. if config.DataRootDirectory == "" {
  1050. wd, err := os.Getwd()
  1051. if err != nil {
  1052. return errors.Trace(common.RedactFilePathsError(err))
  1053. }
  1054. config.DataRootDirectory = wd
  1055. }
  1056. // Create root directory
  1057. dataDirectoryPath := config.GetPsiphonDataDirectory()
  1058. if !common.FileExists(dataDirectoryPath) {
  1059. err := os.Mkdir(dataDirectoryPath, os.ModePerm)
  1060. if err != nil {
  1061. return errors.Tracef(
  1062. "failed to create datastore directory with error: %s",
  1063. common.RedactFilePathsError(err, dataDirectoryPath))
  1064. }
  1065. }
  1066. // Check if the migration from legacy config fields has already been
  1067. // completed. See the Migrate* config fields for more details.
  1068. migrationCompleteFilePath := filepath.Join(config.GetPsiphonDataDirectory(), "migration_complete")
  1069. needMigration := !common.FileExists(migrationCompleteFilePath)
  1070. // Collect notices to emit them after notice files are set
  1071. var noticeMigrationAlertMsgs []string
  1072. var noticeMigrationInfoMsgs []string
  1073. // Migrate notices first to ensure notice files are used for notices if
  1074. // UseNoticeFiles is set.
  1075. homepageFilePath := config.GetHomePageFilename()
  1076. noticesFilePath := config.GetNoticesFilename()
  1077. if migrateFromLegacyFields {
  1078. if needMigration {
  1079. // Move notice files that exist at legacy file paths under the data root
  1080. // directory.
  1081. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, "Config migration: need migration")
  1082. noticeMigrations := migrationsFromLegacyNoticeFilePaths(config)
  1083. successfulMigrations := 0
  1084. for _, migration := range noticeMigrations {
  1085. err := DoFileMigration(migration)
  1086. if err != nil {
  1087. alertMsg := fmt.Sprintf("Config migration: %s", errors.Trace(err))
  1088. noticeMigrationAlertMsgs = append(noticeMigrationAlertMsgs, alertMsg)
  1089. } else {
  1090. successfulMigrations += 1
  1091. }
  1092. }
  1093. infoMsg := fmt.Sprintf("Config migration: %d/%d notice files successfully migrated", successfulMigrations, len(noticeMigrations))
  1094. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, infoMsg)
  1095. } else {
  1096. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, "Config migration: migration already completed")
  1097. }
  1098. }
  1099. if config.UseNoticeFiles != nil {
  1100. err := setNoticeFiles(
  1101. homepageFilePath,
  1102. noticesFilePath,
  1103. config.UseNoticeFiles.RotatingFileSize,
  1104. config.UseNoticeFiles.RotatingSyncFrequency)
  1105. if err != nil {
  1106. return errors.Trace(err)
  1107. }
  1108. }
  1109. // Emit notices now that notice files are set if configured
  1110. for _, msg := range additionalParametersInfoMsgs {
  1111. NoticeInfo(msg)
  1112. }
  1113. for _, msg := range noticeMigrationAlertMsgs {
  1114. NoticeWarning(msg)
  1115. }
  1116. for _, msg := range noticeMigrationInfoMsgs {
  1117. NoticeInfo(msg)
  1118. }
  1119. // Promote legacy fields.
  1120. if config.CustomHeaders == nil {
  1121. config.CustomHeaders = config.UpstreamProxyCustomHeaders
  1122. config.UpstreamProxyCustomHeaders = nil
  1123. }
  1124. if config.RemoteServerListUrl != "" && config.RemoteServerListURLs == nil {
  1125. config.RemoteServerListURLs = promoteLegacyTransferURL(config.RemoteServerListUrl)
  1126. }
  1127. if config.ObfuscatedServerListRootURL != "" && config.ObfuscatedServerListRootURLs == nil {
  1128. config.ObfuscatedServerListRootURLs = promoteLegacyTransferURL(config.ObfuscatedServerListRootURL)
  1129. }
  1130. if config.UpgradeDownloadUrl != "" && config.UpgradeDownloadURLs == nil {
  1131. config.UpgradeDownloadURLs = promoteLegacyTransferURL(config.UpgradeDownloadUrl)
  1132. }
  1133. if config.TunnelProtocol != "" && len(config.LimitTunnelProtocols) == 0 {
  1134. config.LimitTunnelProtocols = []string{config.TunnelProtocol}
  1135. }
  1136. if config.DataStoreDirectory != "" && config.MigrateDataStoreDirectory == "" {
  1137. config.MigrateDataStoreDirectory = config.DataStoreDirectory
  1138. }
  1139. if config.RemoteServerListDownloadFilename != "" && config.MigrateRemoteServerListDownloadFilename == "" {
  1140. config.MigrateRemoteServerListDownloadFilename = config.RemoteServerListDownloadFilename
  1141. }
  1142. if config.ObfuscatedServerListDownloadDirectory != "" && config.MigrateObfuscatedServerListDownloadDirectory == "" {
  1143. config.MigrateObfuscatedServerListDownloadDirectory = config.ObfuscatedServerListDownloadDirectory
  1144. }
  1145. if config.UpgradeDownloadFilename != "" && config.MigrateUpgradeDownloadFilename == "" {
  1146. config.MigrateUpgradeDownloadFilename = config.UpgradeDownloadFilename
  1147. }
  1148. // Supply default values.
  1149. // Create datastore directory.
  1150. dataStoreDirectoryPath := config.GetDataStoreDirectory()
  1151. if !common.FileExists(dataStoreDirectoryPath) {
  1152. err := os.Mkdir(dataStoreDirectoryPath, os.ModePerm)
  1153. if err != nil {
  1154. return errors.Tracef(
  1155. "failed to create datastore directory with error: %s",
  1156. common.RedactFilePathsError(err, dataStoreDirectoryPath))
  1157. }
  1158. }
  1159. // Create OSL directory.
  1160. oslDirectoryPath := config.GetObfuscatedServerListDownloadDirectory()
  1161. if !common.FileExists(oslDirectoryPath) {
  1162. err := os.Mkdir(oslDirectoryPath, os.ModePerm)
  1163. if err != nil {
  1164. return errors.Tracef(
  1165. "failed to create osl directory with error: %s",
  1166. common.RedactFilePathsError(err, oslDirectoryPath))
  1167. }
  1168. }
  1169. if config.ClientVersion == "" {
  1170. config.ClientVersion = "0"
  1171. }
  1172. if config.TunnelPoolSize == 0 {
  1173. config.TunnelPoolSize = TUNNEL_POOL_SIZE
  1174. }
  1175. // Validate config fields.
  1176. if !common.FileExists(config.DataRootDirectory) {
  1177. return errors.TraceNew("DataRootDirectory does not exist")
  1178. }
  1179. if config.PropagationChannelId == "" {
  1180. return errors.TraceNew("propagation channel ID is missing from the configuration file")
  1181. }
  1182. if config.SponsorId == "" {
  1183. return errors.TraceNew("sponsor ID is missing from the configuration file")
  1184. }
  1185. _, err = strconv.Atoi(config.ClientVersion)
  1186. if err != nil {
  1187. return errors.Tracef("invalid client version: %s", err)
  1188. }
  1189. if config.TargetAPIProtocol != "" &&
  1190. !protocol.PsiphonAPIProtocolIsValid(config.TargetAPIProtocol) {
  1191. return errors.TraceNew("invalid TargetAPIProtocol")
  1192. }
  1193. if config.TargetAPIEncoding != "" &&
  1194. !protocol.PsiphonAPIEncodingIsValid(config.TargetAPIEncoding) {
  1195. return errors.TraceNew("invalid TargetAPIEncoding")
  1196. }
  1197. if !config.DisableRemoteServerListFetcher {
  1198. if config.RemoteServerListURLs != nil {
  1199. if config.RemoteServerListSignaturePublicKey == "" {
  1200. return errors.TraceNew("missing RemoteServerListSignaturePublicKey")
  1201. }
  1202. }
  1203. if config.ObfuscatedServerListRootURLs != nil {
  1204. if config.RemoteServerListSignaturePublicKey == "" {
  1205. return errors.TraceNew("missing RemoteServerListSignaturePublicKey")
  1206. }
  1207. }
  1208. }
  1209. if config.EnableUpgradeDownload {
  1210. if len(config.UpgradeDownloadURLs) == 0 {
  1211. return errors.TraceNew("missing UpgradeDownloadURLs")
  1212. }
  1213. if config.UpgradeDownloadClientVersionHeader == "" {
  1214. return errors.TraceNew("missing UpgradeDownloadClientVersionHeader")
  1215. }
  1216. }
  1217. if config.EnableFeedbackUpload {
  1218. if len(config.FeedbackUploadURLs) == 0 {
  1219. return errors.TraceNew("missing FeedbackUploadURLs")
  1220. }
  1221. if config.FeedbackEncryptionPublicKey == "" {
  1222. return errors.TraceNew("missing FeedbackEncryptionPublicKey")
  1223. }
  1224. }
  1225. if config.ObfuscatedSSHAlgorithms != nil &&
  1226. len(config.ObfuscatedSSHAlgorithms) != 4 {
  1227. // TODO: validate each algorithm?
  1228. return errors.TraceNew("invalid ObfuscatedSSHAlgorithms")
  1229. }
  1230. if config.InproxyEnableProxy && config.InproxyMaxClients <= 0 {
  1231. return errors.TraceNew("invalid InproxyMaxClients")
  1232. }
  1233. if !config.DisableTunnels &&
  1234. config.InproxyEnableProxy &&
  1235. !GetAllowOverlappingPersonalCompartmentIDs() &&
  1236. len(config.InproxyProxyPersonalCompartmentID) > 0 &&
  1237. config.InproxyProxyPersonalCompartmentID ==
  1238. config.InproxyClientPersonalCompartmentID {
  1239. // Don't allow an in-proxy client and proxy run in the same app to match.
  1240. return errors.TraceNew("invalid overlapping personal compartment IDs")
  1241. }
  1242. if len(config.InproxyProxyPersonalCompartmentID) > 0 &&
  1243. !inproxy.Enabled() {
  1244. // When in-proxy personal pairing mode is on, fail if the build was
  1245. // made without the PSIPHON_ENABLE_INPROXY build tag.
  1246. //
  1247. // Note that this check could also be enforced in the case of a
  1248. // LimitTunnelProtocols.IsOnlyInproxyTunnelProtocols configuration,
  1249. // but that can be overridden by tactics so we allow it.
  1250. return errors.TraceNew("build does not enable required in-proxy functionality")
  1251. }
  1252. // This constraint is expected by logic in Controller.runTunnels().
  1253. if config.PacketTunnelTunFileDescriptor > 0 && config.TunnelPoolSize != 1 {
  1254. return errors.TraceNew("packet tunnel mode requires TunnelPoolSize to be 1")
  1255. }
  1256. // SessionID must be PSIPHON_API_CLIENT_SESSION_ID_LENGTH lowercase hex-encoded bytes.
  1257. if config.SessionID == "" {
  1258. sessionID, err := MakeSessionId()
  1259. if err != nil {
  1260. return errors.Trace(err)
  1261. }
  1262. config.SessionID = sessionID
  1263. }
  1264. if len(config.SessionID) != 2*protocol.PSIPHON_API_CLIENT_SESSION_ID_LENGTH ||
  1265. -1 != strings.IndexFunc(config.SessionID, func(c rune) bool {
  1266. return !unicode.Is(unicode.ASCII_Hex_Digit, c) || unicode.IsUpper(c)
  1267. }) {
  1268. return errors.TraceNew("invalid SessionID")
  1269. }
  1270. config.paramsMutex.Lock()
  1271. config.params, err = parameters.NewParameters(
  1272. func(err error) {
  1273. NoticeWarning("Parameters getValue failed: %s", err)
  1274. })
  1275. config.paramsMutex.Unlock()
  1276. if err != nil {
  1277. return errors.Trace(err)
  1278. }
  1279. // parametersParameters.Set will validate the config fields applied to
  1280. // parametersParameters.
  1281. err = config.SetParameters("", false, nil)
  1282. if err != nil {
  1283. return errors.Trace(err)
  1284. }
  1285. // Calculate and set the dial parameters hash. After this point, related
  1286. // config fields must not change.
  1287. config.setDialParametersHash()
  1288. // Set defaults for dynamic config fields.
  1289. config.SetDynamicConfig(config.SponsorId, config.Authorizations)
  1290. // Initialize config.deviceBinder and config.config.networkIDGetter. These
  1291. // wrap config.DeviceBinder and config.NetworkIDGetter/NetworkID with
  1292. // loggers.
  1293. //
  1294. // The network ID getter is further wrapped with a cache (see
  1295. // cachingNetworkIDGetter doc).
  1296. //
  1297. // New variables are set to avoid mutating input config fields.
  1298. // Internally, code must use config.deviceBinder and
  1299. // config.networkIDGetter and not the input/exported fields.
  1300. if config.DeviceBinder != nil {
  1301. config.deviceBinder = newLoggingDeviceBinder(config.DeviceBinder)
  1302. }
  1303. networkIDGetter := config.NetworkIDGetter
  1304. if networkIDGetter == nil {
  1305. if networkid.Enabled() {
  1306. networkIDGetter = newCommonNetworkIDGetter()
  1307. } else {
  1308. // Limitation: unlike NetworkIDGetter, which calls back to platform APIs
  1309. // this method of network identification is not dynamic and will not reflect
  1310. // network changes that occur while running.
  1311. if config.NetworkID != "" {
  1312. networkIDGetter = newStaticNetworkIDGetter(config.NetworkID)
  1313. } else {
  1314. networkIDGetter = newStaticNetworkIDGetter(unknownNetworkID)
  1315. }
  1316. }
  1317. }
  1318. config.networkIDGetter = newCachingNetworkIDGetter(
  1319. config,
  1320. newLoggingNetworkIDGetter(networkIDGetter))
  1321. // Initialize config.clientFeatures, which adds feature names on top of
  1322. // those specified by the host application in config.ClientFeatures.
  1323. config.clientFeatures = config.ClientFeatures
  1324. feature := "VPN"
  1325. if config.DeviceBinder != nil && !common.Contains(config.clientFeatures, feature) {
  1326. config.clientFeatures = append(config.clientFeatures, feature)
  1327. }
  1328. // Migrate from old config fields. This results in files being moved under
  1329. // a config specified data root directory.
  1330. if migrateFromLegacyFields && needMigration {
  1331. // If unset, set MigrateDataStoreDirectory to the previous default value for
  1332. // DataStoreDirectory to ensure that datastore files are migrated.
  1333. if config.MigrateDataStoreDirectory == "" {
  1334. wd, err := os.Getwd()
  1335. if err != nil {
  1336. return errors.Trace(err)
  1337. }
  1338. NoticeInfo("MigrateDataStoreDirectory unset, using working directory")
  1339. config.MigrateDataStoreDirectory = wd
  1340. }
  1341. // Move files that exist at legacy file paths under the data root
  1342. // directory.
  1343. migrations, err := migrationsFromLegacyFilePaths(config)
  1344. if err != nil {
  1345. return errors.Trace(err)
  1346. }
  1347. // Do migrations
  1348. successfulMigrations := 0
  1349. for _, migration := range migrations {
  1350. err := DoFileMigration(migration)
  1351. if err != nil {
  1352. NoticeWarning("Config migration: %s", errors.Trace(err))
  1353. } else {
  1354. successfulMigrations += 1
  1355. }
  1356. }
  1357. NoticeInfo(fmt.Sprintf(
  1358. "Config migration: %d/%d legacy files successfully migrated",
  1359. successfulMigrations, len(migrations)))
  1360. // Remove OSL directory if empty
  1361. if config.MigrateObfuscatedServerListDownloadDirectory != "" {
  1362. files, err := ioutil.ReadDir(config.MigrateObfuscatedServerListDownloadDirectory)
  1363. if err != nil {
  1364. NoticeWarning(
  1365. "Error reading OSL directory: %s",
  1366. errors.Trace(common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory)))
  1367. } else if len(files) == 0 {
  1368. err := os.Remove(config.MigrateObfuscatedServerListDownloadDirectory)
  1369. if err != nil {
  1370. NoticeWarning(
  1371. "Error deleting empty OSL directory: %s",
  1372. errors.Trace(common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory)))
  1373. }
  1374. }
  1375. }
  1376. f, err := os.Create(migrationCompleteFilePath)
  1377. if err != nil {
  1378. NoticeWarning(
  1379. "Config migration: failed to create migration completed file with error %s",
  1380. errors.Trace(common.RedactFilePathsError(err, migrationCompleteFilePath)))
  1381. } else {
  1382. NoticeInfo("Config migration: completed")
  1383. f.Close()
  1384. }
  1385. }
  1386. config.committed = true
  1387. return nil
  1388. }
  1389. // GetParameters returns the current parameters.Parameters.
  1390. func (config *Config) GetParameters() *parameters.Parameters {
  1391. config.paramsMutex.Lock()
  1392. defer config.paramsMutex.Unlock()
  1393. return config.params
  1394. }
  1395. // SetParameters resets the parameters.Parameters to the default values,
  1396. // applies any config file values, and then applies the input parameters (from
  1397. // tactics, etc.)
  1398. //
  1399. // Set skipOnError to false when initially applying only config values, as
  1400. // this will validate the values and should fail. Set skipOnError to true when
  1401. // applying tactics to ignore invalid or unknown parameter values from tactics.
  1402. //
  1403. // In the case of applying tactics, do not call Config.parameters.Set
  1404. // directly as this will not first apply config values.
  1405. //
  1406. // If there is an error, the existing Config.parameters are left
  1407. // entirely unmodified.
  1408. func (config *Config) SetParameters(tag string, skipOnError bool, applyParameters map[string]interface{}) error {
  1409. setParameters := []map[string]interface{}{config.makeConfigParameters()}
  1410. if applyParameters != nil {
  1411. setParameters = append(setParameters, applyParameters)
  1412. }
  1413. // Don't hold the lock on config.paramsMutex when signalling
  1414. // GetTacticsAppliedReceivers, or else GetParameters will deadlock.
  1415. // Releasing the lock early here also ensures we don't hold the lock when
  1416. // posting notices.
  1417. config.paramsMutex.Lock()
  1418. tagUnchanged := tag != "" && tag == config.params.Get().Tag()
  1419. validationFlags := 0
  1420. if skipOnError {
  1421. validationFlags |= parameters.ValidationSkipOnError
  1422. }
  1423. counts, err := config.params.Set(tag, validationFlags, setParameters...)
  1424. if err != nil {
  1425. config.paramsMutex.Unlock()
  1426. return errors.Trace(err)
  1427. }
  1428. p := config.params.Get()
  1429. config.paramsMutex.Unlock()
  1430. // Skip emitting notices and invoking GetTacticsAppliedReceivers when the
  1431. // tactics tag is unchanged. The notices are redundant, and the receivers
  1432. // will unnecessarily reset components such as in-proxy broker clients.
  1433. //
  1434. // At this time, the GetTactics call in launchEstablishing can result in
  1435. // redundant SetParameters calls with an unchanged tag.
  1436. //
  1437. // As a fail safe, and since there should not be any unwanted side
  1438. // effects, the above params.Set is still executed even for unchanged tags.
  1439. if tagUnchanged {
  1440. return nil
  1441. }
  1442. NoticeInfo("applied %v parameters with tag '%s'", counts, tag)
  1443. // Emit certain individual parameter values for quick reference in diagnostics.
  1444. NoticeInfo(
  1445. "NetworkLatencyMultiplier Min/Max/Lambda: %f/%f/%f",
  1446. p.Float(parameters.NetworkLatencyMultiplierMin),
  1447. p.Float(parameters.NetworkLatencyMultiplierMax),
  1448. p.Float(parameters.NetworkLatencyMultiplierLambda))
  1449. // Application Parameters are feature flags/config info, delivered as Client
  1450. // Parameters via tactics/etc., to be communicated to the outer application.
  1451. // Emit these now, as notices.
  1452. if p.WeightedCoinFlip(parameters.ApplicationParametersProbability) {
  1453. NoticeApplicationParameters(p.KeyValues(parameters.ApplicationParameters))
  1454. } else {
  1455. // The front end may persist Application Parameters, so clear any previously
  1456. // persisted values.
  1457. NoticeApplicationParameters(parameters.KeyValues{})
  1458. }
  1459. // Signal all registered TacticsAppliedReceivers that new tactics have
  1460. // been applied. Each receiver is responsible for checking if its
  1461. // individual tactics parameters have actually changed.
  1462. for _, receiver := range config.GetTacticsAppliedReceivers() {
  1463. err := receiver.TacticsApplied()
  1464. if err != nil {
  1465. NoticeError("TacticsApplied failed: %v", errors.Trace(err))
  1466. // Log and continue running.
  1467. }
  1468. }
  1469. return nil
  1470. }
  1471. // SetResolver sets the current resolver.
  1472. func (config *Config) SetResolver(resolver *resolver.Resolver) {
  1473. config.resolverMutex.Lock()
  1474. defer config.resolverMutex.Unlock()
  1475. config.resolver = resolver
  1476. }
  1477. // GetResolver returns the current resolver. May return nil.
  1478. func (config *Config) GetResolver() *resolver.Resolver {
  1479. config.resolverMutex.Lock()
  1480. defer config.resolverMutex.Unlock()
  1481. return config.resolver
  1482. }
  1483. // SetTacticsAppliedReceivers registers the list of TacticsAppliedReceivers.
  1484. func (config *Config) SetTacticsAppliedReceivers(receivers []TacticsAppliedReceiver) {
  1485. config.tacticsAppliedReceiversMutex.Lock()
  1486. defer config.tacticsAppliedReceiversMutex.Unlock()
  1487. config.tacticsAppliedReceivers = receivers
  1488. }
  1489. // GetTacticsAppliedReceivers gets the list of registered
  1490. // TacticsAppliedReceivers.
  1491. func (config *Config) GetTacticsAppliedReceivers() []TacticsAppliedReceiver {
  1492. config.tacticsAppliedReceiversMutex.Lock()
  1493. defer config.tacticsAppliedReceiversMutex.Unlock()
  1494. return config.tacticsAppliedReceivers
  1495. }
  1496. // SetDynamicConfig sets the current client sponsor ID and authorizations.
  1497. // Invalid values for sponsor ID are ignored. The caller must not modify the
  1498. // input authorizations slice.
  1499. func (config *Config) SetDynamicConfig(sponsorID string, authorizations []string) {
  1500. config.dynamicConfigMutex.Lock()
  1501. defer config.dynamicConfigMutex.Unlock()
  1502. if sponsorID != "" {
  1503. config.sponsorID = sponsorID
  1504. }
  1505. config.authorizations = authorizations
  1506. }
  1507. // GetSponsorID returns the current client sponsor ID.
  1508. func (config *Config) GetSponsorID() string {
  1509. config.dynamicConfigMutex.Lock()
  1510. defer config.dynamicConfigMutex.Unlock()
  1511. return config.sponsorID
  1512. }
  1513. // IsSplitTunnelEnabled indicates if split tunnel mode is enabled, either for
  1514. // the client's own country, a specified list of countries, or both.
  1515. func (config *Config) IsSplitTunnelEnabled() bool {
  1516. return config.SplitTunnelOwnRegion || len(config.SplitTunnelRegions) > 0
  1517. }
  1518. // GetAuthorizations returns the current client authorizations.
  1519. // The caller must not modify the returned slice.
  1520. func (config *Config) GetAuthorizations() []string {
  1521. config.dynamicConfigMutex.Lock()
  1522. defer config.dynamicConfigMutex.Unlock()
  1523. return config.authorizations
  1524. }
  1525. // GetPsiphonDataDirectory returns the directory under which all persistent
  1526. // files should be stored. This directory is created under
  1527. // config.DataRootDirectory. The motivation for an additional directory is that
  1528. // config.DataRootDirectory defaults to the current working directory, which may
  1529. // include non-tunnel-core files that should be excluded from directory-spanning
  1530. // operations (e.g. excluding all tunnel-core files from backup).
  1531. func (config *Config) GetPsiphonDataDirectory() string {
  1532. return filepath.Join(config.DataRootDirectory, PsiphonDataDirectoryName)
  1533. }
  1534. // GetHomePageFilename the path where the homepage notices file will be created.
  1535. func (config *Config) GetHomePageFilename() string {
  1536. return filepath.Join(config.GetPsiphonDataDirectory(), HomepageFilename)
  1537. }
  1538. // GetNoticesFilename returns the path where the notices file will be created.
  1539. // When the file is rotated it will be moved to config.GetOldNoticesFilename().
  1540. func (config *Config) GetNoticesFilename() string {
  1541. return filepath.Join(config.GetPsiphonDataDirectory(), NoticesFilename)
  1542. }
  1543. // GetOldNoticeFilename returns the path where the rotated notices file will be
  1544. // created.
  1545. func (config *Config) GetOldNoticesFilename() string {
  1546. return filepath.Join(config.GetPsiphonDataDirectory(), OldNoticesFilename)
  1547. }
  1548. // GetDataStoreDirectory returns the directory in which the persistent database
  1549. // will be stored. Created in Config.Commit(). The persistent database contains
  1550. // information such as server entries.
  1551. func (config *Config) GetDataStoreDirectory() string {
  1552. return filepath.Join(config.GetPsiphonDataDirectory(), "datastore")
  1553. }
  1554. // GetObfuscatedServerListDownloadDirectory returns the directory in which
  1555. // obfuscated remote server list downloads will be stored. Created in
  1556. // Config.Commit().
  1557. func (config *Config) GetObfuscatedServerListDownloadDirectory() string {
  1558. return filepath.Join(config.GetPsiphonDataDirectory(), "osl")
  1559. }
  1560. // GetRemoteServerListDownloadFilename returns the filename where the remote
  1561. // server list download will be stored. Data is stored in co-located files
  1562. // (RemoteServerListDownloadFilename.part*) to allow for resumable downloading.
  1563. func (config *Config) GetRemoteServerListDownloadFilename() string {
  1564. return filepath.Join(config.GetPsiphonDataDirectory(), "remote_server_list")
  1565. }
  1566. // GetUpgradeDownloadFilename specifies the filename where upgrade downloads
  1567. // will be stored. This filename is valid when UpgradeDownloadURLs
  1568. // (or UpgradeDownloadUrl) is specified. Data is stored in co-located files
  1569. // (UpgradeDownloadFilename.part*) to allow for resumable downloading.
  1570. func (config *Config) GetUpgradeDownloadFilename() string {
  1571. return filepath.Join(config.GetPsiphonDataDirectory(), UpgradeDownloadFilename)
  1572. }
  1573. // UseUpstreamProxy indicates if an upstream proxy has been
  1574. // configured.
  1575. func (config *Config) UseUpstreamProxy() bool {
  1576. return config.UpstreamProxyURL != ""
  1577. }
  1578. // GetNetworkID returns the current network ID. When NetworkIDGetter
  1579. // is set, this calls into the host application; otherwise, a default
  1580. // value is returned.
  1581. func (config *Config) GetNetworkID() string {
  1582. return config.networkIDGetter.GetNetworkID()
  1583. }
  1584. func (config *Config) SetSignalComponentFailure(signalComponentFailure func()) {
  1585. config.signalComponentFailure.Store(signalComponentFailure)
  1586. }
  1587. // IsInproxyClientPersonalPairingMode indicates that the client is in in-proxy
  1588. // personal pairing mode, where connections are made only through in-proxy
  1589. // proxies with the corresponding personal compartment ID.
  1590. func (config *Config) IsInproxyClientPersonalPairingMode() bool {
  1591. return len(config.InproxyClientPersonalCompartmentID) > 0
  1592. }
  1593. // IsInproxyProxyPersonalPairingMode indicates that the proxy is in in-proxy
  1594. // personal pairing mode, where connections are made only with in-proxy
  1595. // clients with the corresponding personal compartment ID.
  1596. func (config *Config) IsInproxyProxyPersonalPairingMode() bool {
  1597. return len(config.InproxyProxyPersonalCompartmentID) > 0
  1598. }
  1599. // OnInproxyMustUpgrade is invoked when the in-proxy broker returns the
  1600. // MustUpgrade response. When either running a proxy, or when running a
  1601. // client in personal-pairing mode -- two states that require in-proxy
  1602. // functionality -- onInproxyMustUpgrade initiates a shutdown after emitting
  1603. // the InproxyMustUpgrade notice.
  1604. func (config *Config) OnInproxyMustUpgrade() {
  1605. // TODO: check if LimitTunnelProtocols is set to allow only INPROXY tunnel
  1606. // protocols; this is another case where in-proxy functionality is
  1607. // required.
  1608. if config.InproxyEnableProxy || config.IsInproxyClientPersonalPairingMode() {
  1609. if atomic.CompareAndSwapInt32(&config.inproxyMustUpgradePosted, 0, 1) {
  1610. NoticeInproxyMustUpgrade()
  1611. }
  1612. config.signalComponentFailure.Load().(func())()
  1613. }
  1614. }
  1615. func (config *Config) makeConfigParameters() map[string]interface{} {
  1616. // Build set of config values to apply to parameters.
  1617. //
  1618. // Note: names of some config fields such as
  1619. // StaggerConnectionWorkersMilliseconds and LimitMeekBufferSizes have
  1620. // changed in the parameters. The existing config fields are retained for
  1621. // backwards compatibility.
  1622. applyParameters := make(map[string]interface{})
  1623. // To support platform clients that configure NetworkLatencyMultiplier, set
  1624. // the NetworkLatencyMultiplierMin/NetworkLatencyMultiplierMax range to the
  1625. // specified value. Also set the older NetworkLatencyMultiplier tactic, since
  1626. // that will be used in the case of replaying with dial parameters persisted
  1627. // by an older client version.
  1628. if config.NetworkLatencyMultiplier > 0.0 {
  1629. applyParameters[parameters.NetworkLatencyMultiplier] = config.NetworkLatencyMultiplier
  1630. applyParameters[parameters.NetworkLatencyMultiplierMin] = config.NetworkLatencyMultiplier
  1631. applyParameters[parameters.NetworkLatencyMultiplierMax] = config.NetworkLatencyMultiplier
  1632. }
  1633. if config.NetworkLatencyMultiplierMin > 0.0 {
  1634. applyParameters[parameters.NetworkLatencyMultiplierMin] = config.NetworkLatencyMultiplierMin
  1635. }
  1636. if config.NetworkLatencyMultiplierMax > 0.0 {
  1637. applyParameters[parameters.NetworkLatencyMultiplierMax] = config.NetworkLatencyMultiplierMax
  1638. }
  1639. if config.NetworkLatencyMultiplierLambda > 0.0 {
  1640. applyParameters[parameters.NetworkLatencyMultiplierLambda] = config.NetworkLatencyMultiplierLambda
  1641. }
  1642. if len(config.LimitTunnelProtocols) > 0 {
  1643. applyParameters[parameters.LimitTunnelProtocols] = protocol.TunnelProtocols(config.LimitTunnelProtocols)
  1644. }
  1645. if len(config.InitialLimitTunnelProtocols) > 0 && config.InitialLimitTunnelProtocolsCandidateCount > 0 {
  1646. applyParameters[parameters.InitialLimitTunnelProtocols] = protocol.TunnelProtocols(config.InitialLimitTunnelProtocols)
  1647. applyParameters[parameters.InitialLimitTunnelProtocolsCandidateCount] = config.InitialLimitTunnelProtocolsCandidateCount
  1648. }
  1649. if len(config.LimitTLSProfiles) > 0 {
  1650. applyParameters[parameters.LimitTLSProfiles] = protocol.TunnelProtocols(config.LimitTLSProfiles)
  1651. }
  1652. if len(config.LimitQUICVersions) > 0 {
  1653. applyParameters[parameters.LimitQUICVersions] = protocol.QUICVersions(config.LimitQUICVersions)
  1654. }
  1655. if config.EstablishTunnelTimeoutSeconds != nil {
  1656. applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
  1657. }
  1658. if config.EstablishTunnelServerAffinityGracePeriodMilliseconds != nil {
  1659. applyParameters[parameters.EstablishTunnelServerAffinityGracePeriod] = fmt.Sprintf("%dms", *config.EstablishTunnelServerAffinityGracePeriodMilliseconds)
  1660. }
  1661. if config.EstablishTunnelPausePeriodSeconds != nil {
  1662. applyParameters[parameters.EstablishTunnelPausePeriod] = fmt.Sprintf("%ds", *config.EstablishTunnelPausePeriodSeconds)
  1663. }
  1664. if config.ConnectionWorkerPoolSize != 0 {
  1665. applyParameters[parameters.ConnectionWorkerPoolSize] = config.ConnectionWorkerPoolSize
  1666. }
  1667. if config.TunnelPoolSize != 0 {
  1668. applyParameters[parameters.TunnelPoolSize] = config.TunnelPoolSize
  1669. }
  1670. if config.StaggerConnectionWorkersMilliseconds > 0 {
  1671. applyParameters[parameters.StaggerConnectionWorkersPeriod] = fmt.Sprintf("%dms", config.StaggerConnectionWorkersMilliseconds)
  1672. }
  1673. if config.LimitIntensiveConnectionWorkers > 0 {
  1674. applyParameters[parameters.LimitIntensiveConnectionWorkers] = config.LimitIntensiveConnectionWorkers
  1675. }
  1676. applyParameters[parameters.MeekLimitBufferSizes] = config.LimitMeekBufferSizes
  1677. applyParameters[parameters.IgnoreHandshakeStatsRegexps] = config.IgnoreHandshakeStatsRegexps
  1678. if config.EstablishTunnelTimeoutSeconds != nil {
  1679. applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
  1680. }
  1681. if config.FetchRemoteServerListRetryPeriodMilliseconds != nil {
  1682. applyParameters[parameters.FetchRemoteServerListRetryPeriod] = fmt.Sprintf("%dms", *config.FetchRemoteServerListRetryPeriodMilliseconds)
  1683. }
  1684. if config.FetchUpgradeRetryPeriodMilliseconds != nil {
  1685. applyParameters[parameters.FetchUpgradeRetryPeriod] = fmt.Sprintf("%dms", *config.FetchUpgradeRetryPeriodMilliseconds)
  1686. }
  1687. if !config.DisableRemoteServerListFetcher {
  1688. if config.RemoteServerListURLs != nil {
  1689. applyParameters[parameters.RemoteServerListSignaturePublicKey] = config.RemoteServerListSignaturePublicKey
  1690. applyParameters[parameters.RemoteServerListURLs] = config.RemoteServerListURLs
  1691. }
  1692. if config.ObfuscatedServerListRootURLs != nil {
  1693. applyParameters[parameters.RemoteServerListSignaturePublicKey] = config.RemoteServerListSignaturePublicKey
  1694. applyParameters[parameters.ObfuscatedServerListRootURLs] = config.ObfuscatedServerListRootURLs
  1695. }
  1696. }
  1697. if config.EnableUpgradeDownload {
  1698. applyParameters[parameters.UpgradeDownloadURLs] = config.UpgradeDownloadURLs
  1699. applyParameters[parameters.UpgradeDownloadClientVersionHeader] = config.UpgradeDownloadClientVersionHeader
  1700. }
  1701. if config.EnableFeedbackUpload {
  1702. applyParameters[parameters.FeedbackUploadURLs] = config.FeedbackUploadURLs
  1703. applyParameters[parameters.FeedbackEncryptionPublicKey] = config.FeedbackEncryptionPublicKey
  1704. }
  1705. applyParameters[parameters.TunnelRateLimits] = config.RateLimits
  1706. if config.TransformHostNameProbability != nil {
  1707. applyParameters[parameters.TransformHostNameProbability] = *config.TransformHostNameProbability
  1708. }
  1709. if config.FragmentorProbability != nil {
  1710. applyParameters[parameters.FragmentorProbability] = *config.FragmentorProbability
  1711. }
  1712. if len(config.FragmentorLimitProtocols) > 0 {
  1713. applyParameters[parameters.FragmentorLimitProtocols] = protocol.TunnelProtocols(config.FragmentorLimitProtocols)
  1714. }
  1715. if config.FragmentorMinTotalBytes != nil {
  1716. applyParameters[parameters.FragmentorMinTotalBytes] = *config.FragmentorMinTotalBytes
  1717. }
  1718. if config.FragmentorMaxTotalBytes != nil {
  1719. applyParameters[parameters.FragmentorMaxTotalBytes] = *config.FragmentorMaxTotalBytes
  1720. }
  1721. if config.FragmentorMinWriteBytes != nil {
  1722. applyParameters[parameters.FragmentorMinWriteBytes] = *config.FragmentorMinWriteBytes
  1723. }
  1724. if config.FragmentorMaxWriteBytes != nil {
  1725. applyParameters[parameters.FragmentorMaxWriteBytes] = *config.FragmentorMaxWriteBytes
  1726. }
  1727. if config.FragmentorMinDelayMicroseconds != nil {
  1728. applyParameters[parameters.FragmentorMinDelay] = fmt.Sprintf("%dus", *config.FragmentorMinDelayMicroseconds)
  1729. }
  1730. if config.FragmentorMaxDelayMicroseconds != nil {
  1731. applyParameters[parameters.FragmentorMaxDelay] = fmt.Sprintf("%dus", *config.FragmentorMaxDelayMicroseconds)
  1732. }
  1733. if config.MeekTrafficShapingProbability != nil {
  1734. applyParameters[parameters.MeekTrafficShapingProbability] = *config.MeekTrafficShapingProbability
  1735. }
  1736. if len(config.MeekTrafficShapingLimitProtocols) > 0 {
  1737. applyParameters[parameters.MeekTrafficShapingLimitProtocols] = protocol.TunnelProtocols(config.MeekTrafficShapingLimitProtocols)
  1738. }
  1739. if config.MeekMinTLSPadding != nil {
  1740. applyParameters[parameters.MeekMinTLSPadding] = *config.MeekMinTLSPadding
  1741. }
  1742. if config.MeekMaxTLSPadding != nil {
  1743. applyParameters[parameters.MeekMaxTLSPadding] = *config.MeekMaxTLSPadding
  1744. }
  1745. if config.MeekMinLimitRequestPayloadLength != nil {
  1746. applyParameters[parameters.MeekMinLimitRequestPayloadLength] = *config.MeekMinLimitRequestPayloadLength
  1747. }
  1748. if config.MeekMaxLimitRequestPayloadLength != nil {
  1749. applyParameters[parameters.MeekMaxLimitRequestPayloadLength] = *config.MeekMaxLimitRequestPayloadLength
  1750. }
  1751. if config.MeekRedialTLSProbability != nil {
  1752. applyParameters[parameters.MeekRedialTLSProbability] = *config.MeekRedialTLSProbability
  1753. }
  1754. if config.MeekAlternateCookieNameProbability != nil {
  1755. applyParameters[parameters.MeekAlternateCookieNameProbability] = *config.MeekAlternateCookieNameProbability
  1756. }
  1757. if config.MeekAlternateContentTypeProbability != nil {
  1758. applyParameters[parameters.MeekAlternateContentTypeProbability] = *config.MeekAlternateContentTypeProbability
  1759. }
  1760. if config.ObfuscatedSSHMinPadding != nil {
  1761. applyParameters[parameters.ObfuscatedSSHMinPadding] = *config.ObfuscatedSSHMinPadding
  1762. }
  1763. if config.ObfuscatedSSHMaxPadding != nil {
  1764. applyParameters[parameters.ObfuscatedSSHMaxPadding] = *config.ObfuscatedSSHMaxPadding
  1765. }
  1766. if config.LivenessTestMinUpstreamBytes != nil {
  1767. applyParameters[parameters.LivenessTestMinUpstreamBytes] = *config.LivenessTestMinUpstreamBytes
  1768. }
  1769. if config.LivenessTestMaxUpstreamBytes != nil {
  1770. applyParameters[parameters.LivenessTestMaxUpstreamBytes] = *config.LivenessTestMaxUpstreamBytes
  1771. }
  1772. if config.LivenessTestMinDownstreamBytes != nil {
  1773. applyParameters[parameters.LivenessTestMinDownstreamBytes] = *config.LivenessTestMinDownstreamBytes
  1774. }
  1775. if config.LivenessTestMaxDownstreamBytes != nil {
  1776. applyParameters[parameters.LivenessTestMaxDownstreamBytes] = *config.LivenessTestMaxDownstreamBytes
  1777. }
  1778. if config.ReplayCandidateCount != nil {
  1779. applyParameters[parameters.ReplayCandidateCount] = *config.ReplayCandidateCount
  1780. }
  1781. if config.ReplayDialParametersTTLSeconds != nil {
  1782. applyParameters[parameters.ReplayDialParametersTTL] = fmt.Sprintf("%ds", *config.ReplayDialParametersTTLSeconds)
  1783. }
  1784. if config.ReplayTargetUpstreamBytes != nil {
  1785. applyParameters[parameters.ReplayTargetUpstreamBytes] = *config.ReplayTargetUpstreamBytes
  1786. }
  1787. if config.ReplayTargetDownstreamBytes != nil {
  1788. applyParameters[parameters.ReplayTargetDownstreamBytes] = *config.ReplayTargetDownstreamBytes
  1789. }
  1790. if config.ReplayTargetTunnelDurationSeconds != nil {
  1791. applyParameters[parameters.ReplayTargetTunnelDuration] = fmt.Sprintf("%ds", *config.ReplayTargetTunnelDurationSeconds)
  1792. }
  1793. if config.ReplayLaterRoundMoveToFrontProbability != nil {
  1794. applyParameters[parameters.ReplayLaterRoundMoveToFrontProbability] = *config.ReplayLaterRoundMoveToFrontProbability
  1795. }
  1796. if config.ReplayRetainFailedProbability != nil {
  1797. applyParameters[parameters.ReplayRetainFailedProbability] = *config.ReplayRetainFailedProbability
  1798. }
  1799. if config.ReplayIgnoreChangedConfigState != nil {
  1800. applyParameters[parameters.ReplayIgnoreChangedConfigState] = *config.ReplayIgnoreChangedConfigState
  1801. }
  1802. if config.UseOnlyCustomTLSProfiles != nil {
  1803. applyParameters[parameters.UseOnlyCustomTLSProfiles] = *config.UseOnlyCustomTLSProfiles
  1804. }
  1805. if len(config.CustomTLSProfiles) > 0 {
  1806. applyParameters[parameters.CustomTLSProfiles] = config.CustomTLSProfiles
  1807. }
  1808. if config.SelectRandomizedTLSProfileProbability != nil {
  1809. applyParameters[parameters.SelectRandomizedTLSProfileProbability] = *config.SelectRandomizedTLSProfileProbability
  1810. }
  1811. if config.NoDefaultTLSSessionIDProbability != nil {
  1812. applyParameters[parameters.NoDefaultTLSSessionIDProbability] = *config.NoDefaultTLSSessionIDProbability
  1813. }
  1814. if len(config.DisableFrontingProviderTLSProfiles) > 0 {
  1815. applyParameters[parameters.DisableFrontingProviderTLSProfiles] = config.DisableFrontingProviderTLSProfiles
  1816. }
  1817. if config.ClientBurstUpstreamTargetBytes != nil {
  1818. applyParameters[parameters.ClientBurstUpstreamTargetBytes] = *config.ClientBurstUpstreamTargetBytes
  1819. }
  1820. if config.ClientBurstUpstreamDeadlineMilliseconds != nil {
  1821. applyParameters[parameters.ClientBurstUpstreamDeadline] = fmt.Sprintf("%dms", *config.ClientBurstUpstreamDeadlineMilliseconds)
  1822. }
  1823. if config.ClientBurstDownstreamTargetBytes != nil {
  1824. applyParameters[parameters.ClientBurstDownstreamTargetBytes] = *config.ClientBurstDownstreamTargetBytes
  1825. }
  1826. if config.ClientBurstDownstreamDeadlineMilliseconds != nil {
  1827. applyParameters[parameters.ClientBurstDownstreamDeadline] = fmt.Sprintf("%dms", *config.ClientBurstDownstreamDeadlineMilliseconds)
  1828. }
  1829. if config.ApplicationParameters != nil {
  1830. applyParameters[parameters.ApplicationParameters] = config.ApplicationParameters
  1831. }
  1832. if config.CustomHostNameRegexes != nil {
  1833. applyParameters[parameters.CustomHostNameRegexes] = parameters.RegexStrings(config.CustomHostNameRegexes)
  1834. }
  1835. if config.CustomHostNameProbability != nil {
  1836. applyParameters[parameters.CustomHostNameProbability] = *config.CustomHostNameProbability
  1837. }
  1838. if config.CustomHostNameLimitProtocols != nil {
  1839. applyParameters[parameters.CustomHostNameLimitProtocols] = protocol.TunnelProtocols(config.CustomHostNameLimitProtocols)
  1840. }
  1841. if config.ConjureCachedRegistrationTTLSeconds != nil {
  1842. applyParameters[parameters.ConjureCachedRegistrationTTL] = fmt.Sprintf("%ds", *config.ConjureCachedRegistrationTTLSeconds)
  1843. }
  1844. if config.ConjureAPIRegistrarBidirectionalURL != "" {
  1845. applyParameters[parameters.ConjureAPIRegistrarBidirectionalURL] = config.ConjureAPIRegistrarBidirectionalURL
  1846. }
  1847. if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {
  1848. applyParameters[parameters.ConjureAPIRegistrarFrontingSpecs] = config.ConjureAPIRegistrarFrontingSpecs
  1849. }
  1850. if config.ConjureAPIRegistrarMinDelayMilliseconds != nil {
  1851. applyParameters[parameters.ConjureAPIRegistrarMinDelay] = fmt.Sprintf("%dms", *config.ConjureAPIRegistrarMinDelayMilliseconds)
  1852. }
  1853. if config.ConjureAPIRegistrarMaxDelayMilliseconds != nil {
  1854. applyParameters[parameters.ConjureAPIRegistrarMaxDelay] = fmt.Sprintf("%dms", *config.ConjureAPIRegistrarMaxDelayMilliseconds)
  1855. }
  1856. if config.ConjureDecoyRegistrarProbability != nil {
  1857. applyParameters[parameters.ConjureDecoyRegistrarProbability] = *config.ConjureDecoyRegistrarProbability
  1858. }
  1859. if config.ConjureDecoyRegistrarWidth != nil {
  1860. applyParameters[parameters.ConjureDecoyRegistrarWidth] = *config.ConjureDecoyRegistrarWidth
  1861. }
  1862. if config.ConjureDecoyRegistrarMinDelayMilliseconds != nil {
  1863. applyParameters[parameters.ConjureDecoyRegistrarMinDelay] = fmt.Sprintf("%dms", *config.ConjureDecoyRegistrarMinDelayMilliseconds)
  1864. }
  1865. if config.ConjureDecoyRegistrarMaxDelayMilliseconds != nil {
  1866. applyParameters[parameters.ConjureDecoyRegistrarMaxDelay] = fmt.Sprintf("%dms", *config.ConjureDecoyRegistrarMaxDelayMilliseconds)
  1867. }
  1868. if config.ConjureEnableIPv6Dials != nil {
  1869. applyParameters[parameters.ConjureEnableIPv6Dials] = *config.ConjureEnableIPv6Dials
  1870. }
  1871. if config.ConjureEnablePortRandomization != nil {
  1872. applyParameters[parameters.ConjureEnablePortRandomization] = *config.ConjureEnablePortRandomization
  1873. }
  1874. if config.ConjureEnableRegistrationOverrides != nil {
  1875. applyParameters[parameters.ConjureEnableRegistrationOverrides] = *config.ConjureEnableRegistrationOverrides
  1876. }
  1877. if config.ConjureLimitTransports != nil {
  1878. applyParameters[parameters.ConjureLimitTransports] = config.ConjureLimitTransports
  1879. }
  1880. if config.ConjureSTUNServerAddresses != nil {
  1881. applyParameters[parameters.ConjureSTUNServerAddresses] = config.ConjureSTUNServerAddresses
  1882. }
  1883. if config.ConjureDTLSEmptyInitialPacketProbability != nil {
  1884. applyParameters[parameters.ConjureDTLSEmptyInitialPacketProbability] = *config.ConjureDTLSEmptyInitialPacketProbability
  1885. }
  1886. if config.HoldOffTunnelProtocolMinDurationMilliseconds != nil {
  1887. applyParameters[parameters.HoldOffTunnelProtocolMinDuration] = fmt.Sprintf("%dms", *config.HoldOffTunnelProtocolMinDurationMilliseconds)
  1888. }
  1889. if config.HoldOffTunnelProtocolMaxDurationMilliseconds != nil {
  1890. applyParameters[parameters.HoldOffTunnelProtocolMaxDuration] = fmt.Sprintf("%dms", *config.HoldOffTunnelProtocolMaxDurationMilliseconds)
  1891. }
  1892. if len(config.HoldOffTunnelProtocolNames) > 0 {
  1893. applyParameters[parameters.HoldOffTunnelProtocolNames] = protocol.TunnelProtocols(config.HoldOffTunnelProtocolNames)
  1894. }
  1895. if config.HoldOffTunnelProtocolProbability != nil {
  1896. applyParameters[parameters.HoldOffTunnelProtocolProbability] = *config.HoldOffTunnelProtocolProbability
  1897. }
  1898. if config.HoldOffFrontingTunnelMinDurationMilliseconds != nil {
  1899. applyParameters[parameters.HoldOffFrontingTunnelMinDuration] = fmt.Sprintf("%dms", *config.HoldOffFrontingTunnelMinDurationMilliseconds)
  1900. }
  1901. if config.HoldOffFrontingTunnelMaxDurationMilliseconds != nil {
  1902. applyParameters[parameters.HoldOffFrontingTunnelMaxDuration] = fmt.Sprintf("%dms", *config.HoldOffFrontingTunnelMaxDurationMilliseconds)
  1903. }
  1904. if len(config.HoldOffFrontingTunnelProviderIDs) > 0 {
  1905. applyParameters[parameters.HoldOffFrontingTunnelProviderIDs] = config.HoldOffFrontingTunnelProviderIDs
  1906. }
  1907. if config.HoldOffFrontingTunnelProbability != nil {
  1908. applyParameters[parameters.HoldOffFrontingTunnelProbability] = *config.HoldOffFrontingTunnelProbability
  1909. }
  1910. if config.HoldOffDirectTunnelMinDurationMilliseconds != nil {
  1911. applyParameters[parameters.HoldOffDirectTunnelMinDuration] = fmt.Sprintf("%dms", *config.HoldOffDirectTunnelMinDurationMilliseconds)
  1912. }
  1913. if config.HoldOffDirectTunnelMaxDurationMilliseconds != nil {
  1914. applyParameters[parameters.HoldOffDirectTunnelMaxDuration] = fmt.Sprintf("%dms", *config.HoldOffDirectTunnelMaxDurationMilliseconds)
  1915. }
  1916. if len(config.HoldOffDirectTunnelProviderRegions) > 0 {
  1917. applyParameters[parameters.HoldOffDirectTunnelProviderRegions] = parameters.KeyStrings(config.HoldOffDirectTunnelProviderRegions)
  1918. }
  1919. if config.HoldOffDirectTunnelProbability != nil {
  1920. applyParameters[parameters.HoldOffDirectTunnelProbability] = *config.HoldOffDirectTunnelProbability
  1921. }
  1922. if len(config.RestrictDirectProviderRegions) > 0 {
  1923. applyParameters[parameters.RestrictDirectProviderRegions] = parameters.KeyStrings(config.RestrictDirectProviderRegions)
  1924. }
  1925. if config.RestrictDirectProviderIDsClientProbability != nil {
  1926. applyParameters[parameters.RestrictDirectProviderIDsClientProbability] = *config.RestrictDirectProviderIDsClientProbability
  1927. }
  1928. if len(config.RestrictFrontingProviderIDs) > 0 {
  1929. applyParameters[parameters.RestrictFrontingProviderIDs] = config.RestrictFrontingProviderIDs
  1930. }
  1931. if config.RestrictFrontingProviderIDsClientProbability != nil {
  1932. applyParameters[parameters.RestrictFrontingProviderIDsClientProbability] = *config.RestrictFrontingProviderIDsClientProbability
  1933. }
  1934. if config.HoldOffInproxyTunnelMinDurationMilliseconds != nil {
  1935. applyParameters[parameters.HoldOffInproxyTunnelMinDuration] = fmt.Sprintf("%dms", *config.HoldOffInproxyTunnelMinDurationMilliseconds)
  1936. }
  1937. if config.HoldOffInproxyTunnelMaxDurationMilliseconds != nil {
  1938. applyParameters[parameters.HoldOffInproxyTunnelMaxDuration] = fmt.Sprintf("%dms", *config.HoldOffInproxyTunnelMaxDurationMilliseconds)
  1939. }
  1940. if len(config.HoldOffInproxyTunnelProviderRegions) > 0 {
  1941. applyParameters[parameters.HoldOffInproxyTunnelProviderRegions] = parameters.KeyStrings(config.HoldOffInproxyTunnelProviderRegions)
  1942. }
  1943. if config.HoldOffInproxyTunnelProbability != nil {
  1944. applyParameters[parameters.HoldOffInproxyTunnelProbability] = *config.HoldOffInproxyTunnelProbability
  1945. }
  1946. if config.UpstreamProxyAllowAllServerEntrySources != nil {
  1947. applyParameters[parameters.UpstreamProxyAllowAllServerEntrySources] = *config.UpstreamProxyAllowAllServerEntrySources
  1948. }
  1949. if len(config.LimitTunnelDialPortNumbers) > 0 {
  1950. applyParameters[parameters.LimitTunnelDialPortNumbers] = config.LimitTunnelDialPortNumbers
  1951. }
  1952. if config.QUICDialEarlyProbability != nil {
  1953. applyParameters[parameters.QUICDialEarlyProbability] = *config.QUICDialEarlyProbability
  1954. }
  1955. if config.QUICObfuscatedPSKProbability != nil {
  1956. applyParameters[parameters.QUICObfuscatedPSKProbability] = *config.QUICObfuscatedPSKProbability
  1957. }
  1958. if config.QUICDisablePathMTUDiscoveryProbability != nil {
  1959. applyParameters[parameters.QUICDisableClientPathMTUDiscoveryProbability] = *config.QUICDisablePathMTUDiscoveryProbability
  1960. }
  1961. if config.DNSResolverAttemptsPerServer != nil {
  1962. applyParameters[parameters.DNSResolverAttemptsPerServer] = *config.DNSResolverAttemptsPerServer
  1963. }
  1964. if config.DNSResolverAttemptsPerPreferredServer != nil {
  1965. applyParameters[parameters.DNSResolverAttemptsPerPreferredServer] = *config.DNSResolverAttemptsPerPreferredServer
  1966. }
  1967. if config.DNSResolverRequestTimeoutMilliseconds != nil {
  1968. applyParameters[parameters.DNSResolverRequestTimeout] = fmt.Sprintf("%dms", *config.DNSResolverRequestTimeoutMilliseconds)
  1969. }
  1970. if config.DNSResolverAwaitTimeoutMilliseconds != nil {
  1971. applyParameters[parameters.DNSResolverAwaitTimeout] = fmt.Sprintf("%dms", *config.DNSResolverAwaitTimeoutMilliseconds)
  1972. }
  1973. if config.DNSResolverPreresolvedIPAddressProbability != nil {
  1974. applyParameters[parameters.DNSResolverPreresolvedIPAddressProbability] = *config.DNSResolverPreresolvedIPAddressProbability
  1975. }
  1976. if config.DNSResolverPreresolvedIPAddressCIDRs != nil {
  1977. applyParameters[parameters.DNSResolverPreresolvedIPAddressCIDRs] = config.DNSResolverPreresolvedIPAddressCIDRs
  1978. }
  1979. if config.DNSResolverAlternateServers != nil {
  1980. applyParameters[parameters.DNSResolverAlternateServers] = config.DNSResolverAlternateServers
  1981. }
  1982. if config.DNSResolverPreferredAlternateServers != nil {
  1983. applyParameters[parameters.DNSResolverPreferredAlternateServers] = config.DNSResolverPreferredAlternateServers
  1984. }
  1985. if config.DNSResolverPreferAlternateServerProbability != nil {
  1986. applyParameters[parameters.DNSResolverPreferAlternateServerProbability] = *config.DNSResolverPreferAlternateServerProbability
  1987. }
  1988. if config.DNSResolverProtocolTransformSpecs != nil {
  1989. applyParameters[parameters.DNSResolverProtocolTransformSpecs] = config.DNSResolverProtocolTransformSpecs
  1990. }
  1991. if config.DNSResolverProtocolTransformScopedSpecNames != nil {
  1992. applyParameters[parameters.DNSResolverProtocolTransformScopedSpecNames] = config.DNSResolverProtocolTransformScopedSpecNames
  1993. }
  1994. if config.DNSResolverProtocolTransformProbability != nil {
  1995. applyParameters[parameters.DNSResolverProtocolTransformProbability] = *config.DNSResolverProtocolTransformProbability
  1996. }
  1997. if config.DNSResolverQNameRandomizeCasingProbability != nil {
  1998. applyParameters[parameters.DNSResolverQNameRandomizeCasingProbability] = *config.DNSResolverQNameRandomizeCasingProbability
  1999. }
  2000. if config.DNSResolverQNameMustMatchProbability != nil {
  2001. applyParameters[parameters.DNSResolverQNameMustMatchProbability] = *config.DNSResolverQNameMustMatchProbability
  2002. }
  2003. if config.DNSResolverIncludeEDNS0Probability != nil {
  2004. applyParameters[parameters.DNSResolverIncludeEDNS0Probability] = *config.DNSResolverIncludeEDNS0Probability
  2005. }
  2006. if config.DNSResolverCacheExtensionInitialTTLMilliseconds != nil {
  2007. applyParameters[parameters.DNSResolverCacheExtensionInitialTTL] = fmt.Sprintf("%dms", *config.DNSResolverCacheExtensionInitialTTLMilliseconds)
  2008. }
  2009. if config.DNSResolverCacheExtensionVerifiedTTLMilliseconds != nil {
  2010. applyParameters[parameters.DNSResolverCacheExtensionVerifiedTTL] = fmt.Sprintf("%dms", *config.DNSResolverCacheExtensionVerifiedTTLMilliseconds)
  2011. }
  2012. if config.DirectHTTPProtocolTransformSpecs != nil {
  2013. applyParameters[parameters.DirectHTTPProtocolTransformSpecs] = config.DirectHTTPProtocolTransformSpecs
  2014. }
  2015. if config.DirectHTTPProtocolTransformScopedSpecNames != nil {
  2016. applyParameters[parameters.DirectHTTPProtocolTransformScopedSpecNames] = config.DirectHTTPProtocolTransformScopedSpecNames
  2017. }
  2018. if config.DirectHTTPProtocolTransformProbability != nil {
  2019. applyParameters[parameters.DirectHTTPProtocolTransformProbability] = *config.DirectHTTPProtocolTransformProbability
  2020. }
  2021. if config.FrontedHTTPProtocolTransformSpecs != nil {
  2022. applyParameters[parameters.FrontedHTTPProtocolTransformSpecs] = config.FrontedHTTPProtocolTransformSpecs
  2023. }
  2024. if config.FrontedHTTPProtocolTransformScopedSpecNames != nil {
  2025. applyParameters[parameters.FrontedHTTPProtocolTransformScopedSpecNames] = config.FrontedHTTPProtocolTransformScopedSpecNames
  2026. }
  2027. if config.FrontedHTTPProtocolTransformProbability != nil {
  2028. applyParameters[parameters.FrontedHTTPProtocolTransformProbability] = *config.FrontedHTTPProtocolTransformProbability
  2029. }
  2030. if config.OSSHObfuscatorSeedTransformSpecs != nil {
  2031. applyParameters[parameters.OSSHObfuscatorSeedTransformSpecs] = config.OSSHObfuscatorSeedTransformSpecs
  2032. }
  2033. if config.OSSHObfuscatorSeedTransformScopedSpecNames != nil {
  2034. applyParameters[parameters.OSSHObfuscatorSeedTransformScopedSpecNames] = config.OSSHObfuscatorSeedTransformScopedSpecNames
  2035. }
  2036. if config.OSSHObfuscatorSeedTransformProbability != nil {
  2037. applyParameters[parameters.OSSHObfuscatorSeedTransformProbability] = *config.OSSHObfuscatorSeedTransformProbability
  2038. }
  2039. if config.ObfuscatedQUICNonceTransformSpecs != nil {
  2040. applyParameters[parameters.ObfuscatedQUICNonceTransformSpecs] = config.ObfuscatedQUICNonceTransformSpecs
  2041. }
  2042. if config.ObfuscatedQUICNonceTransformScopedSpecNames != nil {
  2043. applyParameters[parameters.ObfuscatedQUICNonceTransformScopedSpecNames] = config.ObfuscatedQUICNonceTransformScopedSpecNames
  2044. }
  2045. if config.ObfuscatedQUICNonceTransformProbability != nil {
  2046. applyParameters[parameters.ObfuscatedQUICNonceTransformProbability] = *config.ObfuscatedQUICNonceTransformProbability
  2047. }
  2048. if config.OSSHPrefixSpecs != nil {
  2049. applyParameters[parameters.OSSHPrefixSpecs] = config.OSSHPrefixSpecs
  2050. }
  2051. if config.OSSHPrefixScopedSpecNames != nil {
  2052. applyParameters[parameters.OSSHPrefixScopedSpecNames] = config.OSSHPrefixScopedSpecNames
  2053. }
  2054. if config.OSSHPrefixProbability != nil {
  2055. applyParameters[parameters.OSSHPrefixProbability] = *config.OSSHPrefixProbability
  2056. }
  2057. if config.OSSHPrefixSplitMinDelayMilliseconds != nil {
  2058. applyParameters[parameters.OSSHPrefixSplitMinDelay] = fmt.Sprintf("%dms", *config.OSSHPrefixSplitMinDelayMilliseconds)
  2059. }
  2060. if config.OSSHPrefixSplitMaxDelayMilliseconds != nil {
  2061. applyParameters[parameters.OSSHPrefixSplitMaxDelay] = fmt.Sprintf("%dms", *config.OSSHPrefixSplitMaxDelayMilliseconds)
  2062. }
  2063. if config.OSSHPrefixEnableFragmentor != nil {
  2064. applyParameters[parameters.OSSHPrefixEnableFragmentor] = *config.OSSHPrefixEnableFragmentor
  2065. }
  2066. if config.ShadowsocksPrefixSpecs != nil {
  2067. applyParameters[parameters.ShadowsocksPrefixSpecs] = config.ShadowsocksPrefixSpecs
  2068. }
  2069. if config.ShadowsocksPrefixScopedSpecNames != nil {
  2070. applyParameters[parameters.ShadowsocksPrefixScopedSpecNames] = config.ShadowsocksPrefixScopedSpecNames
  2071. }
  2072. if config.ShadowsocksPrefixProbability != nil {
  2073. applyParameters[parameters.ShadowsocksPrefixProbability] = *config.ShadowsocksPrefixProbability
  2074. }
  2075. if config.TLSTunnelObfuscatedPSKProbability != nil {
  2076. applyParameters[parameters.TLSTunnelObfuscatedPSKProbability] = *config.TLSTunnelObfuscatedPSKProbability
  2077. }
  2078. if config.TLSTunnelTrafficShapingProbability != nil {
  2079. applyParameters[parameters.TLSTunnelTrafficShapingProbability] = *config.TLSTunnelTrafficShapingProbability
  2080. }
  2081. if config.TLSTunnelMinTLSPadding != nil {
  2082. applyParameters[parameters.TLSTunnelMinTLSPadding] = *config.TLSTunnelMinTLSPadding
  2083. }
  2084. if config.TLSTunnelMaxTLSPadding != nil {
  2085. applyParameters[parameters.TLSTunnelMaxTLSPadding] = *config.TLSTunnelMaxTLSPadding
  2086. }
  2087. if config.TLSFragmentClientHelloProbability != nil {
  2088. applyParameters[parameters.TLSFragmentClientHelloProbability] = *config.TLSFragmentClientHelloProbability
  2089. }
  2090. if len(config.TLSFragmentClientHelloLimitProtocols) > 0 {
  2091. applyParameters[parameters.TLSFragmentClientHelloLimitProtocols] = protocol.TunnelProtocols(config.TLSFragmentClientHelloLimitProtocols)
  2092. }
  2093. if config.SteeringIPCacheTTLSeconds != nil {
  2094. applyParameters[parameters.SteeringIPCacheTTL] = fmt.Sprintf("%ds", *config.SteeringIPCacheTTLSeconds)
  2095. }
  2096. if config.SteeringIPCacheMaxEntries != nil {
  2097. applyParameters[parameters.SteeringIPCacheMaxEntries] = *config.SteeringIPCacheMaxEntries
  2098. }
  2099. if config.SteeringIPProbability != nil {
  2100. applyParameters[parameters.SteeringIPProbability] = *config.SteeringIPProbability
  2101. }
  2102. if config.FrontedHTTPClientReplayDialParametersTTLSeconds != nil {
  2103. applyParameters[parameters.FrontedHTTPClientReplayDialParametersTTL] = fmt.Sprintf("%ds", *config.FrontedHTTPClientReplayDialParametersTTLSeconds)
  2104. }
  2105. if config.FrontedHTTPClientReplayUpdateFrequencySeconds != nil {
  2106. applyParameters[parameters.FrontedHTTPClientReplayUpdateFrequency] = fmt.Sprintf("%ds", *config.FrontedHTTPClientReplayUpdateFrequencySeconds)
  2107. }
  2108. if config.FrontedHTTPClientReplayDialParametersProbability != nil {
  2109. applyParameters[parameters.FrontedHTTPClientReplayDialParametersProbability] = *config.FrontedHTTPClientReplayDialParametersProbability
  2110. }
  2111. if config.FrontedHTTPClientReplayRetainFailedProbability != nil {
  2112. applyParameters[parameters.FrontedHTTPClientReplayRetainFailedProbability] = *config.FrontedHTTPClientReplayRetainFailedProbability
  2113. }
  2114. if config.InproxyPersonalPairingConnectionWorkerPoolSize != 0 {
  2115. applyParameters[parameters.InproxyPersonalPairingConnectionWorkerPoolSize] = config.InproxyPersonalPairingConnectionWorkerPoolSize
  2116. }
  2117. if config.InproxyAllowProxy != nil {
  2118. applyParameters[parameters.InproxyAllowProxy] = *config.InproxyAllowProxy
  2119. }
  2120. if config.InproxyAllowClient != nil {
  2121. applyParameters[parameters.InproxyAllowClient] = *config.InproxyAllowClient
  2122. }
  2123. if config.InproxyTunnelProtocolSelectionProbability != nil {
  2124. applyParameters[parameters.InproxyTunnelProtocolSelectionProbability] = *config.InproxyTunnelProtocolSelectionProbability
  2125. }
  2126. if len(config.InproxyBrokerSpecs) > 0 {
  2127. applyParameters[parameters.InproxyBrokerSpecs] = config.InproxyBrokerSpecs
  2128. }
  2129. if len(config.InproxyPersonalPairingBrokerSpecs) > 0 {
  2130. applyParameters[parameters.InproxyPersonalPairingBrokerSpecs] = config.InproxyPersonalPairingBrokerSpecs
  2131. }
  2132. if len(config.InproxyProxyBrokerSpecs) > 0 {
  2133. applyParameters[parameters.InproxyProxyBrokerSpecs] = config.InproxyProxyBrokerSpecs
  2134. }
  2135. if len(config.InproxyProxyPersonalPairingBrokerSpecs) > 0 {
  2136. applyParameters[parameters.InproxyProxyPersonalPairingBrokerSpecs] = config.InproxyProxyPersonalPairingBrokerSpecs
  2137. }
  2138. if len(config.InproxyClientBrokerSpecs) > 0 {
  2139. applyParameters[parameters.InproxyClientBrokerSpecs] = config.InproxyClientBrokerSpecs
  2140. }
  2141. if len(config.InproxyClientPersonalPairingBrokerSpecs) > 0 {
  2142. applyParameters[parameters.InproxyClientPersonalPairingBrokerSpecs] = config.InproxyClientPersonalPairingBrokerSpecs
  2143. }
  2144. if config.InproxyReplayBrokerDialParametersTTLSeconds != nil {
  2145. applyParameters[parameters.InproxyReplayBrokerDialParametersTTL] = fmt.Sprintf("%ds", *config.InproxyReplayBrokerDialParametersTTLSeconds)
  2146. }
  2147. if config.InproxyReplayBrokerUpdateFrequencySeconds != nil {
  2148. applyParameters[parameters.InproxyReplayBrokerUpdateFrequency] = fmt.Sprintf("%ds", *config.InproxyReplayBrokerUpdateFrequencySeconds)
  2149. }
  2150. if config.InproxyReplayBrokerDialParametersProbability != nil {
  2151. applyParameters[parameters.InproxyReplayBrokerDialParametersProbability] = *config.InproxyReplayBrokerDialParametersProbability
  2152. }
  2153. if config.InproxyReplayBrokerRetainFailedProbability != nil {
  2154. applyParameters[parameters.InproxyReplayBrokerRetainFailedProbability] = *config.InproxyReplayBrokerRetainFailedProbability
  2155. }
  2156. if len(config.InproxyCommonCompartmentIDs) > 0 {
  2157. applyParameters[parameters.InproxyCommonCompartmentIDs] = config.InproxyCommonCompartmentIDs
  2158. }
  2159. if config.InproxyMaxCompartmentIDListLength != nil {
  2160. applyParameters[parameters.InproxyMaxCompartmentIDListLength] = *config.InproxyMaxCompartmentIDListLength
  2161. }
  2162. if config.InproxyProxyAnnounceRequestTimeoutMilliseconds != nil {
  2163. applyParameters[parameters.InproxyProxyAnnounceRequestTimeout] = fmt.Sprintf("%dms", *config.InproxyProxyAnnounceRequestTimeoutMilliseconds)
  2164. }
  2165. if config.InproxyProxyAnnounceDelayMilliseconds != nil {
  2166. applyParameters[parameters.InproxyProxyAnnounceDelay] = fmt.Sprintf("%dms", *config.InproxyProxyAnnounceDelayMilliseconds)
  2167. }
  2168. if config.InproxyProxyAnnounceMaxBackoffDelayMilliseconds != nil {
  2169. applyParameters[parameters.InproxyProxyAnnounceMaxBackoffDelay] = fmt.Sprintf("%dms", *config.InproxyProxyAnnounceMaxBackoffDelayMilliseconds)
  2170. }
  2171. if config.InproxyProxyAnnounceDelayJitter != nil {
  2172. applyParameters[parameters.InproxyProxyAnnounceDelayJitter] = *config.InproxyProxyAnnounceDelayJitter
  2173. }
  2174. if config.InproxyProxyAnswerRequestTimeoutMilliseconds != nil {
  2175. applyParameters[parameters.InproxyProxyAnswerRequestTimeout] = fmt.Sprintf("%dms", *config.InproxyProxyAnswerRequestTimeoutMilliseconds)
  2176. }
  2177. if config.InproxyClientOfferRequestTimeoutMilliseconds != nil {
  2178. applyParameters[parameters.InproxyClientOfferRequestTimeout] = fmt.Sprintf("%dms", *config.InproxyClientOfferRequestTimeoutMilliseconds)
  2179. }
  2180. if config.InproxyClientOfferRequestPersonalTimeoutMilliseconds != nil {
  2181. applyParameters[parameters.InproxyClientOfferRequestPersonalTimeout] = fmt.Sprintf("%dms", *config.InproxyClientOfferRequestPersonalTimeoutMilliseconds)
  2182. }
  2183. if config.InproxyClientOfferRetryDelayMilliseconds != nil {
  2184. applyParameters[parameters.InproxyClientOfferRetryDelay] = fmt.Sprintf("%dms", *config.InproxyClientOfferRetryDelayMilliseconds)
  2185. }
  2186. if config.InproxyClientOfferRetryJitter != nil {
  2187. applyParameters[parameters.InproxyClientOfferRetryJitter] = *config.InproxyClientOfferRetryJitter
  2188. }
  2189. if config.InproxyClientRelayedPacketRequestTimeoutMilliseconds != nil {
  2190. applyParameters[parameters.InproxyClientRelayedPacketRequestTimeout] = fmt.Sprintf("%dms", *config.InproxyClientRelayedPacketRequestTimeoutMilliseconds)
  2191. }
  2192. if config.InproxyDTLSRandomizationProbability != nil {
  2193. applyParameters[parameters.InproxyDTLSRandomizationProbability] = *config.InproxyDTLSRandomizationProbability
  2194. }
  2195. if config.InproxyWebRTCMediaStreamsProbability != nil {
  2196. applyParameters[parameters.InproxyWebRTCMediaStreamsProbability] = *config.InproxyWebRTCMediaStreamsProbability
  2197. }
  2198. if config.InproxyWebRTCDataChannelTrafficShapingProbability != nil {
  2199. applyParameters[parameters.InproxyWebRTCDataChannelTrafficShapingProbability] = *config.InproxyWebRTCDataChannelTrafficShapingProbability
  2200. }
  2201. if config.InproxyWebRTCDataChannelTrafficShapingParameters != nil {
  2202. applyParameters[parameters.InproxyWebRTCDataChannelTrafficShapingParameters] = *config.InproxyWebRTCDataChannelTrafficShapingParameters
  2203. }
  2204. if config.InproxyWebRTCMediaStreamsTrafficShapingProbability != nil {
  2205. applyParameters[parameters.InproxyWebRTCMediaStreamsTrafficShapingProbability] = *config.InproxyWebRTCMediaStreamsTrafficShapingProbability
  2206. }
  2207. if config.InproxyWebRTCMediaStreamsTrafficShapingParameters != nil {
  2208. applyParameters[parameters.InproxyWebRTCMediaStreamsTrafficShapingParameters] = *config.InproxyWebRTCMediaStreamsTrafficShapingParameters
  2209. }
  2210. if len(config.InproxySTUNServerAddresses) > 0 {
  2211. applyParameters[parameters.InproxySTUNServerAddresses] = config.InproxySTUNServerAddresses
  2212. }
  2213. if len(config.InproxySTUNServerAddressesRFC5780) > 0 {
  2214. applyParameters[parameters.InproxySTUNServerAddressesRFC5780] = config.InproxySTUNServerAddressesRFC5780
  2215. }
  2216. if len(config.InproxyProxySTUNServerAddresses) > 0 {
  2217. applyParameters[parameters.InproxyProxySTUNServerAddresses] = config.InproxyProxySTUNServerAddresses
  2218. }
  2219. if len(config.InproxyProxySTUNServerAddressesRFC5780) > 0 {
  2220. applyParameters[parameters.InproxyProxySTUNServerAddressesRFC5780] = config.InproxyProxySTUNServerAddressesRFC5780
  2221. }
  2222. if len(config.InproxyClientSTUNServerAddresses) > 0 {
  2223. applyParameters[parameters.InproxyClientSTUNServerAddresses] = config.InproxyClientSTUNServerAddresses
  2224. }
  2225. if len(config.InproxyClientSTUNServerAddressesRFC5780) > 0 {
  2226. applyParameters[parameters.InproxyClientSTUNServerAddressesRFC5780] = config.InproxyClientSTUNServerAddressesRFC5780
  2227. }
  2228. if config.InproxyClientDiscoverNATProbability != nil {
  2229. applyParameters[parameters.InproxyClientDiscoverNATProbability] = *config.InproxyClientDiscoverNATProbability
  2230. }
  2231. if config.InproxyDisableSTUN != nil {
  2232. applyParameters[parameters.InproxyDisableSTUN] = *config.InproxyDisableSTUN
  2233. }
  2234. if config.InproxyDisablePortMapping != nil {
  2235. applyParameters[parameters.InproxyDisablePortMapping] = *config.InproxyDisablePortMapping
  2236. }
  2237. if config.InproxyDisableInboundForMobileNetworks != nil {
  2238. applyParameters[parameters.InproxyDisableInboundForMobileNetworks] = *config.InproxyDisableInboundForMobileNetworks
  2239. }
  2240. if config.InproxyDisableIPv6ICECandidates != nil {
  2241. applyParameters[parameters.InproxyDisableIPv6ICECandidates] = *config.InproxyDisableIPv6ICECandidates
  2242. }
  2243. if config.InproxyProxyDisableSTUN != nil {
  2244. applyParameters[parameters.InproxyProxyDisableSTUN] = *config.InproxyProxyDisableSTUN
  2245. }
  2246. if config.InproxyProxyDisablePortMapping != nil {
  2247. applyParameters[parameters.InproxyProxyDisablePortMapping] = *config.InproxyProxyDisablePortMapping
  2248. }
  2249. if config.InproxyProxyDisableInboundForMobileNetworks != nil {
  2250. applyParameters[parameters.InproxyProxyDisableInboundForMobileNetworks] = *config.InproxyProxyDisableInboundForMobileNetworks
  2251. }
  2252. if config.InproxyProxyDisableIPv6ICECandidates != nil {
  2253. applyParameters[parameters.InproxyProxyDisableIPv6ICECandidates] = *config.InproxyProxyDisableIPv6ICECandidates
  2254. }
  2255. if config.InproxyClientDisableSTUN != nil {
  2256. applyParameters[parameters.InproxyClientDisableSTUN] = *config.InproxyClientDisableSTUN
  2257. }
  2258. if config.InproxyClientDisablePortMapping != nil {
  2259. applyParameters[parameters.InproxyClientDisablePortMapping] = *config.InproxyClientDisablePortMapping
  2260. }
  2261. if config.InproxyClientDisableInboundForMobileNetworks != nil {
  2262. applyParameters[parameters.InproxyClientDisableInboundForMobileNetworks] = *config.InproxyClientDisableInboundForMobileNetworks
  2263. }
  2264. if config.InproxyClientDisableIPv6ICECandidates != nil {
  2265. applyParameters[parameters.InproxyClientDisableIPv6ICECandidates] = *config.InproxyClientDisableIPv6ICECandidates
  2266. }
  2267. if config.InproxyProxyDiscoverNATTimeoutMilliseconds != nil {
  2268. applyParameters[parameters.InproxyProxyDiscoverNATTimeout] = fmt.Sprintf("%dms", *config.InproxyProxyDiscoverNATTimeoutMilliseconds)
  2269. }
  2270. if config.InproxyClientDiscoverNATTimeoutMilliseconds != nil {
  2271. applyParameters[parameters.InproxyClientDiscoverNATTimeout] = fmt.Sprintf("%dms", *config.InproxyClientDiscoverNATTimeoutMilliseconds)
  2272. }
  2273. if config.InproxyWebRTCAnswerTimeoutMilliseconds != nil {
  2274. applyParameters[parameters.InproxyWebRTCAnswerTimeout] = fmt.Sprintf("%dms", *config.InproxyWebRTCAnswerTimeoutMilliseconds)
  2275. }
  2276. if config.InproxyProxyWebRTCAwaitReadyToProxyTimeoutMilliseconds != nil {
  2277. applyParameters[parameters.InproxyProxyWebRTCAwaitReadyToProxyTimeout] = fmt.Sprintf("%dms", *config.InproxyProxyWebRTCAwaitReadyToProxyTimeoutMilliseconds)
  2278. }
  2279. if config.InproxyClientWebRTCAwaitReadyToProxyTimeoutMilliseconds != nil {
  2280. applyParameters[parameters.InproxyClientWebRTCAwaitReadyToProxyTimeout] = fmt.Sprintf("%dms", *config.InproxyClientWebRTCAwaitReadyToProxyTimeoutMilliseconds)
  2281. }
  2282. if config.InproxyProxyDestinationDialTimeoutMilliseconds != nil {
  2283. applyParameters[parameters.InproxyProxyDestinationDialTimeout] = fmt.Sprintf("%dms", *config.InproxyProxyDestinationDialTimeoutMilliseconds)
  2284. }
  2285. if config.InproxyPsiphonAPIRequestTimeoutMilliseconds != nil {
  2286. applyParameters[parameters.InproxyPsiphonAPIRequestTimeout] = fmt.Sprintf("%dms", *config.InproxyPsiphonAPIRequestTimeoutMilliseconds)
  2287. }
  2288. if config.InproxyProxyTotalActivityNoticePeriodMilliseconds != nil {
  2289. applyParameters[parameters.InproxyProxyTotalActivityNoticePeriod] = fmt.Sprintf("%dms", *config.InproxyProxyTotalActivityNoticePeriodMilliseconds)
  2290. }
  2291. if config.InproxyClientDialRateLimitQuantity != nil {
  2292. applyParameters[parameters.InproxyClientDialRateLimitQuantity] = *config.InproxyClientDialRateLimitQuantity
  2293. }
  2294. if config.InproxyClientDialRateLimitIntervalMilliseconds != nil {
  2295. applyParameters[parameters.InproxyClientDialRateLimitInterval] = fmt.Sprintf("%dms", *config.InproxyClientDialRateLimitIntervalMilliseconds)
  2296. }
  2297. if config.InproxyClientNoMatchFailoverProbability != nil {
  2298. applyParameters[parameters.InproxyClientNoMatchFailoverProbability] = *config.InproxyClientNoMatchFailoverProbability
  2299. }
  2300. if config.InproxyClientNoMatchFailoverPersonalProbability != nil {
  2301. applyParameters[parameters.InproxyClientNoMatchFailoverPersonalProbability] = *config.InproxyClientNoMatchFailoverPersonalProbability
  2302. }
  2303. if config.InproxyFrontingProviderClientMaxRequestTimeouts != nil {
  2304. applyParameters[parameters.InproxyFrontingProviderClientMaxRequestTimeouts] = config.InproxyFrontingProviderClientMaxRequestTimeouts
  2305. }
  2306. if config.InproxyProxyOnBrokerClientFailedRetryPeriodMilliseconds != nil {
  2307. applyParameters[parameters.InproxyProxyOnBrokerClientFailedRetryPeriod] = fmt.Sprintf("%dms", *config.InproxyProxyOnBrokerClientFailedRetryPeriodMilliseconds)
  2308. }
  2309. if len(config.InproxyProxyIncompatibleNetworkTypes) > 0 {
  2310. applyParameters[parameters.InproxyProxyIncompatibleNetworkTypes] = config.InproxyProxyIncompatibleNetworkTypes
  2311. }
  2312. if len(config.InproxyClientIncompatibleNetworkTypes) > 0 {
  2313. applyParameters[parameters.InproxyClientIncompatibleNetworkTypes] = config.InproxyClientIncompatibleNetworkTypes
  2314. }
  2315. if config.NetworkIDCacheTTLMilliseconds != nil {
  2316. applyParameters[parameters.NetworkIDCacheTTL] = fmt.Sprintf("%dms", *config.NetworkIDCacheTTLMilliseconds)
  2317. }
  2318. // When adding new config dial parameters that may override tactics, also
  2319. // update setDialParametersHash.
  2320. return applyParameters
  2321. }
  2322. func (config *Config) setDialParametersHash() {
  2323. // Calculate and store a hash of the config values that may impact
  2324. // dial parameters. This hash is used as part of the dial parameters
  2325. // replay mechanism to detect when persisted dial parameters should
  2326. // be discarded due to conflicting config changes.
  2327. //
  2328. // With a couple of minor exceptions, configuring dial parameters via the
  2329. // config is intended for testing only, and so these parameters are expected
  2330. // to be present in test runs only. It remains an important case to discard
  2331. // replay dial parameters when test config parameters are varied.
  2332. //
  2333. // Hashing the parameter names detects some ambiguous hash cases, such as two
  2334. // consecutive int64 parameters, one omitted and one not, that are flipped.
  2335. // The serialization is not completely unambiguous, and the format is
  2336. // currently limited by legacy cases (not invalidating replay dial parameters
  2337. // for production clients is more important than invalidating for test runs).
  2338. // We cannot hash the entire config JSON as it contains non-dial parameter
  2339. // fields which may frequently change across runs.
  2340. //
  2341. // MD5 hash is used solely as a data checksum and not for any security
  2342. // purpose.
  2343. hash := md5.New()
  2344. if len(config.LimitTunnelProtocols) > 0 {
  2345. hash.Write([]byte("LimitTunnelProtocols"))
  2346. for _, protocol := range config.LimitTunnelProtocols {
  2347. hash.Write([]byte(protocol))
  2348. }
  2349. }
  2350. if len(config.InitialLimitTunnelProtocols) > 0 && config.InitialLimitTunnelProtocolsCandidateCount > 0 {
  2351. hash.Write([]byte("InitialLimitTunnelProtocols"))
  2352. for _, protocol := range config.InitialLimitTunnelProtocols {
  2353. hash.Write([]byte(protocol))
  2354. }
  2355. binary.Write(hash, binary.LittleEndian, int64(config.InitialLimitTunnelProtocolsCandidateCount))
  2356. }
  2357. if len(config.LimitTLSProfiles) > 0 {
  2358. hash.Write([]byte("LimitTLSProfiles"))
  2359. for _, profile := range config.LimitTLSProfiles {
  2360. hash.Write([]byte(profile))
  2361. }
  2362. }
  2363. if len(config.LimitQUICVersions) > 0 {
  2364. hash.Write([]byte("LimitQUICVersions"))
  2365. for _, version := range config.LimitQUICVersions {
  2366. hash.Write([]byte(version))
  2367. }
  2368. }
  2369. // Whether a custom User-Agent is specified is a binary flag: when not set,
  2370. // the replay dial parameters value applies. When set, external
  2371. // considerations apply.
  2372. if _, ok := config.CustomHeaders["User-Agent"]; ok {
  2373. hash.Write([]byte("CustomHeaders User-Agent"))
  2374. hash.Write([]byte{1})
  2375. }
  2376. if config.UpstreamProxyURL != "" {
  2377. hash.Write([]byte("UpstreamProxyURL"))
  2378. hash.Write([]byte(config.UpstreamProxyURL))
  2379. }
  2380. if config.TransformHostNameProbability != nil {
  2381. hash.Write([]byte("TransformHostNameProbability"))
  2382. binary.Write(hash, binary.LittleEndian, *config.TransformHostNameProbability)
  2383. }
  2384. if config.FragmentorProbability != nil {
  2385. hash.Write([]byte("FragmentorProbability"))
  2386. binary.Write(hash, binary.LittleEndian, *config.FragmentorProbability)
  2387. }
  2388. if len(config.FragmentorLimitProtocols) > 0 {
  2389. hash.Write([]byte("FragmentorLimitProtocols"))
  2390. for _, protocol := range config.FragmentorLimitProtocols {
  2391. hash.Write([]byte(protocol))
  2392. }
  2393. }
  2394. if config.FragmentorMinTotalBytes != nil {
  2395. hash.Write([]byte("FragmentorMinTotalBytes"))
  2396. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinTotalBytes))
  2397. }
  2398. if config.FragmentorMaxTotalBytes != nil {
  2399. hash.Write([]byte("FragmentorMaxTotalBytes"))
  2400. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxTotalBytes))
  2401. }
  2402. if config.FragmentorMinWriteBytes != nil {
  2403. hash.Write([]byte("FragmentorMinWriteBytes"))
  2404. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinWriteBytes))
  2405. }
  2406. if config.FragmentorMaxWriteBytes != nil {
  2407. hash.Write([]byte("FragmentorMaxWriteBytes"))
  2408. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxWriteBytes))
  2409. }
  2410. if config.FragmentorMinDelayMicroseconds != nil {
  2411. hash.Write([]byte("FragmentorMinDelayMicroseconds"))
  2412. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinDelayMicroseconds))
  2413. }
  2414. if config.FragmentorMaxDelayMicroseconds != nil {
  2415. hash.Write([]byte("FragmentorMaxDelayMicroseconds"))
  2416. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxDelayMicroseconds))
  2417. }
  2418. if config.MeekTrafficShapingProbability != nil {
  2419. hash.Write([]byte("MeekTrafficShapingProbability"))
  2420. binary.Write(hash, binary.LittleEndian, *config.MeekTrafficShapingProbability)
  2421. }
  2422. if len(config.MeekTrafficShapingLimitProtocols) > 0 {
  2423. hash.Write([]byte("MeekTrafficShapingLimitProtocols"))
  2424. for _, protocol := range config.MeekTrafficShapingLimitProtocols {
  2425. hash.Write([]byte(protocol))
  2426. }
  2427. }
  2428. if config.MeekMinLimitRequestPayloadLength != nil {
  2429. hash.Write([]byte("MeekMinLimitRequestPayloadLength"))
  2430. binary.Write(hash, binary.LittleEndian, int64(*config.MeekMinLimitRequestPayloadLength))
  2431. }
  2432. if config.MeekMaxLimitRequestPayloadLength != nil {
  2433. hash.Write([]byte("MeekMaxLimitRequestPayloadLength"))
  2434. binary.Write(hash, binary.LittleEndian, int64(*config.MeekMaxLimitRequestPayloadLength))
  2435. }
  2436. if config.MeekRedialTLSProbability != nil {
  2437. hash.Write([]byte("MeekRedialTLSProbability"))
  2438. binary.Write(hash, binary.LittleEndian, *config.MeekRedialTLSProbability)
  2439. }
  2440. if config.ObfuscatedSSHMinPadding != nil {
  2441. hash.Write([]byte("ObfuscatedSSHMinPadding"))
  2442. binary.Write(hash, binary.LittleEndian, int64(*config.ObfuscatedSSHMinPadding))
  2443. }
  2444. if config.ObfuscatedSSHMaxPadding != nil {
  2445. hash.Write([]byte("ObfuscatedSSHMaxPadding"))
  2446. binary.Write(hash, binary.LittleEndian, int64(*config.ObfuscatedSSHMaxPadding))
  2447. }
  2448. if config.LivenessTestMinUpstreamBytes != nil {
  2449. hash.Write([]byte("LivenessTestMinUpstreamBytes"))
  2450. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMinUpstreamBytes))
  2451. }
  2452. if config.LivenessTestMaxUpstreamBytes != nil {
  2453. hash.Write([]byte("LivenessTestMaxUpstreamBytes"))
  2454. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMaxUpstreamBytes))
  2455. }
  2456. if config.LivenessTestMinDownstreamBytes != nil {
  2457. hash.Write([]byte("LivenessTestMinDownstreamBytes"))
  2458. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMinDownstreamBytes))
  2459. }
  2460. if config.LivenessTestMaxDownstreamBytes != nil {
  2461. hash.Write([]byte("LivenessTestMaxDownstreamBytes"))
  2462. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMaxDownstreamBytes))
  2463. }
  2464. // Legacy case: these parameters are included in the hash unconditionally,
  2465. // and so will impact almost all production clients. These parameter names
  2466. // are not hashed since that would invalidate all replay dial parameters for
  2467. // existing clients whose hashes predate the inclusion of parameter names.
  2468. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierMin)
  2469. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierMax)
  2470. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierLambda)
  2471. if config.UseOnlyCustomTLSProfiles != nil {
  2472. hash.Write([]byte("UseOnlyCustomTLSProfiles"))
  2473. binary.Write(hash, binary.LittleEndian, *config.UseOnlyCustomTLSProfiles)
  2474. }
  2475. if len(config.CustomTLSProfiles) > 0 {
  2476. hash.Write([]byte("CustomTLSProfiles"))
  2477. for _, customTLSProfile := range config.CustomTLSProfiles {
  2478. encodedCustomTLSProofile, _ := json.Marshal(customTLSProfile)
  2479. hash.Write(encodedCustomTLSProofile)
  2480. }
  2481. }
  2482. if config.SelectRandomizedTLSProfileProbability != nil {
  2483. hash.Write([]byte("SelectRandomizedTLSProfileProbability"))
  2484. binary.Write(hash, binary.LittleEndian, *config.SelectRandomizedTLSProfileProbability)
  2485. }
  2486. if config.NoDefaultTLSSessionIDProbability != nil {
  2487. hash.Write([]byte("NoDefaultTLSSessionIDProbability"))
  2488. binary.Write(hash, binary.LittleEndian, *config.NoDefaultTLSSessionIDProbability)
  2489. }
  2490. if len(config.DisableFrontingProviderTLSProfiles) > 0 {
  2491. hash.Write([]byte("DisableFrontingProviderTLSProfiles"))
  2492. encodedDisableFrontingProviderTLSProfiles, _ :=
  2493. json.Marshal(config.DisableFrontingProviderTLSProfiles)
  2494. hash.Write(encodedDisableFrontingProviderTLSProfiles)
  2495. }
  2496. if len(config.CustomHostNameRegexes) > 0 {
  2497. hash.Write([]byte("CustomHostNameRegexes"))
  2498. for _, customHostNameRegex := range config.CustomHostNameRegexes {
  2499. hash.Write([]byte(customHostNameRegex))
  2500. }
  2501. }
  2502. if config.CustomHostNameProbability != nil {
  2503. hash.Write([]byte("CustomHostNameProbability"))
  2504. binary.Write(hash, binary.LittleEndian, *config.CustomHostNameProbability)
  2505. }
  2506. if len(config.CustomHostNameLimitProtocols) > 0 {
  2507. hash.Write([]byte("CustomHostNameLimitProtocols"))
  2508. for _, protocol := range config.CustomHostNameLimitProtocols {
  2509. hash.Write([]byte(protocol))
  2510. }
  2511. }
  2512. if config.ConjureCachedRegistrationTTLSeconds != nil {
  2513. hash.Write([]byte("ConjureCachedRegistrationTTLSeconds"))
  2514. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureCachedRegistrationTTLSeconds))
  2515. }
  2516. if config.ConjureAPIRegistrarBidirectionalURL != "" {
  2517. hash.Write([]byte("ConjureAPIRegistrarBidirectionalURL"))
  2518. hash.Write([]byte(config.ConjureAPIRegistrarBidirectionalURL))
  2519. }
  2520. if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {
  2521. hash.Write([]byte("ConjureAPIRegistrarFrontingSpecs"))
  2522. for _, frontingSpec := range config.ConjureAPIRegistrarFrontingSpecs {
  2523. encodedFrontSpec, _ := json.Marshal(frontingSpec)
  2524. hash.Write(encodedFrontSpec)
  2525. }
  2526. }
  2527. if config.ConjureAPIRegistrarMinDelayMilliseconds != nil {
  2528. hash.Write([]byte("ConjureAPIRegistrarMinDelayMilliseconds"))
  2529. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureAPIRegistrarMinDelayMilliseconds))
  2530. }
  2531. if config.ConjureAPIRegistrarMaxDelayMilliseconds != nil {
  2532. hash.Write([]byte("ConjureAPIRegistrarMaxDelayMilliseconds"))
  2533. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureAPIRegistrarMaxDelayMilliseconds))
  2534. }
  2535. if config.ConjureDecoyRegistrarWidth != nil {
  2536. hash.Write([]byte("ConjureDecoyRegistrarWidth"))
  2537. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarWidth))
  2538. }
  2539. if config.ConjureDecoyRegistrarMinDelayMilliseconds != nil {
  2540. hash.Write([]byte("ConjureDecoyRegistrarMinDelayMilliseconds"))
  2541. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarMinDelayMilliseconds))
  2542. }
  2543. if config.ConjureDecoyRegistrarMaxDelayMilliseconds != nil {
  2544. hash.Write([]byte("ConjureDecoyRegistrarMaxDelayMilliseconds"))
  2545. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarMaxDelayMilliseconds))
  2546. }
  2547. if config.ConjureLimitTransports != nil {
  2548. hash.Write([]byte("ConjureLimitTransports"))
  2549. for _, transport := range config.ConjureLimitTransports {
  2550. hash.Write([]byte(transport))
  2551. }
  2552. }
  2553. if config.ConjureSTUNServerAddresses != nil {
  2554. hash.Write([]byte("ConjureSTUNServerAddresses"))
  2555. for _, address := range config.ConjureSTUNServerAddresses {
  2556. hash.Write([]byte(address))
  2557. }
  2558. }
  2559. if config.HoldOffTunnelProtocolMinDurationMilliseconds != nil {
  2560. hash.Write([]byte("HoldOffTunnelProtocolMinDurationMilliseconds"))
  2561. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffTunnelProtocolMinDurationMilliseconds))
  2562. }
  2563. if config.HoldOffTunnelProtocolMaxDurationMilliseconds != nil {
  2564. hash.Write([]byte("HoldOffTunnelProtocolMaxDurationMilliseconds"))
  2565. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffTunnelProtocolMaxDurationMilliseconds))
  2566. }
  2567. if len(config.HoldOffTunnelProtocolNames) > 0 {
  2568. hash.Write([]byte("HoldOffTunnelProtocolNames"))
  2569. for _, protocol := range config.HoldOffTunnelProtocolNames {
  2570. hash.Write([]byte(protocol))
  2571. }
  2572. }
  2573. if config.HoldOffTunnelProtocolProbability != nil {
  2574. hash.Write([]byte("HoldOffTunnelProtocolProbability"))
  2575. binary.Write(hash, binary.LittleEndian, *config.HoldOffTunnelProtocolProbability)
  2576. }
  2577. if config.HoldOffFrontingTunnelMinDurationMilliseconds != nil {
  2578. hash.Write([]byte("HoldOffFrontingTunnelMinDurationMilliseconds"))
  2579. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffFrontingTunnelMinDurationMilliseconds))
  2580. }
  2581. if config.HoldOffFrontingTunnelMaxDurationMilliseconds != nil {
  2582. hash.Write([]byte("HoldOffFrontingTunnelMaxDurationMilliseconds"))
  2583. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffFrontingTunnelMaxDurationMilliseconds))
  2584. }
  2585. if len(config.HoldOffFrontingTunnelProviderIDs) > 0 {
  2586. hash.Write([]byte("HoldOffFrontingTunnelProviderIDs"))
  2587. for _, providerID := range config.HoldOffFrontingTunnelProviderIDs {
  2588. hash.Write([]byte(providerID))
  2589. }
  2590. }
  2591. if config.HoldOffFrontingTunnelProbability != nil {
  2592. hash.Write([]byte("HoldOffFrontingTunnelProbability"))
  2593. binary.Write(hash, binary.LittleEndian, *config.HoldOffFrontingTunnelProbability)
  2594. }
  2595. if config.HoldOffDirectTunnelProbability != nil {
  2596. hash.Write([]byte("HoldOffDirectTunnelProbability"))
  2597. binary.Write(hash, binary.LittleEndian, *config.HoldOffDirectTunnelProbability)
  2598. }
  2599. if config.HoldOffDirectTunnelMinDurationMilliseconds != nil {
  2600. hash.Write([]byte("HoldOffDirectTunnelMinDurationMilliseconds"))
  2601. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffDirectTunnelMinDurationMilliseconds))
  2602. }
  2603. if config.HoldOffDirectTunnelMaxDurationMilliseconds != nil {
  2604. hash.Write([]byte("HoldOffDirectTunnelMaxDurationMilliseconds"))
  2605. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffDirectTunnelMaxDurationMilliseconds))
  2606. }
  2607. if len(config.HoldOffDirectTunnelProviderRegions) > 0 {
  2608. hash.Write([]byte("HoldOffDirectTunnelProviderRegions"))
  2609. for providerID, regions := range config.HoldOffDirectTunnelProviderRegions {
  2610. hash.Write([]byte(providerID))
  2611. for _, region := range regions {
  2612. hash.Write([]byte(region))
  2613. }
  2614. }
  2615. }
  2616. if len(config.RestrictDirectProviderRegions) > 0 {
  2617. hash.Write([]byte("RestrictDirectProviderRegions"))
  2618. for providerID, regions := range config.RestrictDirectProviderRegions {
  2619. hash.Write([]byte(providerID))
  2620. for _, region := range regions {
  2621. hash.Write([]byte(region))
  2622. }
  2623. }
  2624. }
  2625. if config.RestrictDirectProviderIDsClientProbability != nil {
  2626. hash.Write([]byte("RestrictDirectProviderIDsClientProbability"))
  2627. binary.Write(hash, binary.LittleEndian, *config.RestrictDirectProviderIDsClientProbability)
  2628. }
  2629. if len(config.RestrictFrontingProviderIDs) > 0 {
  2630. hash.Write([]byte("RestrictFrontingProviderIDs"))
  2631. for _, providerID := range config.RestrictFrontingProviderIDs {
  2632. hash.Write([]byte(providerID))
  2633. }
  2634. }
  2635. if config.RestrictFrontingProviderIDsClientProbability != nil {
  2636. hash.Write([]byte("RestrictFrontingProviderIDsClientProbability"))
  2637. binary.Write(hash, binary.LittleEndian, *config.RestrictFrontingProviderIDsClientProbability)
  2638. }
  2639. if config.HoldOffInproxyTunnelProbability != nil {
  2640. hash.Write([]byte("HoldOffInproxyTunnelProbability"))
  2641. binary.Write(hash, binary.LittleEndian, *config.HoldOffInproxyTunnelProbability)
  2642. }
  2643. if config.HoldOffInproxyTunnelMinDurationMilliseconds != nil {
  2644. hash.Write([]byte("HoldOffInproxyTunnelMinDurationMilliseconds"))
  2645. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffInproxyTunnelMinDurationMilliseconds))
  2646. }
  2647. if config.HoldOffInproxyTunnelMaxDurationMilliseconds != nil {
  2648. hash.Write([]byte("HoldOffInproxyTunnelMaxDurationMilliseconds"))
  2649. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffInproxyTunnelMaxDurationMilliseconds))
  2650. }
  2651. if len(config.HoldOffInproxyTunnelProviderRegions) > 0 {
  2652. hash.Write([]byte("HoldOffInproxyTunnelProviderRegions"))
  2653. for providerID, regions := range config.HoldOffInproxyTunnelProviderRegions {
  2654. hash.Write([]byte(providerID))
  2655. for _, region := range regions {
  2656. hash.Write([]byte(region))
  2657. }
  2658. }
  2659. }
  2660. if len(config.RestrictInproxyProviderRegions) > 0 {
  2661. hash.Write([]byte("RestrictInproxyProviderRegions"))
  2662. for providerID, regions := range config.RestrictInproxyProviderRegions {
  2663. hash.Write([]byte(providerID))
  2664. for _, region := range regions {
  2665. hash.Write([]byte(region))
  2666. }
  2667. }
  2668. }
  2669. if config.RestrictInproxyProviderIDsClientProbability != nil {
  2670. hash.Write([]byte("RestrictInproxyProviderIDsClientProbability"))
  2671. binary.Write(hash, binary.LittleEndian, *config.RestrictInproxyProviderIDsClientProbability)
  2672. }
  2673. if config.UpstreamProxyAllowAllServerEntrySources != nil {
  2674. hash.Write([]byte("UpstreamProxyAllowAllServerEntrySources"))
  2675. binary.Write(hash, binary.LittleEndian, *config.UpstreamProxyAllowAllServerEntrySources)
  2676. }
  2677. if len(config.LimitTunnelDialPortNumbers) > 0 {
  2678. hash.Write([]byte("LimitTunnelDialPortNumbers"))
  2679. encodedLimitTunnelDialPortNumbers, _ :=
  2680. json.Marshal(config.LimitTunnelDialPortNumbers)
  2681. hash.Write(encodedLimitTunnelDialPortNumbers)
  2682. }
  2683. if config.QUICDialEarlyProbability != nil {
  2684. hash.Write([]byte("QUICDialEarlyProbability"))
  2685. binary.Write(hash, binary.LittleEndian, *config.QUICDialEarlyProbability)
  2686. }
  2687. if config.QUICObfuscatedPSKProbability != nil {
  2688. hash.Write([]byte("QUICObfuscatedPSKProbability"))
  2689. binary.Write(hash, binary.LittleEndian, *config.QUICObfuscatedPSKProbability)
  2690. }
  2691. if config.QUICDisablePathMTUDiscoveryProbability != nil {
  2692. hash.Write([]byte("QUICDisablePathMTUDiscoveryProbability"))
  2693. binary.Write(hash, binary.LittleEndian, *config.QUICDisablePathMTUDiscoveryProbability)
  2694. }
  2695. if config.DNSResolverAttemptsPerServer != nil {
  2696. hash.Write([]byte("DNSResolverAttemptsPerServer"))
  2697. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverAttemptsPerServer))
  2698. }
  2699. if config.DNSResolverRequestTimeoutMilliseconds != nil {
  2700. hash.Write([]byte("DNSResolverRequestTimeoutMilliseconds"))
  2701. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverRequestTimeoutMilliseconds))
  2702. }
  2703. if config.DNSResolverAwaitTimeoutMilliseconds != nil {
  2704. hash.Write([]byte("DNSResolverAwaitTimeoutMilliseconds"))
  2705. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverAwaitTimeoutMilliseconds))
  2706. }
  2707. if config.DNSResolverPreresolvedIPAddressCIDRs != nil {
  2708. hash.Write([]byte("DNSResolverPreresolvedIPAddressCIDRs"))
  2709. encodedDNSResolverPreresolvedIPAddressCIDRs, _ :=
  2710. json.Marshal(config.DNSResolverPreresolvedIPAddressCIDRs)
  2711. hash.Write(encodedDNSResolverPreresolvedIPAddressCIDRs)
  2712. }
  2713. if config.DNSResolverPreresolvedIPAddressProbability != nil {
  2714. hash.Write([]byte("DNSResolverPreresolvedIPAddressProbability"))
  2715. binary.Write(hash, binary.LittleEndian, *config.DNSResolverPreresolvedIPAddressProbability)
  2716. }
  2717. if config.DNSResolverAlternateServers != nil {
  2718. hash.Write([]byte("DNSResolverAlternateServers"))
  2719. for _, server := range config.DNSResolverAlternateServers {
  2720. hash.Write([]byte(server))
  2721. }
  2722. }
  2723. if config.DNSResolverPreferAlternateServerProbability != nil {
  2724. hash.Write([]byte("DNSResolverPreferAlternateServerProbability"))
  2725. binary.Write(hash, binary.LittleEndian, *config.DNSResolverPreferAlternateServerProbability)
  2726. }
  2727. if config.DNSResolverProtocolTransformSpecs != nil {
  2728. hash.Write([]byte("DNSResolverProtocolTransformSpecs"))
  2729. encodedDNSResolverProtocolTransformSpecs, _ :=
  2730. json.Marshal(config.DNSResolverProtocolTransformSpecs)
  2731. hash.Write(encodedDNSResolverProtocolTransformSpecs)
  2732. }
  2733. if config.DNSResolverProtocolTransformScopedSpecNames != nil {
  2734. hash.Write([]byte("DNSResolverProtocolTransformScopedSpecNames"))
  2735. encodedDNSResolverProtocolTransformScopedSpecNames, _ :=
  2736. json.Marshal(config.DNSResolverProtocolTransformScopedSpecNames)
  2737. hash.Write(encodedDNSResolverProtocolTransformScopedSpecNames)
  2738. }
  2739. if config.DNSResolverProtocolTransformProbability != nil {
  2740. hash.Write([]byte("DNSResolverProtocolTransformProbability"))
  2741. binary.Write(hash, binary.LittleEndian, *config.DNSResolverProtocolTransformProbability)
  2742. }
  2743. if config.DNSResolverQNameRandomizeCasingProbability != nil {
  2744. hash.Write([]byte("DNSResolverQNameRandomizeCasingProbability"))
  2745. binary.Write(hash, binary.LittleEndian, *config.DNSResolverQNameRandomizeCasingProbability)
  2746. }
  2747. if config.DNSResolverQNameMustMatchProbability != nil {
  2748. hash.Write([]byte("DNSResolverQNameMustMatchProbability"))
  2749. binary.Write(hash, binary.LittleEndian, *config.DNSResolverQNameMustMatchProbability)
  2750. }
  2751. if config.DNSResolverIncludeEDNS0Probability != nil {
  2752. hash.Write([]byte("DNSResolverIncludeEDNS0Probability"))
  2753. binary.Write(hash, binary.LittleEndian, *config.DNSResolverIncludeEDNS0Probability)
  2754. }
  2755. if config.DNSResolverCacheExtensionInitialTTLMilliseconds != nil {
  2756. hash.Write([]byte("DNSResolverCacheExtensionInitialTTLMilliseconds"))
  2757. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverCacheExtensionInitialTTLMilliseconds))
  2758. }
  2759. if config.DNSResolverCacheExtensionVerifiedTTLMilliseconds != nil {
  2760. hash.Write([]byte("DNSResolverCacheExtensionVerifiedTTLMilliseconds"))
  2761. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverCacheExtensionVerifiedTTLMilliseconds))
  2762. }
  2763. if config.DirectHTTPProtocolTransformSpecs != nil {
  2764. hash.Write([]byte("DirectHTTPProtocolTransformSpecs"))
  2765. encodedDirectHTTPProtocolTransformSpecs, _ :=
  2766. json.Marshal(config.DirectHTTPProtocolTransformSpecs)
  2767. hash.Write(encodedDirectHTTPProtocolTransformSpecs)
  2768. }
  2769. if config.DirectHTTPProtocolTransformScopedSpecNames != nil {
  2770. hash.Write([]byte("DirectHTTPProtocolTransformScopedSpecNames"))
  2771. encodedDirectHTTPProtocolTransformScopedSpecNames, _ :=
  2772. json.Marshal(config.DirectHTTPProtocolTransformScopedSpecNames)
  2773. hash.Write(encodedDirectHTTPProtocolTransformScopedSpecNames)
  2774. }
  2775. if config.DirectHTTPProtocolTransformProbability != nil {
  2776. hash.Write([]byte("DirectHTTPProtocolTransformProbability"))
  2777. binary.Write(hash, binary.LittleEndian, *config.DirectHTTPProtocolTransformProbability)
  2778. }
  2779. if config.FrontedHTTPProtocolTransformSpecs != nil {
  2780. hash.Write([]byte("FrontedHTTPProtocolTransformSpecs"))
  2781. encodedFrontedHTTPProtocolTransformSpecs, _ :=
  2782. json.Marshal(config.FrontedHTTPProtocolTransformSpecs)
  2783. hash.Write(encodedFrontedHTTPProtocolTransformSpecs)
  2784. }
  2785. if config.FrontedHTTPProtocolTransformScopedSpecNames != nil {
  2786. hash.Write([]byte("FrontedHTTPProtocolTransformScopedSpecNames"))
  2787. encodedFrontedHTTPProtocolTransformScopedSpecNames, _ :=
  2788. json.Marshal(config.FrontedHTTPProtocolTransformScopedSpecNames)
  2789. hash.Write(encodedFrontedHTTPProtocolTransformScopedSpecNames)
  2790. }
  2791. if config.FrontedHTTPProtocolTransformProbability != nil {
  2792. hash.Write([]byte("FrontedHTTPProtocolTransformProbability"))
  2793. binary.Write(hash, binary.LittleEndian, *config.FrontedHTTPProtocolTransformProbability)
  2794. }
  2795. if config.OSSHObfuscatorSeedTransformSpecs != nil {
  2796. hash.Write([]byte("OSSHObfuscatorSeedTransformSpecs"))
  2797. encodedOSSHObfuscatorSeedTransformSpecs, _ :=
  2798. json.Marshal(config.OSSHObfuscatorSeedTransformSpecs)
  2799. hash.Write(encodedOSSHObfuscatorSeedTransformSpecs)
  2800. }
  2801. if config.OSSHObfuscatorSeedTransformScopedSpecNames != nil {
  2802. hash.Write([]byte("OSSHObfuscatorSeedTransformScopedSpecNames"))
  2803. encodedOSSHObfuscatorSeedTransformScopedSpecNames, _ :=
  2804. json.Marshal(config.OSSHObfuscatorSeedTransformScopedSpecNames)
  2805. hash.Write(encodedOSSHObfuscatorSeedTransformScopedSpecNames)
  2806. }
  2807. if config.OSSHObfuscatorSeedTransformProbability != nil {
  2808. hash.Write([]byte("OSSHObfuscatorSeedTransformProbability"))
  2809. binary.Write(hash, binary.LittleEndian, *config.OSSHObfuscatorSeedTransformProbability)
  2810. }
  2811. if config.ObfuscatedQUICNonceTransformSpecs != nil {
  2812. hash.Write([]byte("ObfuscatedQUICNonceTransformSpecs"))
  2813. encodedObfuscatedQUICNonceTransformSpecs, _ :=
  2814. json.Marshal(config.ObfuscatedQUICNonceTransformSpecs)
  2815. hash.Write(encodedObfuscatedQUICNonceTransformSpecs)
  2816. }
  2817. if config.ObfuscatedQUICNonceTransformScopedSpecNames != nil {
  2818. hash.Write([]byte("ObfuscatedQUICNonceTransformScopedSpecNames"))
  2819. encodedObfuscatedQUICNonceTransformScopedSpecNames, _ :=
  2820. json.Marshal(config.ObfuscatedQUICNonceTransformScopedSpecNames)
  2821. hash.Write(encodedObfuscatedQUICNonceTransformScopedSpecNames)
  2822. }
  2823. if config.ObfuscatedQUICNonceTransformProbability != nil {
  2824. hash.Write([]byte("ObfuscatedQUICNonceTransformProbability"))
  2825. binary.Write(hash, binary.LittleEndian, *config.ObfuscatedQUICNonceTransformProbability)
  2826. }
  2827. if config.OSSHPrefixSpecs != nil {
  2828. hash.Write([]byte("OSSHPrefixSpecs"))
  2829. encodedOSSHPrefixSpecs, _ := json.Marshal(config.OSSHPrefixSpecs)
  2830. hash.Write(encodedOSSHPrefixSpecs)
  2831. }
  2832. if config.OSSHPrefixScopedSpecNames != nil {
  2833. hash.Write([]byte("OSSHPrefixScopedSpecNames"))
  2834. encodedOSSHPrefixScopedSpecNames, _ := json.Marshal(config.OSSHPrefixScopedSpecNames)
  2835. hash.Write(encodedOSSHPrefixScopedSpecNames)
  2836. }
  2837. if config.OSSHPrefixProbability != nil {
  2838. hash.Write([]byte("OSSHPrefixProbability"))
  2839. binary.Write(hash, binary.LittleEndian, *config.OSSHPrefixProbability)
  2840. }
  2841. if config.OSSHPrefixSplitMinDelayMilliseconds != nil {
  2842. hash.Write([]byte("OSSHPrefixSplitMinDelayMilliseconds"))
  2843. binary.Write(hash, binary.LittleEndian, int64(*config.OSSHPrefixSplitMinDelayMilliseconds))
  2844. }
  2845. if config.OSSHPrefixSplitMaxDelayMilliseconds != nil {
  2846. hash.Write([]byte("OSSHPrefixSplitMaxDelayMilliseconds"))
  2847. binary.Write(hash, binary.LittleEndian, int64(*config.OSSHPrefixSplitMaxDelayMilliseconds))
  2848. }
  2849. if config.OSSHPrefixEnableFragmentor != nil {
  2850. hash.Write([]byte("OSSHPrefixEnableFragmentor"))
  2851. binary.Write(hash, binary.LittleEndian, *config.OSSHPrefixEnableFragmentor)
  2852. }
  2853. if config.ShadowsocksPrefixSpecs != nil {
  2854. hash.Write([]byte("ShadowsocksPrefixSpecs"))
  2855. encodedShadowsocksPrefixSpecs, _ := json.Marshal(config.ShadowsocksPrefixSpecs)
  2856. hash.Write(encodedShadowsocksPrefixSpecs)
  2857. }
  2858. if config.ShadowsocksPrefixScopedSpecNames != nil {
  2859. hash.Write([]byte("ShadowsocksPrefixScopedSpecNames"))
  2860. encodedShadowsocksPrefixScopedSpecNames, _ := json.Marshal(config.ShadowsocksPrefixScopedSpecNames)
  2861. hash.Write(encodedShadowsocksPrefixScopedSpecNames)
  2862. }
  2863. if config.ShadowsocksPrefixProbability != nil {
  2864. hash.Write([]byte("ShadowsocksPrefixProbability"))
  2865. binary.Write(hash, binary.LittleEndian, *config.ShadowsocksPrefixProbability)
  2866. }
  2867. if config.TLSTunnelObfuscatedPSKProbability != nil {
  2868. hash.Write([]byte("TLSTunnelObfuscatedPSKProbability"))
  2869. binary.Write(hash, binary.LittleEndian, *config.TLSTunnelObfuscatedPSKProbability)
  2870. }
  2871. if config.TLSTunnelTrafficShapingProbability != nil {
  2872. hash.Write([]byte("TLSTunnelTrafficShapingProbability"))
  2873. binary.Write(hash, binary.LittleEndian, *config.TLSTunnelTrafficShapingProbability)
  2874. }
  2875. if config.TLSTunnelMinTLSPadding != nil {
  2876. hash.Write([]byte("TLSTunnelMinTLSPadding"))
  2877. binary.Write(hash, binary.LittleEndian, int64(*config.TLSTunnelMinTLSPadding))
  2878. }
  2879. if config.TLSTunnelMaxTLSPadding != nil {
  2880. hash.Write([]byte("TLSTunnelMaxTLSPadding"))
  2881. binary.Write(hash, binary.LittleEndian, int64(*config.TLSTunnelMaxTLSPadding))
  2882. }
  2883. if config.TLSFragmentClientHelloProbability != nil {
  2884. hash.Write([]byte("TLSFragmentClientHelloProbability"))
  2885. binary.Write(hash, binary.LittleEndian, *config.TLSFragmentClientHelloProbability)
  2886. }
  2887. if len(config.TLSFragmentClientHelloLimitProtocols) > 0 {
  2888. hash.Write([]byte("TLSFragmentClientHelloLimitProtocols"))
  2889. for _, protocol := range config.TLSFragmentClientHelloLimitProtocols {
  2890. hash.Write([]byte(protocol))
  2891. }
  2892. }
  2893. // Steering IPs are ephemeral and not replayed, so steering IP parameters
  2894. // are excluded here.
  2895. if config.InproxyTunnelProtocolSelectionProbability != nil {
  2896. hash.Write([]byte("InproxyTunnelProtocolSelectionProbability"))
  2897. binary.Write(hash, binary.LittleEndian, *config.InproxyTunnelProtocolSelectionProbability)
  2898. }
  2899. if len(config.InproxyBrokerSpecs) > 0 {
  2900. hash.Write([]byte("InproxyBrokerSpecs"))
  2901. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyBrokerSpecs)))
  2902. }
  2903. if len(config.InproxyPersonalPairingBrokerSpecs) > 0 {
  2904. hash.Write([]byte("InproxyPersonalPairingBrokerSpecs"))
  2905. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyPersonalPairingBrokerSpecs)))
  2906. }
  2907. if len(config.InproxyProxyBrokerSpecs) > 0 {
  2908. hash.Write([]byte("InproxyProxyBrokerSpecs"))
  2909. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxyBrokerSpecs)))
  2910. }
  2911. if len(config.InproxyProxyPersonalPairingBrokerSpecs) > 0 {
  2912. hash.Write([]byte("InproxyProxyPersonalPairingBrokerSpecs"))
  2913. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxyPersonalPairingBrokerSpecs)))
  2914. }
  2915. if len(config.InproxyClientBrokerSpecs) > 0 {
  2916. hash.Write([]byte("InproxyClientBrokerSpecs"))
  2917. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyClientBrokerSpecs)))
  2918. }
  2919. if len(config.InproxyClientPersonalPairingBrokerSpecs) > 0 {
  2920. hash.Write([]byte("InproxyClientPersonalPairingBrokerSpecs"))
  2921. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyClientPersonalPairingBrokerSpecs)))
  2922. }
  2923. if config.InproxyReplayBrokerDialParametersTTLSeconds != nil {
  2924. hash.Write([]byte("InproxyReplayBrokerDialParametersTTLSeconds"))
  2925. binary.Write(hash, binary.LittleEndian, int64(*config.InproxyReplayBrokerDialParametersTTLSeconds))
  2926. }
  2927. if config.InproxyReplayBrokerUpdateFrequencySeconds != nil {
  2928. hash.Write([]byte("InproxyReplayBrokerUpdateFrequencySeconds"))
  2929. binary.Write(hash, binary.LittleEndian, int64(*config.InproxyReplayBrokerUpdateFrequencySeconds))
  2930. }
  2931. if config.InproxyReplayBrokerDialParametersProbability != nil {
  2932. hash.Write([]byte("InproxyReplayBrokerDialParametersProbability"))
  2933. binary.Write(hash, binary.LittleEndian, *config.InproxyReplayBrokerDialParametersProbability)
  2934. }
  2935. if config.InproxyReplayBrokerRetainFailedProbability != nil {
  2936. hash.Write([]byte("InproxyReplayBrokerRetainFailedProbability"))
  2937. binary.Write(hash, binary.LittleEndian, *config.InproxyReplayBrokerRetainFailedProbability)
  2938. }
  2939. if len(config.InproxyCommonCompartmentIDs) > 0 {
  2940. hash.Write([]byte("InproxyCommonCompartmentIDs"))
  2941. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyCommonCompartmentIDs)))
  2942. }
  2943. if config.InproxyMaxCompartmentIDListLength != nil {
  2944. hash.Write([]byte("InproxyMaxCompartmentIDListLength"))
  2945. binary.Write(hash, binary.LittleEndian, int64(*config.InproxyMaxCompartmentIDListLength))
  2946. }
  2947. if config.InproxyDTLSRandomizationProbability != nil {
  2948. hash.Write([]byte("InproxyDTLSRandomizationProbability"))
  2949. binary.Write(hash, binary.LittleEndian, *config.InproxyDTLSRandomizationProbability)
  2950. }
  2951. if config.InproxyWebRTCMediaStreamsProbability != nil {
  2952. hash.Write([]byte("InproxyWebRTCMediaStreamsProbability"))
  2953. binary.Write(hash, binary.LittleEndian, *config.InproxyWebRTCMediaStreamsProbability)
  2954. }
  2955. if config.InproxyWebRTCDataChannelTrafficShapingProbability != nil {
  2956. hash.Write([]byte("InproxyWebRTCDataChannelTrafficShapingProbability"))
  2957. binary.Write(hash, binary.LittleEndian, *config.InproxyWebRTCDataChannelTrafficShapingProbability)
  2958. }
  2959. if config.InproxyWebRTCDataChannelTrafficShapingParameters != nil {
  2960. hash.Write([]byte("InproxyWebRTCDataChannelTrafficShapingParameters"))
  2961. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyWebRTCDataChannelTrafficShapingParameters)))
  2962. }
  2963. if config.InproxyWebRTCMediaStreamsTrafficShapingProbability != nil {
  2964. hash.Write([]byte("InproxyWebRTCMediaStreamsTrafficShapingProbability"))
  2965. binary.Write(hash, binary.LittleEndian, *config.InproxyWebRTCMediaStreamsTrafficShapingProbability)
  2966. }
  2967. if config.InproxyWebRTCMediaStreamsTrafficShapingParameters != nil {
  2968. hash.Write([]byte("InproxyWebRTCMediaStreamsTrafficShapingParameters"))
  2969. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyWebRTCMediaStreamsTrafficShapingParameters)))
  2970. }
  2971. if config.InproxySTUNServerAddresses != nil {
  2972. hash.Write([]byte("InproxySTUNServerAddresses"))
  2973. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxySTUNServerAddresses)))
  2974. }
  2975. if config.InproxySTUNServerAddressesRFC5780 != nil {
  2976. hash.Write([]byte("InproxySTUNServerAddressesRFC5780"))
  2977. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxySTUNServerAddressesRFC5780)))
  2978. }
  2979. if config.InproxyProxySTUNServerAddresses != nil {
  2980. hash.Write([]byte("InproxyProxySTUNServerAddresses"))
  2981. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxySTUNServerAddresses)))
  2982. }
  2983. if config.InproxyProxySTUNServerAddressesRFC5780 != nil {
  2984. hash.Write([]byte("InproxyProxySTUNServerAddressesRFC5780"))
  2985. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyProxySTUNServerAddressesRFC5780)))
  2986. }
  2987. if config.InproxyClientSTUNServerAddresses != nil {
  2988. hash.Write([]byte("InproxyClientSTUNServerAddresses"))
  2989. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyClientSTUNServerAddresses)))
  2990. }
  2991. if config.InproxyClientSTUNServerAddressesRFC5780 != nil {
  2992. hash.Write([]byte("InproxyClientSTUNServerAddressesRFC5780"))
  2993. hash.Write([]byte(fmt.Sprintf("%+v", config.InproxyClientSTUNServerAddressesRFC5780)))
  2994. }
  2995. if config.InproxyClientDiscoverNATProbability != nil {
  2996. hash.Write([]byte("InproxyClientDiscoverNATProbability"))
  2997. binary.Write(hash, binary.LittleEndian, *config.InproxyClientDiscoverNATProbability)
  2998. }
  2999. if config.InproxyDisableSTUN != nil {
  3000. hash.Write([]byte("InproxyDisableSTUN"))
  3001. binary.Write(hash, binary.LittleEndian, *config.InproxyDisableSTUN)
  3002. }
  3003. if config.InproxyDisablePortMapping != nil {
  3004. hash.Write([]byte("InproxyDisablePortMapping"))
  3005. binary.Write(hash, binary.LittleEndian, *config.InproxyDisablePortMapping)
  3006. }
  3007. if config.InproxyDisableInboundForMobileNetworks != nil {
  3008. hash.Write([]byte("InproxyDisableInboundForMobileNetworks"))
  3009. binary.Write(hash, binary.LittleEndian, *config.InproxyDisableInboundForMobileNetworks)
  3010. }
  3011. if config.InproxyDisableIPv6ICECandidates != nil {
  3012. hash.Write([]byte("InproxyDisableIPv6ICECandidates"))
  3013. binary.Write(hash, binary.LittleEndian, *config.InproxyDisableIPv6ICECandidates)
  3014. }
  3015. if config.InproxyProxyDisableSTUN != nil {
  3016. hash.Write([]byte("InproxyProxyDisableSTUN"))
  3017. binary.Write(hash, binary.LittleEndian, *config.InproxyProxyDisableSTUN)
  3018. }
  3019. if config.InproxyProxyDisablePortMapping != nil {
  3020. hash.Write([]byte("InproxyProxyDisablePortMapping"))
  3021. binary.Write(hash, binary.LittleEndian, *config.InproxyProxyDisablePortMapping)
  3022. }
  3023. if config.InproxyProxyDisableInboundForMobileNetworks != nil {
  3024. hash.Write([]byte("InproxyProxyDisableInboundForMobileNetworks"))
  3025. binary.Write(hash, binary.LittleEndian, *config.InproxyProxyDisableInboundForMobileNetworks)
  3026. }
  3027. if config.InproxyProxyDisableIPv6ICECandidates != nil {
  3028. hash.Write([]byte("InproxyProxyDisableIPv6ICECandidates"))
  3029. binary.Write(hash, binary.LittleEndian, *config.InproxyProxyDisableIPv6ICECandidates)
  3030. }
  3031. if config.InproxyClientDisableSTUN != nil {
  3032. hash.Write([]byte("InproxyClientDisableSTUN"))
  3033. binary.Write(hash, binary.LittleEndian, *config.InproxyClientDisableSTUN)
  3034. }
  3035. if config.InproxyClientDisablePortMapping != nil {
  3036. hash.Write([]byte("InproxyClientDisablePortMapping"))
  3037. binary.Write(hash, binary.LittleEndian, *config.InproxyClientDisablePortMapping)
  3038. }
  3039. if config.InproxyClientDisableInboundForMobileNetworks != nil {
  3040. hash.Write([]byte("InproxyClientDisableInboundForMobileNetworks"))
  3041. binary.Write(hash, binary.LittleEndian, *config.InproxyClientDisableInboundForMobileNetworks)
  3042. }
  3043. if config.InproxyClientDisableIPv6ICECandidates != nil {
  3044. hash.Write([]byte("InproxyClientDisableIPv6ICECandidates"))
  3045. binary.Write(hash, binary.LittleEndian, *config.InproxyClientDisableIPv6ICECandidates)
  3046. }
  3047. config.dialParametersHash = hash.Sum(nil)
  3048. }
  3049. // applyAdditionalParameters decodes and applies any additional parameters
  3050. // stored in config.AdditionalParameter to the Config and returns an array
  3051. // of notices which should be logged at the info level. If there is no error,
  3052. // then config.AdditionalParameter is set to "" to conserve memory and further
  3053. // calls will do nothing. This function should only be called once.
  3054. //
  3055. // If there is an error, the existing Config is left entirely unmodified.
  3056. func (config *Config) applyAdditionalParameters() ([]string, error) {
  3057. if config.AdditionalParameters == "" {
  3058. return nil, nil
  3059. }
  3060. b, err := base64.StdEncoding.DecodeString(config.AdditionalParameters)
  3061. if err != nil {
  3062. return nil, errors.Trace(err)
  3063. }
  3064. if len(b) < 32 {
  3065. return nil, errors.Tracef("invalid length, len(b) == %d", len(b))
  3066. }
  3067. var key [32]byte
  3068. copy(key[:], b[:32])
  3069. decrypted, ok := secretbox.Open(nil, b[32:], &[24]byte{}, &key)
  3070. if !ok {
  3071. return nil, errors.TraceNew("secretbox.Open failed")
  3072. }
  3073. var additionalParameters Config
  3074. err = json.Unmarshal(decrypted, &additionalParameters)
  3075. if err != nil {
  3076. return nil, errors.Trace(err)
  3077. }
  3078. src := reflect.ValueOf(&additionalParameters).Elem()
  3079. dest := reflect.ValueOf(config).Elem()
  3080. var infoNotices []string
  3081. for i := 0; i < src.NumField(); i++ {
  3082. if !src.Field(i).IsZero() {
  3083. dest.Field(i).Set(src.Field(i))
  3084. infoNotice := fmt.Sprintf("%s overridden by AdditionalParameters", dest.Type().Field(i).Name)
  3085. infoNotices = append(infoNotices, infoNotice)
  3086. }
  3087. }
  3088. // Reset field to conserve memory since this is a one-time operation.
  3089. config.AdditionalParameters = ""
  3090. return infoNotices, nil
  3091. }
  3092. func promoteLegacyTransferURL(URL string) parameters.TransferURLs {
  3093. transferURLs := make(parameters.TransferURLs, 1)
  3094. transferURLs[0] = &parameters.TransferURL{
  3095. URL: base64.StdEncoding.EncodeToString([]byte(URL)),
  3096. SkipVerify: false,
  3097. OnlyAfterAttempts: 0,
  3098. }
  3099. return transferURLs
  3100. }
  3101. type loggingDeviceBinder struct {
  3102. d DeviceBinder
  3103. }
  3104. func newLoggingDeviceBinder(d DeviceBinder) *loggingDeviceBinder {
  3105. return &loggingDeviceBinder{d: d}
  3106. }
  3107. func (d *loggingDeviceBinder) BindToDevice(fileDescriptor int) (string, error) {
  3108. deviceInfo, err := d.d.BindToDevice(fileDescriptor)
  3109. if err == nil && deviceInfo != "" {
  3110. NoticeBindToDevice(deviceInfo)
  3111. }
  3112. return deviceInfo, err
  3113. }
  3114. const unknownNetworkID = "UNKNOWN"
  3115. type staticNetworkIDGetter struct {
  3116. networkID string
  3117. }
  3118. func newStaticNetworkIDGetter(networkID string) *staticNetworkIDGetter {
  3119. return &staticNetworkIDGetter{networkID: networkID}
  3120. }
  3121. func (n *staticNetworkIDGetter) GetNetworkID() string {
  3122. return n.networkID
  3123. }
  3124. type commonNetworkIDGetter struct {
  3125. }
  3126. func newCommonNetworkIDGetter() *commonNetworkIDGetter {
  3127. return &commonNetworkIDGetter{}
  3128. }
  3129. func (n *commonNetworkIDGetter) GetNetworkID() string {
  3130. networkID, err := networkid.Get()
  3131. if err != nil {
  3132. NoticeError("networkid.Get failed: %v", errors.Trace(err))
  3133. return unknownNetworkID
  3134. }
  3135. return networkID
  3136. }
  3137. type loggingNetworkIDGetter struct {
  3138. n NetworkIDGetter
  3139. }
  3140. func newLoggingNetworkIDGetter(n NetworkIDGetter) *loggingNetworkIDGetter {
  3141. return &loggingNetworkIDGetter{n: n}
  3142. }
  3143. func (n *loggingNetworkIDGetter) GetNetworkID() string {
  3144. networkID := n.n.GetNetworkID()
  3145. // All PII must appear after the initial "-"
  3146. // See: https://godoc.org/github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon#NetworkIDGetter
  3147. logNetworkID := networkID
  3148. index := strings.Index(logNetworkID, "-")
  3149. if index != -1 {
  3150. logNetworkID = logNetworkID[:index]
  3151. }
  3152. if len(logNetworkID)+1 < len(networkID) {
  3153. // Indicate when additional network info was present after the first "-".
  3154. logNetworkID += "+[redacted]"
  3155. }
  3156. NoticeNetworkID(logNetworkID)
  3157. return networkID
  3158. }
  3159. // cachingNetworkIDGetter caches the GetNetworkID result from the underlying
  3160. // network ID getter. The current GetNetworkID implementations take in the
  3161. // range of 1-7ms (Android); 2-3ms (iOS); ~3.5ms (Windows) to execute, on
  3162. // modern devices. To minimize delaying dials and other operations that start
  3163. // with fetching the current network ID, the return values are cached for a
  3164. // short time. On platforms that invoke NetworkChanged, the cache is flushed
  3165. // immediately upon a network change.
  3166. type cachingNetworkIDGetter struct {
  3167. config *Config
  3168. n NetworkIDGetter
  3169. mutex sync.Mutex
  3170. cachedNetworkID string
  3171. cacheExpiry time.Time
  3172. }
  3173. func newCachingNetworkIDGetter(
  3174. config *Config, n NetworkIDGetter) *cachingNetworkIDGetter {
  3175. return &cachingNetworkIDGetter{
  3176. config: config,
  3177. n: n,
  3178. }
  3179. }
  3180. func (n *cachingNetworkIDGetter) GetNetworkID() string {
  3181. n.mutex.Lock()
  3182. defer n.mutex.Unlock()
  3183. if n.cachedNetworkID != "" && n.cacheExpiry.After(time.Now()) {
  3184. return n.cachedNetworkID
  3185. }
  3186. networkID := n.n.GetNetworkID()
  3187. p := n.config.GetParameters().Get()
  3188. ttl := p.Duration(parameters.NetworkIDCacheTTL)
  3189. if ttl > 0 {
  3190. n.cachedNetworkID = networkID
  3191. n.cacheExpiry = time.Now().Add(ttl)
  3192. }
  3193. return networkID
  3194. }
  3195. func (n *cachingNetworkIDGetter) FlushCache() {
  3196. n.mutex.Lock()
  3197. defer n.mutex.Unlock()
  3198. n.cachedNetworkID = ""
  3199. n.cacheExpiry = time.Time{}
  3200. }
  3201. // migrationsFromLegacyNoticeFilePaths returns the file migrations which must be
  3202. // performed to move notice files from legacy file paths, which were configured
  3203. // with the legacy config fields HomepageNoticesFilename and
  3204. // RotatingNoticesFilename, to the new file paths used by Psiphon which exist
  3205. // under the data root directory.
  3206. func migrationsFromLegacyNoticeFilePaths(config *Config) []FileMigration {
  3207. var noticeMigrations []FileMigration
  3208. if config.MigrateHomepageNoticesFilename != "" {
  3209. noticeMigrations = append(noticeMigrations, FileMigration{
  3210. Name: "hompage",
  3211. OldPath: config.MigrateHomepageNoticesFilename,
  3212. NewPath: config.GetHomePageFilename(),
  3213. })
  3214. }
  3215. if config.MigrateRotatingNoticesFilename != "" {
  3216. migrations := []FileMigration{
  3217. {
  3218. Name: "notices",
  3219. OldPath: config.MigrateRotatingNoticesFilename,
  3220. NewPath: config.GetNoticesFilename(),
  3221. IsDir: false,
  3222. },
  3223. {
  3224. Name: "notices.1",
  3225. OldPath: config.MigrateRotatingNoticesFilename + ".1",
  3226. NewPath: config.GetNoticesFilename() + ".1",
  3227. },
  3228. }
  3229. noticeMigrations = append(noticeMigrations, migrations...)
  3230. }
  3231. return noticeMigrations
  3232. }
  3233. // migrationsFromLegacyFilePaths returns the file migrations which must be
  3234. // performed to move files from legacy file paths, which were configured with
  3235. // legacy config fields, to the new file paths used by Psiphon which exist
  3236. // under the data root directory.
  3237. // Note: an attempt is made to redact any file paths from the returned error.
  3238. func migrationsFromLegacyFilePaths(config *Config) ([]FileMigration, error) {
  3239. migrations := []FileMigration{
  3240. {
  3241. Name: "psiphon.boltdb",
  3242. OldPath: filepath.Join(config.MigrateDataStoreDirectory, "psiphon.boltdb"),
  3243. NewPath: filepath.Join(config.GetDataStoreDirectory(), "psiphon.boltdb"),
  3244. },
  3245. {
  3246. Name: "psiphon.boltdb.lock",
  3247. OldPath: filepath.Join(config.MigrateDataStoreDirectory, "psiphon.boltdb.lock"),
  3248. NewPath: filepath.Join(config.GetDataStoreDirectory(), "psiphon.boltdb.lock"),
  3249. },
  3250. }
  3251. if config.MigrateRemoteServerListDownloadFilename != "" {
  3252. // Migrate remote server list files
  3253. rslMigrations := []FileMigration{
  3254. {
  3255. Name: "remote_server_list",
  3256. OldPath: config.MigrateRemoteServerListDownloadFilename,
  3257. NewPath: config.GetRemoteServerListDownloadFilename(),
  3258. },
  3259. {
  3260. Name: "remote_server_list.part",
  3261. OldPath: config.MigrateRemoteServerListDownloadFilename + ".part",
  3262. NewPath: config.GetRemoteServerListDownloadFilename() + ".part",
  3263. },
  3264. {
  3265. Name: "remote_server_list.part.etag",
  3266. OldPath: config.MigrateRemoteServerListDownloadFilename + ".part.etag",
  3267. NewPath: config.GetRemoteServerListDownloadFilename() + ".part.etag",
  3268. },
  3269. }
  3270. migrations = append(migrations, rslMigrations...)
  3271. }
  3272. if config.MigrateObfuscatedServerListDownloadDirectory != "" {
  3273. // Migrate OSL registry file and downloads
  3274. oslFileRegex, err := regexp.Compile(`^osl-.+$`)
  3275. if err != nil {
  3276. return nil, errors.TraceMsg(err, "failed to compile regex for osl files")
  3277. }
  3278. files, err := ioutil.ReadDir(config.MigrateObfuscatedServerListDownloadDirectory)
  3279. if err != nil {
  3280. NoticeWarning(
  3281. "Migration: failed to read OSL download directory with error %s",
  3282. common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory))
  3283. } else {
  3284. for _, file := range files {
  3285. if oslFileRegex.MatchString(file.Name()) {
  3286. fileMigration := FileMigration{
  3287. Name: "osl",
  3288. OldPath: filepath.Join(config.MigrateObfuscatedServerListDownloadDirectory, file.Name()),
  3289. NewPath: filepath.Join(config.GetObfuscatedServerListDownloadDirectory(), file.Name()),
  3290. }
  3291. migrations = append(migrations, fileMigration)
  3292. }
  3293. }
  3294. }
  3295. }
  3296. if config.MigrateUpgradeDownloadFilename != "" {
  3297. // Migrate downloaded upgrade files
  3298. oldUpgradeDownloadFilename := filepath.Base(config.MigrateUpgradeDownloadFilename)
  3299. // Create regex for:
  3300. // <old_upgrade_download_filename>
  3301. // <old_upgrade_download_filename>.<client_version_number>
  3302. // <old_upgrade_download_filename>.<client_version_number>.part
  3303. // <old_upgrade_download_filename>.<client_version_number>.part.etag
  3304. upgradeDownloadFileRegex, err := regexp.Compile(`^` + oldUpgradeDownloadFilename + `(\.\d+(\.part(\.etag)?)?)?$`)
  3305. if err != nil {
  3306. return nil, errors.TraceMsg(err, "failed to compile regex for upgrade files")
  3307. }
  3308. upgradeDownloadDir := filepath.Dir(config.MigrateUpgradeDownloadFilename)
  3309. files, err := ioutil.ReadDir(upgradeDownloadDir)
  3310. if err != nil {
  3311. NoticeWarning(
  3312. "Migration: failed to read upgrade download directory with error %s",
  3313. common.RedactFilePathsError(err, upgradeDownloadDir))
  3314. } else {
  3315. for _, file := range files {
  3316. if upgradeDownloadFileRegex.MatchString(file.Name()) {
  3317. oldFileSuffix := strings.TrimPrefix(file.Name(), oldUpgradeDownloadFilename)
  3318. fileMigration := FileMigration{
  3319. Name: "upgrade",
  3320. OldPath: filepath.Join(upgradeDownloadDir, file.Name()),
  3321. NewPath: config.GetUpgradeDownloadFilename() + oldFileSuffix,
  3322. }
  3323. migrations = append(migrations, fileMigration)
  3324. }
  3325. }
  3326. }
  3327. }
  3328. return migrations, nil
  3329. }