Exemple #1
0
void cleanup(void) {
	if(db) {
		redisAsyncFree(db);
		db = NULL;
	}
	sspCleanup();
}
Exemple #2
0
redisAsyncContext *
redis_nginx_open_context(u_char *host, int port, int database, u_char *password, redisAsyncContext **context)
{
    redisAsyncContext *ac = NULL;

    if ((context == NULL) || (*context == NULL) || (*context)->err) {
        ac = redisAsyncConnect((const char *)host, port);
        if (ac == NULL) {
            ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "redis_nginx_adapter: could not allocate the redis context for %s:%d", host, port);
            return NULL;
        }

        if (ac->err) {
            ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "redis_nginx_adapter: could not create the redis context for %s:%d - %s", host, port, ac->errstr);
            redisAsyncFree(ac);
            return NULL;
        }

        redis_nginx_event_attach(ac);

        if (context != NULL) {
            *context = ac;
        }
        if(password) {
          redisAsyncCommand(ac, redis_nginx_auth_callback, context, AUTH_COMMAND, password);
        }
        redisAsyncCommand(ac, redis_nginx_select_callback, context, SELECT_DATABASE_COMMAND, database);
    } else {
        ac = *context;
    }

    return ac;
}
Exemple #3
0
RedisProxy::~RedisProxy()
{
 /*   if (_connected && nullptr != _context) {
        redisAsyncDisconnect(_context);
    }*/

    if (nullptr != _context) {
        redisAsyncFree(_context);
        _context = nullptr;
    }
}
Exemple #4
0
static void dispatch_conn_context_deinit(conn_context *cc)
{
    if (cc->ctx) {
        redisFree(cc->ctx);
        cc->ctx == NULL;
    }

    if (cc->actx) {
        redisAsyncFree(cc->actx);
        cc->actx == NULL;
    }
}
Exemple #5
0
void 
redis_nginx_auth_callback(redisAsyncContext *ac, void *rep, void *privdata)
{
    redisAsyncContext **context = privdata;
    redisReply *reply = rep;
    if ((reply == NULL) || (reply->type == REDIS_REPLY_ERROR)) {
        if (context != NULL) {
            *context = NULL;
        }
        ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "redis_nginx_adapter: AUTH command failed, probably because the password is incorrect");
        redisAsyncFree(ac);
    }
}
Exemple #6
0
void
redis_nginx_select_callback(redisAsyncContext *ac, void *rep, void *privdata)
{
    //redisAsyncContext **context = privdata;
    redisReply *reply = rep;
    if ((reply == NULL) || (reply->type == REDIS_REPLY_ERROR)) {
        /*if (context != NULL) {
            *context = NULL;
        }*/
        ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "redis_nginx_adapter: could not select redis database");
        redisAsyncFree(ac);
    }
}
Exemple #7
0
static void
lua_redis_fin (void *arg)
{
	struct lua_redis_userdata *ud = arg;

	if (ud->ctx) {
		ud->terminated = 1;
		redisAsyncFree (ud->ctx);
		lua_redis_free_args (ud);
		event_del (&ud->timeout);
		luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
	}
}
Exemple #8
0
/**
 * Detect disconnection of a pub/sub client. We need to clean up the command.
 */
void on_http_disconnect(struct evhttp_connection *evcon, void *ctx) {
	struct pubsub_client *ps = ctx;

	(void)evcon;

	/* clean up redis object */
	redisAsyncFree(ps->s->ac);

	/* clean up command object */
	if(ps->cmd) {
		cmd_free(ps->cmd);
	}
	free(ps);
}
Exemple #9
0
/** \brief QUIT command
 *         Emits and awaits response for an async QUIT command.
 *         It's used to disconnect with redis
 *  \param ctx redis context
 */
