[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-inetutils] [PATCH] Make `tftpd' IPv6-compatible
From: |
Guillem Jover |
Subject: |
Re: [bug-inetutils] [PATCH] Make `tftpd' IPv6-compatible |
Date: |
Wed, 8 Sep 2010 06:38:06 +0200 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
Hi!
On Tue, 2010-09-07 at 18:05:37 +0200, Ludovic Courtès wrote:
> The attached patch makes ‘tftpd’ IPv6-compatible. As a side effect, it
> makes it usable (!) on current GNU/Linux when a client connects via an
> address other than the loopback address (FROM is always AF_INET6 on my
> machine.)
>
> The patch assumes that IPv6 support is available. Besides, it’d be
> better to import Gnulib’s ‘inet_ntop’ modules.
Mats was already working on this, see also my review on that thread.
I'll comment on this one anyway, as I've seen some problems.
> From 3be7f44305103b39a0e1bc79a9960feb5d142485 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <address@hidden>
> Date: Tue, 7 Sep 2010 17:53:23 +0200
> Subject: [PATCH] Make `tftpd' IPv6-compatible.
> diff --git a/src/tftpd.c b/src/tftpd.c
> index 70602fa..719db81 100644
> --- a/src/tftpd.c
> +++ b/src/tftpd.c
> @@ -124,7 +124,8 @@ static int logging;
>
> static const char *errtomsg (int);
> static void nak (int);
> -static const char *verifyhost (struct sockaddr_in *);
> +static char *verify_host (struct sockaddr_storage *, socklen_t,
> + char *, size_t);
Why remove the constness? the returned string is not supposed to be
modified nor freed.
> @@ -268,18 +269,19 @@ main (int argc, char *argv[])
> memset (&sin, 0, sizeof (sin));
> - sin.sin_family = AF_INET;
> + sin.ss_family = from.ss_family;
> if (bind (peer, (struct sockaddr *) &sin, sizeof (sin)) < 0)
The socklen_t argument should be fromlen so that this works on the
BSDs.
> @@ -360,8 +362,10 @@ again:
> ecode = (*pf->f_validate) (&filename, tp->th_opcode);
> if (logging)
> {
> + char node[1024];
This should be NI_MAXHOST instead.
> syslog (LOG_INFO, "%s: %s request for %s: %s",
> - verifyhost (&from),
> + verify_host (&from, sizeof from,
Here fromlen too.
> + node, sizeof node),
> tp->th_opcode == WRQ ? "write" : "read",
> filename, errtomsg (ecode));
> }
> @@ -736,17 +740,29 @@ nak (int error)
> syslog (LOG_ERR, "nak: %m\n");
> }
>
> -static const char *
> -verifyhost (struct sockaddr_in *fromp)
> +static char *
> +verify_host (struct sockaddr_storage *addr, socklen_t addr_len,
> + char *host_and_service, size_t len)
> {
> - struct hostent *hp;
> -
> - hp = gethostbyaddr ((char *) &fromp->sin_addr, sizeof (fromp->sin_addr),
> - fromp->sin_family);
> - if (hp)
> - return hp->h_name;
> + int err;
> + char host[512], service[256];
Here NI_MAXHOST and NI_MAXSERV instead of magic values.
> +
> + err = getnameinfo ((struct sockaddr *) addr, addr_len,
> + host, sizeof host,
> + service, sizeof service,
> + 0);
> +
> + if (err)
> + inet_ntop (addr->ss_family,
> + addr->ss_family == AF_INET
> + ? (void *) &((struct sockaddr_in *) addr)->sin_addr
> + : (void *) &((struct sockaddr_in6 *) addr)->sin6_addr,
> + host_and_service, len);
The inet_ntop call should not be needed, getnameinfo should be able to
handle numeric addresses just fine.
> else
> - return inet_ntoa (fromp->sin_addr);
> + snprintf (host_and_service, len, "%s%s%s",
> + host, *service ? "/" : "", service);
> +
> + return host_and_service;
> }
regards,
guillem