2020-05-02 20:02:19 +08:00
|
|
|
package dns
|
|
|
|
|
2021-09-10 23:36:25 +08:00
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"sync/atomic"
|
|
|
|
)
|
2020-05-02 20:02:19 +08:00
|
|
|
|
2020-05-06 20:10:18 +08:00
|
|
|
// UPStream is a dns upstream.
|
|
|
|
type UPStream struct {
|
2020-05-02 20:02:19 +08:00
|
|
|
index uint32
|
|
|
|
servers []string
|
|
|
|
}
|
|
|
|
|
2020-05-06 20:10:18 +08:00
|
|
|
// NewUPStream returns a new UpStream.
|
|
|
|
func NewUPStream(servers []string) *UPStream {
|
2021-09-10 23:36:25 +08:00
|
|
|
// default port for dns upstream servers
|
|
|
|
for i, server := range servers {
|
|
|
|
if _, port, _ := net.SplitHostPort(server); port == "" {
|
|
|
|
servers[i] = net.JoinHostPort(server, "53")
|
|
|
|
}
|
|
|
|
}
|
2020-05-06 20:10:18 +08:00
|
|
|
return &UPStream{servers: servers}
|
2020-05-02 20:02:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Server returns a dns server.
|
2020-05-06 20:10:18 +08:00
|
|
|
func (u *UPStream) Server() string {
|
2020-05-02 20:02:19 +08:00
|
|
|
return u.servers[atomic.LoadUint32(&u.index)%uint32(len(u.servers))]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Switch switches to the next dns server.
|
2020-05-06 20:10:18 +08:00
|
|
|
func (u *UPStream) Switch() string {
|
2020-05-02 20:02:19 +08:00
|
|
|
return u.servers[atomic.AddUint32(&u.index, 1)%uint32(len(u.servers))]
|
|
|
|
}
|
|
|
|
|
2020-05-03 20:02:11 +08:00
|
|
|
// SwitchIf switches to the next dns server if needed.
|
2020-05-06 20:10:18 +08:00
|
|
|
func (u *UPStream) SwitchIf(server string) string {
|
2020-05-03 20:02:11 +08:00
|
|
|
if u.Server() == server {
|
|
|
|
return u.Switch()
|
|
|
|
}
|
|
|
|
return u.Server()
|
|
|
|
}
|
|
|
|
|
2020-05-02 20:02:19 +08:00
|
|
|
// Len returns the number of dns servers.
|
2020-05-06 20:10:18 +08:00
|
|
|
func (u *UPStream) Len() int {
|
2020-05-02 20:02:19 +08:00
|
|
|
return len(u.servers)
|
|
|
|
}
|