static void SCLogAsyncRedisSendQuit(SCLogRedisContext * ctx)
{
    if (ctx->connected) {
        redisAsyncCommand(ctx->async, SCRedisAsyncQuitCommandCallback, ctx, "QUIT");
        SCLogInfo("QUIT Command sent to redis. Connection will terminate!");
    }

    redisAsyncFree(ctx->async);
    event_base_dispatch(ctx->ev_base);
    ctx->async = NULL;
    event_base_free(ctx->ev_base);
    ctx->ev_base = NULL;
    ctx->connected = 0;
}
Exemple #10
0
void RedisProxy::connect()
{
    if(_connected) {
        return;
    }
    SLOG(DEBUG) << "redis connect begin...";

    _context = redisAsyncConnect(_ip.c_str(), _port);
    if(!_context)
    {
        SLOG(WARNING) << "allocate redis async connection fail!";
        return;
    }

    if(_context->err != 0)
    {
        SLOG(WARNING) << "connect fail[" << _context->err << "]";
        redisAsyncFree(_context);
        _context = nullptr;
        return;
    }

    _context->data = this;
    _context->ev.data = this;
    _context->ev.addRead = RedisProxy::redis_add_read;
    _context->ev.delRead = RedisProxy::redis_del_read;
    _context->ev.addWrite = RedisProxy::redis_add_write;
    _context->ev.delWrite = RedisProxy::redis_del_write;
    _context->ev.cleanup = RedisProxy::redis_cleanup;

    
    _read_io = std::make_shared<IO>(_context->c.fd, EV_READ, false);//FIXME:add EV_ET in future
    _read_io->on_read([this]() {
        LOG(INFO) << "on read";
        redisAsyncHandleRead(_context);        
    });
    _write_io = std::make_shared<IO>(_context->c.fd, EV_WRITE, false);//FIXME:add EV_ET in future
    LOG(INFO) << "redis fd:" << _context->c.fd;
    _write_io->on_write([this]() {
        LOG(INFO) << "on write";
        redisAsyncHandleWrite(_context);
    });

    _connected = get_local_loop()->add_io(_read_io, false)
        && get_local_loop()->add_io(_write_io, false);

    redisAsyncSetConnectCallback(_context, RedisProxy::handle_connect);
    redisAsyncSetDisconnectCallback(_context, RedisProxy::handle_disconnect);
}
int RedisConnectionAsync::asyncConnect()
{
    _ac = redisAsyncConnect(_host.c_str(), _port);
    if (_ac == nullptr) return -1;
    _ac->data = (void*)this;

    if (_ac->err) {
        redisAsyncFree(_ac);
        _ac = nullptr;
        return -1;
        // throw RedisException((std::string)"RedisAsyncConnect: "+_ac->errstr);
    }
    if (redisAsyncSetConnectCallback(_ac, &connected)!=REDIS_OK ||
        redisAsyncSetDisconnectCallback(_ac, &disconnected)!=REDIS_OK) {
        redisAsyncFree(_ac);
        _ac = nullptr;
        return -1;
        // throw RedisException("RedisAsyncConnect: Can't register callbacks");
    }

#if HIREDISPP_USE_LIBEVENT
    if (redisLibeventAttach(_ac, (struct event_base *)_loopbase)!=REDIS_OK) {
        redisAsyncFree(_ac);
        _ac = nullptr;
        return -1;
        // throw RedisException("redisLibeventAttach: nothing should be attached when something is already attached");
    }
    // Send PING command, so libevent start working
    redisAsyncCommand(_ac, nullptr, nullptr, "PING");
#else
    // actually start io proccess
    ev_io_start(EV_DEFAULT, &((((redisLibevEvents*)(_ac->ev.data)))->rev));
    ev_io_start(EV_DEFAULT, &((((redisLibevEvents*)(_ac->ev.data)))->wev));
#endif
    return 0;
}
Exemple #12
0
/**
 * @brief Stop eredis and free all ressources allocated
 *
 * @param e eredis
 */
  void
