[systemd-devel] [PATCH] add REMOTE_ADDR and REMOTE_PORT for Accept=yes

Ronny Chevalier chevalier.ronny at gmail.com
Mon Mar 9 15:18:20 PDT 2015


2015-03-09 23:09 GMT+01:00 Shawn Landden <shawn at churchofgit.com>:
> On Mon, Mar 9, 2015 at 1:18 PM, Lennart Poettering <lennart at poettering.net>
> wrote:
>>
>> On Mon, 09.03.15 13:09, Shawn Landden (shawn at churchofgit.com) wrote:
>>
>> > +        if (UNIT_DEREF(s->accept_socket)) {
>> > +                union sockaddr_union sa;
>> > +                socklen_t salen = sizeof(sa);
>> > +
>> > +                r = getpeername(s->socket_fd, &sa.sa, &salen);
>> > +                if (r < 0) {
>> > +                        r = -errno;
>> > +                        goto fail;
>> > +                }
>> > +
>> > +                if (sa.sa.sa_family == AF_INET ||
>> > +                    sa.sa.sa_family == AF_INET6) {
>> > +                        _cleanup_free_ char *addr = NULL;
>> > +                        uint16_t port = (uint16_t)sockaddr_port(&sa);
>>
>> We try to avoid invoking functions in the same lines as we declare
>> variables.
>>
>> Also, even though this cannot fail in this case, I think it would be
>> nicer, to make port an int, and check for < 0 and return an error in
>> that case...
>>
>> > +
>> > +                        r = sockaddr_pretty(&sa.sa, salen, true, false,
>> > &addr);
>> > +                        if (r < 0)
>> > +                                goto fail;
>> > +
>> > +                        if (!(our_env[n_env++] =
>> > strappend("REMOTE_ADDR=", addr))) {
>>
>> In newer code we try to avoid making assignments and doing if checks
>> in the same line.
>>
> Taking this out would be pretty gruesome because of use of the
> post-increment operator.

Maybe by using a temporary variable like this:

char *env_str;

[...]

env_str = strappend("REMOTE_ADDR", addr);
if (!env_str) {
        r = -ENOMEM;
        goto fail;
}
our_env[n_env++] = env_str;

And the same with the other one ?

>>
>> >
>> > -int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool
>> > translate_ipv6, char **ret) {
>> > +int sockaddr_port(const union sockaddr_union *sa) {
>> > +        assert_return(sa->sa.sa_family == AF_INET6 ||
>> > +                      sa->sa.sa_family == AF_INET,
>> > +                      -ENOTSUP);
>>
>> assert_return() is a macro to use only for cases where there's a clear
>> programming error of the caller. But I am pretty sure that this is not
>> the case here. If it gets called on an non-AF_INET/AF_INET6 socket
>> then this should fail without logging.
>>
>> Also I think an error code of EAFNOSUPPORT would be more appropriate.
>>
>> Hmm, and I think this should probably take an actual "struct
>> sockaddr", rather than a union sockaddr_union...
>>
>> > @@ -475,42 +485,40 @@ int sockaddr_pretty(const struct sockaddr *_sa,
>> > socklen_t salen, bool translate_
>> >
>> >          switch (sa->sa.sa_family) {
>> >
>> > -        case AF_INET: {
>> > -                uint32_t a;
>> > -
>> > -                a = ntohl(sa->in.sin_addr.s_addr);
>> > -
>> > -                if (asprintf(&p,
>> > -                             "%u.%u.%u.%u:%u",
>> > -                             a >> 24, (a >> 16) & 0xFF, (a >> 8) &
>> > 0xFF, a & 0xFF,
>> > -                             ntohs(sa->in.sin_port)) < 0)
>> > -                        return -ENOMEM;
>> > -
>> > -                break;
>> > -        }
>> > -
>> > +        case AF_INET:
>> >          case AF_INET6: {
>> > -                static const unsigned char ipv4_prefix[] = {
>> > -                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
>> > -                };
>> > -
>> > -                if (translate_ipv6 && memcmp(&sa->in6.sin6_addr,
>> > ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
>> > -                        const uint8_t *a =
>> > sa->in6.sin6_addr.s6_addr+12;
>> > +                char a[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
>> > +                const char *addr;
>> > +                bool ipv4_mapped = false;
>> > +
>> > +                if (inet_ntop(sa->sa.sa_family,
>> > +                              /* this field of the API is kinda
>> > braindead,
>> > +                               * should take head of struct so it can
>> > be passed the union...*/
>> > +                              sa->sa.sa_family == AF_INET6 ?
>> > +                                &sa->in6.sin6_addr :
>> > +                                &sa->in.sin_addr,
>> > +                              a, sizeof(a)) == NULL)
>> > +                      return -ENOMEM;
>> > +
>> > +                /* glibc inet_ntop() presents v4-mapped addresses in
>> > ::ffff:a.b.c.d form */
>> > +                if (translate_ipv6 && sa->sa.sa_family == AF_INET6 &&
>> > strchr(a, '.')) {
>> > +                        ipv4_mapped = true;
>> > +                        addr = strempty(startswith(a, "::ffff:"));
>>
>> I think it would be a lot nicer to check the raw IP prefix as before,
>> and only then format things, then first formatting and then looking at
>> the string again.
>>
>> We shouldn't bind us too closely to the precise formatting. I mean, if
>> one day libc decides to format the thing as ipv6 again, or with
>> uppercase hex chars, we shouldn't break.
>>
>> > +                } else
>> > +                        addr = &a[0];
>> > +
>> > +                if (include_port) {
>> > +                        uint16_t port = (uint16_t)sockaddr_port(sa);
>>
>> No function calls in variable declarations, please. Same rule as above
>> applies.
>> Lennart
>>
>> --
>> Lennart Poettering, Red Hat
>> _______________________________________________
>> systemd-devel mailing list
>> systemd-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
>
>
>
> --
> Shawn Landden
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
>


More information about the systemd-devel mailing list