>> It's less unsafe than SO_REUSEADDR, however it completely ignores
>> TIME_WAIT,  which has two purposes (according to W.R. Stevens):
>>
>> - If the client performs the active close, it allows the socket to
>> remember to resend the final ACK in response to the server's FIN.
>> Otherwise the client would respond with a RST.
>>
>> - It ensures that no re-incarnations of the same four-tuple
>> occur within 2
>> * MSL, ensuring that no packets that were lost on the network from the
>> first incarnation get used as part of the new incarnation.
>>
>> Avoiding TIME_WAIT altogether keeps TCP from doing a proper
>> full-duplex
>> close and also allows old packets to screw up TCP state.
>
> right, there are cases where proper connection close processing is
> required.  and you don't need to worry much about duplicate request
> caching for the services we're talking about here, so it's probably not
> as critical for rpcproxyd.
>
>> Which timeout is 5 minutes? (sparing me the trouble of finding it
> myself).
>
> the RPC client side idle timeout is 5 minutes in the reference
> implementation (Solaris).

Hmm. Okay. Without looking at the code, I'm going to assume that this is
handled in the core rpc code, and not in the per-transport bits.

If this is indeed the case, then the client will close the connection to
the proxy after five minutes, which in turns kicks off a timer in the
proxy to close the unused transport after 30 seconds.

Though I better dig deeper before I claim this is the case ;)

>> I figured 30 for caching un-used tcp connections sounded like a good
>> number as it means that if TIME_WAIT period is 2 minutes,
>> that the most
>> TIME_WAIT connections that you can have to a given remote
>> service at any time is 4.
>>
>> A bit more thought could be had for timeouts (wishlist):
>> - TCP connect()s aren't timedout. (uses EINPROGRESS, but will wait
>> indefinitely, which I think is bounded by the kernel anyway).
>
> there is a SYN retry limit controllable via sysctl for all sockets on
> the system.  by default the active end tries sending SYN 6 times with
> exponential backoff.  eventually the connection attempt will time out if
> the remote peer doesn't respond with SYN,ACK after the last SYN is sent.
> i think it's on the order of a couple of minutes.

Great. This is probably a ENETUNREACH error.

>
>> - UDP retransmission occurs in the proxy itself, which is currently
>> hardcoded to retry 5 times, once every two seconds.  I can
>> trivially set it up so that it gets the actual timeout values from the
>
>> client though and use those parameters.
>
> that should probably have exponential backoff, but it probably isn't
> critical.
>

Yup.  10 seconds of retries probably isn't big enough.  Will add the
needed logic when I get the chance.

>> > you will also need a unique connection for each
>> program/version number
>> > combination to a given server; ie you can't share a single
>> socket among
>> > different program/version numbers (even though some
>> implementations try
>> > to do this, it is a bad practice, in my opinion).
>> >
>>
>> So, I know I discussed this with you last week, however I was
>> under the
>> impression that that was needed for the case where you
>> support re-binding
>> of the transport.  I'm not up to speed of who are the users of such a
>> thing (I'm assuming NFSv4).
>
> if you expect to cache these associations for a long time, you will need
> to rebind every so often in case the server decides to move the service
> to another port.  with UDP, anyway.
>
> you also can't assume that all the services you need to talk to
> (PORTMAP, NFS, MOUNTD, etc) will live on the same port.  for a truly
> general implementation you will need to use a separate connection for
> each service.

rpcproxyd will make as many outbound connections as needed.  They are
indexed by:

(
  addrlen == conn->addrlen
  && !memcmp(addr, conn->addr, addrlen)
  && domain == conn->domain  /* eg: AF_INET */
  && type   == conn->type    /* eg: SOCK_STREAM */
)

There is no re-using a connection based on prog && vers.

As such, if the service moves a port, it will be the client's
responsibility to either a) pass in the updated addr in a call the
clntproxy_create or b) pass in addr with addr->sin_port == 0 so the
portmapper is consulted again.

I don't think any of the existing rpc classes support transparent
rebinding of service address.

>
> but you said "assuming NFSv4," so maybe none of this matters.  i would
> hope that a connection cache would be good for any application using
> RPC.

Well, I'm thinking that with NFSv4 you may want to rebind the underlying
socket instead of creating a new socket with it comes time to migrate.

>
>> > to support IPv6 you will need support for rpcbind versions
>> 3 and 4; but
>> > that may be an issue outside of rpcproxyd.
>> >
>>
>> Okay.  I'm not so familiar with RPCB, but it is just a PMAP
>> on steroids, right?
>
> the later versions of the rpcbind protocol support additional operations
> that allow IPv6-style information to be returned.  version 2 does not
> support IPv6, as far as i know, but i'm no expert.
>

Great.

This brings up the question though: does current util-linux even support
IPv6?  It (the one on my debian box) has explicit calls to pmap_getport,
which appears to be IPv4 only.

Thanks,

Mike Waychison

_______________________________________________
autofs mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/autofs

Reply via email to