eredis_free( eredis_t *e )
{
  int i;
  char *s;
  eredis_reader_t *r;

  /* Flag for shutdown */
  SET_SHUTDOWN(e);

  /* Loop trash */
  if (e->loop) {
    if (IS_INTHR( e )) /* Thread - wait to EVBREAK_ALL */
      pthread_join( e->async_thr, NULL );
    else /* Re-run loop until EVBREAK_ALL */
      eredis_run( e );

    ev_loop_destroy( e->loop );
    e->loop = NULL;
  }

  /* Shutdown what's left */
  for (i=0; i<e->hosts_nb; i++) {
    host_t *h = &e->hosts[i];
    if (h->async_ctx)
      redisAsyncFree( h->async_ctx );
    free(h->target);
  }
  free(e->hosts);

  /* Clear rqueue */
  while ((r = _eredis_rqueue_shift( e ))) {
    if (r->free)
      _eredis_reader_free( r );
    else
      fprintf(stderr,"eredis: eredis_free: reader not in 'free' state!?\n");
  }

  /* Clear wqueue */
  while ((s = _eredis_wqueue_shift( e, NULL )))
    free(s);

  pthread_mutex_destroy( &e->async_lock );
  pthread_mutex_destroy( &e->reader_lock );
  pthread_cond_destroy( &e->reader_cond );

  free(e);
}
Exemple #13
0
void
rspamd_redis_finalize_learn (struct rspamd_task *task, gpointer runtime,
		gpointer ctx)
{
	struct redis_stat_runtime *rt = REDIS_RUNTIME (runtime);
	redisAsyncContext *redis;

	if (event_get_base (&rt->timeout_event)) {
		event_del (&rt->timeout_event);
	}

	if (rt->redis) {
		redis = rt->redis;
		rt->redis = NULL;
		redisAsyncFree (redis);
	}
}
Exemple #14
0
/* Called on connection termination */
static void
rspamd_redis_cache_fin (gpointer data)
{
	struct rspamd_redis_cache_runtime *rt = data;
	redisAsyncContext *redis;

	rt->has_event = FALSE;
	if (event_get_base (&rt->timeout_event)) {
		event_del (&rt->timeout_event);
	}

	if (rt->redis) {
		redis = rt->redis;
		rt->redis = NULL;
		/* This calls for all callbacks pending */
		redisAsyncFree (redis);
	}
}
Exemple #15
0
/** \brief SCConfLogReopenAsyncRedis() Open or re-opens connection to redis for logging.
 *  \param log_ctx Log file context allocated by caller
 */
