Project

General

Profile

Actions

Feature #3154

closed

server.socket-route-id new config option proposal

Added by devnexen about 2 years ago. Updated almost 2 years ago.

Status:
Missing Feedback
Priority:
Low
Category:
core
Target version:
-
ASK QUESTIONS IN Forums:
No

Description

- Adding new `socket-route-id` option to set the route id of the server socket on Linux, FreeBSD and OpenBSD.
- Patch from master.


Files

Actions #1

Updated by gstrauss about 2 years ago

You seem to be assuming that lighttpd is started as root, which is not always the case.

To set SO_MARK on Linux, lighttpd needs to be started as root, or the user process starting lighttpd must have the CAP_NET_ADMIN capability.

Would you please provide some context for readers on why this feature in your patch is useful, and why the host firewall is not setting the mark, or an upstream process is not setting the routing table (e.g. container setup)?

Actions #2

Updated by devnexen about 2 years ago

Not necessarily ran as root that s right thus is an option; but maybe it makes less sense to support Linux due to this (and OpenBSD requires being root too) and supporting only FreeBSD then.

Actions #3

Updated by gstrauss about 2 years ago

Repeating what I asked above:

Would you please provide some context for readers on why this feature in your patch is useful, and why the host firewall is not setting the mark, or an upstream process is not setting the routing table (e.g. container setup)?

Actions #4

Updated by devnexen about 2 years ago

In the case of FreeBSD let's imagine we have instances of lighttpd and upon ipfw setting a cookie ids to filter then in those cases, it might be helpful to be able to set it from the app point of view.

Actions #5

Updated by gstrauss about 2 years ago

In the case of FreeBSD let's imagine we have instances of lighttpd and upon ipfw setting a cookie ids to filter then in those cases,

I am aware of how packet marking works. I am asked for a little more justification on why there are not (often) better ways to configure this, e.g. configuring the firewall for a known listening IP and port.

it might be helpful to be able to set it from the app point of view.

how so?

Actions #6

Updated by gstrauss about 2 years ago

  • Status changed from New to Need Feedback
  • Priority changed from Normal to Low
Actions #7

Updated by devnexen about 2 years ago

Speaking only about FreeBSD, with ipfw you can match the socket id and in this platform there is not really handy way to set it from the code user standpoint.

Actions #8

Updated by gstrauss about 2 years ago

  • Status changed from Need Feedback to Missing Feedback

Are you even trying to be convincing? You might not fully understand what I am attempting to convey with the words "convince" or "justify".

You need to be root (or have root-level privileges) to configure the host firewall. lighttpd typically is configured to listen on well-known ports, and this can trivially be incorporated into ipfw rules.

Why should your patch be included in the official lighttpd distribution?

Actions #9

Updated by gstrauss about 2 years ago

Similar to #2368 SO_BINDTODEVICE. lighttpd "could" create interfaces for lots of socket options, but why?

Some compelling reasoning might be more helpful than your above posts conveying "ooh, look: a shiny, extraneous configuration knob!"

.

Some technical feedback on your patch: The patch does not exclude AF_UNIX for which SO_MARK and related options do not apply. Also, the patch might not be backwards compatible with earlier versions of various OS which might not define those socket options. Already mentioned was the root restriction on some OS.

You may try the following instead, but this patch is unlikely to be made part of the official lighttpd distribution as you have repeatedly ignored/failed to answer the questions I posed above.

