From: Neil Brown <neilb@suse.de>
To: Jeff Layton <jlayton@poochiereds.net>
Cc: nfs@lists.sourceforge.net, Steve Dickson <SteveD@redhat.com>
Subject: Re: [PATCH 09/11] nfs-utils: mount: Fixed mounts to multi-home servers
Date: Thu, 1 Mar 2007 12:48:34 +1100 [thread overview]
Message-ID: <17894.12530.165078.511522@notabene.brown> (raw)
In-Reply-To: message from Jeff Layton on Tuesday February 27
On Tuesday February 27, jlayton@poochiereds.net wrote:
>
> I know we saw this with Solaris servers in particular (it's been a
> while, but I think I was testing against Solaris 8). The fedora BZ is
> here if you want to see all the gory details:
>
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=212471
>
> I'm thinking we will have to deal with this situation, unfortunately, so
> maybe disconnecting the socket after getting the address is the best thing?
>
> -- Jeff
Thanks for the link... Looks like we do need to be very careful about
connecting UDP sockets.
This patch maybe?
NeilBrown
diff --git a/support/include/conn.h b/support/include/conn.h
index 1761dc4..11f16ab 100644
--- a/support/include/conn.h
+++ b/support/include/conn.h
@@ -35,7 +35,7 @@ int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int,
struct sockaddr_in *);
u_long nfsvers_to_mnt(const u_long);
u_long mntvers_to_nfs(const u_long);
-int get_socket(struct sockaddr_in *, u_int, int);
+int get_socket(struct sockaddr_in *, u_int, int, int);
CLIENT * mnt_openclnt(clnt_addr_t *, int *);
void mnt_closeclnt(CLIENT *, int);
diff --git a/support/nfs/conn.c b/support/nfs/conn.c
index 89f7676..1020b47 100644
--- a/support/nfs/conn.c
+++ b/support/nfs/conn.c
@@ -49,7 +49,7 @@ u_long mntvers_to_nfs(const u_long vers)
* RPC_ANYSOCK is returned which will cause
* the RPC code to create the socket instead.
*/
-int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
+int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp, int conn)
{
int so, cc, type;
struct sockaddr_in laddr;
@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
return RPC_ANYSOCK;
}
}
- if (type == SOCK_STREAM || type == SOCK_DGRAM) {
+ if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
cc = connect(so, (struct sockaddr *)saddr, namelen);
if (cc < 0) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
@@ -129,9 +129,10 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
CLIENT *clnt=NULL;
int sock, stat;
static char clnt_res;
+ struct sockaddr dissolve;
rpc_createerr.cf_stat = stat = errno = 0;
- sock = get_socket(saddr, prot, FALSE);
+ sock = get_socket(saddr, prot, FALSE, TRUE);
if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
/*
* TCP timeout. Bubble up the error to see
@@ -141,8 +142,22 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
goto out_bad;
}
+ if (caddr) {
+ /* Get the address of our end of this connection */
+ socklen_t len = sizeof(*caddr);
+ if (getsockname(sock, caddr, &len) != 0)
+ caddr->sin_family = 0;
+ }
+
switch(prot) {
case IPPROTO_UDP:
+ /* The socket is connected (so we could getsockname successfully),
+ * but some servers on multi-homed hosts reply from
+ * the wrong address, so if we stay connected, we lose the reply.
+ */
+ dissolve.sa_family = AF_UNSPEC;
+ connect(sock, &dissolve, sizeof(dissolve));
+
clnt = clntudp_bufcreate(saddr, prog, vers,
RETRY_TIMEOUT, &sock,
RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
@@ -166,15 +181,7 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
rpc_createerr.cf_stat = stat;
}
clnt_destroy(clnt);
- if (sock != -1) {
- if (caddr) {
- /* Get the address of our end of this connection */
- socklen_t len = sizeof(*caddr);
- if (getsockname(sock, caddr, &len) != 0)
- caddr->sin_family = 0;
- }
- close(sock);
- }
+ close(sock);
if (stat == RPC_SUCCESS)
return 1;
@@ -191,7 +198,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
/* contact the mount daemon via TCP */
mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
- *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE);
+ *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);
switch (mnt_pmap->pm_prot) {
case IPPROTO_UDP:
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 507ccdb..0f66bdf 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -306,7 +306,7 @@ getport(
enum clnt_stat stat;
saddr->sin_port = htons (PMAPPORT);
- socket = get_socket(saddr, prot, FALSE);
+ socket = get_socket(saddr, prot, FALSE, FALSE);
switch (prot) {
case IPPROTO_UDP:
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
next prev parent reply other threads:[~2007-03-01 1:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-26 11:18 [PATCH 09/11] nfs-utils: mount: Fixed mounts to multi-home servers Steve Dickson
2007-02-27 6:32 ` Neil Brown
2007-02-27 18:12 ` Jeff Layton
2007-03-01 1:48 ` Neil Brown [this message]
2007-03-11 19:58 ` Jeff Layton
2007-03-11 22:38 ` Neil Brown
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=17894.12530.165078.511522@notabene.brown \
--to=neilb@suse.de \
--cc=SteveD@redhat.com \
--cc=jlayton@poochiereds.net \
--cc=nfs@lists.sourceforge.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox