Skip to content

Commit

Permalink
Make use of updated redis module status response
Browse files Browse the repository at this point in the history
  • Loading branch information
abedra committed Jun 10, 2019
1 parent 1e48fe2 commit 205116a
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 91 deletions.
99 changes: 35 additions & 64 deletions ngx_http_repsheet_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,80 +75,51 @@ ngx_int_t evaluate_cache_connection(ngx_http_request_t *r, repsheet_main_conf_t
return NGX_OK;
}

Status status(redisContext *context, char *actor) {
redisReply *reply;
reply = redisCommand(context, "REPSHEET.STATUS %s", actor);
void free_cache_status(repsheet_cache_status_t *cache_status) {
free(cache_status->status_str);
free(cache_status->reason);
free(cache_status);
}

repsheet_cache_status_t *status(redisContext *context, char *actor) {
repsheet_cache_status_t *cache_status = malloc(sizeof(repsheet_cache_status_t));
redisReply *reply = redisCommand(context, "REPSHEET.STATUS %s", actor);

if (reply) {
if (reply->type == REDIS_REPLY_ERROR) {
freeReplyObject(reply);
return DISCONNECTED;
cache_status->status = DISCONNECTED;
return cache_status;
} else if (reply->type != REDIS_REPLY_ARRAY) {
freeReplyObject(reply);
cache_status->status = ERROR;
return cache_status;
} else {
char *message = reply->str;

if (ngx_strncmp(message, "WHITELISTED", ngx_strlen(message)) == 0) {
freeReplyObject(reply);
return WHITELISTED;
}

if (ngx_strncmp(message, "BLACKLISTED", ngx_strlen(message)) == 0) {
freeReplyObject(reply);
return BLACKLISTED;
}

if (ngx_strncmp(message, "MARKED", ngx_strlen(message)) == 0) {
freeReplyObject(reply);
return MARKED;
if (reply->elements != 2) {
cache_status->status = ERROR;
return cache_status;
}

cache_status->status_str = strdup(reply->element[0]->str);
cache_status->reason = strdup(reply->element[1]->str);
freeReplyObject(reply);
return OK;
}
} else {
return DISCONNECTED;
}
}

// TODO: Fold reason fetch into status to prevent additional calls
ngx_int_t get_reason(redisContext *context, char *actor, Status status, char *reason) {
redisReply *reply;

switch (status) {
case WHITELISTED:
reply = redisCommand(context, "GET %s:repsheet:ip:whitelisted", actor);
break;
case BLACKLISTED:
reply = redisCommand(context, "GET %s:repsheet:ip:blacklisted", actor);
break;
case MARKED:
reply = redisCommand(context, "GET %s:repsheet:ip:marked", actor);
break;
default:
return INVALID;
}

if (reply) {
if (reply->type == REDIS_REPLY_ERROR) {
freeReplyObject(reply);
return DISCONNECTED;
} else {
ngx_memcpy(reason, reply->str, reply->len);
freeReplyObject(reply);
return OK;
if (ngx_strncmp(cache_status->status_str, "WHITELISTED", ngx_strlen(cache_status->status_str)) == 0) {
cache_status->status = WHITELISTED;
return cache_status;
} else if (ngx_strncmp(cache_status->status_str, "BLACKLISTED", ngx_strlen(cache_status->status_str)) == 0) {
cache_status->status = BLACKLISTED;
return cache_status;
} else if (ngx_strncmp(cache_status->status_str, "MARKED", ngx_strlen(cache_status->status_str)) == 0) {
cache_status->status = MARKED;
return cache_status;
} else {
cache_status->status = OK;
return cache_status;
}
}
} else {
return DISCONNECTED;
cache_status->status = DISCONNECTED;
return cache_status;
}
}

ngx_int_t is_ip_whitelisted(Status status) {
return status == WHITELISTED;
}

ngx_int_t is_ip_blacklisted(Status status) {
return status == BLACKLISTED;
}

ngx_int_t is_ip_marked(Status status) {
return status == MARKED;
}
7 changes: 2 additions & 5 deletions ngx_http_repsheet_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
#include "ngx_http_repsheet_module.h"

ngx_int_t evaluate_cache_connection(ngx_http_request_t *r, repsheet_main_conf_t *main_conf);
Status status(redisContext *context, char *actor);
ngx_int_t is_ip_whitelisted(Status status);
ngx_int_t is_ip_blacklisted(Status status);
ngx_int_t is_ip_marked(Status status);
ngx_int_t get_reason(redisContext *context, char *actor, Status status, char *reason);
repsheet_cache_status_t *status(redisContext *context, char *actor);
void free_cache_status(repsheet_cache_status_t *cache_status);

#endif
47 changes: 25 additions & 22 deletions ngx_http_repsheet_lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,36 +27,39 @@ ngx_int_t lookup_ip(ngx_http_request_t *r, repsheet_main_conf_t *main_conf, reps
return NGX_HTTP_FORBIDDEN;
}

Status lookup_result = status(main_conf->redis.connection, address);
repsheet_cache_status_t *cache_status = status(main_conf->redis.connection, address);

if (lookup_result == DISCONNECTED) {
if (cache_status->status == DISCONNECTED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - The Redis request failed, bypassing further operations");
free_cache_status(cache_status);
return NGX_DECLINED;
}

char reason[MAX_REASON_LENGTH];
memset(reason, '\0', MAX_REASON_LENGTH);
int reason_result = get_reason(main_conf->redis.connection, address, lookup_result, reason);

if (lookup_result != OK) {
if (reason_result == DISCONNECTED || reason_result == INVALID) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - Could not retrieve reason");
ngx_memcpy(reason, "UNKNOWN", 7);
}

if (is_ip_marked(lookup_result)) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s was found on repsheet. Reason: %s", address, reason);
if (cache_status->status != OK) {
if (cache_status->status == INVALID) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - Could not retrieve reason, bypassing");
free_cache_status(cache_status);
return NGX_DECLINED;
} else if (cache_status->status == MARKED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s was found on repsheet. Reason: %s", address, cache_status->reason);
set_repsheet_header(r);
}

if (lookup_result == WHITELISTED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s is whitelisted by repsheet. Reason: %s", address, reason);
free_cache_status(cache_status);
return NGX_DECLINED;
} else if (cache_status->status == WHITELISTED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s is whitelisted by repsheet. Reason: %s", address, cache_status->reason);
free_cache_status(cache_status);
return NGX_DECLINED;
} else if (lookup_result == BLACKLISTED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s was blocked by repsheet. Reason: %s", address, reason);
} else if (cache_status->status == BLACKLISTED) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - IP %s was blocked by repsheet. Reason: %s", address, cache_status->reason);
free_cache_status(cache_status);
return NGX_HTTP_FORBIDDEN;
} else {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[Repsheet] - Invalid status %s, bypassing", cache_status->status_str);
free_cache_status(cache_status);
return NGX_DECLINED;
}
} else {
free_cache_status(cache_status);
return NGX_DECLINED;
}

return NGX_DECLINED;
}
7 changes: 7 additions & 0 deletions ngx_http_repsheet_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define BLACKLISTED 2
#define MARKED 3
#define INVALID 4
#define ERROR 5

#define MAX_REASON_LENGTH 1024

Expand All @@ -17,6 +18,12 @@

typedef int Status;

typedef struct {
Status status;
char *status_str;
char *reason;
} repsheet_cache_status_t;

typedef struct {
ngx_str_t host;
ngx_uint_t port;
Expand Down

0 comments on commit 205116a

Please sign in to comment.