Пример #1
0
// Returns / creates instance of Redis connection
func (redisBroker *RedisBroker) open() (redis.Conn, error) {
	if redisBroker.socketPath != "" {
		return redis.Dial("unix", redisBroker.socketPath, redis.DialPassword(redisBroker.password), redis.DialDatabase(redisBroker.db))
	}

	// package redis takes care of pwd or db
	return redis.Dial("tcp", redisBroker.host, redis.DialPassword(redisBroker.password), redis.DialDatabase(redisBroker.db))
}
Пример #2
0
// Returns a new pool of Redis connections
func (redisBroker *RedisBroker) newPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:     3,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			var (
				c   redis.Conn
				err error
			)

			if redisBroker.password != "" {
				c, err = redis.Dial("tcp", redisBroker.host,
					redis.DialPassword(redisBroker.password))
			} else {
				c, err = redis.Dial("tcp", redisBroker.host)
			}

			if err != nil {
				return nil, err
			}
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
}
Пример #3
0
// Returns / creates instance of Redis connection
func (redisBackend *RedisBackend) open() (redis.Conn, error) {
	if redisBackend.password != "" {
		return redis.Dial("tcp", redisBackend.host,
			redis.DialPassword(redisBackend.password))
	}
	return redis.Dial("tcp", redisBackend.host)
}
Пример #4
0
func NewRedisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   config.GetInt("redis_max_idle"),
		MaxActive: config.GetInt("redis_concurrent"), // max number of connections
		Dial: func() (redis.Conn, error) {
			var (
				c   redis.Conn
				err error
			)
			redis_host := fmt.Sprintf("%s:%s", config.GetMulti("redis_host", "redis_port")...)

			redis_passwd := config.Get("redis_passwd")
			if redis_passwd != "" {
				pwd := redis.DialPassword(redis_passwd)
				c, err = redis.Dial("tcp", redis_host, pwd)
			} else {
				c, err = redis.Dial("tcp", redis_host)
			}

			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
}
Пример #5
0
// Iterate through `machines`, trying to connect to each in turn.
// Returns the first successful connection or the last error encountered.
// Assumes that `machines` is non-empty.
func tryConnect(machines []string, password string) (redis.Conn, error) {
	var err error
	for _, address := range machines {
		var conn redis.Conn
		network := "tcp"
		if _, err = os.Stat(address); err == nil {
			network = "unix"
		}
		log.Debug(fmt.Sprintf("Trying to connect to redis node %s", address))

		dialops := []redis.DialOption{
			redis.DialConnectTimeout(time.Second),
			redis.DialReadTimeout(time.Second),
			redis.DialWriteTimeout(time.Second),
		}

		if password != "" {
			dialops = append(dialops, redis.DialPassword(password))
		}

		conn, err = redis.Dial(network, address, dialops...)

		if err != nil {
			continue
		}
		return conn, nil
	}
	return nil, err
}
Пример #6
0
// Returns / creates instance of Redis connection
func (redisBroker *RedisBroker) open() (redis.Conn, error) {
	if redisBroker.password != "" {
		return redis.Dial("tcp", redisBroker.host,
			redis.DialPassword(redisBroker.password))
	}
	return redis.Dial("tcp", redisBroker.host)
}
Пример #7
0
// create pool
func newPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   80,
		MaxActive: 12000, // max number of connections
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", Conf.RedisHost, redis.DialPassword(Conf.RedisPwd))
			if err != nil {
				panic(err.Error())
			}
			return c, err
		},
	}
}
Пример #8
0
// ping executes a PING command against addr until timeout occurs.
func (p *Process) ping(addr string, timeout time.Duration) error {
	// Default to local process if addr not specified.
	if addr == "" {
		addr = fmt.Sprintf("localhost:%s", p.Port)
	}

	logger := p.Logger.New("fn", "ping", "addr", addr, "timeout", timeout)
	logger.Info("sending")

	timer := time.NewTimer(timeout)
	defer timer.Stop()

	ticker := time.NewTicker(checkInterval)
	defer ticker.Stop()

	for {
		// Attempt to ping the server.
		if ok := func() bool {
			logger.Info("sending PING")

			conn, err := redis.Dial("tcp", addr,
				redis.DialPassword(p.Password),
				redis.DialConnectTimeout(timeout),
				redis.DialReadTimeout(timeout),
				redis.DialWriteTimeout(timeout),
			)
			if err != nil {
				logger.Error("conn error", "err", err)
				return false
			}
			defer conn.Close()

			if _, err := conn.Do("PING"); err != nil {
				logger.Error("error getting upstream status", "err", err)
				return false
			}

			logger.Info("PONG received")
			return true
		}(); ok {
			return nil
		}

		select {
		case <-timer.C:
			logger.Info("timeout")
			return ErrTimeout
		case <-ticker.C:
		}
	}
}
Пример #9
0
func GetRedisConn() {
	// tcp连接
	var err error
	dialoption := redis.DialPassword("admin")
	rs, err = redis.Dial("tcp", "localhost:6379", dialoption)

	// 若连接出错,则打印错误信息,返回
	if err != nil {
		fmt.Println(err)
		fmt.Println("redis connect error")
	} else {
		fmt.Println("redis conn success")
	}
}
Пример #10
0
func main() {
	var (
		listen = flag.String("listen", ":8080", "HTTP listen address")
		// proxy  = flag.String("proxy", "", "Optional comma-separated list of URLs to proxy uppercase requests")
	)
	flag.Parse()

	var logger log.Logger
	logger = log.NewLogfmtLogger(os.Stderr)
	logger = log.NewContext(logger).With("listen", *listen).With("caller", log.DefaultCaller)
	loglevel := levels.New(logger)

	ctx := context.Background()

	redisURL := os.Getenv("REDIS_URL")
	redisPassword := os.Getenv("REDIS_PASSWORD")
	if redisURL == "" || redisPassword == "" {
		_ = loglevel.Crit("err", "missing REDIS connection information")
		return
	}

	infra, err := BuildInfrastructure(InfrastructureOptions{
		DialURL:    os.Getenv("REDIS_URL"),
		DialOption: []redis.DialOption{redis.DialPassword(redisPassword)},
	})
	if err != nil {
		_ = loglevel.Crit("err", fmt.Sprintf("Infrastructure error: %v", err))
		return
	}
	defer infra.conn.Close()

	var svc CacheService
	svc = cacheService{}
	svc = loggingMiddleware(logger)(svc)

	cacheHandler := httptransport.NewServer(
		ctx,
		makeCacheEndpoint(svc),
		decodeCacheRequest,
		encodeResponse,
	)

	http.Handle("/cache", cacheHandler)
	_ = logger.Log("msg", "HTTP", "addr", *listen)
	_ = logger.Log("err", http.ListenAndServe(*listen, nil))
}
Пример #11
0
// RedisInfo executes an INFO command against a Redis server and returns the results.
func (p *Process) RedisInfo(addr string, timeout time.Duration) (*RedisInfo, error) {
	// Default to local process if addr not specified.
	if addr == "" {
		addr = fmt.Sprintf("localhost:%s", p.Port)
	}

	logger := p.Logger.New("fn", "replInfo", "addr", addr)
	logger.Info("sending INFO")

	// Connect to the redis server.
	conn, err := redis.Dial("tcp", addr,
		redis.DialPassword(p.Password),
		redis.DialConnectTimeout(timeout),
		redis.DialReadTimeout(timeout),
		redis.DialWriteTimeout(timeout),
	)
	if err != nil {
		logger.Info("dial error", "err", err)
		return nil, err
	}
	defer conn.Close()

	// Execute INFO command.
	reply, err := conn.Do("INFO")
	if err != nil {
		logger.Error("info error", "err", err)
		return nil, err
	}

	buf, ok := reply.([]byte)
	if !ok {
		logger.Error("info reply type error", "type", fmt.Sprintf("%T", buf))
		return nil, fmt.Errorf("unexpected INFO reply format: %T", buf)
	}

	// Parse the bulk string reply info a typed object.
	info, err := ParseRedisInfo(string(buf))
	if err != nil {
		logger.Error("parse info error", "err", err)
		return nil, fmt.Errorf("parse info: %s", err)
	}

	logger.Info("INFO received")
	return info, nil
}
Пример #12
0
// RedisPool will read env and init a redis pool
func RedisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   100,
		MaxActive: 12000,
		Dial: func() (redis.Conn, error) {
			addr := os.Getenv("REDIS_ADDR")
			port := os.Getenv("REDIS_PORT")
			passwd := os.Getenv("REDIS_PASSWD")
			option := redis.DialPassword(passwd)

			c, err := redis.Dial("tcp", addr+":"+port, option)
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
}
Пример #13
0
// creates a redis connection pool to use
func (r Redis) newPool(server, password string) *redis.Pool {
	return &redis.Pool{
		MaxIdle:     3,
		IdleTimeout: 5 * time.Second,
		Dial: func() (redis.Conn, error) {
			c, err := redis.DialURL(server, redis.DialConnectTimeout(30*time.Second),
				redis.DialWriteTimeout(10*time.Second), redis.DialPassword(password))

			if err != nil {
				return nil, fmt.Errorf("Failed to reach redis - %v", err)
			}
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
}
Пример #14
0
// Connection is to connect Redis server
func (rd *RD) setPool(host string, port uint16, pass string) {
	rd.Pool = &redis.Pool{
		MaxIdle:   80,
		MaxActive: 12000, // max number of connections
		Dial: func() (redis.Conn, error) {
			var c redis.Conn
			var err error
			if pass != "" {
				//plus password
				c, err = redis.Dial("tcp", fmt.Sprintf("%s:%d", host, port), redis.DialPassword(pass))
			} else {
				c, err = redis.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
			}
			if err != nil {
				panic(err.Error())
			}
			return c, err
		},
	}
}
Пример #15
0
func (p *RedisCounterStorage) initalPool() {
	p.pool = &redis.Pool{
		MaxIdle:     p.redisConfig.MaxIdle,
		IdleTimeout: p.redisConfig.IdleTimeout,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp",
				p.redisConfig.Address,
				redis.DialDatabase(p.redisConfig.Db),
				redis.DialPassword(p.redisConfig.Password))

			if err != nil {
				return nil, err
			}
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
		Wait: true,
	}
}
Пример #16
0
func (t *topology) PublishIPs(name string, localAddrs []string) error {
	if t.cfg.host == "" {
		debugf("Not publishing IPs because, no host configured")
	}

	dialOpts := []redis.DialOption{
		redis.DialPassword(t.cfg.password),
		redis.DialDatabase(t.cfg.db),
	}
	if t.transCfg != nil {
		d, err := transport.MakeDialer(t.transCfg)
		if err != nil {
			return err
		}
		dialOpts = append(dialOpts, redis.DialNetDial(d.Dial))
	}

	conn, err := redis.Dial("tcp", t.cfg.host, dialOpts...)
	if err != nil {
		return err
	}
	defer conn.Close()

	_, err = conn.Do("HSET", name, "ipaddrs", strings.Join(localAddrs, ","))
	if err != nil {
		logp.Err("[%s] Fail to set the IP addresses: %s", name, err)
		return err
	}

	_, err = conn.Do("EXPIRE", name, int(t.cfg.expire.Seconds()))
	if err != nil {
		logp.Err("[%s] Fail to set the expiration time: %s", name, err)
		return err
	}

	t.updateMap(conn)
	return nil
}
Пример #17
0
func testredis() {
	fmt.Printf("test redis")
	c, err := redis.Dial("tcp", "115.29.188.30:7379", redis.DialPassword("zouke7788"), redis.DialDatabase(7))
	if err != nil {
		panic(err)
	}
	defer c.Close()

	c.Send("SET", "go_basecode_lang", "xxxx1")
	c.Flush()
	c.Receive()

	c.Send("GET", "go_basecode_lang")
	c.Flush()
	value, err := c.Receive()
	if nil != err {
		panic(err)
	}

	fmt.Printf("%s", value)

	return
}
Пример #18
0
// Returns a new pool of Redis connections
func (redisBroker *RedisBroker) newPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:     100,
		IdleTimeout: 60 * time.Second,
		MaxActive:   300,
		Dial: func() (redis.Conn, error) {
			var (
				c    redis.Conn
				err  error
				opts = make([]redis.DialOption, 0)
			)

			if redisBroker.password != "" {
				opts = append(opts, redis.DialPassword(redisBroker.password))
			}

			if redisBroker.socketPath != "" {
				c, err = redis.Dial("unix", redisBroker.socketPath, opts...)
			} else {
				c, err = redis.Dial("tcp", redisBroker.host, opts...)
			}

			if redisBroker.db != 0 {
				_, err = c.Do("SELECT", redisBroker.db)
			}

			if err != nil {
				return nil, err
			}
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
}
Пример #19
0
func main() {
	var err error
	c, err = redis.DialURL("redis://fiadata.redis.cache.windows.net:6379", redis.DialPassword(os.Getenv("REDIS_DIAL_PASSWORD")))
	if err != nil {
		log.Fatal(err)
	}

	reply, err := c.Do("SET", "foo", "bar")
	if err != nil {
		log.Fatal(err)
	}

	log.Println(reply.(string))

	reply, err = c.Do("GET", "foo")
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(reply.([]uint8)))
	http.Handle("/", http.FileServer(http.Dir("./")))
	log.Println("Server started at http://localhost:8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
Пример #20
0
// GetCerts gets a list of certs from the database, or another cluster member.
func (r *Redis) GetCerts() ([]core.CertBundle, error) {
	if database.CentralStore {
		return database.GetCerts()
	}

	conn := pool.Get()
	defer conn.Close()

	// get known members(other than me) to 'poll' for certs
	members, _ := redis.Strings(conn.Do("SMEMBERS", "members"))
	if len(members) == 0 {
		// should only happen on new cluster
		// assume i'm ok to be master so don't reset imported certs
		config.Log.Trace("[cluster] - Assuming OK to be master, using certs from my database...")
		return common.GetCerts()
	}
	for i := range members {
		if members[i] == self {
			// if i'm in the list of members, new requests should have failed while `waitForMembers`ing
			config.Log.Trace("[cluster] - Assuming I was in sync, using certs from my database...")
			return common.GetCerts()
		}
	}

	c, err := redis.DialURL(config.ClusterConnection, redis.DialConnectTimeout(15*time.Second), redis.DialPassword(config.ClusterToken))
	if err != nil {
		return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err)
	}
	defer c.Close()

	message := make(chan interface{})
	subconn := redis.PubSubConn{c}

	// subscribe to channel that certs will be published on
	if err := subconn.Subscribe("certs"); err != nil {
		return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err)
	}
	defer subconn.Close()

	// listen always
	go func() {
		for {
			message <- subconn.Receive()
		}
	}()

	// todo: maybe use ttl?
	// timeout is how long to wait for the listed members to come back online
	timeout := time.After(time.Duration(20) * time.Second)

	// loop attempts for timeout, allows last dead members to start back up
	for {
		select {
		case <-timeout:
			return nil, fmt.Errorf("Timed out waiting for certs from %v", strings.Join(members, ", "))
		default:
			// request certs from each member until successful
			for _, member := range members {
				// memberTimeout is how long to wait for a member to respond with list of certs
				memberTimeout := time.After(3 * time.Second)

				// ask a member for its certs
				config.Log.Trace("[cluster] - Attempting to request certs from %v...", member)
				_, err := conn.Do("PUBLISH", "portal", fmt.Sprintf("get-certs %s", member))
				if err != nil {
					return nil, err
				}

				// wait for member to respond
				for {
					select {
					case <-memberTimeout:
						config.Log.Debug("[cluster] - Timed out waiting for certs from %v", member)
						goto nextCertMember
					case msg := <-message:
						switch v := msg.(type) {
						case redis.Message:
							config.Log.Trace("[cluster] - Received message on 'certs' channel")
							var certs []core.CertBundle
							err = parseBody(v.Data, &certs)
							if err != nil {
								return nil, fmt.Errorf("Failed to marshal certs - %v", err.Error())
							}
							config.Log.Trace("[cluster] - Certs from cluster: %#v\n", certs)
							return certs, nil
						case error:
							return nil, fmt.Errorf("Subscriber failed to receive certs - %v", v.Error())
						}
					}
				}
			nextCertMember:
			}
		}
	}
}
Пример #21
0
// updateMaster gets the address of the master node from sentinel
func updateMaster() error {
	config.Log.Debug("Contacting sentinel for address of master...")

	// connect to sentinel in order to query for the master address
	r, err := redis.DialURL("redis://"+config.SentinelAddress, redis.DialConnectTimeout(config.TimeoutNotReady), redis.DialReadTimeout(config.TimeoutSentinelPoll), redis.DialPassword(config.SentinelPassword))
	if err != nil {
		return fmt.Errorf("Failed to reach sentinel - %v", err)
	}

	// retrieve the master redis address
	addr, err := redis.Strings(r.Do("SENTINEL", "get-master-addr-by-name", config.MonitorName))
	if err != nil {
		return fmt.Errorf("Failed to get-master-addr-by-name - %v", err)
	}

	// cleanup after ourselves
	r.Close()

	// construct a useable address from sentinel's response
	masterAddr = fmt.Sprintf("%v:%v", addr[0], addr[1])
	config.Log.Debug("Master address: '%v'", masterAddr)

	// wait for redis to transition to master
	if err = verifyMaster(masterAddr, config.SentinelPassword); err != nil {
		return fmt.Errorf("Could not verify master - %v", err)
	}

	return nil
}
Пример #22
0
// verifyMaster verifies that the decided master node has fully transitioned
func verifyMaster(addr, pass string) error {
	// connect to redis in order to verify its state
	r, err := redis.DialURL("redis://"+addr, redis.DialConnectTimeout(config.TimeoutNotReady), redis.DialPassword(pass))
	if err != nil {
		return fmt.Errorf("Failed to reach redis at: '%v'", addr)
	}

	// give redis some time to transition
	timeout := time.After(config.TimeoutMasterWait)

	for {
		select {
		case <-timeout:
			return fmt.Errorf("Timed out waiting for redis to transition to master")
		default:
			// retrieve the redis node's role
			info, err := redis.Bytes(r.Do("INFO", "replication"))
			if err != nil {
				return fmt.Errorf("Failed to get INFO - %v", err)
			}

			// check if node is master
			if strings.Contains(string(info), "role:master") {
				return nil
			}
		}
	}

	// cleanup after ourselves
	r.Close()

	return nil
}
Пример #23
0
func TestMain(m *testing.M) {
	// clean test dir
	os.RemoveAll("/tmp/clusterTest")

	// initialize backend if redis-server found
	initialize()

	conn, err := redis.DialURL(config.ClusterConnection, redis.DialConnectTimeout(30*time.Second), redis.DialPassword(config.ClusterToken))
	if err != nil {
		return
	}
	hostname, _ := os.Hostname()
	self := fmt.Sprintf("%v:%v", hostname, config.ApiPort)
	defer conn.Do("SREM", "members", self)
	defer conn.Close()

	rtn := m.Run()

	// clean test dir
	os.RemoveAll("/tmp/clusterTest")
	// just in case, ensure clean members
	conn.Do("SREM", "members", self)
	conn.Close()

	os.Exit(rtn)
}
Пример #24
0
func (r *Redis) Init() error {
	hostname, _ := os.Hostname()
	self = fmt.Sprintf("%v:%v", hostname, config.ApiPort)
	pool = r.newPool(config.ClusterConnection, config.ClusterToken)

	// get services
	services, err := r.GetServices()
	if err != nil {
		return fmt.Errorf("Failed to get services - %v", err)
	}
	// write services
	if services != nil {
		config.Log.Trace("[cluster] - Setting services...")
		err = common.SetServices(services)
		if err != nil {
			return fmt.Errorf("Failed to set services - %v", err)
		}
	}

	// get routes
	routes, err := r.GetRoutes()
	if err != nil {
		return fmt.Errorf("Failed to get routes - %v", err)
	}
	// write routes
	if routes != nil {
		config.Log.Trace("[cluster] - Setting routes...")
		err = common.SetRoutes(routes)
		if err != nil {
			return fmt.Errorf("Failed to set routes - %v", err)
		}
	}

	// get certs
	certs, err := r.GetCerts()
	if err != nil {
		return fmt.Errorf("Failed to get certs - %v", err)
	}
	// write certs
	if certs != nil {
		config.Log.Trace("[cluster] - Setting certs...")
		err = common.SetCerts(certs)
		if err != nil {
			return fmt.Errorf("Failed to set certs - %v", err)
		}
	}

	// get vips
	vips, err := r.GetVips()
	if err != nil {
		return fmt.Errorf("Failed to get vips - %v", err)
	}
	// write vips
	if vips != nil {
		config.Log.Trace("[cluster] - Setting vips...")
		err = common.SetVips(vips)
		if err != nil {
			return fmt.Errorf("Failed to set vips - %v", err)
		}
	}

	// note: keep subconn connection initialization out here or sleep after `go r.subscribe()`
	// don't set read timeout on subscriber - it dies if no 'updates' within that time
	s, err := redis.DialURL(config.ClusterConnection, redis.DialConnectTimeout(30*time.Second), redis.DialPassword(config.ClusterToken))
	if err != nil {
		return fmt.Errorf("Failed to reach redis for subconn - %v", err)
	}

	r.subconn = redis.PubSubConn{s}
	r.subconn.Subscribe("portal")

	p := pool.Get()
	defer p.Close()

	p.Do("SET", self, "alive", "EX", ttl)
	_, err = p.Do("SADD", "members", self)
	if err != nil {
		return fmt.Errorf("Failed to add myself to list of members - %v", err)
	}

	go r.subscribe()
	go r.heartbeat()
	go r.cleanup()

	return nil
}
Пример #25
0
func main() {
	// Load the configuration
	m := multiconfig.NewWithPath(os.Getenv("config"))
	cfg := &dns.Config{}
	m.MustLoad(cfg)

	// Parse the log level
	lvl, err := log.LvlFromString(cfg.LogLevel)
	if err != nil {
		panic(err)
	}

	// Create a new logger
	l := log.New()
	l.SetHandler(
		log.LvlFilterHandler(lvl, log.StdoutHandler),
	)

	// Start the initialization
	il := l.New("module", "init")
	il.Info("Starting up the application")

	// Parse the Redis connection string
	url := redisurl.Parse(cfg.Redis)

	// Create an options list
	opts := []redis.DialOption{}
	if url.Database != 0 {
		opts = append(opts, redis.DialDatabase(url.Database))
	}
	if url.Password != "" {
		opts = append(opts, redis.DialPassword(url.Password))
	}

	// Verify the DNS setup
	results, err := net.LookupNS(cfg.Domain)
	if err != nil {
		il.Warn("Unable to look up the NS of domain", "domain", cfg.Domain, "error", err.Error())
	}
	if len(results) > 0 {
		found := false
		for _, record := range results {
			if record.Host == cfg.Hostname {
				found = true
			}
		}
		if !found {
			existing := []string{}
			for _, record := range results {
				existing = append(existing, record.Host)
			}

			il.Warn("Invalid NS records for the domain", "domain", cfg.Domain, "records", existing)
		}
	} else {
		il.Warn("No NS records found for domain", "domain", cfg.Domain, "error", err.Error())
	}

	// Dial the server
	rc, err := redis.Dial("tcp", url.Host+":"+strconv.Itoa(url.Port), opts...)
	if err != nil {
		il.Crit("Unable to connect to the Redis server", "error", err.Error())
		return
	}

	// Initialize the DNS server
	ds := &dns.DNS{
		Config: cfg,
		Redis:  rc,
	}
	if err := ds.ListenAndServe(); err != nil {
		il.Crit("Error while listening to the specified port", "error", err.Error())
	}
}