sequence

This paper mainly studies UDPServer of nacOS-coreDNS-Plugin

UDPServer

nacos-coredns-plugin/nacos/udp_server.go

type UDPServer struct {
	port int
	host string
	vipClient *NacosClient
}
Copy the code

The UDPServer defines the port, host, and vipClient attributes

StartServer

nacos-coredns-plugin/nacos/udp_server.go

func (us *UDPServer) StartServer(){ var conn *net.UDPConn for i := 0; i < 3; i++ { r := rand.New(rand.NewSource(time.Now().UnixNano())) port := r.Intn(1000) + 54951 us.port = port conn1, ok := us.tryListen() if ok { conn = conn1 NacosClientLogger.Info("udp server start, port: " + strconv.Itoa(port)) break } if ! ok && i == 2 { NacosClientLogger.Critical("failed to start udp server after trying 3 times.") os.Exit(1) } } UDP_Port = us.port defer conn.Close() for { us.handleClient(conn) } }Copy the code

The StartServer method loops tryListen() for three times, and exit if all fails. If successful, the for loop executes handleClient

tryListen

nacos-coredns-plugin/nacos/udp_server.go

func (us *UDPServer) tryListen() (*net.UDPConn, bool) { addr, err := net.ResolveUDPAddr("udp", us.host+":"+ strconv.Itoa(us.port)) if err ! = nil { NacosClientLogger.Error("Can't resolve address: ", err) return nil , false } conn, err := net.ListenUDP("udp", addr) if err ! = nil { NacosClientLogger.Error("Error listening:", err) return nil, false } return conn, true }Copy the code

The tryListen method executes net.ResolveUDPAddr first, and then executes Net. ListenUDP

handleClient

nacos-coredns-plugin/nacos/udp_server.go

type PushData struct { PushType string `json:"type"` Data string `json:"data"` LastRefTime int64 `json:"lastRefTime"` } func (us *UDPServer) handleClient(conn *net.UDPConn) { data := make([]byte, 4024) n, remoteAddr, err := conn.ReadFromUDP(data) if err ! = nil { NacosClientLogger.Error("failed to read UDP msg because of ", err) return } s := TryDecompressData(data[:n]) NacosClientLogger.Info("receive push: " + s + " from: ", remoteAddr) var pushData PushData err1 := json.Unmarshal([]byte(s), &pushData) if err1 ! = nil { NacosClientLogger.Warn("failed to process push data, ", err1) return } domain, err1 := ProcessDomainString(pushData.Data) NacosClientLogger.Info("receive domain: " , domain) if err1 ! = nil { NacosClientLogger.Warn("failed to process push data: " + s, err1) } key := GetCacheKey(domain.Name, LocalIP()) us.vipClient.domainMap.Set(key, domain) ack := make(map[string]string) ack["type"] = "push-ack" ack["lastRefTime"] = strconv.FormatInt(pushData.LastRefTime, 10) ack["data"] = "" bs,_ := json.Marshal(ack) conn.WriteToUDP(bs, remoteAddr) }Copy the code

The handleClient method executes conn.ReadFromUDP, decompresses the data with TryDecompressData, and Unmarshal executes ProcessDomainString for PushData to get the domain, Perform us. VipClient. DomainMap. Set (key, domain), finally construct data returned back an ack

summary

The UDPServer of nacos-coreDNS-plugin defines the attributes of port, host and vipClient. It provides the StartServer method; The StartServer method loops tryListen() for three times, and exit if all fails. If successful, the for loop executes handleClient.

doc

  • nacos-coredns-plugin