Re: [PATCH] rpc: xs_bind - do not bind when requesting a random ephemeral port

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sounds reasonable to me.

On Mon, Sep 8, 2014 at 8:08 PM, Trond Myklebust
<trond.myklebust@xxxxxxxxxxxxxxx> wrote:
> On Fri, Sep 5, 2014 at 12:40 PM, Chris Perl <chris.perl@xxxxxxxxx> wrote:
>> When attempting to establish a local ephemeral endpoint for a TCP or UDP
>> socket, do not explicitly call bind, instead let it happen implicilty when the
>> socket is first used.
>>
>> The main motivating factor for this change is when TCP runs out of unique
>> ephemeral ports (i.e.  cannot find any ephemeral ports which are not a part of
>> *any* TCP connection).  In this situation if you explicitly call bind, then the
>> call will fail with EADDRINUSE.  However, if you allow the allocation of an
>> ephemeral port to happen implicitly as part of connect (or other functions),
>> then ephemeral ports can be reused, so long as the combination of (local_ip,
>> local_port, remote_ip, remote_port) is unique for TCP sockets on the system.
>>
>> This doesn't matter for UDP sockets, but it seemed easiest to treat TCP and UDP
>> sockets the same.
>>
>> This can allow mount.nfs(8) to continue to function successfully, even in the
>> face of misbehaving applications which are creating a large number of TCP
>> connections.
>>
>> Signed-off-by: Chris Perl <chris.perl@xxxxxxxxx>
>> ---
>>  net/sunrpc/xprtsock.c | 20 ++++++++++++++++++--
>>  1 file changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
>> index 43cd89e..7ed47b4 100644
>> --- a/net/sunrpc/xprtsock.c
>> +++ b/net/sunrpc/xprtsock.c
>> @@ -1746,13 +1746,29 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock)
>>         unsigned short port = xs_get_srcport(transport);
>>         unsigned short last;
>>
>> +       /*
>> +        * If we are asking for any ephemeral port (i.e. port == 0 &&
>> +        * transport->xprt.resvport == 0), don't bind.  Let the local
>> +        * port selection happen implicitly when the socket is used
>> +        * (for example at connect time).
>> +        *
>> +        * This ensures that we can continue to establish TCP
>> +        * connections even when all local ephemeral ports are already
>> +        * a part of some TCP connection.  This makes no difference
>> +        * for UDP sockets, but also doens't harm them.
>> +        *
>> +        * If we're asking for any reserved port (i.e. port == 0 &&
>> +        * transport->xprt.resvport == 1) xs_get_srcport above will
>> +        * ensure that port is non-zero and we will bind as needed.
>> +        */
>> +       if (port == 0)
>> +               return 0;
>> +
>>         memcpy(&myaddr, &transport->srcaddr, transport->xprt.addrlen);
>>         do {
>>                 rpc_set_port((struct sockaddr *)&myaddr, port);
>>                 err = kernel_bind(sock, (struct sockaddr *)&myaddr,
>>                                 transport->xprt.addrlen);
>> -               if (port == 0)
>> -                       break;
>>                 if (err == 0) {
>>                         transport->srcport = port;
>>                         break;
>> --
>> 1.8.3.1
>>
>
> This change looks harmless to me, but since we've lived with the
> current situation for several years, I'm not prepared to consider it a
> must-fix for 3.17 quite yet. If it's OK with you, I'll therefore queue
> it for 3.18.
>
> --
> Trond Myklebust
>
> Linux NFS client maintainer, PrimaryData
>
> trond.myklebust@xxxxxxxxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux