func readRemoteList()

in config/config.go [474:579]


func readRemoteList(
	raw []byte,
	glRC *RemoteConfig,
	remotes RemoteStore,
	maxNumSrcTCPPorts uint16,
	minBatchInterval time.Duration,
	logger *log.Logger,
) error {
	c := new(RemoteFileConfig)

	if err := json.Unmarshal(raw, c); err != nil {
		return errors.Wrap(err, "configuration file parse error")
	}

	// Populate global variables
	glRC.Location = strings.ToLower(c.Local.Location)
	if glRC.Location == "" {
		logger.Warn("Location not provided in config file")
	}

	glRC.HostName = strings.ToLower(c.Local.HostName)
	if glRC.HostName == "" {
		logger.Debug("Hostname not provided in config file")
		glRC.HostName, _ = GetHostname(logger)
	} else {
		logger.Info("Remotely assigned hostname for metrics uploading",
			zap.String("metrics_hostname", glRC.HostName))
	}

	glRC.InterfaceName = strings.ToLower(c.Local.InterfaceName)
	switch {
	case runtime.GOOS == "linux" && strings.Contains(glRC.InterfaceName, "en"),
		runtime.GOOS == "darwin" && strings.Contains(glRC.InterfaceName, "eth"):
		logger.Warn("Specified interface may not be applicable to actual OS",
			zap.String("interface", glRC.InterfaceName),
			zap.String("OS", runtime.GOOS))
	}

	srcIP, err := network.GetSourceAddr("ip4", strings.ToLower(c.Local.SrcAddress),
		glRC.HostName, glRC.InterfaceName, logger)
	if err != nil {
		srcIP, err = network.GetSourceAddr("ip6", strings.ToLower(c.Local.SrcAddress),
			glRC.HostName, glRC.InterfaceName, logger)
		if err != nil {
			return errors.Wrap(err, "could not retrieve an IPv4 or IPv6 source address")
		}
	}
	glRC.SrcAddress = *srcIP
	logger.Debug("Arachne agent's source IP address", zap.Any("address", glRC.SrcAddress))

	glRC.TargetTCPPort = c.Local.TargetTCPPort
	if glRC.Timeout, err = time.ParseDuration(c.Local.Timeout); err != nil {
		return errors.Wrap(err, "failed to parse the timeout")
	}
	glRC.SrcTCPPortRange[0] = c.Local.BaseSrcTCPPort
	if c.Local.NumSrcTCPPorts > maxNumSrcTCPPorts {
		return errors.Errorf("not more than %d ephemeral source TCP ports may be used",
			maxNumSrcTCPPorts)
	}
	if c.Local.NumSrcTCPPorts == 0 {
		return errors.New("cannot specify zero source TCP ports")
	}
	glRC.SrcTCPPortRange[1] = c.Local.BaseSrcTCPPort + layers.TCPPort(c.Local.NumSrcTCPPorts) - 1
	if glRC.SrcTCPPortRange.Contains(glRC.TargetTCPPort) {
		return errors.Errorf("the listen TCP port cannot reside in the range of the ephemeral TCP "+
			"source ports [%d-%d]", glRC.SrcTCPPortRange[0], glRC.SrcTCPPortRange[1])
	}
	if glRC.BatchInterval, err = time.ParseDuration(c.Local.BatchInterval); err != nil {
		return errors.Wrap(err, "failed to parse the batch interval")
	}
	if glRC.BatchInterval < minBatchInterval {
		return errors.Errorf("the batch cycle interval cannot be shorter than %v", minBatchInterval)
	}
	if glRC.PollOrchestratorInterval.Success, err =
		time.ParseDuration(c.Local.PollOrchestratorIntervalSuccess); err != nil {
		return errors.Wrap(err, "failed to parse the Orchestrator poll interval for success")
	}
	if glRC.PollOrchestratorInterval.Failure, err =
		time.ParseDuration(c.Local.PollOrchestratorIntervalFailure); err != nil {
		return errors.Wrap(err, "failed to parse the Orchestrator poll interval for failure")
	}

	glRC.QoSEnabled = isTrue(c.Local.QoSEnabled)
	glRC.ResolveDNS = isTrue(c.Local.ResolveDNS)

	DNSInput := strings.Split(c.Local.DNSServersAlt, ",")
	for _, server := range DNSInput {
		currDNSIP := net.ParseIP(strings.TrimSpace(server))
		if currDNSIP == nil {
			return errors.Errorf("configuration file parse error: "+
				"invalid IP address for DNS server: %v", currDNSIP)
		}
		glRC.DNSServersAlt = append(glRC.DNSServersAlt, currDNSIP)

	}
	logger.Debug("Alternate DNS servers configured", zap.Any("servers", glRC.DNSServersAlt))

	walkTargets(glRC, c.Internal, false, remotes, logger)
	walkTargets(glRC, c.External, true, remotes, logger)

	for key, r := range remotes {
		logger.Debug("Remote", zap.String("key", key), zap.Any("object", r))
	}

	return nil
}