All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: steved@redhat.com, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 04/14] text-based mount command: get_client_address support for IPv6
Date: Thu, 10 Jul 2008 15:43:10 -0400	[thread overview]
Message-ID: <20080710194310.GC27734@fieldses.org> (raw)
In-Reply-To: <5E74A13F-4A79-4356-8BBE-7B535F00EA66@oracle.com>

On Thu, Jul 10, 2008 at 03:36:21PM -0400, Chuck Lever wrote:
> On Jul 10, 2008, at 3:30 PM, J. Bruce Fields wrote:
>> On Wed, Jul 09, 2008 at 08:37:24PM -0400, Chuck Lever wrote:
>>> Introduce IPv6-enabled version of get_client_address.  The legacy  
>>> mount
>>> command could use this eventually as well.
>>>
>>> I don't remember how to tell an NFSv4 server to disable the callback
>>> channel:  whether an ANY address is passed with SETCLIENTID, or a
>>> loopback address is passed.  The patch allows either to be used with 
>>> a
>>> compile-time switch.
>>
>> I would have thought INADDR_ANY.  But in any case we should just pick
>> one....
>
> Well, yes, but we should pick the "correct" one.  :-)  The patch does it 
> this way just to make a note of this issue so we can make a decision 
> before committing this upstream.
>
> Does RFC 3530 have any recommendation about this?

Not that I can find on a quick skim.

I don't see why the spec would forbid running over loopback, though, in
which case a loopback callback address would make sense.  And I assume
INADDR_ANY is always meaningless as a destination address, so is a
logical way to tell the server it can't call back to you.

--b.

