@@ -130,6 +130,7 @@ const (
130130 maxPerRegionWgConfs = 4
131131 maxAnyWgConfs = 8
132132 wsMaxPermaWgKeys = 5
133+ maxDNSSyncTries = 2
133134
134135 disablePermaCreds = true
135136
@@ -2520,45 +2521,80 @@ func listKeys(h *http.Client, ent *WsEntitlement, bearer string) (*WsWgListKeysR
25202521}
25212522
25222523// getDNSFilters returns the current DNS filter list.
2524+ // retried [maxDNSSyncTries] times after random wait > 1s (but less than 2s).
25232525func getDNSFilters (h * http.Client , ent * WsEntitlement , bearer string ) ([]WsFilter , error ) {
25242526 if len (bearer ) <= 0 {
25252527 return nil , errWsNoToken
25262528 }
25272529 tokst := tokenState (bearer )
2530+
2531+ minwait := 1000 // ms
2532+ maxjitter := 1000 // ms
2533+
25282534 u := baseurl (ent .TestDomain , ent .Cid ).JoinPath (wsgetfilterspath )
2529- req , err := http .NewRequest ("GET" , u .String (), nil )
2530- if err != nil {
2531- return nil , log .EE ("ws: filters: get: req err: %v" , err )
2532- }
2533- authHeader (req , bearer )
2534- didAndDBHeader (req , ent .Did , ent .DidToken , ent .TestDomain )
2535+ for t := range maxDNSSyncTries {
2536+ canretry := t < maxDNSSyncTries - 1
2537+ wait := time .Duration (minwait + rand .IntN (maxjitter )) * time .Millisecond
25352538
2536- if log .Verbose {
2537- log .V ("ws: filters: get: req: %s tok %s" , u .String (), tokst )
2538- }
2539+ req , err := http .NewRequest ("GET" , u .String (), nil )
2540+ if err != nil {
2541+ return nil , log .EE ("ws: filters: get: req err: %v" , err )
2542+ }
2543+ authHeader (req , bearer )
2544+ didAndDBHeader (req , ent .Did , ent .DidToken , ent .TestDomain )
25392545
2540- res , err := h .Do (req )
2541- if err != nil || res == nil {
2542- return nil , log .EE ("ws: filters: get: do err (nil? %t / tok? %s): %v" , res == nil , tokst , err )
2543- }
2544- defer core .Close (res .Body )
2545- updateDidTokenIfNeeded (ent , res )
2546- if res .StatusCode != http .StatusOK {
2547- return nil , wsErr (res , "getrob/" + tokst )
2548- }
2546+ if log .Verbose {
2547+ log .V ("ws: filters: get: (#%d) req: %s tok %s" , t , u .String (), tokst )
2548+ }
25492549
2550- var out WsFiltersResponse
2551- if _ , err = wsRes (res , & out , "getrob/" + tokst ); err != nil {
2552- return nil , err
2553- }
2554- if len (out .Data .Filters ) <= 0 {
2555- return nil , log .EE ("ws: filters: get: %v; tok? %s" , errWsNoFilters , tokst )
2556- }
2557- log .I ("ws: filters: get: ok (tok? %s); %d filters" , tokst , len (out .Data .Filters ))
2558- return out .Data .Filters , nil
2550+ res , err := h .Do (req )
2551+ if err != nil || res == nil {
2552+ if canretry {
2553+ log .W ("ws: filters: get: (#%d) do err (nil? %t / tok? %s): %v; retry in %s" ,
2554+ t , res == nil , tokst , err , core .FmtPeriod (wait ))
2555+ time .Sleep (wait )
2556+ continue
2557+ }
2558+ return nil , log .EE ("ws: filters: get: (#%d) do err (nil? %t / tok? %s): %v" , t , res == nil , tokst , err )
2559+ }
2560+ updateDidTokenIfNeeded (ent , res )
2561+ if res .StatusCode != http .StatusOK {
2562+ if canretry {
2563+ core .Close (res .Body )
2564+ log .W ("ws: filters: get: (#%d) (%d) retry in %s; tok? %s" ,
2565+ t , res .StatusCode , core .FmtPeriod (wait ), tokst )
2566+ time .Sleep (wait )
2567+ continue
2568+ }
2569+ err2 := wsErr (res , "getfilter/" + tokst )
2570+ core .Close (res .Body )
2571+ return nil , err2
2572+ }
2573+
2574+ var out WsFiltersResponse
2575+ _ , err = wsRes (res , & out , "getfilter/" + tokst )
2576+ core .Close (res .Body )
2577+ if err != nil {
2578+ return nil , err // no retry
2579+ }
2580+
2581+ if len (out .Data .Filters ) <= 0 {
2582+ if canretry {
2583+ log .W ("ws: filters: get: (#%d) empty filters retry in %s; tok? %s" , t , core .FmtPeriod (wait ), tokst )
2584+ time .Sleep (wait )
2585+ continue
2586+ }
2587+ return nil , log .EE ("ws: filters: get: (#%d) %v; tok? %s" , t , errWsNoFilters , tokst )
2588+ }
2589+ log .I ("ws: filters: get: (#%d) ok (tok? %s); %d filters" , t , tokst , len (out .Data .Filters ))
2590+ return out .Data .Filters , nil
2591+ } // else: maxDNSSyncTries not set or exceeded?
2592+
2593+ return nil , log .EE ("ws: filters: get: unreachable; tok? %s" , tokst )
25592594}
25602595
25612596// setDNSFilter enables or disables on a DNS filterID.
2597+ // retried [maxDNSSyncTries] times after random wait > 1s (but less than 2s).
25622598func setDNSFilter (h * http.Client , ent * WsEntitlement , bearer , filterID string , enable bool ) error {
25632599 if len (bearer ) <= 0 {
25642600 return errWsNoToken
@@ -2573,38 +2609,69 @@ func setDNSFilter(h *http.Client, ent *WsEntitlement, bearer, filterID string, e
25732609 return log .EE ("ws: filters: set: marshal err: %v" , err )
25742610 }
25752611
2612+ minwait := 1000 // ms
2613+ maxjitter := 1000 // ms
2614+
25762615 u := baseurl (ent .TestDomain , ent .Cid ).JoinPath (wssetfilterpath )
2577- req , err := http .NewRequest ("PUT" , u .String (), strings .NewReader (string (body )))
2578- if err != nil {
2579- return log .EE ("ws: filters: set: req err: %v" , err )
2580- }
2581- req .Header .Set ("Content-Type" , "application/json" )
2582- authHeader (req , bearer )
2583- didAndDBHeader (req , ent .Did , ent .DidToken , ent .TestDomain )
2616+ for t := range maxDNSSyncTries {
2617+ canretry := t < maxDNSSyncTries - 1
2618+ wait := time .Duration (minwait + rand .IntN (maxjitter )) * time .Millisecond
25842619
2585- if log .Verbose {
2586- log .V ("ws: filters: set: %s status=%d req: %s tok %s" , filterID , status , u .String (), tokst )
2587- }
2620+ req , err := http .NewRequest ("PUT" , u .String (), strings .NewReader (string (body )))
2621+ if err != nil {
2622+ return log .EE ("ws: filters: set: req err: %v" , err )
2623+ }
2624+ req .Header .Set ("Content-Type" , "application/json" )
2625+ authHeader (req , bearer )
2626+ didAndDBHeader (req , ent .Did , ent .DidToken , ent .TestDomain )
25882627
2589- res , err := h .Do (req )
2590- if err != nil || res == nil {
2591- return log .EE ("ws: filters: set: do err (nil? %t / tok? %s): %v" , res == nil , tokst , err )
2592- }
2593- defer core .Close (res .Body )
2594- updateDidTokenIfNeeded (ent , res )
2595- if res .StatusCode != http .StatusOK {
2596- return wsErr (res , "setrob(" + filterID + ")/" + tokst )
2597- }
2628+ if log .Verbose {
2629+ log .V ("ws: filters: set: (#%d) %s status=%d req: %s tok %s" , t , filterID , status , u .String (), tokst )
2630+ }
25982631
2599- var out WsFilterSetResponse
2600- if _ , err = wsRes (res , & out , "setrob(" + filterID + ")/" + tokst ); err != nil {
2601- return err
2602- }
2603- if out .Data .Success != 1 {
2604- return log .EE ("ws: filters: set: %s status=%d success!=1; tok? %s" , filterID , status , tokst )
2605- }
2606- log .I ("ws: filters: set: ok %s status=%d (tok? %s)" , filterID , status , tokst )
2607- return nil
2632+ res , err := h .Do (req )
2633+ if err != nil || res == nil {
2634+ if canretry {
2635+ log .W ("ws: filters: set: (#%d) do err (nil? %t / tok? %s): %v; retry in %s" ,
2636+ t , res == nil , tokst , err , core .FmtPeriod (wait ))
2637+ time .Sleep (wait )
2638+ continue
2639+ }
2640+ return log .EE ("ws: filters: set: (#%d) do err (nil? %t / tok? %s): %v" , t , res == nil , tokst , err )
2641+ }
2642+ updateDidTokenIfNeeded (ent , res )
2643+ if res .StatusCode != http .StatusOK {
2644+ if canretry {
2645+ core .Close (res .Body )
2646+ log .W ("ws: filters: set: (#%d) %s status=%d (%d) retry in %s; tok? %s" ,
2647+ t , filterID , status , res .StatusCode , core .FmtPeriod (wait ), tokst )
2648+ time .Sleep (wait )
2649+ continue
2650+ }
2651+ err2 := wsErr (res , "setrob(" + filterID + ")/" + tokst )
2652+ core .Close (res .Body )
2653+ return err2
2654+ }
2655+
2656+ var out WsFilterSetResponse
2657+ _ , err = wsRes (res , & out , "setrob(" + filterID + ")/" + tokst )
2658+ core .Close (res .Body )
2659+ if err != nil {
2660+ return err // no retry
2661+ }
2662+ if out .Data .Success != 1 {
2663+ if canretry {
2664+ log .W ("ws: filters: set: (#%d) %s status=%d success!=1 retry in %s; tok? %s" , t , filterID , status , core .FmtPeriod (wait ), tokst )
2665+ time .Sleep (wait )
2666+ continue
2667+ }
2668+ return log .EE ("ws: filters: set: (#%d) %s status=%d success!=1; tok? %s" , t , filterID , status , tokst )
2669+ }
2670+ log .I ("ws: filters: set: (#%d) ok %s status=%d (tok? %s)" , t , filterID , status , tokst )
2671+ return nil
2672+ } // else: maxDNSSyncTries not set or exceeded?
2673+
2674+ return log .EE ("ws: filters: set: %s status=%d unreachable; tok? %s" , filterID , status , tokst )
26082675}
26092676
26102677// syncDNSFilters reconciles the Robert DNS filters on the server with the desired state
0 commit comments