@@ -840,8 +840,12 @@ type WsWgConfig struct {
840840 Servers []WsServerList `json:"servers"` // all servers in the server list
841841 Creds * WsWgCreds `json:"creds"` // base64 encoded private key
842842 PermaCreds * WsWgPermanentConfig `json:"permacreds,omitempty"` // permanent WG config; nil if not yet fetched
843+ LastUpdate time.Time
843844}
844845
846+ // wsUpdateThreshold is the minimum interval between session calls when ops.ForceInit() is false.
847+ const wsUpdateThreshold = 40 * time .Minute
848+
845849/*
846850{
847851"kind": "ws#v1",
@@ -1083,7 +1087,7 @@ func (a *WsClient) Update(ops *x.RpnOps) (newstate []byte, err error) {
10831087 ops = a .Ops ()
10841088 }
10851089 start := time .Now ()
1086- b , refreshed , err := makeWsWgFrom (a .http , c , * ops , true /*updating*/ )
1090+ b , refreshed , needsRedo , err := makeWsWgFrom (a .http , c , * ops , true /*updating*/ )
10871091 if err != nil || ! refreshed {
10881092 log .E ("ws: update: refreshed? %t; err: %v" , refreshed , err )
10891093 return nil , core .OneErr (err , errWsRetryUpdate )
@@ -1094,7 +1098,11 @@ func (a *WsClient) Update(ops *x.RpnOps) (newstate []byte, err error) {
10941098 if _ , err := a .shallowCopyConfig (b ); err != nil {
10951099 return nil , log .EE ("ws: update: shallow copy err: %v" , err )
10961100 }
1097- log .I ("ws: update: refreshed? %t; took %v" , refreshed , core .FmtTimeAsPeriod (start ))
1101+ log .I ("ws: update: refreshed? %t / redo? %t; took %v" , refreshed , needsRedo , core .FmtTimeAsPeriod (start ))
1102+ if ! needsRedo {
1103+ return nil , nil
1104+ }
1105+
10981106 return a .State ()
10991107}
11001108
@@ -2090,11 +2098,11 @@ func (w *BaseClient) MakeWsWgFrom(entitlementOrWsConfigJson []byte, did string,
20902098}
20912099
20922100func (w * BaseClient ) makeWsWgFrom (existingConf * WsWgConfig , ops x.RpnOps ) (* WsClient , error ) {
2093- ws , _ , err := makeWsWgFrom (& w .h2 , existingConf , ops , false /*not updating*/ )
2101+ ws , _ , _ , err := makeWsWgFrom (& w .h2 , existingConf , ops , false /*not updating*/ )
20942102 return ws , err
20952103}
20962104
2097- func makeWsWgFrom (h * http.Client , existingConf * WsWgConfig , ops x.RpnOps , updating bool ) (ws * WsClient , refreshedSess bool , err error ) {
2105+ func makeWsWgFrom (h * http.Client , existingConf * WsWgConfig , ops x.RpnOps , updating bool ) (ws * WsClient , refreshedSess , needsRedo bool , err error ) {
20982106 existingEnt := existingConf .Entitlement
20992107 if existingEnt == nil || len (existingEnt .SessionToken ) <= 0 {
21002108 err = errWsNoEntitlement
@@ -2124,19 +2132,36 @@ func makeWsWgFrom(h *http.Client, existingConf *WsWgConfig, ops x.RpnOps, updati
21242132 }
21252133
21262134 usingExitingSess := false
2127- newSess , err := getSession (h , existingEnt )
2128- if err == nil {
2129- existingConf .Session = newSess // update session with the latest info
2130- refreshedSess = true
2131- } else {
2135+
2136+ var newSess * WsSession
2137+ skipSess := ! ops .ForceInit () &&
2138+ ! existingConf .LastUpdate .IsZero () &&
2139+ time .Since (existingConf .LastUpdate ) < wsUpdateThreshold
2140+
2141+ if skipSess {
2142+ if settings .Debug {
2143+ log .D ("ws: make: using existing session (from: %s); tok? %s" , fmtTime (existingConf .LastUpdate ), tokst )
2144+ }
2145+ newSess = existingConf .Session
21322146 usingExitingSess = true
2133- log .W ("ws: make: get session err: %v; using existing; tok? %s" , err , tokst )
2134- newSess = existingConf .Session // use existing session
2147+ refreshedSess = true // treated as refreshed even though we skipped the network call
2148+ } else {
2149+ var sessErr error
2150+ newSess , sessErr = getSession (h , existingEnt )
2151+ if sessErr == nil {
2152+ existingConf .Session = newSess // update session with the latest info
2153+ existingConf .LastUpdate = time .Now ()
2154+ refreshedSess = true
2155+ } else {
2156+ usingExitingSess = true
2157+ log .W ("ws: make: get session err: %v; using existing; tok? %s" , sessErr , tokst )
2158+ newSess = existingConf .Session // use existing session
2159+ }
21352160 }
21362161
21372162 exp , err := time .Parse (time .DateOnly , newSess .ExpiryDate )
21382163 if err != nil {
2139- err = log .EE ("ws: make: parsing expiry %s (newSess? %t); err: %v" , newSess .ExpiryDate , ! usingExitingSess , err )
2164+ err = log .EE ("ws: make: parsing expiry %s (newSess? %t / skipSess? %t ); err: %v" , newSess .ExpiryDate , ! usingExitingSess , skipSess , err )
21402165 return
21412166 }
21422167
@@ -2145,6 +2170,11 @@ func makeWsWgFrom(h *http.Client, existingConf *WsWgConfig, ops x.RpnOps, updati
21452170 // skip server refresh if ops requests it; but honour loc hash change regardless
21462171 downloadServerList := (existingLocHash != newSess .LocHash ) || ops .FetchServers ()
21472172 if active {
2173+ // sync Robert DNS filters with the desired preset configuration (best-effort; non-fatal).
2174+ if dnsConfig := ops .DNSConfig (); len (dnsConfig ) > 0 {
2175+ go syncDNSFilters (h , existingEnt , newSess , dnsConfig )
2176+ } // else: no-op
2177+
21482178 maybeNewServers := existingServers
21492179 hasnew := false
21502180 if downloadServerList {
@@ -2159,30 +2189,30 @@ func makeWsWgFrom(h *http.Client, existingConf *WsWgConfig, ops x.RpnOps, updati
21592189 }
21602190
21612191 if len (maybeNewServers ) <= 0 { // no new servers, no existing servers; bail
2162- return nil , refreshedSess , core .OneErr (err , errWsNoServerList )
2192+ return nil , refreshedSess , needsRedo , core .OneErr (err , errWsNoServerList )
21632193 }
21642194 }
21652195
2166- // sync Robert DNS filters with the desired preset configuration (best-effort; non-fatal).
2167- if dnsConfig := ops . DNSConfig (); len ( dnsConfig ) > 0 {
2168- go syncDNSFilters ( h , existingEnt , newSess , dnsConfig )
2169- } // else: no-op
2170-
2171- // create wg confs from new or existing server list
2172- // always reconfigure (as /WgConfigs/connect must be done once every wg_ttl, which is 60m )
2173- maybeNewCreds , maybeNewPermaCreds , maybeNewWgConfs , uerr := genWgConfs ( h , existingCreds , existingConf . PermaCreds , newSess , maybeNewServers , existingConf . Entitlement , ops )
2174- loge ( uerr )( "ws: make: gen wg confs; tok? %s; downloadloc? %t / hasnewloc? %t len (%d/%d); ops: %v; err? %v" ,
2175- tokst , downloadServerList , hasnew , len ( existingServers ), len ( maybeNewServers ), & ops , uerr )
2176-
2177- if uerr == nil {
2178- existingConf .Servers = maybeNewServers
2179- existingConf .Configs = maybeNewWgConfs
2180- existingConf .Creds = maybeNewCreds
2181- existingConf . PermaCreds = maybeNewPermaCreds // may be nil
2182- } else if performingUpdate {
2183- // error out early as this was meant to create an update config for later use
2184- // but it itself is not the currently active config aka "existingConf"
2185- return nil , refreshedSess , uerr
2196+ skipGen := ! ops . ForceInit () && ! hasnew
2197+ if skipGen {
2198+ log . D ( "ws: make: skip gen (use existing servers and creds); tok? %s" , tokst )
2199+ } else {
2200+ maybeNewCreds , maybeNewPermaCreds , maybeNewWgConfs , uerr := genWgConfs ( h , existingCreds , existingConf . PermaCreds , newSess , maybeNewServers , existingConf . Entitlement , ops )
2201+ loge ( uerr )( "ws: make: gen wg confs; tok? %s; downloadloc? %t / hasnewloc? %t len (%d/%d); ops: %v; err? %v" ,
2202+ tokst , downloadServerList , hasnew , len ( existingServers ), len ( maybeNewServers ), & ops , uerr )
2203+
2204+ if uerr == nil {
2205+ // TODO: needsRedo must be set iff creds and/or serverlist has changed
2206+ needsRedo = true
2207+ existingConf . Servers = maybeNewServers
2208+ existingConf .Configs = maybeNewWgConfs
2209+ existingConf .Creds = maybeNewCreds
2210+ existingConf .PermaCreds = maybeNewPermaCreds // may be nil
2211+ } else if performingUpdate {
2212+ // error out early as this was meant to create an update config for later use
2213+ // but it itself is not the currently active config aka "existingConf"
2214+ return nil , refreshedSess , needsRedo , uerr
2215+ }
21862216 }
21872217 } else {
21882218 log .W ("ws: make: session expired at %s (newSess? %t); tok? %s" , fmtTime (exp ), ! usingExitingSess , tokst )
0 commit comments