@@ -55,19 +55,16 @@ func ApplyECH(c *Config, config *tls.Config) error {
5555 }
5656 config .EncryptedClientHelloConfigList = ECHConfig
5757 }()
58- // direct base64 config
58+ // query config from dns
5959 if strings .Contains (c .EchConfigList , "://" ) {
60- // query config from dns
61- parts := strings .Split (c .EchConfigList , "+" )
60+ // parse ECH DNS server in format of "example.com+https://1.1.1.1/ dns-query"
61+ parts := strings .SplitN (c .EchConfigList , "+" , 2 )
6262 if len (parts ) == 2 {
63- // parse ECH DNS server in format of "example.com+https://1.1.1.1/dns-query"
6463 nameToQuery = parts [0 ]
6564 DNSServer = parts [1 ]
66- } else if len ( parts ) == 1 {
65+ } else {
6766 // normal format
6867 DNSServer = parts [0 ]
69- } else {
70- return errors .New ("Invalid ECH DNS server format: " , c .EchConfigList )
7168 }
7269 if nameToQuery == "" {
7370 return errors .New ("Using DNS for ECH Config needs serverName or use Server format example.com+https://1.1.1.1/dns-query" )
@@ -77,6 +74,7 @@ func ApplyECH(c *Config, config *tls.Config) error {
7774 return errors .New ("Failed to query ECH DNS record for domain: " , nameToQuery , " at server: " , DNSServer ).Base (err )
7875 }
7976 } else {
77+ // direct base64 config
8078 ECHConfig , err = base64 .StdEncoding .DecodeString (c .EchConfigList )
8179 if err != nil {
8280 return errors .New ("Failed to unmarshal ECHConfigList: " , err )
@@ -157,7 +155,7 @@ func QueryRecord(domain string, server string, sockopt *internet.SocketConfig) (
157155 // If expire is zero value, it means we are in initial state, wait for the query to finish
158156 // otherwise return old value immediately and update in a goroutine
159157 // but if the cache is too old, wait for update
160- if configRecord .expire == (time. Time {} ) || configRecord .expire .Add (time .Hour * 4 ).Before (time .Now ()) {
158+ if configRecord .expire . IsZero ( ) || configRecord .expire .Add (time .Hour * 4 ).Before (time .Now ()) {
161159 return echConfigCache .Update (domain , server , false , sockopt )
162160 } else {
163161 // If someone already acquired the lock, it means it is updating, do not start another update goroutine
@@ -256,14 +254,17 @@ func dnsQuery(server string, domain string, sockopt *internet.SocketConfig) ([]b
256254 }
257255 dnsResolve = respBody
258256 } else if strings .HasPrefix (server , "udp://" ) { // for classic udp dns server
259- udpServerAddr := server [len ("udp://" ):]
257+ udpServerURL , err := url .Parse (server )
258+ if err != nil {
259+ return nil , 0 , errors .New ("failed to parse udp dns server " , server , " for ECH: " , err )
260+ }
260261 // default port 53 if not specified
261- if ! strings . Contains ( udpServerAddr , ":" ) {
262- udpServerAddr = udpServerAddr + ":53"
262+ if udpServerURL . Port () == "" {
263+ udpServerURL . Host = udpServerURL . Host + ":53"
263264 }
264- dest , err := net .ParseDestination ("udp" + ":" + udpServerAddr )
265+ dest , err := net .ParseDestination ("udp" + ":" + udpServerURL . Host )
265266 if err != nil {
266- return nil , 0 , errors .New ("failed to parse udp dns server " , udpServerAddr , " for ECH: " , err )
267+ return nil , 0 , errors .New ("failed to parse udp dns server " , udpServerURL . Host , " for ECH: " , err )
267268 }
268269 dnsTimeoutCtx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
269270 defer cancel ()
0 commit comments