static redisContext *connect(struct config config) { redisContext *c = NULL; if (config.type == CONN_TCP) { c = redisConnect(config.tcp.host, config.tcp.port); } else if (config.type == CONN_UNIX) { c = redisConnectUnix(config.unix.path); } else if (config.type == CONN_FD) { /* Create a dummy connection just to get an fd to inherit */ redisContext *dummy_ctx = redisConnectUnix(config.unix.path); if (dummy_ctx) { int fd = disconnect(dummy_ctx, 1); printf("Connecting to inherited fd %d\n", fd); c = redisConnectFd(fd); } } else { assert(NULL); } if (c == NULL) { printf("Connection error: can't allocate redis context\n"); exit(1); } else if (c->err) { printf("Connection error: %s\n", c->errstr); redisFree(c); exit(1); } return select_database(c); }
int connectToRemoteCache(void) { #ifdef HAVE_REDIS struct timeval timeout = { 1, 500000 }; // 1.5 seconds int num, i; if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_NORMAL, "[Redis] %s(%s:%u)", __FUNCTION__, readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port); /* Synchronous */ #ifndef WIN32 if(readOnlyGlobals.redis.remote_redis_host[0] == '/') readOnlyGlobals.redis.read_context = redisConnectUnix(readOnlyGlobals.redis.remote_redis_host); else #endif readOnlyGlobals.redis.read_context = redisConnectWithTimeout(readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port, timeout); if(readOnlyGlobals.redis.read_context->err) { traceEvent(TRACE_ERROR, "Redis Connection error: %s", readOnlyGlobals.redis.read_context->errstr); exit(-1); } /* Asynchronous */ for(i=0; i<MAX_NUM_REDIS_CONNECTIONS; i++) { #ifndef WIN32 if(readOnlyGlobals.redis.remote_redis_host[0] == '/') readOnlyGlobals.redis.write_context[i] = redisConnectUnix(readOnlyGlobals.redis.remote_redis_host); else #endif readOnlyGlobals.redis.write_context[i] = redisConnectWithTimeout(readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port, timeout); if(readOnlyGlobals.redis.write_context[i]->err) { traceEvent(TRACE_ERROR, "Redis Connection error: %s", readOnlyGlobals.redis.write_context[i]->errstr); exit(-1); } } pthread_rwlock_init(&readOnlyGlobals.redis.lock_get, NULL); for(i=0; i<MAX_NUM_REDIS_CONNECTIONS; i++) { unsigned long id = i; pthread_rwlock_init(&readOnlyGlobals.redis.lock_set_delete[i], NULL); pthread_create(&readOnlyGlobals.redis.reply_loop, NULL, redisAsyncLoop, (void*)id); } createLocalCacheServer(); #endif return(0); }
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); test("Returns error when the port is not open: "); c = redisConnect((char*)"localhost", 1); test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr,"Connection refused") == 0); redisFree(c); test("Returns error when the unix socket path doesn't accept connections: "); c = redisConnectUnix((char*)"/tmp/idontexist.sock"); test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ redisFree(c); }
/* Connect to the client. If force is not zero the connection is performed * even if there is already a connected socket. */ static int cliConnect(int force) { if (context == NULL || force) { if (context != NULL) redisFree(context); if (config.hostsocket == NULL) { context = redisConnect(config.hostip,config.hostport); } else { context = redisConnectUnix(config.hostsocket); } if (context->err) { fprintf(stderr,"Could not connect to Redis at "); if (config.hostsocket == NULL) fprintf(stderr,"%s:%d: %s\n",config.hostip,config.hostport,context->errstr); else fprintf(stderr,"%s: %s\n",config.hostsocket,context->errstr); redisFree(context); context = NULL; return REDIS_ERR; } /* Do AUTH and select the right DB. */ if (cliAuth() != REDIS_OK) return REDIS_ERR; if (cliSelect() != REDIS_OK) return REDIS_ERR; } return REDIS_OK; }
static ERL_NIF_TERM get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { redisContext *c; redisReply *reply; ErlNifBinary uid, ibin; if (!enif_inspect_binary(env, argv[0], &uid)) return enif_make_badarg(env); c = redisConnectUnix((const char*)"/tmp/redis.sock"); if (c->err) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "redis_connection_error")); } reply = redisCommand(c, "GET %b", uid.data, uid.size); redisFree(c); if(reply->type == REDIS_REPLY_NIL){ freeReplyObject(reply); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "nil_reply")); } else { enif_alloc_binary(reply->len, &ibin); memcpy(ibin.data, reply->str, reply->len); freeReplyObject(reply); return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &ibin)); } }
redisContext *_myredisConnect(struct config config) { redisContext *c = NULL; redisReply *reply; char cmd[256]; int len; if (config.type == CONN_TCP) { c = redisConnect(config.tcp.host, config.tcp.port); } else if (config.type == CONN_UNIX_SOCK) { c = redisConnectUnix(config.unix_sock.path); } else { assert(NULL); } if (c->err && pFile) { info_print("Connection error: %s\n", c->errstr); return c; } /* Authenticate */ if (config.auth) { reply = redisCommand(c,"AUTH %s",config.password); if(reply) { freeReplyObject(reply); } } return c; }
redisContext* _nss_redis_redis_connect() { if (c) { return c; } if(*_nss_redis_config.host == '/') { c = redisConnectUnix(_nss_redis_config.host); } else{ c = redisConnect(_nss_redis_config.host, _nss_redis_config.port); } if(c->err) { redisFree(c); c = NULL; goto connected; } if(_nss_redis_redis_auth(c) == false) { c = NULL; goto connected; } connected: return c; }
int mdb_connect_unix(const char *path) { _mdb.c = redisConnectUnix(path); if (!_mdb.c || _mdb.c->err) return -1; return 0; }
static ERL_NIF_TERM put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { redisContext *c; redisReply *reply = NULL; ErlNifBinary bucket, key, uid, world, val; if (!enif_inspect_binary(env, argv[0], &bucket)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &key)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[2], &world)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[3], &uid)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[4], &val)) return enif_make_badarg(env); c = redisConnectUnix((const char*)"/tmp/redis.sock"); if (c->err) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "redis_connection_error")); } redisAppendCommand(c, "MULTI"); redisAppendCommand(c, "SET %b %b", uid.data, uid.size, val.data, val.size); redisAppendCommand(c, "SADD %b %b", bucket.data, bucket.size, key.data, key.size); redisAppendCommand(c, "SADD %b %b", world.data, world.size, bucket.data, bucket.size); redisAppendCommand(c, "EXEC"); for (int i=0; i<6; i++) { redisReply *reply = NULL; redisGetReply(c, (void **) &reply); free(reply); } redisFree(c); return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_atom(env, "put")); }
static void __connect(redisContext **target) { *target = blocking_context = (use_unix ? redisConnectUnix("/tmp/redis.sock") : redisConnect((char*)"127.0.0.1", 6379)); if (blocking_context->err) { printf("Connection error: %s\n", blocking_context->errstr); exit(1); } }
static int lhiredis_connect(lua_State * L) { luahiredis_Connection * pResult = NULL; redisContext * pContext = NULL; const char * host_or_socket = luaL_checkstring(L, 1); /* TODO: Support Timeout and UnixTimeout flavors */ if (lua_isnoneornil(L, 2)) { pContext = redisConnectUnix(host_or_socket); } else { pContext = redisConnect(host_or_socket, luaL_checkint(L, 2)); } if (!pContext) { luaL_checkstack(L, 2, "not enough stack to push error"); lua_pushnil(L); lua_pushliteral(L, "failed to create hiredis context"); return 2; } if (pContext->err) { int result = push_error(L, pContext); redisFree(pContext); pContext = NULL; return result; } luaL_checkstack(L, 1, "not enough stack to create connection"); pResult = (luahiredis_Connection *)lua_newuserdata( L, sizeof(luahiredis_Connection) ); pResult->pContext = pContext; if (luaL_newmetatable(L, LUAHIREDIS_CONN_MT)) { /* Module table to be set as upvalue */ luaL_checkstack(L, 1, "not enough stack to register connection MT"); lua_pushvalue(L, lua_upvalueindex(1)); setfuncs(L, M, 1); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); } lua_setmetatable(L, -2); return 1; }
int main(){ char *socket = getenv("REDIS_UNIX_SOCKET"); if(!socket) { errx(1, "env REDIS_SOCKET is not defined"); } redisContext *r = redisConnectUnix(socket); if(r->err) { errx(1, "failed redisConnectUnix: '%s' %s", socket, r->errstr); } test_getpwnam(r); test_getpwuid(r); done_testing(); exit(0); }
static redisContext *connect(struct config config) { redisContext *c = NULL; if (config.type == CONN_TCP) { c = redisConnect(config.tcp.host, config.tcp.port); } else if (config.type == CONN_UNIX) { c = redisConnectUnix(config.unix.path); } else { assert(NULL); } if (c->err) { printf("Connection error: %s\n", c->errstr); exit(1); } return select_database(c); }
static ERL_NIF_TERM ping(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { redisContext *c; redisReply *reply; c = redisConnectUnix((const char*)"/tmp/redis.sock"); if (c->err) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "redis_connection_error")); } reply = redisCommand(c,"PING"); freeReplyObject(reply); redisFree(c); return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_atom(env, "pong")); }
static int lua_connect_unix (lua_State *L) { const char *path = luaL_checkstring(L, 1); int timeout = luaL_optint(L, 3, -1); int nonblock = lua_toboolean(L, 4); if (timeout == -1) { if (nonblock == 1) { redisContext *con = redisConnectUnixNonBlock(path); return pushConnection(L, con); } else { redisContext *con = redisConnectUnix(path); return pushConnection(L, con); } } else { struct timeval to; to.tv_sec = timeout; to.tv_usec = 0; redisContext *con = redisConnectUnixWithTimeout(path, to); return pushConnection(L, con); } };
/* Connect to the server. If force is not zero the connection is performed * even if there is already a connected socket. */ static int cliConnect(int force) { if (context == NULL || force) { if (context != NULL) redisFree(context); if (config.hostsocket == NULL) { context = redisConnect(config.hostip,config.hostport); } else { context = redisConnectUnix(config.hostsocket); } if (context->err) { fprintf(stderr,"Could not connect to Redis at "); if (config.hostsocket == NULL) fprintf(stderr,"%s:%d: %s\n",config.hostip,config.hostport,context->errstr); else fprintf(stderr,"%s: %s\n",config.hostsocket,context->errstr); redisFree(context); context = NULL; return REDIS_ERR; } /* Set aggressive KEEP_ALIVE socket option in the Redis context socket * in order to prevent timeouts caused by the execution of long * commands. At the same time this improves the detection of real * errors. */ anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL); /* Do AUTH and select the right DB. */ if (cliAuth() != REDIS_OK) return REDIS_ERR; if (cliSelect() != REDIS_OK) return REDIS_ERR; } return REDIS_OK; }
static int perform_redis_search(const uschar *command, uschar *server, uschar **resultptr, uschar **errmsg, BOOL *defer_break, uint *do_cache) { redisContext *redis_handle = NULL; /* Keep compilers happy */ redisReply *redis_reply = NULL; redisReply *entry = NULL; redisReply *tentry = NULL; redis_connection *cn; int ssize = 0; int offset = 0; int yield = DEFER; int i, j; uschar *result = NULL; uschar *server_copy = NULL; uschar *tmp, *ttmp; uschar *sdata[3]; /* Disaggregate the parameters from the server argument. The order is host:port(socket) We can write to the string, since it is in a nextinlist temporary buffer. This copy is also used for debugging output. */ memset(sdata, 0, sizeof(sdata)) /* Set all to NULL */; for (i = 2; i > 0; i--) { uschar *pp = Ustrrchr(server, '/'); if (!pp) { *errmsg = string_sprintf("incomplete Redis server data: %s", i == 2 ? server : server_copy); *defer_break = TRUE; return DEFER; } *pp++ = 0; sdata[i] = pp; if (i == 2) server_copy = string_copy(server); /* sans password */ } sdata[0] = server; /* What's left at the start */ /* If the database or password is an empty string, set it NULL */ if (sdata[1][0] == 0) sdata[1] = NULL; if (sdata[2][0] == 0) sdata[2] = NULL; /* See if we have a cached connection to the server */ for (cn = redis_connections; cn; cn = cn->next) if (Ustrcmp(cn->server, server_copy) == 0) { redis_handle = cn->handle; break; } if (!cn) { uschar *p; uschar *socket = NULL; int port = 0; /* int redis_err = REDIS_OK; */ if ((p = Ustrchr(sdata[0], '('))) { *p++ = 0; socket = p; while (*p != 0 && *p != ')') p++; *p = 0; } if ((p = Ustrchr(sdata[0], ':'))) { *p++ = 0; port = Uatoi(p); } else port = Uatoi("6379"); if (Ustrchr(server, '/')) { *errmsg = string_sprintf("unexpected slash in Redis server hostname: %s", sdata[0]); *defer_break = TRUE; return DEFER; } DEBUG(D_lookup) debug_printf("REDIS new connection: host=%s port=%d socket=%s database=%s\n", sdata[0], port, socket, sdata[1]); /* Get store for a new handle, initialize it, and connect to the server */ /* XXX: Use timeouts ? */ redis_handle = socket ? redisConnectUnix(CCS socket) : redisConnect(CCS server, port); if (!redis_handle) { *errmsg = string_sprintf("REDIS connection failed"); *defer_break = FALSE; goto REDIS_EXIT; } /* Add the connection to the cache */ cn = store_get(sizeof(redis_connection)); cn->server = server_copy; cn->handle = redis_handle; cn->next = redis_connections; redis_connections = cn; } else { DEBUG(D_lookup) debug_printf("REDIS using cached connection for %s\n", server_copy); } /* Authenticate if there is a password */ if(sdata[2]) if (!(redis_reply = redisCommand(redis_handle, "AUTH %s", sdata[2]))) { *errmsg = string_sprintf("REDIS Authentication failed: %s\n", redis_handle->errstr); *defer_break = FALSE; goto REDIS_EXIT; } /* Select the database if there is a dbnumber passed */ if(sdata[1]) { if (!(redis_reply = redisCommand(redis_handle, "SELECT %s", sdata[1]))) { *errmsg = string_sprintf("REDIS: Selecting database=%s failed: %s\n", sdata[1], redis_handle->errstr); *defer_break = FALSE; goto REDIS_EXIT; } DEBUG(D_lookup) debug_printf("REDIS: Selecting database=%s\n", sdata[1]); } /* split string on whitespace into argv */ { uschar * argv[32]; int i; const uschar * s = command; int siz, ptr; uschar c; while (isspace(*s)) s++; for (i = 0; *s && i < nele(argv); i++) { for (argv[i] = NULL, siz = ptr = 0; (c = *s) && !isspace(c); s++) if (c != '\\' || *++s) /* backslash protects next char */ argv[i] = string_cat(argv[i], &siz, &ptr, s, 1); *(argv[i]+ptr) = '\0'; DEBUG(D_lookup) debug_printf("REDIS: argv[%d] '%s'\n", i, argv[i]); while (isspace(*s)) s++; } /* Run the command. We use the argv form rather than plain as that parses into args by whitespace yet has no escaping mechanism. */ redis_reply = redisCommandArgv(redis_handle, i, (const char **) argv, NULL); if (!redis_reply) { *errmsg = string_sprintf("REDIS: query failed: %s\n", redis_handle->errstr); *defer_break = FALSE; goto REDIS_EXIT; } } switch (redis_reply->type) { case REDIS_REPLY_ERROR: *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str); *defer_break = FALSE; *do_cache = 0; goto REDIS_EXIT; /* NOTREACHED */ case REDIS_REPLY_NIL: DEBUG(D_lookup) debug_printf("REDIS: query was not one that returned any data\n"); result = string_sprintf(""); *do_cache = 0; goto REDIS_EXIT; /* NOTREACHED */ case REDIS_REPLY_INTEGER: ttmp = (redis_reply->integer != 0) ? US"true" : US"false"; result = string_cat(result, &ssize, &offset, US ttmp, Ustrlen(ttmp)); break; case REDIS_REPLY_STRING: case REDIS_REPLY_STATUS: result = string_cat(result, &ssize, &offset, US redis_reply->str, redis_reply->len); break; case REDIS_REPLY_ARRAY: /* NOTE: For now support 1 nested array result. If needed a limitless result can be parsed */ for (i = 0; i < redis_reply->elements; i++) { entry = redis_reply->element[i]; if (result) result = string_cat(result, &ssize, &offset, US"\n", 1); switch (entry->type) { case REDIS_REPLY_INTEGER: tmp = string_sprintf("%d", entry->integer); result = string_cat(result, &ssize, &offset, US tmp, Ustrlen(tmp)); break; case REDIS_REPLY_STRING: result = string_cat(result, &ssize, &offset, US entry->str, entry->len); break; case REDIS_REPLY_ARRAY: for (j = 0; j < entry->elements; j++) { tentry = entry->element[j]; if (result) result = string_cat(result, &ssize, &offset, US"\n", 1); switch (tentry->type) { case REDIS_REPLY_INTEGER: ttmp = string_sprintf("%d", tentry->integer); result = string_cat(result, &ssize, &offset, US ttmp, Ustrlen(ttmp)); break; case REDIS_REPLY_STRING: result = string_cat(result, &ssize, &offset, US tentry->str, tentry->len); break; case REDIS_REPLY_ARRAY: DEBUG(D_lookup) debug_printf("REDIS: result has nesting of arrays which" " is not supported. Ignoring!\n"); break; default: DEBUG(D_lookup) debug_printf( "REDIS: result has unsupported type. Ignoring!\n"); break; } } break; default: DEBUG(D_lookup) debug_printf("REDIS: query returned unsupported type\n"); break; } } break; } if (result) { result[offset] = 0; store_reset(result + offset + 1); } else { yield = FAIL; *errmsg = US"REDIS: no data found"; } REDIS_EXIT: /* Free store for any result that was got; don't close the connection, as it is cached. */ if (redis_reply) freeReplyObject(redis_reply); /* Non-NULL result indicates a sucessful result */ if (result) { *resultptr = result; return OK; } else { DEBUG(D_lookup) debug_printf("%s\n", *errmsg); /* NOTE: Required to close connection since it needs to be reopened */ return yield; /* FAIL or DEFER */ } }
int main(int argc, char *argv[]) { int ret = 1; size_t bufSize = 8192; int batchSize = 2000; if (argc > 1) { batchSize = atoi(argv[1]); if (batchSize <= 0) { fprintf(stderr, "Dodgy batch size\n"); exit(1); } } char *buffer = calloc(bufSize, sizeof(char)); uint64_t cnt = 0; redisReply *reply = NULL; redisContext *c = redisConnectUnix("/var/lib/redis/redis.sock"); if (c != NULL && c->err) { printf("Error: %s\n", c->errstr); goto cleanup; } reply = redisCommand(c, "DEL testhll"); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } freeReplyObject(reply); int batchPos = 0; int len = 0; while ((len = readln(stdin, '\n', &buffer, &bufSize)) > 0) { cnt++; redisAppendCommand(c, "PFADD testhll %s", buffer); batchPos++; if (batchSize == batchPos) { batchPos = 0; for (int j = 0; j < batchSize; j++) { redisGetReply(c, (void **)&reply); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } else if (reply->type == REDIS_REPLY_ERROR) { printf("Failed: %s\n", reply->str); goto cleanup; } freeReplyObject(reply); } } } if (batchPos > 0) { for (int j = 0; j < batchPos; j++) { redisGetReply(c, (void **)&reply); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } else if (reply->type == REDIS_REPLY_ERROR) { printf("Failed: %s\n", reply->str); goto cleanup; } freeReplyObject(reply); } } reply = redisCommand(c, "PFCOUNT testhll"); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } printf("%ld %lld\n", cnt, reply->integer); ret = 0; cleanup: if (reply != NULL) freeReplyObject(reply); free(buffer); redisFree(c); return ret; }
/* Internal host connect - Sync or Async */ static int _host_connect( host_t *h, eredis_reader_t *r ) { redisContext *c; if (r) { /* Sync - not in EV context */ c = (h->port) ? redisConnect( h->target, h->port ) : redisConnectUnix( h->target ); if (! c) { fprintf(stderr, "eredis: error: connect sync %s NULL\n", h->target); return 0; } if (c->err) { #if EREDIS_VERBOSE>0 printf( "eredis: error: connect sync %s %d\n", h->target, c->err); #endif redisFree( c ); return 0; } r->ctx = c; r->host = h; } else { redisAsyncContext *ac; /* ASync - in EV context */ ac = (h->port) ? redisAsyncConnect( h->target, h->port ) : redisAsyncConnectUnix( h->target ); if (! ac) { printf( "eredis: error: connect async %s undef\n", h->target); return 0; } if (ac->err) { #if EREDIS_VERBOSE>0 printf( "eredis: error: connect async %s %d\n", h->target, ac->err); #endif redisAsyncFree( ac ); return 0; } h->async_ctx = ac; /* data for _redis_*_cb */ ac->data = h; /* Order is important here */ /* attach */ redisLibevAttach( h->e->loop, ac ); /* set callbacks */ redisAsyncSetDisconnectCallback( ac, _redis_disconnect_cb ); redisAsyncSetConnectCallback( ac, _redis_connect_cb ); c = (redisContext*) ac; } /* Apply keep-alive */ #ifdef HOST_TCP_KEEPALIVE if (h->port) { redisEnableKeepAlive( c ); if (r && (h->e->sync_to.tv_sec||h->e->sync_to.tv_usec)) { redisSetTimeout( c, h->e->sync_to ); } } #endif /* Override the maxbuf */ c->reader->maxbuf = EREDIS_READER_MAX_BUF; return 1; }