@@ -23,6 +23,7 @@ type Proxy struct {
2323 serversInfo ServersInfo
2424 questionSizeEstimator QuestionSizeEstimator
2525 registeredServers []RegisteredServer
26+ staticServers []RegisteredServer
2627 dns64Resolvers []string
2728 dns64Prefixes []string
2829 serversBlockingFragments []string
@@ -35,6 +36,7 @@ type Proxy struct {
3536 sources []* Source
3637 tcpListeners []* net.TCPListener
3738 registeredRelays []RegisteredServer
39+ staticRelays []RegisteredServer
3840 listenAddresses []string
3941 localDoHListenAddresses []string
4042 monitoringUI MonitoringUIConfig
@@ -336,99 +338,139 @@ func (proxy *Proxy) StartProxy() {
336338}
337339
338340func (proxy * Proxy ) updateRegisteredServers () error {
341+ registeredServersNew := make ([]RegisteredServer , 0 )
342+ registeredRelaysNew := make ([]RegisteredServer , 0 )
339343 for _ , source := range proxy .sources {
340- registeredServers , err := source .Parse ()
344+ servers , err := source .Parse ()
341345 if err != nil {
342- if len (registeredServers ) == 0 {
346+ if len (servers ) == 0 {
343347 dlog .Criticalf ("Unable to use source [%s]: [%s]" , source .name , err )
344348 return err
345349 }
346350 dlog .Warnf (
347351 "Error in source [%s]: [%s] -- Continuing with reduced server count [%d]" ,
348352 source .name ,
349353 err ,
350- len (registeredServers ),
354+ len (servers ),
351355 )
352356 }
353- for _ , registeredServer := range registeredServers {
354- if registeredServer .stamp .Proto != stamps .StampProtoTypeDNSCryptRelay &&
355- registeredServer .stamp .Proto != stamps .StampProtoTypeODoHRelay {
356- if len (proxy .ServerNames ) > 0 {
357- if ! includesName (proxy .ServerNames , registeredServer .name ) {
358- continue
359- }
360- } else if registeredServer .stamp .Props & proxy .requiredProps != proxy .requiredProps {
357+ registeredServersNew , registeredRelaysNew = proxy .buildRegisteredServers (servers , registeredServersNew , registeredRelaysNew )
358+ }
359+ if len (proxy .staticServers ) > 0 {
360+ registeredServersNew = append (registeredServersNew , proxy .staticServers ... )
361+ }
362+ if len (proxy .staticRelays ) > 0 {
363+ registeredRelaysNew = append (registeredRelaysNew , proxy .staticRelays ... )
364+ }
365+ if len (registeredServersNew ) > 0 {
366+ proxy .registeredServers = registeredServersNew
367+ }
368+ if len (registeredRelaysNew ) > 0 {
369+ proxy .registeredRelays = registeredRelaysNew
370+ }
371+ dlog .Debugf ("Total count of registered servers %v" , len (proxy .registeredServers ))
372+ dlog .Debugf ("Total count of registered relays %v" , len (proxy .registeredRelays ))
373+ proxy .serversInfo .registerServers (proxy .registeredServers )
374+ proxy .serversInfo .registerRelays (proxy .registeredRelays )
375+ return nil
376+ }
377+
378+ func (proxy * Proxy ) buildRegisteredServers (servers , registeredServersNew , registeredRelaysNew []RegisteredServer ) (serversAppended , relaysAppended []RegisteredServer ) {
379+ for _ , server := range servers {
380+ if server .stamp .Proto != stamps .StampProtoTypeDNSCryptRelay &&
381+ server .stamp .Proto != stamps .StampProtoTypeODoHRelay {
382+ if len (proxy .ServerNames ) > 0 {
383+ if ! includesName (proxy .ServerNames , server .name ) {
361384 continue
362385 }
386+ } else if server .stamp .Props & proxy .requiredProps != proxy .requiredProps {
387+ continue
363388 }
364- if includesName (proxy .DisabledServerNames , registeredServer .name ) {
389+ }
390+ if includesName (proxy .DisabledServerNames , server .name ) {
391+ continue
392+ }
393+ if proxy .SourceIPv4 || proxy .SourceIPv6 {
394+ isIPv4 , isIPv6 := true , false
395+ if server .stamp .Proto == stamps .StampProtoTypeDoH {
396+ isIPv4 , isIPv6 = true , true
397+ }
398+ if strings .HasPrefix (server .stamp .ServerAddrStr , "[" ) {
399+ isIPv4 , isIPv6 = false , true
400+ }
401+ if ! (proxy .SourceIPv4 == isIPv4 || proxy .SourceIPv6 == isIPv6 ) {
365402 continue
366403 }
367- if proxy .SourceIPv4 || proxy .SourceIPv6 {
368- isIPv4 , isIPv6 := true , false
369- if registeredServer .stamp .Proto == stamps .StampProtoTypeDoH {
370- isIPv4 , isIPv6 = true , true
371- }
372- if strings .HasPrefix (registeredServer .stamp .ServerAddrStr , "[" ) {
373- isIPv4 , isIPv6 = false , true
374- }
375- if ! (proxy .SourceIPv4 == isIPv4 || proxy .SourceIPv6 == isIPv6 ) {
404+ }
405+ if server .stamp .Proto == stamps .StampProtoTypeDNSCryptRelay ||
406+ server .stamp .Proto == stamps .StampProtoTypeODoHRelay {
407+ isNew , stampChanged , dupNewInstance := checkServerForNewBuild (& server , proxy .registeredRelays , registeredRelaysNew )
408+ if dupNewInstance != nil {
409+ dupNewInstance .stamp = server .stamp
410+ } else {
411+ registeredRelaysNew = append (registeredRelaysNew , server )
412+ if isNew {
413+ dlog .Debugf ("Adding [%s] to the set of available relays" , server .name )
414+ } else if ! stampChanged {
376415 continue
377416 }
378417 }
379- if registeredServer .stamp .Proto == stamps .StampProtoTypeDNSCryptRelay ||
380- registeredServer .stamp .Proto == stamps .StampProtoTypeODoHRelay {
381- var found bool
382- for i , currentRegisteredRelay := range proxy .registeredRelays {
383- if currentRegisteredRelay .name == registeredServer .name {
384- found = true
385- if currentRegisteredRelay .stamp .String () != registeredServer .stamp .String () {
386- dlog .Infof (
387- "Updating stamp for [%s] was: %s now: %s" ,
388- registeredServer .name ,
389- currentRegisteredRelay .stamp .String (),
390- registeredServer .stamp .String (),
391- )
392- proxy .registeredRelays [i ].stamp = registeredServer .stamp
393- dlog .Debugf ("Total count of registered relays %v" , len (proxy .registeredRelays ))
394- }
395- }
396- }
397- if ! found {
398- dlog .Debugf ("Adding [%s] to the set of available relays" , registeredServer .name )
399- proxy .registeredRelays = append (proxy .registeredRelays , registeredServer )
400- }
418+ dlog .Debugf ("Count of registered relays %v" , len (registeredRelaysNew ))
419+ } else {
420+ if ! ((proxy .SourceDNSCrypt && server .stamp .Proto == stamps .StampProtoTypeDNSCrypt ) ||
421+ (proxy .SourceDoH && server .stamp .Proto == stamps .StampProtoTypeDoH ) ||
422+ (proxy .SourceODoH && server .stamp .Proto == stamps .StampProtoTypeODoHTarget )) {
423+ continue
424+ }
425+ isNew , stampChanged , dupNewInstance := checkServerForNewBuild (& server , proxy .registeredServers , registeredServersNew )
426+ if dupNewInstance != nil {
427+ dupNewInstance .stamp = server .stamp
401428 } else {
402- if ! ((proxy .SourceDNSCrypt && registeredServer .stamp .Proto == stamps .StampProtoTypeDNSCrypt ) ||
403- (proxy .SourceDoH && registeredServer .stamp .Proto == stamps .StampProtoTypeDoH ) ||
404- (proxy .SourceODoH && registeredServer .stamp .Proto == stamps .StampProtoTypeODoHTarget )) {
429+ registeredServersNew = append (registeredServersNew , server )
430+ if isNew {
431+ dlog .Debugf ("Adding [%s] to the set of wanted resolvers" , server .name )
432+ } else if ! stampChanged {
405433 continue
406434 }
407- var found bool
408- for i , currentRegisteredServer := range proxy .registeredServers {
409- if currentRegisteredServer .name == registeredServer .name {
410- found = true
411- if currentRegisteredServer .stamp .String () != registeredServer .stamp .String () {
412- dlog .Infof ("Updating stamp for [%s] was: %s now: %s" , registeredServer .name , currentRegisteredServer .stamp .String (), registeredServer .stamp .String ())
413- proxy .registeredServers [i ].stamp = registeredServer .stamp
414- }
415- }
416- }
417- if ! found {
418- dlog .Debugf ("Adding [%s] to the set of wanted resolvers" , registeredServer .name )
419- proxy .registeredServers = append (proxy .registeredServers , registeredServer )
420- dlog .Debugf ("Total count of registered servers %v" , len (proxy .registeredServers ))
421- }
422435 }
436+ dlog .Debugf ("Count of registered servers %v" , len (registeredServersNew ))
423437 }
424438 }
425- for _ , registeredServer := range proxy .registeredServers {
426- proxy .serversInfo .registerServer (registeredServer .name , registeredServer .stamp )
439+ return registeredServersNew , registeredRelaysNew
440+ }
441+
442+ func checkServerForNewBuild (server * RegisteredServer , serversCur , serversNew []RegisteredServer ) (isNew , stampChanged bool , dupNewInstance * RegisteredServer ) {
443+ foundServer , stampChanged := serverStampChanged (serversCur , server )
444+ if foundServer == nil || stampChanged {
445+ // in case the same name exists in (different) sources
446+ dupNewInstance , stampChanged2 := serverStampChanged (serversNew , server )
447+ isNew = foundServer == nil && dupNewInstance == nil
448+ if dupNewInstance != nil {
449+ foundServer = dupNewInstance
450+ }
451+ stampChanged = stampChanged || stampChanged2
427452 }
428- for _ , registeredRelay := range proxy .registeredRelays {
429- proxy .serversInfo .registerRelay (registeredRelay .name , registeredRelay .stamp )
453+ if stampChanged {
454+ dlog .Infof (
455+ "Updating stamp for [%s] was: %s now: %s" ,
456+ server .name ,
457+ foundServer .stamp .String (),
458+ server .stamp .String (),
459+ )
430460 }
431- return nil
461+ return isNew , stampChanged , dupNewInstance
462+ }
463+
464+ func serverStampChanged (servers []RegisteredServer , server * RegisteredServer ) (found * RegisteredServer , changed bool ) {
465+ for _ , s := range servers {
466+ if s .name == server .name {
467+ found = & s
468+ if s .stamp .String () != server .stamp .String () {
469+ changed = true
470+ }
471+ }
472+ }
473+ return found , changed
432474}
433475
434476func (proxy * Proxy ) udpListener (clientPc * net.UDPConn ) {
0 commit comments