>
>>
>>
>> --b.
>>
>>>
>>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>>> ---
>>>
>>> utils/mount/network.c |  122 +++++++++++++++++++++++++++++++++++++++ 
>>> ++++++++++
>>> utils/mount/network.h |    2 +
>>> 2 files changed, 124 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/utils/mount/network.c b/utils/mount/network.c
>>> index 3f2721b..128d7f7 100644
>>> --- a/utils/mount/network.c
>>> +++ b/utils/mount/network.c
>>> @@ -918,3 +918,125 @@ int get_client_address(struct sockaddr_in  
>>> *saddr, struct sockaddr_in *caddr)
>>> 	}
>>> 	return 1;
>>> }
>>> +
>>> +/*
>>> + * Try a getsockname() on a connected datagram socket.
>>> + *
>>> + * Returns 1 and fills in @buf if successful; otherwise, zero.
>>> + *
>>> + * A connected datagram socket prevents leaving a socket in  
>>> TIME_WAIT.
>>> + * This conserves the ephemeral port number space, helping reduce  
>>> failed
>>> + * socket binds during mount storms.
>>> + */
>>> +static int nfs_ca_sockname(const struct sockaddr *sap, const  
>>> socklen_t salen,
>>> +			   struct sockaddr *buf, socklen_t *buflen)
>>> +{
>>> +	struct sockaddr_in sin = {
>>> +		.sin_family		= AF_INET,
>>> +		.sin_addr.s_addr	= htonl(INADDR_ANY),
>>> +	};
>>> +	struct sockaddr_in6 sin6 = {
>>> +		.sin6_family		= AF_INET6,
>>> +		.sin6_addr		= IN6ADDR_ANY_INIT,
>>> +	};
>>> +	int sock;
>>> +
>>> +	sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP);
>>> +	if (sock < 0)
>>> +		return 0;
>>> +
>>> +	switch (sap->sa_family) {
>>> +	case AF_INET:
>>> +		if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
>>> +			close(sock);
>>> +			return 0;
>>> +		}
>>> +		break;
>>> +	case AF_INET6:
>>> +		if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
>>> +			close(sock);
>>> +			return 0;
>>> +		}
>>> +		break;
>>> +	default:
>>> +		errno = EAFNOSUPPORT;
>>> +		return 0;
>>> +	}
>>> +
>>> +	if (connect(sock, sap, salen) < 0) {
>>> +		close(sock);
>>> +		return 0;
>>> +	}
>>> +
>>> +	return !getsockname(sock, buf, buflen);
>>> +}
>>> +
>>> +/*
>>> + * Try to generate an address that prevents the server from calling 
>>> us.
>>> + *
>>> + * Returns 1 and fills in @buf if successful; otherwise, zero.
>>> + */
>>> +static int nfs_ca_gai(const struct sockaddr *sap, const socklen_t  
>>> salen,
>>> +		      struct sockaddr *buf, socklen_t *buflen)
>>> +{
>>> +	struct addrinfo *gai_results;
>>> +	struct addrinfo gai_hint = {
>>> +		.ai_family	= sap->sa_family,
>>> +#ifdef GENERATE_LOOPBACK_ADDRESS
>>> +		.ai_flags	= 0,		/* loopback */
>>> +#else
>>> +		.ai_flags	= AI_PASSIVE,	/* ANYADDR */
>>> +#endif
>>> +	};
>>> +
>>> +	if (getaddrinfo(NULL, "", &gai_hint, &gai_results))
>>> +		return 0;
>>> +
>>> +	*buflen = gai_results->ai_addrlen;
>>> +	memcpy(buf, gai_results->ai_addr, *buflen);
>>> +
>>> +	freeaddrinfo(gai_results);
>>> +
>>> +	return 1;
>>> +}
>>> +
>>> +/**
>>> + * nfs_callback_address - acquire our local network address
>>> + * @sap: pointer to address of remote
>>> + * @sap_len: length of address
>>> + * @buf: pointer to buffer to be filled in with local network  
>>> address
>>> + * @buflen: IN: length of buffer to fill in; OUT: length of filled- 
>>> in address
>>> + *
>>> + * Discover a network address that an NFSv4 server can use to call  
>>> us back.
>>> + * On multi-homed clients, this address depends on which NIC we use 
>>> to
>>> + * route requests to the server.
>>> + *
>>> + * Returns 1 and fills in @buf if an unambiguous local address is
>>> + * available; returns 1 and fills in an appropriate ANYADDR address
>>> + * if a local address isn't available; otherwise, returns zero.
>>> + */
>>> +int nfs_callback_address(const struct sockaddr *sap, const  
>>> socklen_t salen,
>>> +			 struct sockaddr *buf, socklen_t *buflen)
>>> +{
>>> +	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf;
>>> +
>>> +	if (nfs_ca_sockname(sap, salen, buf, buflen) == 0)
>>> +		if (nfs_ca_gai(sap, salen, buf, buflen) == 0)
>>> +			goto out_failed;
>>> +
>>> +	/*
>>> +	 * The server can't use an interface ID that was generated
>>> +	 * here on the client, so always clear sin6_scope_id.
>>> +	 */
>>> +	if (sin6->sin6_family == AF_INET6)
>>> +		sin6->sin6_scope_id = 0;
>>> +
>>> +	return 1;
>>> +
>>> +out_failed:
>>> +	*buflen = 0;
>>> +	if (verbose)
>>> +		nfs_error(_("%s: failed to construct callback address"));
>>> +	return 0;
>>> +
>>> +}
>>> diff --git a/utils/mount/network.h b/utils/mount/network.h
>>> index 8da7e20..2f4ff3a 100644
>>> --- a/utils/mount/network.h
>>> +++ b/utils/mount/network.h
>>> @@ -58,6 +58,8 @@ int nfs_string_to_sockaddr(const char *, const  
>>> size_t,
>>> int nfs_present_sockaddr(const struct sockaddr *,
>>> 			 const socklen_t, char *, const size_t);
>>> int get_client_address(struct sockaddr_in *, struct sockaddr_in *);
>>> +int nfs_callback_address(const struct sockaddr *, const socklen_t,
>>> +		struct sockaddr *, socklen_t *);
>>> int nfs_call_umount(clnt_addr_t *, dirpath *);
>>> int clnt_ping(struct sockaddr_in *, const unsigned long,
>>> 		const unsigned long, const unsigned int,
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" 
>>> in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> --
> Chuck Lever
> chuck[dot]lever[at]oracle[dot]com
>
>
>

  reply	other threads:[~2008-07-10 19:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-10  0:37 [PATCH 00/14] Support for mounting NFSv4 servers over IPv6 Chuck Lever
     [not found] ` <20080710001725.6137.83845.stgit-lQeC5l55kZ7wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-07-10  0:37   ` [PATCH 01/14] nfs-utils: Introduce new ./configure option: "--enable-ipv6" Chuck Lever
2008-07-10  0:37   ` [PATCH 02/14] text-based mount command: Add headers needed for IPv6 support Chuck Lever
2008-07-10  0:37   ` [PATCH 03/14] mount command: Add functions to manage addresses in string form Chuck Lever
2008-07-10  0:37   ` [PATCH 04/14] text-based mount command: get_client_address support for IPv6 Chuck Lever
     [not found]     ` <20080710003723.6137.51761.stgit-lQeC5l55kZ7wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-07-10 19:30       ` J. Bruce Fields
2008-07-10 19:36         ` Chuck Lever
2008-07-10 19:43           ` J. Bruce Fields [this message]
2008-07-10 20:35             ` Chuck Lever
     [not found]               ` <76bd70e30807101335y54f8b479v39953a772e08e88c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-11 19:06                 ` J. Bruce Fields
2008-07-11 19:16                   ` Chuck Lever
2008-07-10  0:37   ` [PATCH 05/14] text-based mount command: Add helper to construct network addresses Chuck Lever
2008-07-10  0:37   ` [PATCH 06/14] text-based mount command: "addr=" option support for IPv6 addresses Chuck Lever
2008-07-10  0:37   ` [PATCH 07/14] text-based mount command: "clientaddr=" " Chuck Lever
2008-07-10  0:37   ` [PATCH 08/14] text-based mount command: "mounthost=" " Chuck Lever
2008-07-10  0:37   ` [PATCH 09/14] text-based mount command: Add IPv6 support to set_mandatory_options Chuck Lever
2008-07-10  0:37   ` [PATCH 10/14] text-based mount command: Support raw IPv6 address hostnames Chuck Lever
2008-07-10  0:38   ` [PATCH 11/14] text-based mount command: Remove unused IPv4-only functions Chuck Lever
2008-07-10  0:38   ` [PATCH 12/14] text-based mount options: rename functions in stropts.c Chuck Lever
2008-07-10  0:38   ` [PATCH 13/14] text-based mount command: remove unnecessary headers from stropts.c Chuck Lever
2008-07-10  0:38   ` [PATCH 14/14] mount command: Remove RPC headers from network.h Chuck Lever
  -- strict thread matches above, loose matches on Subject: below --
2008-07-11 20:34 [PATCH 00/14] Support for mounting NFSv4 servers over IPv6 Chuck Lever
     [not found] ` <20080711203322.478.52095.stgit-lQeC5l55kZ7wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-07-11 20:34   ` [PATCH 04/14] text-based mount command: get_client_address support for IPv6 Chuck Lever

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080710194310.GC27734@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=steved@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.