static int SCConfLogReopenAsyncRedis(LogFileCtx *log_ctx)
{
    SCLogRedisContext * ctx = log_ctx->redis;
    const char *redis_server = log_ctx->redis_setup.server;
    int redis_port = log_ctx->redis_setup.port;

    /* only try to reconnect once per second */
    if (ctx->tried >= time(NULL)) {
        return -1;
    }

    ctx->async = redisAsyncConnect(redis_server, redis_port);

    if (ctx->ev_base != NULL) {
        event_base_free(ctx->ev_base);
    }

    if (ctx->async == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC, "Error allocate redis async.");
        ctx->tried = time(NULL);
        return -1;
    }

    if (ctx->async != NULL && ctx->async->err) {
        SCLogError(SC_ERR_SOCKET, "Error setting to redis async: [%s].", ctx->async->errstr);
        ctx->tried = time(NULL);
        return -1;
    }

    ctx->ev_base = event_base_new();

    if (ctx->ev_base == NULL) {
        ctx->tried = time(NULL);
        redisAsyncFree(ctx->async);
        ctx->async = NULL;
        return -1;
    }

    redisLibeventAttach(ctx->async, ctx->ev_base);

    log_ctx->redis = ctx;
    log_ctx->Close = SCLogFileCloseRedis;
    return 0;
}
Exemple #16
0
static void
rspamd_redis_fin_learn (gpointer data)
{
	struct redis_stat_runtime *rt = REDIS_RUNTIME (data);
	redisAsyncContext *redis;

	rt->has_event = FALSE;
	/* Stop timeout */
	if (event_get_base (&rt->timeout_event)) {
		event_del (&rt->timeout_event);
	}

	if (rt->redis) {
		redis = rt->redis;
		rt->redis = NULL;
		/* This calls for all callbacks pending */
		redisAsyncFree (redis);
	}
}
Exemple #17
0
static void
rspamd_redis_async_cbdata_cleanup (struct rspamd_redis_stat_cbdata *cbdata)
{
	guint i;
	gchar *k;

	if (cbdata && !cbdata->wanna_die) {
		/* Avoid double frees */
		cbdata->wanna_die = TRUE;
		redisAsyncFree (cbdata->redis);

		for (i = 0; i < cbdata->cur_keys->len; i ++) {
			k = g_ptr_array_index (cbdata->cur_keys, i);
			g_free (k);
		}

		g_ptr_array_free (cbdata->cur_keys, TRUE);

		if (cbdata->elt) {
			cbdata->elt->cbdata = NULL;
			/* Re-enable parent event */
			cbdata->elt->async->enabled = TRUE;

			/* Replace ucl object */
			if (cbdata->cur) {
				if (cbdata->elt->stat) {
					ucl_object_unref (cbdata->elt->stat);
				}

				cbdata->elt->stat = cbdata->cur;
				cbdata->cur = NULL;
			}
		}

		if (cbdata->cur) {
			ucl_object_unref (cbdata->cur);
		}

		g_slice_free1 (sizeof (*cbdata), cbdata);
	}
}
Exemple #18
0
static void
rspamd_redis_timeout (gint fd, short what, gpointer d)
{
	struct redis_stat_runtime *rt = REDIS_RUNTIME (d);
	struct rspamd_task *task;
	redisAsyncContext *redis;

	task = rt->task;

	msg_err_task_check ("connection to redis server %s timed out",
			rspamd_upstream_name (rt->selected));

	rspamd_upstream_fail (rt->selected);

	if (rt->redis) {
		redis = rt->redis;
		rt->redis = NULL;
		/* This calls for all callbacks pending */
		redisAsyncFree (redis);
	}
}
Exemple #19
0
static int lua_create_client(lua_State *L)
{
  lua_redis_client_t *lua_redis_client = NULL;
  redisAsyncContext *redis_async_context = NULL;
  luv_ref_t *ref;
  const char *host = luaL_checkstring(L, 1);
  int port = luaL_checkint(L, 2);

  redis_async_context = redisAsyncConnect(host, port);

  if(redis_async_context->err)
  {
    redisAsyncFree(redis_async_context);
    return luaL_error(L, redis_async_context->errstr);
  }

  redisLibevAttach(EV_DEFAULT_ redis_async_context);

  lua_redis_client = (lua_redis_client_t *)lua_newuserdata(
                                          L, sizeof(lua_redis_client_t));


  lua_redis_client->redis_async_context = redis_async_context;

  luaL_getmetatable(L, LUA_REDIS_CLIENT_MT);
  lua_setmetatable(L, -2);

  lua_newtable(L);
  lua_setfenv(L, -2);

  ref = ref_alloc();
  ref->L = L;
  lua_pushvalue(L, -1);
  ref->r = luaL_ref(L, LUA_REGISTRYINDEX);
  redis_async_context->data = ref;

  return 1;
}
Exemple #20
0
void _redis_close()
{
    int outstanding = 0;

    if (handle) {
        if (handle->conn) {
            redisFree(handle->conn);
        }
        if (handle->async) { 
            redisAsyncFree(handle->async);
		}
		if (handle->event_base){
			event_base_loopbreak(handle->event_base);
		}
        if (handle->redis_thread){
        	pthread_cancel(handle->redis_thread);
		}
        g_mutex_free(handle->lock);
        g_free(handle->redis_ip);
        free(handle);
        handle = NULL;
    }
}
Exemple #21
0
ucl_object_t *
rspamd_redis_get_stat (gpointer runtime,
		gpointer ctx)
{
	struct redis_stat_runtime *rt = REDIS_RUNTIME (runtime);
	struct rspamd_redis_stat_elt *st;
	redisAsyncContext *redis;

	if (rt->ctx->stat_elt) {
		st = rt->ctx->stat_elt->ud;

		if (rt->redis) {
			redis = rt->redis;
			rt->redis = NULL;
			redisAsyncFree (redis);
		}

		if (st->stat) {
			return ucl_object_ref (st->stat);
		}
	}

	return NULL;
}
Exemple #22
0
/* 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;
}
Exemple #23
0
/***
 * @function rspamd_redis.make_request({params})
 * Make request to redis server, params is a table of key=value arguments in any order
 * @param {task} task worker task object
 * @param {ip} host server address
 * @param {function} callback callback to be called in form `function (task, err, data)`
 * @param {string} cmd command to be sent to redis
 * @param {table} args numeric array of strings used as redis arguments
 * @param {number} timeout timeout in seconds for request (1.0 by default)
 * @return {boolean} `true` if a request has been scheduled
 */
