diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | backport-httpd-2.4.43-socket-activation.patch | 299 | ||||
| -rw-r--r-- | backport-httpd-2.4.59-gettid.patch | 14 | ||||
| -rw-r--r-- | backport-httpd-2.4.60-socket-activation.patch | 610 | ||||
| -rw-r--r-- | httpd.spec | 8 | ||||
| -rw-r--r-- | sources | 2 | 
6 files changed, 618 insertions, 317 deletions
@@ -1 +1,3 @@ +/httpd-2.4.58.tar.bz2  /httpd-2.4.59.tar.bz2 +/httpd-2.4.60.tar.bz2 diff --git a/backport-httpd-2.4.43-socket-activation.patch b/backport-httpd-2.4.43-socket-activation.patch deleted file mode 100644 index dd875c6..0000000 --- a/backport-httpd-2.4.43-socket-activation.patch +++ /dev/null @@ -1,299 +0,0 @@ -diff --git a/server/listen.c b/server/listen.c -index 5242c2a..e2e028a 100644 ---- a/server/listen.c -+++ b/server/listen.c -@@ -34,6 +34,10 @@ - #include <unistd.h> - #endif -  -+#ifdef HAVE_SYSTEMD -+#include <systemd/sd-daemon.h> -+#endif -+ - /* we know core's module_index is 0 */ - #undef APLOG_MODULE_INDEX - #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX -@@ -59,9 +63,12 @@ static int ap_listenbacklog; - static int ap_listencbratio; - static int send_buffer_size; - static int receive_buffer_size; -+#ifdef HAVE_SYSTEMD -+static int use_systemd = -1; -+#endif -  - /* TODO: make_sock is just begging and screaming for APR abstraction */ --static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) -+static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen) - { -     apr_socket_t *s = server->sd; -     int one = 1; -@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) -         return stat; -     } -  --#if APR_HAVE_IPV6 --    if (server->bind_addr->family == APR_INET6) { --        stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); --        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { --            ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) --                          "make_sock: for address %pI, apr_socket_opt_set: " --                          "(IPV6_V6ONLY)", --                          server->bind_addr); --            apr_socket_close(s); --            return stat; --        } --    } --#endif -- -     /* -      * To send data over high bandwidth-delay connections at full -      * speed we must force the TCP window to open wide enough to keep the -@@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) -     } - #endif -  --    if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { --        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) --                      "make_sock: could not bind to address %pI", --                      server->bind_addr); --        apr_socket_close(s); --        return stat; --    } -+    if (do_bind_listen) { -+#if APR_HAVE_IPV6 -+        if (server->bind_addr->family == APR_INET6) { -+            stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); -+            if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { -+                ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) -+                              "make_sock: for address %pI, apr_socket_opt_set: " -+                              "(IPV6_V6ONLY)", -+                              server->bind_addr); -+                apr_socket_close(s); -+                return stat; -+            } -+        } -+#endif -  --    if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { --        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) --                      "make_sock: unable to listen for connections " --                      "on address %pI", --                      server->bind_addr); --        apr_socket_close(s); --        return stat; -+        if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { -+            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) -+                          "make_sock: could not bind to address %pI", -+                          server->bind_addr); -+            apr_socket_close(s); -+            return stat; -+        } -+ -+        if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { -+            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) -+                          "make_sock: unable to listen for connections " -+                          "on address %pI", -+                          server->bind_addr); -+            apr_socket_close(s); -+            return stat; -+        } -     } -  - #ifdef WIN32 -@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, -     return found; - } -  -+#ifdef HAVE_SYSTEMD -+ -+static int find_systemd_socket(process_rec * process, apr_port_t port) { -+    int fdcount, fd; -+    int sdc = sd_listen_fds(0); -+ -+    if (sdc < 0) { -+        ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) -+                      "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", -+                      sdc); -+        return -1; -+    } -+ -+    if (sdc == 0) { -+        ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) -+                      "find_systemd_socket: At least one socket must be set."); -+        return -1; -+    } -+ -+    fdcount = atoi(getenv("LISTEN_FDS")); -+    for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { -+        if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { -+            return fd; -+        } -+    } -+ -+    return -1; -+} -+ -+static apr_status_t alloc_systemd_listener(process_rec * process, -+                                           int fd, const char *proto, -+                                           ap_listen_rec **out_rec) -+{ -+    apr_status_t rv; -+    struct sockaddr sa; -+    socklen_t len = sizeof(struct sockaddr); -+    apr_os_sock_info_t si; -+    ap_listen_rec *rec; -+    *out_rec = NULL; -+ -+    memset(&si, 0, sizeof(si)); -+ -+    rv = getsockname(fd, &sa, &len); -+ -+    if (rv != 0) { -+        rv = apr_get_netos_error(); -+        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489) -+                      "getsockname on %d failed.", fd); -+        return rv; -+    } -+ -+    si.os_sock = &fd; -+    si.family = sa.sa_family; -+    si.local = &sa; -+    si.type = SOCK_STREAM; -+    si.protocol = APR_PROTO_TCP; -+ -+    rec = apr_palloc(process->pool, sizeof(ap_listen_rec)); -+    rec->active = 0; -+    rec->next = 0; -+ -+ -+    rv = apr_os_sock_make(&rec->sd, &si, process->pool); -+    if (rv != APR_SUCCESS) { -+        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490) -+                      "apr_os_sock_make on %d failed.", fd); -+        return rv; -+    } -+ -+    rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd); -+    if (rv != APR_SUCCESS) { -+        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491) -+                      "apr_socket_addr_get on %d failed.", fd); -+        return rv; -+    } -+ -+    rec->protocol = apr_pstrdup(process->pool, proto); -+ -+    *out_rec = rec; -+ -+    return make_sock(process->pool, rec, 0); -+} -+ -+static const char *set_systemd_listener(process_rec *process, apr_port_t port, -+                                        const char *proto) -+{ -+    ap_listen_rec *last, *new; -+    apr_status_t rv; -+    int fd = find_systemd_socket(process, port); -+    if (fd < 0) { -+        return "Systemd socket activation is used, but this port is not " -+                "configured in systemd"; -+    } -+ -+    last = ap_listeners; -+    while (last && last->next) { -+        last = last->next; -+    } -+ -+    rv = alloc_systemd_listener(process, fd, proto, &new); -+    if (rv != APR_SUCCESS) { -+        return "Failed to setup socket passed by systemd using socket activation"; -+    } -+ -+    if (last == NULL) { -+        ap_listeners = last = new; -+    } -+    else { -+        last->next = new; -+        last = new; -+    } -+ -+    return NULL; -+} -+ -+#endif /* HAVE_SYSTEMD */ -+ - static const char *alloc_listener(process_rec *process, const char *addr, -                                   apr_port_t port, const char* proto, -                                   void *slave) -@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool) -                 } -             } - #endif --            if (make_sock(pool, lr) == APR_SUCCESS) { -+            if (make_sock(pool, lr, 1) == APR_SUCCESS) { -                 ++num_open; -             } -             else { -@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) -         } -     } -  --    if (open_listeners(s->process->pool)) { --        return 0; -+#ifdef HAVE_SYSTEMD -+    if (use_systemd) { -+        const char *userdata_key = "ap_open_systemd_listeners"; -+        void *data; -+        /* clear the enviroment on our second run -+        * so that none of our future children get confused. -+        */ -+        apr_pool_userdata_get(&data, userdata_key, s->process->pool); -+        if (!data) { -+            apr_pool_userdata_set((const void *)1, userdata_key, -+                                apr_pool_cleanup_null, s->process->pool); -+        } -+        else { -+            sd_listen_fds(1); -+        } -+    } -+    else -+#endif -+    { -+        if (open_listeners(s->process->pool)) { -+            return 0; -+        } -     } -  -     for (lr = ap_listeners; lr; lr = lr->next) { -@@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s, -                             duplr->bind_addr); -                 return stat; -             } --            make_sock(p, duplr); -+            make_sock(p, duplr, 1); - #if AP_NONBLOCK_WHEN_MULTI_LISTEN -             use_nonblock = (ap_listeners && ap_listeners->next); -             stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); -@@ -825,6 +971,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, -     if (argc < 1 || argc > 2) { -         return "Listen requires 1 or 2 arguments."; -     } -+#ifdef HAVE_SYSTEMD -+    if (use_systemd == -1) { -+        use_systemd = sd_listen_fds(0) > 0; -+    } -+#endif -  -     rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); -     if (rv != APR_SUCCESS) { -@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, -         ap_str_tolower(proto); -     } -  -+#ifdef HAVE_SYSTEMD -+    if (use_systemd) { -+        return set_systemd_listener(cmd->server->process, port, proto); -+    } -+#endif -+ -     return alloc_listener(cmd->server->process, host, port, proto, NULL); - } diff --git a/backport-httpd-2.4.59-gettid.patch b/backport-httpd-2.4.59-gettid.patch deleted file mode 100644 index 4857e37..0000000 --- a/backport-httpd-2.4.59-gettid.patch +++ /dev/null @@ -1,14 +0,0 @@ - -Upstream-Status: not pushed upstream - ---- httpd-2.4.54/server/log.c.gettid -+++ httpd-2.4.54/server/log.c -@@ -968,7 +972,7 @@ - #if APR_HAS_THREADS -         field_start = len; -         len += cpystrn(buf + len, ":tid ", buflen - len); --        item_len = log_tid(info, NULL, buf + len, buflen - len); -+        item_len = log_tid(info, "g", buf + len, buflen - len); -         if (!item_len) -             len = field_start; -         else diff --git a/backport-httpd-2.4.60-socket-activation.patch b/backport-httpd-2.4.60-socket-activation.patch new file mode 100644 index 0000000..59708ae --- /dev/null +++ b/backport-httpd-2.4.60-socket-activation.patch @@ -0,0 +1,610 @@ +--- httpd-2.4.28/server/listen.c.socketactivation	2017-08-16 19:48:29.000000000 +0300 ++++ httpd-2.4.28/server/listen.c	2017-10-14 18:48:36.275690612 +0300 +@@ -18,114 +18,107 @@ + #include "apr_strings.h" +  + #define APR_WANT_STRFUNC + #include "apr_want.h" + #include "apr_version.h" +  + #include "ap_config.h" + #include "httpd.h" + #include "http_main.h" + #include "http_config.h" + #include "http_core.h" + #include "ap_listen.h" + #include "http_log.h" + #include "mpm_common.h" +  + #include <stdlib.h> + #if APR_HAVE_UNISTD_H + #include <unistd.h> + #endif +  ++#ifdef HAVE_SYSTEMD ++#include <systemd/sd-daemon.h> ++#endif ++ + /* we know core's module_index is 0 */ + #undef APLOG_MODULE_INDEX + #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX +  + AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL; +  + /* Let ap_num_listen_buckets be global so that it can +  * be printed by ap_log_mpm_common(), but keep the listeners +  * buckets static since it is used only here to close them +  * all (including duplicated) with ap_close_listeners(). +  */ + AP_DECLARE_DATA int ap_num_listen_buckets; + static ap_listen_rec **ap_listen_buckets; +  + /* Determine once, at runtime, whether or not SO_REUSEPORT +  * is usable on this platform, and hence whether or not +  * listeners can be duplicated (if configured). +  */ + AP_DECLARE_DATA int ap_have_so_reuseport = -1; +  + static ap_listen_rec *old_listeners; + static int ap_listenbacklog; + static int ap_listencbratio; + static int send_buffer_size; + static int receive_buffer_size; ++#ifdef HAVE_SYSTEMD ++static int use_systemd = -1; ++#endif +  + /* TODO: make_sock is just begging and screaming for APR abstraction */ +-static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) ++static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen) + { +     apr_socket_t *s = server->sd; +     int one = 1; + #if APR_HAVE_IPV6 + #ifdef AP_ENABLE_V4_MAPPED +     int v6only_setting = 0; + #else +     int v6only_setting = 1; + #endif + #endif +     apr_status_t stat; +  + #ifndef WIN32 +     stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); +     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { +         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00067) +                       "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", +                       server->bind_addr); +         apr_socket_close(s); +         return stat; +     } + #endif +  +     stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one); +     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { +         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00068) +                       "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)", +                       server->bind_addr); +         apr_socket_close(s); +         return stat; +     } +  +-#if APR_HAVE_IPV6 +-    if (server->bind_addr->family == APR_INET6) { +-        stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); +-        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { +-            ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) +-                          "make_sock: for address %pI, apr_socket_opt_set: " +-                          "(IPV6_V6ONLY)", +-                          server->bind_addr); +-            apr_socket_close(s); +-            return stat; +-        } +-    } +-#endif +- +     /* +      * To send data over high bandwidth-delay connections at full +      * speed we must force the TCP window to open wide enough to keep the +      * pipe full.  The default window size on many systems +      * is only 4kB.  Cross-country WAN connections of 100ms +      * at 1Mb/s are not impossible for well connected sites. +      * If we assume 100ms cross-country latency, +      * a 4kB buffer limits throughput to 40kB/s. +      * +      * To avoid this problem I've added the SendBufferSize directive +      * to allow the web master to configure send buffer size. +      * +      * The trade-off of larger buffers is that more kernel memory +      * is consumed.  YMMV, know your customers and your network! +      * +      * -John Heidemann <johnh@isi.edu> 25-Oct-96 +      * +      * If no size is specified, use the kernel default. +      */ +     if (send_buffer_size) { +@@ -153,55 +146,71 @@ +     ap_sock_disable_nagle(s); + #endif +  + #if defined(SO_REUSEPORT) +     if (ap_have_so_reuseport && ap_listencbratio > 0) { +         int thesock; +         apr_os_sock_get(&thesock, s); +         if (setsockopt(thesock, SOL_SOCKET, SO_REUSEPORT, +                        (void *)&one, sizeof(int)) < 0) { +             stat = apr_get_netos_error(); +             ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02638) +                           "make_sock: for address %pI, apr_socket_opt_set: " +                           "(SO_REUSEPORT)", +                           server->bind_addr); +             apr_socket_close(s); +             return stat; +         } +     } + #endif +  +-    if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { +-        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) +-                      "make_sock: could not bind to address %pI", +-                      server->bind_addr); +-        apr_socket_close(s); +-        return stat; +-    } ++    if (do_bind_listen) { ++#if APR_HAVE_IPV6 ++        if (server->bind_addr->family == APR_INET6) { ++            stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); ++            if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { ++                ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) ++                              "make_sock: for address %pI, apr_socket_opt_set: " ++                              "(IPV6_V6ONLY)", ++                              server->bind_addr); ++                apr_socket_close(s); ++                return stat; ++            } ++        } ++#endif +  +-    if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { +-        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) +-                      "make_sock: unable to listen for connections " +-                      "on address %pI", +-                      server->bind_addr); +-        apr_socket_close(s); +-        return stat; ++        if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { ++            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) ++                          "make_sock: could not bind to address %pI", ++                          server->bind_addr); ++            apr_socket_close(s); ++            return stat; ++        } ++ ++        if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { ++            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) ++                          "make_sock: unable to listen for connections " ++                          "on address %pI", ++                          server->bind_addr); ++            apr_socket_close(s); ++            return stat; ++        } +     } +  + #ifdef WIN32 +     /* I seriously doubt that this would work on Unix; I have doubts that +      * it entirely solves the problem on Win32.  However, since setting +      * reuseaddr on the listener -prior- to binding the socket has allowed +      * us to attach to the same port as an already running instance of +      * Apache, or even another web server, we cannot identify that this +      * port was exclusively granted to this instance of Apache. +      * +      * So set reuseaddr, but do not attempt to do so until we have the +      * parent listeners successfully bound. +      */ +     stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); +     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { +         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00074) +                     "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", +                      server->bind_addr); +         apr_socket_close(s); +         return stat; +@@ -283,40 +292,159 @@ + static int match_address(const apr_sockaddr_t *sa, +                          const char *hostname, apr_port_t port, +                          const char *scope_id, apr_pool_t *p) + { +     const char *old_scope = NULL; +  + #if APR_VERSION_AT_LEAST(1,7,0) +     /* To be clever here we could correctly match numeric and +      * non-numeric zone ids.  Ignore failure, old_scope will be left +      * as NULL. */ +     (void) apr_sockaddr_zone_get(sa, &old_scope, NULL, p); + #endif +      +     return port == sa->port +         && ((!hostname && !sa->hostname) +             || (hostname && sa->hostname && !strcmp(sa->hostname, hostname))) +         && ((!scope_id && !old_scope) +             || (scope_id && old_scope && !strcmp(scope_id, old_scope)));             + } +  ++ ++#ifdef HAVE_SYSTEMD ++ ++static int find_systemd_socket(process_rec * process, apr_port_t port) { ++    int fdcount, fd; ++    int sdc = sd_listen_fds(0); ++ ++    if (sdc < 0) { ++        ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) ++                      "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", ++                      sdc); ++        return -1; ++    } ++ ++    if (sdc == 0) { ++        ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) ++                      "find_systemd_socket: At least one socket must be set."); ++        return -1; ++    } ++ ++    fdcount = atoi(getenv("LISTEN_FDS")); ++    for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { ++        if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { ++            return fd; ++        } ++    } ++ ++    return -1; ++} ++ ++static apr_status_t alloc_systemd_listener(process_rec * process, ++                                           int fd, const char *proto, ++                                           ap_listen_rec **out_rec) ++{ ++    apr_status_t rv; ++    struct sockaddr sa; ++    socklen_t len = sizeof(struct sockaddr); ++    apr_os_sock_info_t si; ++    ap_listen_rec *rec; ++    *out_rec = NULL; ++ ++    memset(&si, 0, sizeof(si)); ++ ++    rv = getsockname(fd, &sa, &len); ++ ++    if (rv != 0) { ++        rv = apr_get_netos_error(); ++        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489) ++                      "getsockname on %d failed.", fd); ++        return rv; ++    } ++ ++    si.os_sock = &fd; ++    si.family = sa.sa_family; ++    si.local = &sa; ++    si.type = SOCK_STREAM; ++    si.protocol = APR_PROTO_TCP; ++ ++    rec = apr_palloc(process->pool, sizeof(ap_listen_rec)); ++    rec->active = 0; ++    rec->next = 0; ++ ++ ++    rv = apr_os_sock_make(&rec->sd, &si, process->pool); ++    if (rv != APR_SUCCESS) { ++        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490) ++                      "apr_os_sock_make on %d failed.", fd); ++        return rv; ++    } ++ ++    rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd); ++    if (rv != APR_SUCCESS) { ++        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491) ++                      "apr_socket_addr_get on %d failed.", fd); ++        return rv; ++    } ++ ++    rec->protocol = apr_pstrdup(process->pool, proto); ++ ++    *out_rec = rec; ++ ++    return make_sock(process->pool, rec, 0); ++} ++ ++static const char *set_systemd_listener(process_rec *process, apr_port_t port, ++                                        const char *proto) ++{ ++    ap_listen_rec *last, *new; ++    apr_status_t rv; ++    int fd = find_systemd_socket(process, port); ++    if (fd < 0) { ++        return "Systemd socket activation is used, but this port is not " ++                "configured in systemd"; ++    } ++ ++    last = ap_listeners; ++    while (last && last->next) { ++        last = last->next; ++    } ++ ++    rv = alloc_systemd_listener(process, fd, proto, &new); ++    if (rv != APR_SUCCESS) { ++        return "Failed to setup socket passed by systemd using socket activation"; ++    } ++ ++    if (last == NULL) { ++        ap_listeners = last = new; ++    } ++    else { ++        last->next = new; ++        last = new; ++    } ++ ++    return NULL; ++} ++ ++#endif /* HAVE_SYSTEMD */ ++ ++ + /* ### This logic doesn't cope with DNS changes across a restart. */ + static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, +                           const char *addr, apr_port_t port, +                           const char *scope_id, apr_pool_t *temp_pool) + { +     int found = 0; +  +     while (*from) { +         apr_sockaddr_t *sa = (*from)->bind_addr; +  +         /* Some listeners are not real so they will not have a bind_addr. */ +         if (sa) { +             ap_listen_rec *new; +  +             /* Re-use the existing record if it matches completely +              * against an existing listener. */ +             if (match_address(sa, addr, port, scope_id, temp_pool)) { +                 found = 1; +                 if (!to) { +                     break; +@@ -512,41 +640,41 @@ +                     if (lr->bind_addr->port == cur->bind_addr->port +                         && IS_IN6ADDR_ANY(cur->bind_addr) +                         && apr_socket_opt_get(cur->sd, APR_IPV6_V6ONLY, +                                               &v6only_setting) == APR_SUCCESS +                         && v6only_setting == 0) { +  +                         /* Remove the current listener from the list */ +                         previous->next = lr->next; +                         lr = previous; /* maintain current value of previous after +                                         * post-loop expression is evaluated +                                         */ +                         skip = 1; +                         break; +                     } +                 } +                 if (skip) { +                     continue; +                 } +             } + #endif +-            if (make_sock(pool, lr) == APR_SUCCESS) { ++            if (make_sock(pool, lr, 1) == APR_SUCCESS) { +                 ++num_open; +             } +             else { + #if APR_HAVE_IPV6 +                 /* If we tried to bind to ::, and the next listener is +                  * on 0.0.0.0 with the same port, don't give a fatal +                  * error. The user will still get a warning from make_sock +                  * though. +                  */ +                 if (lr->next != NULL +                     && IS_IN6ADDR_ANY(lr->bind_addr) +                     && lr->bind_addr->port == lr->next->bind_addr->port +                     && IS_INADDR_ANY(lr->next->bind_addr)) { +  +                     /* Remove the current listener from the list */ +                     if (previous) { +                         previous->next = lr->next; +                     } +                     else { +                         ap_listeners = lr->next; +@@ -624,42 +752,62 @@ +              * use the default for this listener. +              */ +             for (addr = ls->addrs; addr && !found; addr = addr->next) { +                 for (lr = ap_listeners; lr; lr = lr->next) { +                     if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) && +                         lr->bind_addr->port == addr->host_port) { +                         ap_set_server_protocol(ls, lr->protocol); +                         found = 1; +                         break; +                     } +                 } +             } +  +             if (!found) { +                 /* TODO: set protocol defaults per-Port, eg 25=smtp */ +                 ap_set_server_protocol(ls, "http"); +             } +         } +     } +  +-    if (open_listeners(s->process->pool)) { +-        return 0; ++#ifdef HAVE_SYSTEMD ++    if (use_systemd) { ++        const char *userdata_key = "ap_open_systemd_listeners"; ++        void *data; ++        /* clear the enviroment on our second run ++        * so that none of our future children get confused. ++        */ ++        apr_pool_userdata_get(&data, userdata_key, s->process->pool); ++        if (!data) { ++            apr_pool_userdata_set((const void *)1, userdata_key, ++                                apr_pool_cleanup_null, s->process->pool); ++        } ++        else { ++            sd_listen_fds(1); ++        } ++    } ++    else ++#endif ++    { ++        if (open_listeners(s->process->pool)) { ++            return 0; ++        } +     } +  +     for (lr = ap_listeners; lr; lr = lr->next) { +         num_listeners++; +         found = 0; +         for (ls = s; ls && !found; ls = ls->next) { +             for (addr = ls->addrs; addr && !found; addr = addr->next) { +                 if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) && +                     lr->bind_addr->port == addr->host_port) { +                     found = 1; +                     ap_apply_accept_filter(s->process->pool, lr, ls); +                 } +             } +         } +  +         if (!found) { +             ap_apply_accept_filter(s->process->pool, lr, s); +         } +     } +  +@@ -715,41 +863,41 @@ +             char *hostname; +             apr_port_t port; +             apr_sockaddr_t *sa; +             duplr = apr_palloc(p, sizeof(ap_listen_rec)); +             duplr->slave = NULL; +             duplr->protocol = apr_pstrdup(p, lr->protocol); +             hostname = apr_pstrdup(p, lr->bind_addr->hostname); +             port = lr->bind_addr->port; +             apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, p); +             duplr->bind_addr = sa; +             duplr->next = NULL; +             stat = apr_socket_create(&duplr->sd, duplr->bind_addr->family, +                                      SOCK_STREAM, 0, p); +             if (stat != APR_SUCCESS) { +                 ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(02640) +                             "ap_duplicate_listeners: for address %pI, " +                             "cannot duplicate a new socket!", +                             duplr->bind_addr); +                 return stat; +             } +-            make_sock(p, duplr); ++            make_sock(p, duplr, 1); + #if AP_NONBLOCK_WHEN_MULTI_LISTEN +             use_nonblock = (ap_listeners && ap_listeners->next); +             stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); +             if (stat != APR_SUCCESS) { +                 ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02641) +                               "unable to control socket non-blocking status"); +                 return stat; +             } + #endif +             ap_apply_accept_filter(p, duplr, s); +  +             if (last == NULL) { +                 (*buckets)[i] = last = duplr; +             } +             else { +                 last->next = duplr; +                 last = duplr; +             } +             lr = lr->next; +         } +@@ -695,74 +843,87 @@ +  +     } + } +  + AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, +                                                 int argc, char *const argv[]) + { +     char *host, *scope_id, *proto; +     apr_port_t port; +     apr_status_t rv; +     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); +  +     if (err != NULL) { +         return err; +     } +  +     if (argc < 1 || argc > 2) { +         return "Listen requires 1 or 2 arguments."; +     } +  ++#ifdef HAVE_SYSTEMD ++    if (use_systemd == -1) { ++        use_systemd = sd_listen_fds(0) > 0; ++    } ++#endif ++ +     rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); +     if (rv != APR_SUCCESS) { +         return "Invalid address or port"; +     } +  +     if (host && !strcmp(host, "*")) { +         host = NULL; +     } +  + #if !APR_VERSION_AT_LEAST(1,7,0) +     if (scope_id) { +         return apr_pstrcat(cmd->pool, +                            "Scope ID in address '", argv[0], +                            "' not supported with APR " APR_VERSION_STRING, +                            NULL); +     } + #endif +  +     if (!port) { +         return "Port must be specified"; +     } +  +     if (argc != 2) { +         if (port == 443) { +             proto = "https"; +         } else { +             proto = "http"; +         } +     } +     else { +         proto = apr_pstrdup(cmd->pool, argv[1]); +         ap_str_tolower(proto); +     } +  ++#ifdef HAVE_SYSTEMD ++    if (use_systemd) { ++        return set_systemd_listener(cmd->server->process, port, proto); ++    } ++#endif ++ ++ +     return alloc_listener(cmd->server->process, host, port, proto, +                           scope_id, NULL, cmd->temp_pool); + } +  + AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, +                                                      void *dummy, +                                                      const char *arg) + { +     int b; +     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); +  +     if (err != NULL) { +         return err; +     } +  +     b = atoi(arg); +     if (b < 1) { +         return "ListenBacklog must be > 0"; +     } +  @@ -7,7 +7,7 @@  Name:             httpd  Summary:          Apache HTTP Server -Version:          2.4.59 +Version:          2.4.60  Release:          1  License:          ASL 2.0  URL:              https://httpd.apache.org/ @@ -60,12 +60,11 @@ Patch6:           backport-httpd-2.4.43-corelimit.patch  Patch7:           backport-httpd-2.4.25-selinux.patch  Patch8:           backport-httpd-2.4.54-icons.patch  Patch9:           backport-httpd-2.4.43-cachehardmax.patch -Patch10:          backport-httpd-2.4.43-socket-activation.patch +Patch10:          backport-httpd-2.4.60-socket-activation.patch  Patch11:          backport-httpd-2.4.43-sslciphdefault.patch  Patch12:          backport-httpd-2.4.43-sslprotdefault.patch  Patch13:          backport-httpd-2.4.43-enable-sslv3.patch  Patch14:          backport-layout_add_openEuler.patch -Patch15:          backport-httpd-2.4.59-gettid.patch  BuildRequires:    gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel  BuildRequires:    zlib-devel libselinux-devel lua-devel brotli-devel @@ -502,6 +501,9 @@ exit $rv  %{_rpmconfigdir}/macros.d/macros.httpd  %changelog +* Tue Jul 02 2024 Funda Wang <fundawang@yeah.net> - 2.4.60-1 +- New version 2.4.60 +  * Sat Apr 06 2024 Funda Wang <fundawang@yeah.net> - 2.4.59-1  - New version 2.4.59 @@ -1 +1 @@ -9f77eb01b2fddfb4b32d469af90fb01b  httpd-2.4.59.tar.bz2 +50b1fcf3637b16a20c6c8e5e8da404bc  httpd-2.4.60.tar.bz2  | 
