C语言中的Apache模块:如何将数据写入客户端套接字?

C语言中的Apache模块:如何将数据写入客户端套接字?,c,apache,sockets,mod-perl,apache2-module,C,Apache,Sockets,Mod Perl,Apache2 Module,我创建了一个简单的mod_perl模块,它将一个以0结尾的字符串写入连接到843端口的端口。它工作正常,但在我的CentOS 5 Linux机器上,每个httpd子级使用2000万 因此,我试图用C重写我的模块,但我不确定如何通过协议处理程序接收的conn\u rec结构访问客户端套接字 我在邮件列表中询问并尝试添加#define CORE_PRIVATE并使用ap_get_module_config(conn->conn_config,&CORE_module),但这破坏了我的web服务器:该

我创建了一个简单的mod_perl模块,它将一个以0结尾的字符串写入连接到843端口的端口。它工作正常,但在我的CentOS 5 Linux机器上,每个httpd子级使用2000万

因此,我试图用C重写我的模块,但我不确定如何通过协议处理程序接收的conn\u rec结构访问客户端套接字

我在邮件列表中询问并尝试添加#define CORE_PRIVATE并使用ap_get_module_config(conn->conn_config,&CORE_module),但这破坏了我的web服务器:该字符串既提供给端口843(正常),也提供给端口80(不正常)

这里有人有什么建议吗

这是我的SocketPolicy.pm(工作正常,但需要大量内存):


那么,为什么我的Perl模块可以工作而C模块不能工作呢?

对于内容处理程序,约定是 在httpd.conf和 然后在运行时使用

if (!r->handler || (strcmp(r->handler, "XXX") != 0))
   return DECLINED;
但对于协议处理程序,没有这样的约定。 您必须为httpd.conf引入一些关键字 检查一下。例如(Apache附带的源代码)在上引入了ProtocolEcho。或者在我的情况下,您可以检查端口:

   if (conn->base_server->port != 843)
           return DECLINED;
下面是用于相同目的但使用的工作模块,这比直接写入客户端套接字要好:

static MP_INLINE
apr_socket_t *mpxs_Apache2__Connection_client_socket(pTHX_ conn_rec *c,
                                                    apr_socket_t *s)
{
    apr_socket_t *socket =
        ap_get_module_config(c->conn_config, &core_module);

    if (s) {
        ap_set_module_config(c->conn_config, &core_module, s);
    }

    return socket;
}
/*
LoadModule socket_policy_module modules/mod_socket_policy.so
Listen 843
<VirtualHost _default_:843>
</VirtualHost>
*/
#include <httpd.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <http_config.h>
#include <http_log.h>

#define POLICY "<?xml version=\"1.0\"?>\n" \
               "<!DOCTYPE cross-domain-policy SYSTEM\n" \
               "\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
               "<cross-domain-policy>\n" \
               "<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
               "</cross-domain-policy>\n"

static int socket_policy_handler(conn_rec *conn) {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;

        if (conn->base_server->port != 843)
                return DECLINED;

        bb = apr_brigade_create(conn->pool, conn->bucket_alloc);
        /* this will send the terminating 0 as well */
        b = apr_bucket_immortal_create(POLICY, sizeof(POLICY), bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        b = apr_bucket_eos_create(bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(conn->output_filters, bb);
        if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, conn->base_server, "output error");
                return DECLINED;
        }

        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, conn->base_server,
            "served socket policy to %s", conn->remote_ip);
        return OK;
}

static void register_hooks(apr_pool_t *pool) {
        ap_hook_process_connection(socket_policy_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA socket_policy_module = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        register_hooks
};
/*
LoadModule socket\u policy\u module modules/mod\u socket\u policy.so
听着
*/
#包括
#包括
#包括
#包括
#包括
#定义策略“\n”\
“\n”\
“\n”\
“\n”\
“\n”
静态int套接字策略处理程序(conn\u rec*conn){
apr_bucket_Batch*bb;
apr_bucket*b;
apr_状态_t rv;
如果(连接->基本服务器->端口!=843)
回报率下降;
bb=apr\U BACKUP\U create(连接->池,连接->桶分配);
/*这也将发送终止0*/
b=apr\u bucket\u percentral\u create(策略,sizeof(策略),bb->bucket\u alloc);
APR_旅_插入_尾(bb,b);
b=apr\u bucket\u eos\u create(bb->bucket\u alloc);
APR_旅_插入_尾(bb,b);
rv=ap_通过(连接->输出过滤器,bb);
如果(rv!=四月成功){
ap_日志_错误(APLOG_标记,APLOG_错误,0,conn->base_服务器,“输出错误”);
回报率下降;
}
ap_日志_错误(APLOG_标记、APLOG_通知、0、conn->base_服务器、,
“已向%s提供套接字策略”,连接->远程\u ip);
返回OK;
}
静态无效寄存器挂钩(apr\U pool\U t*pool){
ap\u hook\u process\u connection(socket\u policy\u handler,NULL,NULL,APR\u hook\u MIDDLE);
}
模块AP\U模块\U声明\U数据套接字\U策略\U模块={
标准20_模块_材料,
无效的
无效的
无效的
无效的
无效的
登记钩
};

如果SELinux处于活动状态,则需要此命令,否则Apache将无法绑定到新端口:semanage port-a-t http\u port\u t-p tcp 843
   if (conn->base_server->port != 843)
           return DECLINED;
/*
LoadModule socket_policy_module modules/mod_socket_policy.so
Listen 843
<VirtualHost _default_:843>
</VirtualHost>
*/
#include <httpd.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <http_config.h>
#include <http_log.h>

#define POLICY "<?xml version=\"1.0\"?>\n" \
               "<!DOCTYPE cross-domain-policy SYSTEM\n" \
               "\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
               "<cross-domain-policy>\n" \
               "<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
               "</cross-domain-policy>\n"

static int socket_policy_handler(conn_rec *conn) {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;

        if (conn->base_server->port != 843)
                return DECLINED;

        bb = apr_brigade_create(conn->pool, conn->bucket_alloc);
        /* this will send the terminating 0 as well */
        b = apr_bucket_immortal_create(POLICY, sizeof(POLICY), bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        b = apr_bucket_eos_create(bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(conn->output_filters, bb);
        if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, conn->base_server, "output error");
                return DECLINED;
        }

        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, conn->base_server,
            "served socket policy to %s", conn->remote_ip);
        return OK;
}

static void register_hooks(apr_pool_t *pool) {
        ap_hook_process_connection(socket_policy_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA socket_policy_module = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        register_hooks
};