Example #1
0
File: map.c Project: Sp1l/rspamd
/* Start watching event for all maps */
void
rspamd_map_watch (struct rspamd_config *cfg,
		struct event_base *ev_base,
		struct rspamd_dns_resolver *resolver)
{
	GList *cur = cfg->maps;
	struct rspamd_map *map;
	struct file_map_data *fdata;

	/* First of all do synced read of data */
	while (cur) {
		map = cur->data;
		map->ev_base = ev_base;
		map->r = resolver;
		event_base_set (map->ev_base, &map->ev);

		if (map->protocol == MAP_PROTO_FILE) {
			evtimer_set (&map->ev, file_callback, map);
			/* Read initial data */
			fdata = map->map_data;
			if (fdata->st.st_mtime != -1) {
				/* Do not try to read non-existent file */
				read_map_file (map, map->map_data);
			}
			/* Plan event with jitter */
			jitter_timeout_event (map, FALSE, TRUE, FALSE);
		}
		else if (map->protocol == MAP_PROTO_HTTP) {
			evtimer_set (&map->ev, http_callback, map);
			jitter_timeout_event (map, FALSE, TRUE, FALSE);
		}

		cur = g_list_next (cur);
	}
}
Example #2
0
/**
 * Common file callback
 */
static void
file_callback (gint fd, short what, void *ud)
{
    struct rspamd_map *map = ud;
    struct file_map_data *data = map->map_data;
    struct stat st;
    rspamd_mempool_t *pool;

    pool = map->pool;

    if (g_atomic_int_get (map->locked)) {
        msg_info_pool (
            "don't try to reread map as it is locked by other process, will reread it later");
        jitter_timeout_event (map, TRUE, FALSE);
        return;
    }

    g_atomic_int_inc (map->locked);
    jitter_timeout_event (map, FALSE, FALSE);
    if (stat (data->filename,
              &st) != -1 &&
            (st.st_mtime > data->st.st_mtime || data->st.st_mtime == -1)) {
        /* File was modified since last check */
        memcpy (&data->st, &st, sizeof (struct stat));
    }
    else {
        g_atomic_int_set (map->locked, 0);
        return;
    }

    msg_info_pool ("rereading map file %s", data->filename);
    read_map_file (map, data);
    g_atomic_int_set (map->locked, 0);
}
Example #3
0
/**
 * Async HTTP callback
 */
static void
http_callback (gint fd, short what, void *ud)
{
    struct rspamd_map *map = ud;
    struct http_map_data *data;
    gint sock;
    struct http_callback_data *cbd;
    rspamd_mempool_t *pool;

    data = map->map_data;
    pool = map->pool;

    if (g_atomic_int_get (map->locked)) {
        msg_info_pool (
            "don't try to reread map as it is locked by other process, will reread it later");
        if (data->conn->ud == NULL) {
            jitter_timeout_event (map, TRUE, TRUE);
        }
        else {
            jitter_timeout_event (map, TRUE, FALSE);
        }
        return;
    }

    g_atomic_int_inc (map->locked);
    jitter_timeout_event (map, FALSE, FALSE);
    /* Connect asynced */
    if ((sock = connect_http (map, data, TRUE)) == -1) {
        g_atomic_int_set (map->locked, 0);
        return;
    }
    else {
        /* Plan event */
        cbd = g_slice_alloc (sizeof (struct http_callback_data));
        cbd->ev_base = map->ev_base;
        cbd->map = map;
        cbd->data = data;
        cbd->remain_buf = NULL;
        cbd->cbdata.state = 0;
        cbd->cbdata.prev_data = *cbd->map->user_data;
        cbd->cbdata.cur_data = NULL;
        cbd->cbdata.map = cbd->map;
        cbd->tv.tv_sec = HTTP_CONNECT_TIMEOUT;
        cbd->tv.tv_usec = 0;
        cbd->fd = sock;
        data->conn->ud = cbd;
        msg_debug_pool ("reading map data from %s", data->host);
        write_http_request (cbd);
    }
}
Example #4
0
File: map.c Project: Sp1l/rspamd
/**
 * Async HTTP callback
 */
static void
http_callback (gint fd, short what, void *ud)
{
	struct rspamd_map *map = ud;
	struct http_map_data *data;
	struct http_callback_data *cbd;
	rspamd_mempool_t *pool;
	gchar tmpbuf[PATH_MAX];

	data = map->map_data;
	pool = map->pool;

	if (!g_atomic_int_compare_and_exchange (map->locked, 0, 1)) {
		msg_debug_pool (
				"don't try to reread map as it is locked by other process, will reread it later");
		jitter_timeout_event (map, TRUE, FALSE, FALSE);
		return;
	}

	/* Plan event */
	cbd = g_slice_alloc0 (sizeof (struct http_callback_data));

	rspamd_snprintf (tmpbuf, sizeof (tmpbuf),
			"%s" G_DIR_SEPARATOR_S "rspamd_map%d-XXXXXX",
			map->cfg->temp_dir, map->id);
	cbd->out_fd = mkstemp (tmpbuf);

	if (cbd->out_fd == -1) {
		g_slice_free1 (sizeof (*cbd), cbd);
		msg_err_pool ("cannot create tempfile: %s", strerror (errno));
		jitter_timeout_event (map, FALSE, FALSE, TRUE);
		g_atomic_int_set (map->locked, 0);

		return;
	}

	cbd->tmpfile = g_strdup (tmpbuf);
	cbd->ev_base = map->ev_base;
	cbd->map = map;
	cbd->data = data;
	cbd->fd = -1;
	cbd->cbdata.state = 0;
	cbd->cbdata.prev_data = *cbd->map->user_data;
	cbd->cbdata.cur_data = NULL;
	cbd->cbdata.map = cbd->map;
	cbd->stage = map_resolve_host2;
	double_to_tv (map->cfg->map_timeout, &cbd->tv);
	REF_INIT_RETAIN (cbd, free_http_cbdata);

	msg_debug_pool ("reading map data from %s", data->host);
	/* Send both A and AAAA requests */
	if (map->r->r) {
		if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
				map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
				data->host, RDNS_REQUEST_A)) {
			REF_RETAIN (cbd);
		}
		if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
				map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
				data->host, RDNS_REQUEST_AAAA)) {
			REF_RETAIN (cbd);
		}

		jitter_timeout_event (map, FALSE, FALSE, FALSE);
		map->dtor = free_http_cbdata_dtor;
		map->dtor_data = cbd;
	}
	else {
		msg_warn_pool ("cannot load map: DNS resolver is not initialized");
		jitter_timeout_event (map, FALSE, FALSE, TRUE);
	}

	/* We don't need own ref as it is now refcounted by DNS requests */
	REF_RELEASE (cbd);
}