diff --git a/src/network.c b/src/network.c
index 7c486221..1518586e 100644
--- a/src/network.c
+++ b/src/network.c
@@ -180,6 +180,7 @@ static void network_srv_sockets_append(server *srv, server_socket *srv_socket) {
 typedef struct {
     /* global or per-socket config; not patched per connection */
     int listen_backlog;
+    uint32_t socket_route_id;
     unsigned char ssl_enabled;
     unsigned char use_ipv6;
     unsigned char set_v6only; /* set_v6only is only a temporary option */
@@ -221,6 +222,9 @@ static void network_merge_config_cpv(network_socket_config * const pconf, const
       case 7: /* server.v4mapped */
         pconf->v4mapped = (0 != cpv->v.u);
         break;
+      case 8: /* server.socket-route-id */
+        pconf->socket_route_id = cpv->v.u;
+        break;
       default:/* should not happen */
         return;
     }
@@ -474,6 +478,23 @@ static int network_server_init(server *srv, network_socket_config *s, buffer *ho
                }
        }
 #endif
 #endif
+
+#if defined(__linux__) && defined(SO_MARK)
+    int optname = SO_MARK;
+#elif defined(__FreeBSD__) && defined(SO_USER_COOKIE)
+    int optname = SO_USER_COOKIE;
+#elif defined(__OpenBSD__) && defined(SO_RTABLE)
+    int optname = SO_RTABLE;
+#else
+    int optname = 0;
+#endif
+    if (optname && family != AF_UNIX && 0 != s->socket_route_id) {
+        if (setsockopt(srv_socket->fd, SOL_SOCKET, optname,
+                       &s->socket_route_id, sizeof(s->socket_route_id)) < 0) {
+            log_perror(srv->errh, __FILE__, __LINE__,
+              "can't set socket-route-id '%u'", s->socket_route_id);
+        }
+    }

        return 0;
@@ -629,6 +654,9 @@ int network_init(server *srv, int stdin_fd) {
      ,{ CONST_STR_LEN("server.v4mapped"),
         T_CONFIG_BOOL,
         T_CONFIG_SCOPE_CONNECTION }
+     ,{ CONST_STR_LEN("server.socket-route-id"),
+        T_CONFIG_INT,
+        T_CONFIG_SCOPE_SOCKET }
     #if 0 /* TODO: more integration needed ... */
      ,{ CONST_STR_LEN("mbedtls.engine"),
         T_CONFIG_BOOL,
Actions #10

Updated by gstrauss almost 2 years ago

  • Target version deleted (1.4.xx)
Actions #11

Updated by gstrauss almost 2 years ago

Missing Feedback.

Actions #12

Updated by devnexen almost 2 years ago

gstrauss wrote in #note-9:

Similar to #2368 SO_BINDTODEVICE. lighttpd "could" create interfaces for lots of socket options, but why?

Some compelling reasoning might be more helpful than your above posts conveying "ooh, look: a shiny, extraneous configuration knob!"

.

Thanks for the feedback.

Some technical feedback on your patch: The patch does not exclude AF_UNIX for which SO_MARK and related options do not apply. Also, the patch might not be backwards compatible with earlier versions of various OS which might not define those socket options. Already mentioned was the root restriction on some OS.

SO_MARK since 2.6.25 might be safe enough now ?

You may try the following instead, but this patch is unlikely to be made part of the official lighttpd distribution as you have repeatedly ignored/failed to answer the questions I posed above.

[...]

Almost only FreeBSD needs an uint32_t type.

Actions #13

Updated by gstrauss almost 2 years ago

SO_MARK since 2.6.25 might be safe enough now ?

That is not my question to answer. Asking me to do more research into this is a non-starter.

[Edit:] my patch addresses the problem I raised about your patch regarding undefined identifiers.

Almost only FreeBSD needs an uint32_t type.

That sentence in unclear to me. What do you mean? lighttpd already runs on FreeBSD and lighttpd code already uses uint32_t.

[Edit:] setsockopt() takes a (void *) and socklen_t. lighttpd having a consistent interface across platforms works fine, even on FreeBSD as long as sizeof(int) == sizeof(uint32_t) on a theoretical platform running FreeBSD. While theoretically possible to differ, this is not the case in widespread practice where the most common ABIs used by FreeBSD on 32-bit and 64-bit hardware are ILP32 and LP64. All that said, your patch is wrong. According to https://www.unix.com/man-page/FreeBSD/2/setsockopt/, FreeBSD takes a uint32_t for SO_USER_COOKIE. On Linux, setsockopt() takes an int for SO_MARK. Same common ABIs apply to Linux as to FreeBSD. In the patch above, lighttpd stores pconf->socket_route_id in a uint32_t, specified as 32-bits (4 bytes).

this patch is unlikely to be made part of the official lighttpd distribution as you have repeatedly ignored/failed to answer the questions I posed above.

Some compelling reasoning might be more helpful than your above posts conveying "ooh, look: a shiny, extraneous configuration knob!"

Still not provided; Missing Feedback. The conversation is unlikely to proceed absent some compelling reasoning.

Actions

Also available in: Atom