config.go 138 KB

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