diff options
| author | Mark Nunberg <mnunberg@haskalah.org> | 2018-09-25 20:50:02 -0400 | 
|---|---|---|
| committer | Mark Nunberg <mnunberg@haskalah.org> | 2018-09-25 20:51:34 -0400 | 
| commit | 3cb4fb2395919ff91d29c7ab66634f5211eaca89 (patch) | |
| tree | 448b28137a37e265158ed99797b25506c7f505e9 | |
| parent | cbe4ae63aecee40674509a2bf23bc5db067e7f3d (diff) | |
| download | hiredict-3cb4fb2395919ff91d29c7ab66634f5211eaca89.tar.xz | |
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).
| -rw-r--r-- | test.c | 55 | 
1 files changed, 35 insertions, 20 deletions
| @@ -4,6 +4,7 @@  #include <string.h>  #include <strings.h>  #include <sys/time.h> +#include <netdb.h>  #include <assert.h>  #include <unistd.h>  #include <signal.h> @@ -91,7 +92,7 @@ static int disconnect(redisContext *c, int keep_fd) {      return -1;  } -static redisContext *connect(struct config config) { +static redisContext *do_connect(struct config config) {      redisContext *c = NULL;      if (config.type == CONN_TCP) { @@ -248,7 +249,7 @@ static void test_append_formatted_commands(struct config config) {      char *cmd;      int len; -    c = connect(config); +    c = do_connect(config);      test("Append format command: "); @@ -434,18 +435,32 @@ static void test_free_null(void) {  static void test_blocking_connection_errors(void) {      redisContext *c; - -    test("Returns error when host cannot be resolved: "); -    c = redisConnect((char*)"idontexist.test", 6379); -    test_cond(c->err == REDIS_ERR_OTHER && -        (strcmp(c->errstr,"Name or service not known") == 0 || -         strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 || -         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); +    struct addrinfo hints = {.ai_family = AF_INET}; +    struct addrinfo *ai_tmp = NULL; +    const char *bad_domain = "idontexist.com"; + +    int rv = getaddrinfo(bad_domain, "6379", &hints, &ai_tmp); +    if (rv != 0) { +        // Address does *not* exist +        test("Returns error when host cannot be resolved: "); +        // First see if this domain name *actually* resolves to NXDOMAIN +        c = redisConnect("dontexist.com", 6379); +        test_cond( +            c->err == REDIS_ERR_OTHER && +            (strcmp(c->errstr, "Name or service not known") == 0 || +             strcmp(c->errstr, "Can't resolve: sadkfjaskfjsa.com") == 0 || +             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: ");      c = redisConnect((char*)"localhost", 1); @@ -463,7 +478,7 @@ static void test_blocking_connection(struct config config) {      redisContext *c;      redisReply *reply; -    c = connect(config); +    c = do_connect(config);      test("Is able to deliver commands: ");      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";      struct timeval tv; -    c = connect(config); +    c = do_connect(config);      test("Successfully completes a command when the timeout is not exceeded: ");      reply = redisCommand(c,"SET foo fast");      freeReplyObject(reply); @@ -556,7 +571,7 @@ static void test_blocking_connection_timeouts(struct config config) {      freeReplyObject(reply);      disconnect(c, 0); -    c = connect(config); +    c = do_connect(config);      test("Does not return a reply when the command times out: ");      s = write(c->fd, cmd, strlen(cmd));      tv.tv_sec = 0; @@ -590,7 +605,7 @@ static void test_blocking_io_errors(struct config config) {      int major, minor;      /* 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 */          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);      redisFree(c); -    c = connect(config); +    c = do_connect(config);      test("Returns I/O error on socket timeout: ");      struct timeval tv = { 0, 1000 };      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) { -    redisContext *c = connect(config); +    redisContext *c = do_connect(config);      redisReply **replies;      int i, num;      long long t1, t2; | 
