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__); }
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; } } }
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); }
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); }
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); }
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"); }
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)); } }
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)); } }
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); }
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); }
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; }
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); }
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); }
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); }
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); } }
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; }
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; }
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); }
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); }
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); } }
// @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()); }
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); }
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); }
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); }
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)); }
/* 连接某个服务进程的监听接口,发送停止消息 */ 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); }
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; }
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); }
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); }
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); }