static int
lua_redis_make_request (lua_State *L)
{
	struct lua_redis_userdata *ud;
	struct rspamd_lua_ip *addr = NULL;
	struct rspamd_task *task = NULL;
	const gchar *cmd = NULL;
	gint top, cbref = -1;
	struct timeval tv;
	gboolean ret = FALSE;
	gdouble timeout = REDIS_DEFAULT_TIMEOUT;

	if (lua_istable (L, 1)) {
		/* Table version */
		lua_pushstring (L, "task");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TUSERDATA) {
			task = lua_check_task (L, -1);
		}
		lua_pop (L, 1);

		lua_pushstring (L, "callback");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TFUNCTION) {
			/* This also pops function from the stack */
			cbref = luaL_ref (L, LUA_REGISTRYINDEX);
		}
		else {
			msg_err ("bad callback argument for lua redis");
			lua_pop (L, 1);
		}

		lua_pushstring (L, "cmd");
		lua_gettable (L, -2);
		cmd = lua_tostring (L, -1);
		lua_pop (L, 1);

		lua_pushstring (L, "host");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TUSERDATA) {
			addr = lua_check_ip (L, -1);
		}
		lua_pop (L, 1);

		lua_pushstring (L, "timeout");
		lua_gettable (L, -2);
		timeout = lua_tonumber (L, -1);
		lua_pop (L, 1);

		if (task != NULL && addr != NULL && cbref != -1 && cmd != NULL) {
			ud =
					rspamd_mempool_alloc (task->task_pool,
							sizeof (struct lua_redis_userdata));
			ud->task = task;
			ud->L = L;
			ud->cbref = cbref;
			lua_pushstring (L, "args");
			lua_redis_parse_args (L, -1, cmd, ud);
			ret = TRUE;
		}
		else {
			if (cbref != -1) {
				luaL_unref (L, LUA_REGISTRYINDEX, cbref);
			}

			msg_err ("incorrect function invocation");
		}
	}
	else if ((task = lua_check_task (L, 1)) != NULL) {
		addr = lua_check_ip (L, 2);
		top = lua_gettop (L);
		/* Now get callback */
		if (lua_isfunction (L, 3) && addr != NULL && addr->addr && top >= 4) {
			/* Create userdata */
			ud =
				rspamd_mempool_alloc (task->task_pool,
					sizeof (struct lua_redis_userdata));
			ud->task = task;
			ud->L = L;

			/* Pop other arguments */
			lua_pushvalue (L, 3);
			/* Get a reference */
			ud->cbref = luaL_ref (L, LUA_REGISTRYINDEX);

			cmd = luaL_checkstring (L, 4);
			if (top > 4) {
				lua_redis_parse_args (L, 5, cmd, ud);
			}
			else {
				lua_redis_parse_args (L, 0, cmd, ud);
			}

			ret = TRUE;
		}
		else {
			msg_err ("incorrect function invocation");
		}
	}

	if (ret) {
		ud->terminated = 0;
		ud->ctx = redisAsyncConnect (rspamd_inet_address_to_string (addr->addr),
				rspamd_inet_address_get_port (addr->addr));
		redisAsyncSetConnectCallback (ud->ctx, lua_redis_connect_cb);

		if (ud->ctx == NULL || ud->ctx->err) {
			ud->terminated = 1;
			redisAsyncFree (ud->ctx);
			lua_redis_free_args (ud);
			luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
			lua_pushboolean (L, FALSE);

			return 1;
		}
		redisLibeventAttach (ud->ctx, ud->task->ev_base);
		ret = redisAsyncCommandArgv (ud->ctx,
					lua_redis_callback,
					ud,
					ud->nargs,
					(const gchar **)ud->args,
					NULL);
		if (ret == REDIS_OK) {
			rspamd_session_add_event (ud->task->s,
					lua_redis_fin,
					ud,
					g_quark_from_static_string ("lua redis"));

			double_to_tv (timeout, &tv);
			event_set (&ud->timeout, -1, EV_TIMEOUT, lua_redis_timeout, ud);
			event_base_set (ud->task->ev_base, &ud->timeout);
			event_add (&ud->timeout, &tv);
		}
		else {
			msg_info ("call to redis failed: %s", ud->ctx->errstr);
			ud->terminated = 1;
			lua_redis_free_args (ud);
			redisAsyncFree (ud->ctx);
			luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
		}
	}

	lua_pushboolean (L, ret);

	return 1;
}
Exemple #24
0
void destroyRedis(redisAsyncContext *ctx)
{
	redisAsyncDisconnect(ctx);
	redisAsyncFree(ctx);
}