source: branches/fc20-dev/server/common/oursrc/httpdmods/mod_original_dst.c @ 2542

Last change on this file since 2542 was 2435, checked in by achernya, 11 years ago
Port httpdmods to httpd 2.4 mod_original_dst has very few changes; the mpm.h header is now missing, so hardcode the accept function in the now-nonexistant #define. If a better way to do this is found, this hard-coding should be replaced, but from inspecing the 2.4.4 source, this appears to be the best way. mod_authz_afsgroup has more extensive changes, due to the differences in how Apache 2.4 handles authorization. In theory, this should work the same way as before, and reduces the amount of code, as Apache will no longer force us to parse lines that are not relevant to us.
File size: 2.8 KB
Line 
1/* mod_original_dst
2 * version 1.0, released 2011-03-25
3 * Anders Kaseorg <andersk@mit.edu>
4 *
5 * This replaces the address of incoming connections with the original
6 * destination, before any local masquerading (as given by
7 * SO_ORIGINAL_DST).
8 */
9
10#include <sys/types.h>
11#include <sys/socket.h>
12#include <limits.h>
13#include <netdb.h>
14#include <linux/netfilter_ipv4.h>
15
16#include "ap_config.h"
17#include "ap_listen.h"
18#include "apr_portable.h"
19#include "http_config.h"
20#include "http_log.h"
21#include "httpd.h"
22#include "unixd.h"
23
24#define MPM_ACCEPT_FUNC ap_unixd_accept
25
26extern void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
27
28static apr_status_t original_dst_accept_func(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans)
29{
30    apr_status_t status = MPM_ACCEPT_FUNC(accepted, lr, ptrans);
31    if (status != APR_SUCCESS)
32        return status;
33
34    apr_socket_t *csd = *accepted;
35
36    apr_sockaddr_t *local_addr;
37    status = apr_socket_addr_get(&local_addr, APR_LOCAL, csd);
38    if (status != APR_SUCCESS) {
39        ap_log_perror(APLOG_MARK, APLOG_EMERG, status, ptrans,
40                      "original_dst_accept_func: apr_socket_addr_get failed");
41        apr_socket_close(csd);
42        return APR_EGENERAL;
43    }
44
45    int sockdes;
46    status = apr_os_sock_get(&sockdes, csd);
47    if (status != APR_SUCCESS) {
48        ap_log_perror(APLOG_MARK, APLOG_EMERG, status, ptrans,
49                      "original_dst_accept_func: apr_os_sock_get failed");
50        apr_socket_close(csd);
51        return APR_EGENERAL;
52    }
53
54    socklen_t salen = sizeof(local_addr->sa);
55    status = getsockopt(sockdes, SOL_IP, SO_ORIGINAL_DST, &local_addr->sa, &salen);
56    if (status == 0) {
57        local_addr->salen = salen;
58        apr_sockaddr_vars_set(local_addr, local_addr->sa.sin.sin_family, htons(local_addr->sa.sin.sin_port));
59        return APR_SUCCESS;
60    } else if (errno == ENOENT) {
61        return APR_SUCCESS;
62    } else {
63        ap_log_perror(APLOG_MARK, APLOG_EMERG, errno, ptrans,
64                      "original_dst_accept_func: getsockopt failed");
65        apr_socket_close(csd);
66        return APR_EGENERAL;
67    }
68}
69
70static int original_dst_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
71{
72    ap_listen_rec *lr;
73    for (lr = ap_listeners; lr; lr = lr->next)
74        if (lr->accept_func == MPM_ACCEPT_FUNC)
75            lr->accept_func = original_dst_accept_func;
76    return OK;
77}
78
79static void original_dst_register_hooks(apr_pool_t *p)
80{
81    ap_hook_post_config(original_dst_post_config, NULL, NULL, APR_HOOK_MIDDLE);
82}
83
84module AP_MODULE_DECLARE_DATA original_dst_module =
85{
86    STANDARD20_MODULE_STUFF,
87    NULL,                           /* per-directory config creator */
88    NULL,                           /* dir config merger */
89    NULL,                           /* server config creator */
90    NULL,                           /* server config merger */
91    NULL,                           /* command table */
92    original_dst_register_hooks,    /* set up other request processing hooks */
93};
Note: See TracBrowser for help on using the repository browser.