> The server detects that the connection is closed. It doesn't close the
> socket immediately and starts waiting for the client to reconnect (or
> another client, etc). As the socket is not closed, from client's point
> of view, the connection is still not fully closaed, so it keeps
> waiting before reconnecting with the same source port; a kind of
> deadlock.
> 
> The diff below fixes this by checking for EOF before sleeping.
> 
> OK?

Yes. Unfortunately NEEDQ and DISCONN may be both set, so we still need
to check for DISCONN here before NEEDQ.

Or the whole block could become

        if (NEEDQ set and not DISCONN set)
                nfsrv_rcv block
        if (DISCONN set)
                nfsrv_zapsock

but that's probably what the compiler will rewrite the logic into.

> Index: nfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_syscalls.c,v
> diff -u -p -r1.119 nfs_syscalls.c
> --- nfs_syscalls.c    3 Aug 2023 09:49:09 -0000       1.119
> +++ nfs_syscalls.c    11 Jan 2024 15:15:12 -0000
> @@ -338,6 +338,15 @@ loop:
>                               nfs_sndlock(&slp->ns_solock, NULL);
>                               nfsrv_rcv(slp->ns_so, (caddr_t)slp, M_WAIT);
>                               nfs_sndunlock(&slp->ns_solock);
> +
> +                             /*
> +                              * The client may have closed the connection.
> +                              * If so, zap the socket before sleeping,
> +                              * allowing the client to reconnect with the
> +                              * same source port.
> +                              */
> +                             if (ISSET(slp->ns_flag, SLP_DISCONN))
> +                                     nfsrv_zapsock(slp);
>                       }
>  
>                       error = nfsrv_dorec(slp, nfsd, &nd);
> 

Reply via email to