Skip NXDOMAIN test when using evil ISPs
Some ISPs like to inject their own "Suggestions" page whenever you hit NXDOMAIN. This confuses Redis as well as addrinfo (black-holing the route).
This commit is contained in:
parent
cbe4ae63ae
commit
3cb4fb2395
53
test.c
53
test.c
@ -4,6 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -91,7 +92,7 @@ static int disconnect(redisContext *c, int keep_fd) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static redisContext *connect(struct config config) {
|
static redisContext *do_connect(struct config config) {
|
||||||
redisContext *c = NULL;
|
redisContext *c = NULL;
|
||||||
|
|
||||||
if (config.type == CONN_TCP) {
|
if (config.type == CONN_TCP) {
|
||||||
@ -248,7 +249,7 @@ static void test_append_formatted_commands(struct config config) {
|
|||||||
char *cmd;
|
char *cmd;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
|
|
||||||
test("Append format command: ");
|
test("Append format command: ");
|
||||||
|
|
||||||
@ -434,18 +435,32 @@ static void test_free_null(void) {
|
|||||||
|
|
||||||
static void test_blocking_connection_errors(void) {
|
static void test_blocking_connection_errors(void) {
|
||||||
redisContext *c;
|
redisContext *c;
|
||||||
|
struct addrinfo hints = {.ai_family = AF_INET};
|
||||||
|
struct addrinfo *ai_tmp = NULL;
|
||||||
|
const char *bad_domain = "idontexist.com";
|
||||||
|
|
||||||
test("Returns error when host cannot be resolved: ");
|
int rv = getaddrinfo(bad_domain, "6379", &hints, &ai_tmp);
|
||||||
c = redisConnect((char*)"idontexist.test", 6379);
|
if (rv != 0) {
|
||||||
test_cond(c->err == REDIS_ERR_OTHER &&
|
// Address does *not* exist
|
||||||
(strcmp(c->errstr,"Name or service not known") == 0 ||
|
test("Returns error when host cannot be resolved: ");
|
||||||
strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
|
// First see if this domain name *actually* resolves to NXDOMAIN
|
||||||
strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
|
c = redisConnect("dontexist.com", 6379);
|
||||||
strcmp(c->errstr,"No address associated with hostname") == 0 ||
|
test_cond(
|
||||||
strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
|
c->err == REDIS_ERR_OTHER &&
|
||||||
strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 ||
|
(strcmp(c->errstr, "Name or service not known") == 0 ||
|
||||||
strcmp(c->errstr,"no address associated with name") == 0));
|
strcmp(c->errstr, "Can't resolve: sadkfjaskfjsa.com") == 0 ||
|
||||||
redisFree(c);
|
strcmp(c->errstr,
|
||||||
|
"nodename nor servname provided, or not known") == 0 ||
|
||||||
|
strcmp(c->errstr, "No address associated with hostname") == 0 ||
|
||||||
|
strcmp(c->errstr, "Temporary failure in name resolution") == 0 ||
|
||||||
|
strcmp(c->errstr,
|
||||||
|
"hostname nor servname provided, or not known") == 0 ||
|
||||||
|
strcmp(c->errstr, "no address associated with name") == 0));
|
||||||
|
redisFree(c);
|
||||||
|
} else {
|
||||||
|
printf("Skipping NXDOMAIN test. Found evil ISP!\n");
|
||||||
|
freeaddrinfo(ai_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
test("Returns error when the port is not open: ");
|
test("Returns error when the port is not open: ");
|
||||||
c = redisConnect((char*)"localhost", 1);
|
c = redisConnect((char*)"localhost", 1);
|
||||||
@ -463,7 +478,7 @@ static void test_blocking_connection(struct config config) {
|
|||||||
redisContext *c;
|
redisContext *c;
|
||||||
redisReply *reply;
|
redisReply *reply;
|
||||||
|
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
|
|
||||||
test("Is able to deliver commands: ");
|
test("Is able to deliver commands: ");
|
||||||
reply = redisCommand(c,"PING");
|
reply = redisCommand(c,"PING");
|
||||||
@ -544,7 +559,7 @@ static void test_blocking_connection_timeouts(struct config config) {
|
|||||||
const char *cmd = "DEBUG SLEEP 3\r\n";
|
const char *cmd = "DEBUG SLEEP 3\r\n";
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
test("Successfully completes a command when the timeout is not exceeded: ");
|
test("Successfully completes a command when the timeout is not exceeded: ");
|
||||||
reply = redisCommand(c,"SET foo fast");
|
reply = redisCommand(c,"SET foo fast");
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
@ -556,7 +571,7 @@ static void test_blocking_connection_timeouts(struct config config) {
|
|||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
disconnect(c, 0);
|
disconnect(c, 0);
|
||||||
|
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
test("Does not return a reply when the command times out: ");
|
test("Does not return a reply when the command times out: ");
|
||||||
s = write(c->fd, cmd, strlen(cmd));
|
s = write(c->fd, cmd, strlen(cmd));
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
@ -590,7 +605,7 @@ static void test_blocking_io_errors(struct config config) {
|
|||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
/* Connect to target given by config. */
|
/* Connect to target given by config. */
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
{
|
{
|
||||||
/* Find out Redis version to determine the path for the next test */
|
/* Find out Redis version to determine the path for the next test */
|
||||||
const char *field = "redis_version:";
|
const char *field = "redis_version:";
|
||||||
@ -625,7 +640,7 @@ static void test_blocking_io_errors(struct config config) {
|
|||||||
strcmp(c->errstr,"Server closed the connection") == 0);
|
strcmp(c->errstr,"Server closed the connection") == 0);
|
||||||
redisFree(c);
|
redisFree(c);
|
||||||
|
|
||||||
c = connect(config);
|
c = do_connect(config);
|
||||||
test("Returns I/O error on socket timeout: ");
|
test("Returns I/O error on socket timeout: ");
|
||||||
struct timeval tv = { 0, 1000 };
|
struct timeval tv = { 0, 1000 };
|
||||||
assert(redisSetTimeout(c,tv) == REDIS_OK);
|
assert(redisSetTimeout(c,tv) == REDIS_OK);
|
||||||
@ -659,7 +674,7 @@ static void test_invalid_timeout_errors(struct config config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_throughput(struct config config) {
|
static void test_throughput(struct config config) {
|
||||||
redisContext *c = connect(config);
|
redisContext *c = do_connect(config);
|
||||||
redisReply **replies;
|
redisReply **replies;
|
||||||
int i, num;
|
int i, num;
|
||||||
long long t1, t2;
|
long long t1, t2;
|
||||||
|
Loading…
Reference in New Issue
Block a user