⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perchild.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
    h.p = r->pool;    h.headers = apr_pstrcat(h.p, r->the_request, CRLF, "Host: ", r->hostname,                             CRLF, NULL);    apr_table_do((int (*) (void *, const char *, const char *))                 perchild_header_field, (void *) &h, r->headers_in, NULL);     h.headers = apr_pstrcat(h.p, h.headers, CRLF, NULL);    iov[0].iov_base = h.headers;    iov[0].iov_len = strlen(h.headers) + 1;    iov[1].iov_base = request_body;    iov[1].iov_len = l + 1;    msg.msg_name = NULL;    msg.msg_namelen = 0;    msg.msg_iov = iov;    msg.msg_iovlen = 2;    cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sfd));    cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sfd);    cmsg->cmsg_level = SOL_SOCKET;    cmsg->cmsg_type = SCM_RIGHTS;    memcpy(CMSG_DATA(cmsg), &sfd, sizeof(sfd));    msg.msg_control = cmsg;    msg.msg_controllen = cmsg->cmsg_len;    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                  "Writing message to %d, passing sd:  %d", sconf->output, sfd);    if ((rv = sendmsg(sconf->output, &msg, 0)) == -1) {        apr_pool_destroy(r->pool);        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                  "Writing message failed %d %d", rv, errno);        return -1;    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                  "Writing message succeeded %d", rv);    apr_pool_destroy(r->pool);    return 1;}static char *make_perchild_socket(const char *fullsockname, int sd[2]){    socketpair(PF_UNIX, SOCK_STREAM, 0, sd);    return NULL;}static int perchild_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s){    int i;    server_rec *sr;    perchild_server_conf *sconf;    int def_sd[2];    def_sd[0] = -1;    def_sd[1] = -1;    for (sr = s; sr; sr = sr->next) {        sconf = (perchild_server_conf *)ap_get_module_config(sr->module_config,                                                      &mpm_perchild_module);        if (sconf->input == -1) {            sconf->fullsockname = apr_pstrcat(sr->process->pool,                                              sconf->sockname, ".DEFAULT", NULL);            if (def_sd[0] == -1) {                if (!make_perchild_socket(sconf->fullsockname, def_sd)) {                    /* log error */                }            }            sconf->input = def_sd[0];            sconf->output = def_sd[1];        }    }    for (i = 0; i < num_daemons; i++) {        if (child_info_table[i].uid == -1) {            child_info_table[i].input = def_sd[0];            child_info_table[i].output = def_sd[1];        }    }    thread_socket_table = (int *)apr_pcalloc(p, thread_limit * sizeof(int));    for (i = 0; i < thread_limit; i++) {        thread_socket_table[i] = AP_PERCHILD_THISCHILD;    }    ap_child_table = (ap_ctable *)apr_pcalloc(p, server_limit * sizeof(ap_ctable));    return OK;}static int perchild_post_read(request_rec *r){    int thread_num = r->connection->id % thread_limit;    perchild_server_conf *sconf = (perchild_server_conf *)                            ap_get_module_config(r->server->module_config,                                                  &mpm_perchild_module);    if (thread_socket_table[thread_num] != AP_PERCHILD_THISCHILD) {        apr_socket_t *csd = NULL;        apr_os_sock_put(&csd, &thread_socket_table[thread_num],                         r->connection->pool);        ap_sock_disable_nagle(csd);        ap_set_module_config(r->connection->conn_config, &core_module, csd);        return OK;    }    else {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                      "Determining if request should be passed. "                     "Child Num: %d, SD: %d, sd from table: %d, hostname from server: %s", child_num,                      sconf->input, child_info_table[child_num].input,                      r->server->server_hostname);        /* sconf is the server config for this vhost, so if our socket         * is not the same that was set in the config, then the request         * needs to be passed to another child. */        if (sconf->input != child_info_table[child_num].input) {            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                          "Passing request.");            if (pass_request(r) == -1) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0,                             ap_server_conf, "Could not pass request to proper "                             "child, request will not be honored.");            }            longjmp(jmpbuffer, 1);         }        return OK;    }    return OK;}static void perchild_hooks(apr_pool_t *p){    /* The perchild open_logs phase must run before the core's, or stderr     * will be redirected to a file, and the messages won't print to the     * console.     */    static const char *const aszSucc[] = {"core.c", NULL};    one_process = 0;    ap_hook_open_logs(perchild_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);    ap_hook_pre_config(perchild_pre_config, NULL, NULL, APR_HOOK_MIDDLE);     ap_hook_post_config(perchild_post_config, NULL, NULL, APR_HOOK_MIDDLE);     /* Both of these must be run absolutely first.  If this request isn't for      * this server then we need to forward it to the proper child.  No sense     * tying up this server running more post_read request hooks if it is     * just going to be forwarded along.  The process_connection hook allows     * perchild to receive the passed request correctly, by automatically     * filling in the core_input_filter's ctx pointer.     */    ap_hook_post_read_request(perchild_post_read, NULL, NULL,                              APR_HOOK_REALLY_FIRST);    ap_hook_process_connection(perchild_process_connection, NULL, NULL,                                APR_HOOK_REALLY_FIRST);}static const char *set_num_daemons(cmd_parms *cmd, void *dummy,                                   const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    num_daemons = atoi(arg);    if (num_daemons > server_limit) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: NumServers of %d exceeds ServerLimit value "                    "of %d servers,", num_daemons, server_limit);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     " lowering NumServers to %d.  To increase, please "                    "see the", server_limit);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     " ServerLimit directive.");       num_daemons = server_limit;    }     else if (num_daemons < 1) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: Require NumServers > 0, setting to 1");        num_daemons = 1;    }    return NULL;}static const char *set_threads_to_start(cmd_parms *cmd, void *dummy,                                        const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    threads_to_start = atoi(arg);    if (threads_to_start > thread_limit) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: StartThreads of %d exceeds ThreadLimit value"                     " of %d threads,", threads_to_start,                     thread_limit);        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      " lowering StartThreads to %d. To increase, please"                     " see the", thread_limit);        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      " ThreadLimit directive.");    }    else if (threads_to_start < 1) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: Require StartThreads > 0, setting to 1");        threads_to_start = 1;    }    return NULL;}static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy,                                         const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    min_spare_threads = atoi(arg);    if (min_spare_threads <= 0) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: detected MinSpareThreads set to non-positive.");       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "Resetting to 1 to avoid almost certain Apache failure.");       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "Please read the documentation.");       min_spare_threads = 1;    }           return NULL;}static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy,                                         const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    max_spare_threads = atoi(arg);    if (max_spare_threads >= thread_limit) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: detected MinSpareThreads set higher than");       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "ThreadLimit. Resetting to %d", thread_limit);       max_spare_threads = thread_limit;    }    return NULL;}static const char *set_max_threads(cmd_parms *cmd, void *dummy, const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    max_threads = atoi(arg);    if (max_threads > thread_limit) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: detected MaxThreadsPerChild set higher than");       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "ThreadLimit. Resetting to %d", thread_limit);       max_threads = thread_limit;    }    return NULL;}static const char *set_child_per_uid(cmd_parms *cmd, void *dummy, const char *u,                                     const char *g, const char *num){    int i;    int max_this_time = atoi(num) + curr_child_num;        for (i = curr_child_num; i < max_this_time; i++, curr_child_num++) {        if (i > num_daemons) {            return "Trying to use more child ID's than NumServers.  Increase "                   "NumServers in your config file.";        }            child_info_table[i].uid = ap_uname2id(u);        child_info_table[i].gid = ap_gname2id(g); #ifndef BIG_SECURITY_HOLE        if (child_info_table[i].uid == 0 || child_info_table[i].gid == 0) {            return "Assigning root user/group to a child.";        }#endif    }    return NULL;}static const char *assign_childuid(cmd_parms *cmd, void *dummy, const char *uid,                                   const char *gid){    int i;    int matching = 0;    int u = ap_uname2id(uid);    int g = ap_gname2id(gid);    const char *errstr;    int socks[2];    perchild_server_conf *sconf = (perchild_server_conf *)                            ap_get_module_config(cmd->server->module_config,                                                  &mpm_perchild_module);    sconf->fullsockname = apr_pstrcat(cmd->pool, sconf->sockname, ".", uid,                                      ":", gid, NULL);    if ((errstr = make_perchild_socket(sconf->fullsockname, socks))) {        return errstr;    }    sconf->input = socks[0];     sconf->output = socks[1];    for (i = 0; i < num_daemons; i++) {        if (u == child_info_table[i].uid && g == child_info_table[i].gid) {            child_info_table[i].input = sconf->input;            child_info_table[i].output = sconf->output;            matching++;            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,                          "filling out child_info_table; UID: %d, GID: %d, "                         "SD: %d %d, OUTPUT: %d %d, Child Num: %d",                          child_info_table[i].uid, child_info_table[i].gid,                          sconf->input, child_info_table[i].input, sconf->output,                         child_info_table[i].output, i);        }    }    if (!matching) {        return "Unable to find process with matching uid/gid.";    }    return NULL;}static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) {    int tmp_server_limit;        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    tmp_server_limit = atoi(arg);    /* you cannot change ServerLimit across a restart; ignore     * any such attempts     */    if (first_server_limit &&        tmp_server_limit != server_limit) {        /* how do we log a message?  the error log is a bit bucket at this         * point; we'll just have to set a flag so that ap_mpm_run()         * logs a warning later         */        changed_limit_at_restart = 1;        return NULL;    }    server_limit = tmp_server_limit;        if (server_limit > MAX_SERVER_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "WARNING: ServerLimit of %d exceeds compile time limit "                    "of %d servers,", server_limit, MAX_SERVER_LIMIT);       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);       server_limit = MAX_SERVER_LIMIT;    }     else if (server_limit < 1) {	ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                      "WARNING: Require ServerLimit > 0, setting to 1");	server_limit = 1;    }    return NULL;}static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) {    int tmp_thread_limit;        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    tmp_thread_limit = at

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -