Exemple #1
0
void acl_mem_slice_set(ACL_MEM_SLICE *mem_slice)
{
	const char *myname = "acl_mem_slice_set";

	if (__mem_slice_key != (acl_pthread_key_t) -1) {
		return;
	}

	__mem_slice_key = mem_slice->tls_key;
	__mem_base = mem_slice->slice_pool->base;
	__mem_nslice = mem_slice->slice_pool->nslice;
	__mem_nalloc_gc = mem_slice->nalloc_gc;
	__mem_slice_flag = mem_slice->slice_flag;
	__mem_slice_list = mem_slice->slice_list;
	__mem_slice_list_lock = mem_slice->slice_list_lock;

	__mem_list_init_size = __mem_nalloc_gc / 10;
	if (__mem_list_init_size < 1000)
		__mem_list_init_size = 1000;
	else if (__mem_list_init_size > 1000000)
		__mem_list_init_size = 1000000;

	acl_mem_hook(tls_mem_alloc,
		tls_mem_calloc,
		tls_mem_realloc,
		tls_mem_strdup,
		tls_mem_strndup,
		tls_mem_memdup,
		tls_mem_free);
	acl_msg_info("%s(%d): set ACL_MEM_SLICE, with tls", myname, __LINE__);
}
Exemple #2
0
ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset, size_t count)
{
	ACL_FIBER *me;

	if (__sys_sendfile64 == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_sendfile64(out_fd, in_fd, offset, count);
		if (!acl_var_hook_sys_api || n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_write(out_fd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me)) {
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
			return -1;
		}
	}
}
Exemple #3
0
PROCTL_SERVICE *proctl_service_new(const char *filepath, int argc, char *argv[])
{
	const char *myname = "proctl_service_new";
	PROCTL_SERVICE *service;
	ACL_VSTRING *cmdline = acl_vstring_alloc(256);
	int   i;

	acl_assert(cmdline);

	/* 组建启动进程命令行参数表 */

	/* 为了避免参数传递时可能因其中间含有空格而被分隔成
	 * 多个参数,所以需要在参数两边加上引号
	 */

	acl_vstring_strcat(cmdline, "\"");
	acl_vstring_strcat(cmdline, filepath);
	acl_vstring_strcat(cmdline, "\" ");

	for (i = 0; i < argc; i++) {
		acl_vstring_strcat(cmdline, "\"");
		acl_vstring_strcat(cmdline, argv[i]);
		acl_vstring_strcat(cmdline, "\" ");
	}

	acl_msg_info("%s(%d): filepath=%s, cmdline=%s",
		myname, __LINE__, filepath, acl_vstring_str(cmdline));

	service = proctl_service_alloc(filepath, cmdline);
	proctl_service_add(service);
	return (service);
}
Exemple #4
0
int acl_master_flow_put(int len)
{
	char  myname[] = "acl_master_flow_put";
	char  buf[BUFFER_SIZE];
	int   count;
	int   n = 0;

	/*
	 * Sanity check.
	 */
	if (len <= 0)
		acl_msg_panic("%s: bad length %d", myname, len);

	/*
	 * Write or discard N bytes.
	 */
	memset(buf, 0, len > BUFFER_SIZE ? BUFFER_SIZE : len);

	for (count = len; count > 0; count -= n) {
		n = write(ACL_MASTER_FLOW_WRITE,
				buf,
				count > BUFFER_SIZE ?  BUFFER_SIZE : count);
		if (n < 0)
			return (-1);
	}

	if (acl_msg_verbose)
		acl_msg_info("%s: %d %d", myname, len, len - count);
	return (len - count);
}
Exemple #5
0
int     tls_scache_update(TLS_SCACHE *cp, char *cache_id, const char *buf, ssize_t len)
{
    ACL_VSTRING *hex_data;

    /*
     * Logging.
     */
    if (cp->verbose)
	acl_msg_info("put %s session id=%s [data %ld bytes]",
		 cp->cache_label, cache_id, (long) len);

    /*
     * Encode the cache entry.
     */
    hex_data = tls_scache_encode(cp, cache_id, buf, len);

    /*
     * Store the cache entry.
     * 
     * XXX Berkeley DB supports huge database keys and values. SDBM seems to
     * have a finite limit, and DBM simply can't be used at all.
     */
    DICT_PUT(cp->db, cache_id, strlen(cache_id), STR(hex_data), LEN(hex_data));

    /*
     * Clean up.
     */
    acl_vstring_free(hex_data);

    return (1);
}
Exemple #6
0
static void usage(ACL_VSTREAM *client)
{
	acl_vstream_fprintf(client, "usage: progname|-h[help]"
		"|-d|{action}[START|STOP|QUIT|LIST|PROBE]|-f|filepath|-a|args\r\n");
	acl_msg_info("usage: progname|-h[help]|-d|{action}[START|STOP|QUIT|LIST|PROBE]"
		"|-f|filepath|-a|args");
}
Exemple #7
0
inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt)
{
	ACL_FIBER *me;

	if (__sys_readv == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_readv(fd, iov, iovcnt);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_read(fd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Exemple #8
0
inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags)
{
	ACL_FIBER *me;

	if (__sys_recvmsg == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_recvmsg(sockfd, msg, flags);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_read(sockfd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Exemple #9
0
ACL_WATCHDOG *acl_watchdog_create(unsigned timeout,
	ACL_WATCHDOG_FN action, char *context)
{
	const char* myname = "acl_watchdog_create";
	struct sigaction sig_action;
	ACL_WATCHDOG *wp;

	wp = (ACL_WATCHDOG *) acl_mymalloc(sizeof(*wp));
	if ((wp->timeout = timeout / ACL_WATCHDOG_STEPS) == 0)
		acl_msg_panic("%s: timeout %d too small", myname, timeout);
	wp->action = action;
	wp->context = context;
	wp->saved_watchdog = acl_watchdog_curr;
	wp->saved_time = alarm(0);
	sigemptyset(&sig_action.sa_mask);
#ifdef SA_RESTART
	sig_action.sa_flags = SA_RESTART;
#else
	sig_action.sa_flags = 0;
#endif
	sig_action.sa_handler = acl_watchdog_event;
	if (sigaction(SIGALRM, &sig_action, &wp->saved_action) < 0)
		acl_msg_fatal("%s: sigaction(SIGALRM): %s",
			myname, acl_last_serror());
	if (acl_msg_verbose > 1)
		acl_msg_info("%s: %p %d", myname, (void *) wp, timeout);
	return (acl_watchdog_curr = wp);
}
Exemple #10
0
void acl_mem_slice_delay_destroy(void)
{
	const char *myname = "acl_mem_slice_delay_destroy";
	int   i, n;

	if (__mem_slice_list_lock == NULL)
		return;

	thread_mutex_lock(__mem_slice_list_lock);
	n = private_array_size(__mem_slice_list);
	for (i = 0; i < n; i++) {
		ACL_MEM_SLICE *mem_slice = (ACL_MEM_SLICE*)
			private_array_index(__mem_slice_list, i);
		if (mem_slice == NULL)
			break;
		if (mem_slice->delay_free == 0)
			continue;
		if (acl_slice_pool_used(mem_slice->slice_pool) <= 0) {
			acl_msg_info("%s(%d): thread(%ld) free mem slice now",
				myname, __LINE__, mem_slice->tid);

			acl_slice_pool_destroy(mem_slice->slice_pool);
			private_array_destroy(mem_slice->list, NULL);
			mem_slice->list = NULL;

			/* 将子线程的线程局部存储内存池从全局内存池句柄集合中删除 */
			private_array_delete_obj(__mem_slice_list, mem_slice, NULL);
			acl_default_free(__FILE__, __LINE__, mem_slice);
		} else
			mem_slice_gc(mem_slice);
	}

	thread_mutex_unlock(__mem_slice_list_lock);
}
Exemple #11
0
int acl_set_eugid(uid_t euid, gid_t egid)
{
	int   saved_error = acl_last_error();
	char  tbuf[256];

	if (geteuid() != 0 && seteuid(0)) {
		acl_msg_error("set_eugid: seteuid(0): %s",
			acl_last_strerror(tbuf, sizeof(tbuf)));
		return -1;
	}
	if (setegid(egid) < 0) {
		acl_msg_error("set_eugid: setegid(%ld): %s", (long) egid,
			acl_last_strerror(tbuf, sizeof(tbuf)));
		return -1;
	}
	if (setgroups(1, &egid) < 0) {
		acl_msg_error("set_eugid: setgroups(%ld): %s", (long) egid,
			acl_last_strerror(tbuf, sizeof(tbuf)));
		return -1;
	}
	if (euid != 0 && seteuid(euid) < 0) {
		acl_msg_error("set_eugid: seteuid(%ld): %s", (long) euid,
			acl_last_strerror(tbuf, sizeof(tbuf)));
		return -1;
	}
	if (acl_msg_verbose)
		acl_msg_info("set_eugid: euid %ld egid %ld",
			(long) euid, (long) egid);

	acl_set_error(saved_error);
	return 0;
}
Exemple #12
0
static void tlsmgr_prng_exch_event(int unused_event acl_unused, void *dummy)
{
    const char *myname = "tlsmgr_prng_exch_event";
    unsigned char randbyte;
    int     next_period;
    struct acl_stat st;

    if (acl_msg_verbose)
	acl_msg_info("%s: update PRNG exchange file", myname);

    /*
     * Sanity check. If the PRNG exchange file was removed, there is no point
     * updating it further. Restart the process and update the new file.
     */
    if (acl_fstat(rand_exch->fd.file, &st) < 0)
	acl_msg_fatal("%s: cannot fstat() the PRNG exchange file: %s", myname, acl_last_serror());
    if (st.st_nlink == 0) {
	acl_msg_warn("%s: PRNG exchange file was removed -- exiting to reopen", myname);
	sleep(1);
	exit(0);
    }
    tls_prng_exch_update(rand_exch);

    /*
     * Make prediction difficult for outsiders and calculate the time for the
     * next execution randomly.
     */
    RAND_bytes(&randbyte, 1);
    next_period = (var_tls_prng_exch_period * randbyte) / UCHAR_MAX;
    acl_event_request_timer(__eventp, tlsmgr_prng_exch_event, dummy, next_period, 0);
}
Exemple #13
0
static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert,
	const TLS_CLIENT_START_PROPS *props)
{
    char  **cpp;

    /* Non-null by contract */
    TLScontext->peer_fingerprint = tls_fingerprint(peercert, props->fpt_dgst);

    if (props->tls_level != TLS_LEV_FPRINT)
	return;

    /*
     * Compare the fingerprint against each acceptable value, ignoring
     * upper/lower case differences.
     */
    for (cpp = props->matchargv->argv; *cpp; ++cpp)
	if (strcasecmp(TLScontext->peer_fingerprint, *cpp) == 0) {
	    TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
	    break;
	}
    if (props->log_level >= 2)
	acl_msg_info("%s %s%s fingerprint %s", props->namaddr,
		TLS_CERT_IS_MATCHED(TLScontext) ? "Matched " : "",
		props->fpt_dgst, TLScontext->peer_fingerprint);
}
Exemple #14
0
TLS_SCACHE *tls_scache_open(const char *dbname, const char *cache_label,
	int verbose, int timeout)
{
    const char *myname = "tls_scache_open";
    TLS_SCACHE *cp;
    DICT   *dict;

    /*
     * Logging.
     */
    if (verbose)
	acl_msg_info("open %s TLS cache %s", cache_label, dbname);

    /*
     * Open the dictionary with O_TRUNC, so that we never have to worry about
     * opening a damaged file after some process terminated abnormally.
     */
#ifdef SINGLE_UPDATER
#define DICT_FLAGS (DICT_FLAG_DUP_REPLACE)
#elif defined(ACL_UNIX)
#define DICT_FLAGS \
	(DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE)
#elif defined(ACL_MS_WINDOWS)
#define DICT_FLAGS \
	(DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE)
#endif

    dict = dict_open(dbname, O_RDWR | O_CREAT | O_TRUNC, DICT_FLAGS);

    /*
     * Sanity checks.
     */
    if (dict->lock_fd < 0)
	acl_msg_fatal("%s: dictionary %s is not a regular file", myname, dbname);
#ifdef SINGLE_UPDATER
    if (acl_myflock(dict->lock_fd, INTERNAL_LOCK,
		MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0)
	acl_msg_fatal("%s: cannot lock dictionary %s for exclusive use: %s",
		myname, dbname, acl_last_serror());
#endif
    if (dict->update == 0)
	acl_msg_fatal("%s: dictionary %s does not support update operations", myname, dbname);
    if (dict->delete_it == 0)
	acl_msg_fatal("%s: dictionary %s does not support delete operations", myname, dbname);
    if (dict->sequence == 0)
	acl_msg_fatal("%s: dictionary %s does not support sequence operations", myname, dbname);

    /*
     * Create the TLS_SCACHE object.
     */
    cp = (TLS_SCACHE *) acl_mymalloc(sizeof(*cp));
    cp->flags = 0;
    cp->db = dict;
    cp->cache_label = acl_mystrdup(cache_label);
    cp->verbose = verbose;
    cp->timeout = timeout;
    cp->saved_cursor = 0;

    return (cp);
}
Exemple #15
0
int     tls_scache_lookup(TLS_SCACHE *cp, char *cache_id, ACL_VSTRING *session)
{
    char *hex_data;
    size_t size;

    /*
     * Logging.
     */
    if (cp->verbose)
	acl_msg_info("lookup %s session id=%s", cp->cache_label, cache_id);

    /*
     * Initialize. Don't leak data.
     */
    if (session)
	ACL_VSTRING_RESET(session);

    /*
     * Search the cache database.
     */
    if ((DICT_GET(cp->db, cache_id, strlen(cache_id), &hex_data, &size)) == 0)
	return (0);

    /*
     * Decode entry and delete if expired or malformed.
     */
    if (tls_scache_decode(cp, cache_id, hex_data, (int) strlen(hex_data), session) == 0) {
	tls_scache_delete(cp, cache_id);
	acl_myfree(hex_data);
	return (0);
    } else {
	acl_myfree(hex_data);
	return (1);
    }
}
Exemple #16
0
int acl_unix_trigger(ACL_EVENT *event, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_unix_trigger";
	struct ACL_UNIX_TRIGGER *up;
	ACL_SOCKET fd;

	if (acl_msg_verbose > 0)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_unix_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return -1;
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	up = (struct ACL_UNIX_TRIGGER *) acl_mymalloc(sizeof(*up));
	up->service = acl_mystrdup(service);
	up->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
			timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX);

	/*
	 * Write the request...
	 */
	if (acl_vstream_writen(up->stream, buf, len) < 0
		|| acl_vstream_writen(up->stream, "", 1) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */
#ifdef	__USE_TIMER
	if (timeout > 0)
		acl_event_request_timer(event, acl_unix_trigger_timer,
			(void *) up, (timeout + 100) * 1000000);
	acl_event_enable_read(event, up->stream, 0,
		acl_unix_trigger_event, (void *) up);
#else
	if (timeout > 0)
		acl_event_enable_read(event, up->stream, timeout + 100,
			acl_unix_trigger_event, (void *) up);
	else
		acl_event_enable_read(event, up->stream, 0,
			acl_unix_trigger_event, (void *) up);
#endif

	return 0;
}
Exemple #17
0
int     acl_master_notify(int pid, unsigned generation, int status)
{
	char   *myname = "acl_master_notify";
	ACL_MASTER_STATUS stat_buf;

	/*
	 * We use a simple binary protocol to minimize security risks.
	 * Since this is local IPC, there are no byte order or word
	 * length issues. The server treats this information as gossip,
	 * so sending a bad PID or a bad status code will only have
	 * amusement value.
	 */
	stat_buf.pid = pid;
	stat_buf.gen = generation;
	stat_buf.avail = status;

	if (write(ACL_MASTER_STATUS_FD, (char *) &stat_buf, sizeof(stat_buf))
	    != sizeof(stat_buf)) {
		acl_msg_warn("%s(%d), %s: status %d, error %s",
			__FILE__, __LINE__, myname, status, strerror(errno));
		return -1;
	} else if (acl_msg_verbose)
		acl_msg_info("%s(%d)->%s: OK, status %d, pid = %d",
			__FILE__, __LINE__, myname, status, pid);

	return 0;
}
Exemple #18
0
int zdb_key_walk(ZDB *db, int (*walk_fn)(ZDB_KEY_STORE*))
{
	const char *myname = "zdb_key_walk";
	ZDB_KEY_STORE *store;
	ACL_SCAN_DIR *scan = NULL;
	const char *fname;
	char  pathbuf[256];
	int   ret = 0;

	scan = acl_scan_dir_open(db->key_path, 1);
	if (scan == NULL) {
		acl_msg_error("%s: open dir %s error(%s)",
			myname, db->key_path, acl_last_serror());
		return (-1);
	}

	while (1) {
		fname = acl_scan_dir_next_file(scan);
		if (fname == NULL) {
			acl_msg_info("%s: scan over for %s\n", myname, db->key_path);
			break;
		}
		if (strrncasecmp(fname, ".key", 4) != 0) {
			acl_msg_info("%s: skip %s/%s\n", myname,
				acl_scan_dir_path(scan), fname);
			continue;
		}
		snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
			acl_scan_dir_path(scan), fname);
		store = zdb_key_store_open2(db, pathbuf);
		if (store == NULL) {
			acl_msg_error("%s: open file(%s) error(%s)",
				myname, pathbuf, acl_last_serror());
			ret = -1;
			break;
		}

		ret = walk_fn(store);
		zdb_key_store_close(store);

		if (ret < 0)
			break;
	}

	acl_scan_dir_close(scan);
	return (ret);
}
Exemple #19
0
int zdb_dat_walk(ZDB *db, int (*walk_fn)(ZDB_DAT_STORE *store))
{
	const char *myname = "zdb_dat_walk";
	int   ret = 0, i;

	for (i = 0; db->dat_disks[i].path != NULL; i++) {
		acl_msg_info("%s(%d): begin scan %s",
			myname, __LINE__, db->dat_disks[i].path);
		ret = zdb_dat_scan_path(db, db->dat_disks[i].path, walk_fn);
		acl_msg_info("%s(%d): scan %s end\n",
			myname, __LINE__, db->dat_disks[i].path);
		if (ret < 0)
			break;
	}

	return (ret);
}
Exemple #20
0
void acl_master_log_open(const char *procname)
{
	const char *myname = "acl_master_log_open";
	char *master_log;

	/* use master's log before chroot */
	master_log = getenv("MASTER_LOG");
	if (master_log == NULL) {
		acl_msg_info("%s(%d): no MASTER_LOG's env value", myname, __LINE__);
	} else {
		acl_msg_open(master_log, procname);
		var_master_log_opened = 1;
		if (acl_msg_verbose)
			acl_msg_info("%s(%d): service: %s, log opened now.",
				myname, __LINE__, procname);
	}
}
Exemple #21
0
	// @override
	void on_accept(acl::socket_stream& conn)
	{
		acl_msg_info(">>>accept connection: %d", conn.sock_handle());
		conn.set_rw_timeout(0);
		acl::memcache_session session("127.0.0.1:11211");
		http_servlet servlet(&conn, &session);
		servlet.setLocalCharset("gb2312");

		while (true)
		{
			if (servlet.doRun() == false)
				break;
		}

		acl_msg_info(">>>close one connection: %d, %s",
			conn.sock_handle(), acl::last_serror());
	}
Exemple #22
0
static int tls_scache_decode(TLS_SCACHE *cp, const char *cache_id,
	const char *hex_data, ssize_t hex_data_len, ACL_VSTRING *out_session)
{
    const char *myname = "tls+scache_decode";
    TLS_SCACHE_ENTRY *entry;
    ACL_VSTRING *bin_data;

    /*
     * Sanity check.
     */
    if (hex_data_len < (ssize_t) (2 * (offsetof(TLS_SCACHE_ENTRY, session)))) {
	acl_msg_warn("%s: %s TLS cache: truncated entry for %s: %.100s",
		 myname, cp->cache_label, cache_id, hex_data);
	return (0);
    }

    /*
     * Disassemble the TLS session cache entry.
     * 
     * No early returns or we have a memory leak.
     */
#define FREE_AND_RETURN(ptr, x) { acl_vstring_free(ptr); return (x); }

    bin_data = acl_vstring_alloc(hex_data_len / 2 + 1);
    if (acl_hex_decode(bin_data, hex_data, hex_data_len) == 0) {
	acl_msg_warn("%s: %s TLS cache: malformed entry for %s: %.100s",
		 myname, cp->cache_label, cache_id, hex_data);
	FREE_AND_RETURN(bin_data, 0);
    }
    entry = (TLS_SCACHE_ENTRY *) STR(bin_data);

    /*
     * Logging.
     */
    if (cp->verbose)
	acl_msg_info("read %s TLS cache entry %s: time=%ld [data %ld bytes]",
		 cp->cache_label, cache_id, (long) entry->timestamp,
	      (long) (LEN(bin_data) - offsetof(TLS_SCACHE_ENTRY, session)));

    /*
     * Other mandatory restrictions.
     */
    if (entry->timestamp + cp->timeout < time((time_t *) 0))
	FREE_AND_RETURN(bin_data, 0);

    /*
     * Optional output.
     */
    if (out_session != 0)
	acl_vstring_memcpy(out_session, entry->session,
	       LEN(bin_data) - offsetof(TLS_SCACHE_ENTRY, session));

    /*
     * Clean up.
     */
    FREE_AND_RETURN(bin_data, 1);
}
Exemple #23
0
void    acl_watchdog_pat(void)
{
	const char* myname = "acl_watchdog_pat";

	if (acl_watchdog_curr)
		acl_watchdog_curr->trip_run = 0;
	if (acl_msg_verbose > 1)
		acl_msg_info("%s: %p", myname, (void *) acl_watchdog_curr);
}
Exemple #24
0
static int new_client_session_cb(SSL *ssl, SSL_SESSION *session)
{
    const char *myname = "new_client_session_cb";
    TLS_SESS_STATE *TLScontext;
    ACL_VSTRING *session_data;

    /*
     * The cache name (if caching is enabled in tlsmgr(8)) and the cache ID
     * string for this session are stored in the TLScontext. It cannot be
     * null at this point.
     */
    if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0)
	acl_msg_panic("%s: null TLScontext in new session callback", myname);

    /*
     * We only get here if the cache_type is not empty. This callback is not
     * set unless caching is enabled and the cache_type is stored in the
     * server SSL context.
     */
    if (TLScontext->cache_type == 0)
	acl_msg_panic("%s: null session cache type in new session callback", myname);

    if (TLScontext->log_level >= 2)
	acl_msg_info("save session %s to %s cache", TLScontext->serverid, TLScontext->cache_type);

#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)

    /*
     * Ugly Hack: OpenSSL before 0.9.6a does not store the verify result in
     * sessions for the client side. We modify the session directly which is
     * version specific, but this bug is version specific, too.
     * 
     * READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before beta1 have this
     * bug, it has been fixed during development of 0.9.6a. The development
     * version of 0.9.7 can have this bug, too. It has been fixed on
     * 2000/11/29.
     */
    session->verify_result = SSL_get_verify_result(TLScontext->con);
#endif

    /*
     * Passivate and save the session object. Errors are non-fatal, since
     * caching is only an optimization.
     */
    if ((session_data = tls_session_passivate(session)) != 0) {
	tls_mgr_update(TLScontext->cache_type, TLScontext->serverid,
		STR(session_data), (int) LEN(session_data));
	acl_vstring_free(session_data);
    }

    /*
     * Clean up.
     */
    SSL_SESSION_free(session);			/* 200502 */

    return (1);
}
Exemple #25
0
ssize_t tls_prng_file_read(TLS_PRNG_SRC *fh, size_t len)
{
    const char *myname = "tls_prng_file_read";
    char    buffer[8192];
    ssize_t to_read;
    ssize_t count;

    if (acl_msg_verbose)
	acl_msg_info("%s: seed internal pool from file %s", myname, fh->name);

    if (acl_lseek(fh->fd.file, 0, SEEK_SET) < 0) {
	if (acl_msg_verbose)
	    acl_msg_info("%s: cannot seek entropy file %s: %s",
		myname, fh->name, acl_last_serror());
	return (-1);
    }
    errno = 0;
    for (to_read = (ssize_t) len; to_read > 0; to_read -= count) {
#ifdef ACL_UNIX
		count = acl_timed_read(fh->fd.file, buffer,
				to_read > (ssize_t) sizeof(buffer) ?
				(ssize_t) sizeof(buffer) : to_read,
				fh->timeout, NULL);
#elif defined(WIN32)
		count = acl_file_read(fh->fd.file, buffer,
				to_read > (ssize_t) sizeof(buffer) ?
				(ssize_t) sizeof(buffer) : to_read,
				fh->timeout, NULL);
#endif
		if (count < 0) {
			if (acl_msg_verbose)
				acl_msg_info("%s: cannot read entropy file %s: %s",
					myname, fh->name, acl_last_serror());
			return (-1);
		}
		if (count == 0)
			break;
		RAND_seed(buffer, count);
    }
    if (acl_msg_verbose)
		acl_msg_info("%s: read %ld bytes from entropy file %s: %s",
			myname, (long) (len - to_read), fh->name, acl_last_serror());
    return ((ssize_t) (len - to_read));
}
Exemple #26
0
/* 连接某个服务进程的监听接口,发送停止消息 */
static void proctl_monitor_stop_service(ACL_VSTREAM *client,
	const char *filepath, const char *args)
{
	const char *myname = "proctl_monitor_stop_service";
	ACL_VSTREAM *stream;
	char  addr[256], ebuf[256], buf[1024], logfile[MAX_PATH];
	int   n;

	get_lock_file2(filepath, logfile, sizeof(logfile));

	if (get_addr_from_file(logfile, addr, sizeof(addr)) < 0) {
		acl_vstream_fprintf(client, "-ERR|get addr error from %s\r\n", filepath);
		acl_msg_error("%s(%d): get addr for filepath(%s) error",
			myname, __LINE__, filepath);
		return;
	}

	stream = acl_vstream_connect(addr, ACL_BLOCKING, 10, 10, 1024);
	if (stream == NULL) {
		acl_vstream_fprintf(client, "-ERR|connect addr=%s error, file=%s\r\n",
			addr, filepath);
		acl_msg_error("%s(%d): connect addr(%s) error(%s)",
			myname, __LINE__, addr, acl_last_strerror(ebuf, sizeof(ebuf)));
		return;
	}

	if (args && *args)
		n = acl_vstream_fprintf(stream, "%s|-d|STOP|-f|%s|-a|%s\r\n",
				filepath, filepath, args);
	else
		n = acl_vstream_fprintf(stream, "%s|-d|STOP|-f|%s\r\n",
				filepath, filepath);

	buf[0] = 0;

	if (n == ACL_VSTREAM_EOF) {
		acl_vstream_fprintf(client, "-ERR|write to addr=%s error, file=%s\r\n",
			addr, filepath);
		acl_msg_error("%s(%d): fprintf to acl_master error(%s)",
			myname, __LINE__, acl_last_strerror(ebuf, sizeof(ebuf)));
	} else if (acl_vstream_gets_nonl(stream, buf, sizeof(buf)) == ACL_VSTREAM_EOF) {
		acl_vstream_fprintf(client, "-ERR|filepath(%s), not get respond\r\n", filepath);
		acl_msg_error("%s(%d): not get respond, filepath(%s)",
			myname, __LINE__, filepath);
	} else if (strncasecmp(buf, "+OK", 3) != 0) {
		acl_vstream_fprintf(client, "-ERR|filepath(%s), child respond(%s)\r\n",
			filepath, buf);
		acl_msg_error("%s(%d): child respond error(%s), filepath(%s)",
			myname, __LINE__, buf, filepath);
	} else {
		acl_vstream_fprintf(client, "+OK|stopped %s\r\n", filepath);
		acl_msg_info("%s(%d): stop child(%s) ok", myname, __LINE__, filepath);
	}

	acl_vstream_close(stream);
}
Exemple #27
0
void app_libcore_log_end(void)
{
	if (__log_wrap == NULL)
		return;
	if (__log_wrap->h_log == NULL)
		return;
	acl_msg_info("service exit now");
	e_log_free(__log_wrap->h_log);
	__log_wrap->h_log = NULL;
}
Exemple #28
0
void    acl_watchdog_stop(ACL_WATCHDOG *wp)
{
	const char* myname = "acl_watchdog_stop";

	if (wp != acl_watchdog_curr)
		acl_msg_panic("%s: wrong watchdog instance", myname);
	alarm(0);
	if (acl_msg_verbose > 1)
		acl_msg_info("%s: %p", myname, (void *) wp);
}
Exemple #29
0
void service_set_dns(SERVICE *service, ACL_AIO *aio,
	const char *dns_list, int dns_lookup_timeout,
	int dns_cache_limit, const char *hosts_list)
{
	const char *myname = "service_set_dns";
	ACL_ARGV *argv;
	ACL_ITER iter;

	/* 创建DNS域名查询对象:外挂式查询或非阻塞式查询 */

	if (!dns_list || !strcmp(dns_list, "")) {
		int nthreads = 100, idle = 60;

		/* 创建外挂式DNS查询对象 */
		service->dns_server = dns_server_create(aio, 300);
		service->dns_table = acl_htable_create(100, 0);
		/* 创建半驻留线程池对象 */
		service->wq = acl_workq_create(nthreads, idle, NULL, NULL);
		return;
	}

	/* 采用直接发送DNS协议方式进行查询的对象 */

	argv = acl_argv_split(dns_list, ",; \t");

	service->dns_handle = acl_dns_create(aio, dns_lookup_timeout);
	if (dns_cache_limit > 0)
		acl_dns_open_cache(service->dns_handle, dns_cache_limit);

	/* 添加DNS服务器地址 */

	acl_foreach(iter, argv) {
		char *addr = (char*) iter.data;
		char *ptr1 = strchr(addr, ':'), *ptr2;
		int  port, netmask = 24;

		if (ptr1) {
			*ptr1++ = 0;
			ptr2 = strchr(ptr1, ':');
			if (ptr2) {
				*ptr2++ = 0;
				netmask = atoi(ptr2);
				if (netmask <= 0 || netmask >= 32)
					netmask = 24;
			}
			port = atoi(ptr1);
			if (port <= 0 || port >= 65535)
				port = 53;
		} else
			port = 53;

		acl_msg_info("%s(%d): add dns addr (%s:%d)",
				myname, __LINE__, addr, port);
		acl_dns_add_dns(service->dns_handle, addr, port, netmask);
	}
Exemple #30
0
int acl_inet_trigger(ACL_EVENT *eventp, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_inet_trigger";
	struct ACL_INET_TRIGGER *ip;
	int     fd;

	if (acl_msg_verbose > 1)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_inet_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return (-1);
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	ip = (struct ACL_INET_TRIGGER *) acl_mymalloc(sizeof(*ip));
	ip->fd = fd;
	ip->service = acl_mystrdup(service);
	ip->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
		timeout, ACL_VSTREAM_TYPE_LISTEN_INET);
	ip->eventp = eventp;

	/*
	 * Write the request...
	 */
	if (acl_write_buf(fd, buf, len, timeout) < 0
		|| acl_write_buf(fd, "", 1, timeout) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */

	if (timeout > 0)
		acl_event_enable_read(ip->eventp, ip->stream, timeout + 100,
			acl_inet_trigger_event, (void *) ip);
	else
		acl_event_enable_read(ip->eventp, ip->stream, 0,
			acl_inet_trigger_event, (void *) ip);

	return (0);
}