RFC 2054
WebNFS Client Specification
RFC 2054: WebNFS Client Specification π
Okay bestie, this is RFC 2054, the WebNFS Client Specification, and it's giving lightweight, no-nonsense, straight-to-the-point networking energy π β¨
- Number: RFC 2054
- Title: WebNFS Client Specification
- Author: B. Callaghan, Sun Microsystems, Inc.
- Network Working Group: the group that published it πΈ
- Category: Informational
- Date: October 1996
- Obsoletes / Updates: the title block doesn't list anything it obsoletes or updates π¦
Status of This Memo π
So, the vibe check: this memo is here to provide information for the Internet community π It does not specify an Internet standard of any kind, so it's not a standard, not even a little bit π Distribution of this memo is unlimited, so share the love π«Ά
Abstract π
This doc describes a lightweight binding mechanism that lets NFS clients get service from WebNFS-enabled servers with a minimum of protocol overhead π§ Removing that overhead gives WebNFS clients faster responses to requests, easy transit through packet filter firewalls and TCP-based proxies, and better server scalability. Iconic, honestly π
Table of Contents ποΈ
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2
2. TCP vs UDP . . . . . . . . . . . . . . . . . . . . . . . . 2
3. Well-known Port . . . . . . . . . . . . . . . . . . . . . 2
4. NFS Version 3 . . . . . . . . . . . . . . . . . . . . . . 3
4.1 Transfer Size . . . . . . . . . . . . . . . . . . . . . 3
4.2 Fast Writes . . . . . . . . . . . . . . . . . . . . . . 4
4.3 READDIRPLUS . . . . . . . . . . . . . . . . . . . . . . 4
5. Public Filehandle . . . . . . . . . . . . . . . . . . . . 5
5.1 NFS Version 2 Public Filehandle . . . . . . . . . . . . 5
5.2 NFS Version 3 Public Filehandle . . . . . . . . . . . . 5
6. Multi-component Lookup . . . . . . . . . . . . . . . . . . 6
6.1 Canonical Path vs. Native Path . . . . . . . . . . . . . 6
6.2 Symbolic Links . . . . . . . . . . . . . . . . . . . . . 7
6.2.1 Absolute Link . . . . . . . . . . . . . . . . . . . . 8
6.2.2 Relative Link . . . . . . . . . . . . . . . . . . . . 8
6.3 Filesystem Spanning Pathnames . . . . . . . . . . . . . 9
7. Contacting the Server . . . . . . . . . . . . . . . . . . 9
8. Mount Protocol . . . . . . . . . . . . . . . . . . . . . . 11
9. Exploiting Concurrency . . . . . . . . . . . . . . . . . . 12
9.1 Read-ahead . . . . . . . . . . . . . . . . . . . . . . . 12
9.2 Concurrent File Download . . . . . . . . . . . . . . . . 13
10. Timeout and Retransmission . . . . . . . . . . . . . . . . 13
11. Bibliography . . . . . . . . . . . . . . . . . . . . . . . 15
12. Security Considerations . . . . . . . . . . . . . . . . . 16
13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . 16
14. Author's Address . . . . . . . . . . . . . . . . . . . . . 16
1. Introduction π
Okay so NFS is the protocol that gives you access to shared filesystems across networks π It's designed to be machine, operating system, network architecture, and transport protocol independent, which is seriously main character energy. Right now it comes in two versions: version 2 [RFC1094] and version 3 [RFC1813]. Both are built on Sun RPC [RFC1831], along with its associated eXternal Data Representation (XDR) [RFC1832] and Binding Protocol [RFC1833].
WebNFS adds extra semantics that can be applied to NFS version 2 and 3. It gets rid of the overhead of the PORTMAP and MOUNT protocols, makes the protocol easier to use where firewall transit is required, and cuts down on the number of LOOKUP requests you need to find a particular file on the server β¨ WebNFS server requirements are described in RFC 2055, so go check that one too π§
2. TCP vs UDP π¦
NFS is most well known for using UDP, and honestly that's fine on local area networks π But on wide area networks with error-prone, high-latency connections and bandwidth contention, TCP is well respected for its congestion control and superior error handling π₯ A growing number of NFS implementations now support NFS over TCP connections, so the trend is literally on our side.
Using NFS version 3 is especially well matched to TCP as a transport protocol π Version 3 gets rid of the arbitrary 8k transfer size limit from version 2, so you can READ or WRITE very large streams of data over a TCP connection. Note that NFS version 2 also works on TCP connections, but the benefits of TCP data streaming won't be as great π
A WebNFS client must first attempt to connect to its server with a TCP connection. If the server refuses the connection, the client should attempt to use UDP πΈ
3. Well-known Port π§
Internet protocols are usually identified by registered port number assignments. RPC based protocols are different, though π They register a 32 bit program number and a dynamically assigned port with the portmap service, and the portmap service sits on the well-known port 111. Since NFS is RPC-based, NFS servers register their port assignment with the portmap service.
NFS servers have to re-register at the same port after a server crash and recovery. That way clients can recover simply by retransmitting an RPC request until they get a response, which is way simpler than having the client keep checking with the portmap service for a new port assignment π«Ά NFS servers typically pull this off with a constant port assignment, 2049, for both UDP and TCP.
To skip the overhead of contacting the server's portmap service, and to make it easier to get through packet filtering firewalls, WebNFS clients optimistically assume that WebNFS servers register on port 2049 π Most NFS servers already use this port assignment, so this client optimism is totally justified π Refer to section 8 for further details on port binding.
6. Multi-component Lookup β¨
Okay bestie, so normally a NFS LOOKUP (v2 or v3) is one-name-at-a-time energy π You hand it a directory filehandle plus the name of something inside that directory, and it gives you back that thing's filehandle. If a client needs to walk a whole pathname with lots of pieces, it has to start at the first component's directory filehandle and do a LOOKUP for each piece, one by one. Like, evaluating the Unix path "a/b/c" means separate LOOKUPs for "a", then "b", then "c" π¦
Here's where it gets iconic: a LOOKUP that uses the public filehandle can take a pathname with multiple components in one go π₯ The server is expected to evaluate the whole path and hand back the filehandle for the final component. Both canonical (slash-separated) and server native pathnames work here π
Instead of doing the three-step thing like this:
LOOKUP FH=0x0 "a" --->
<--- FH=0x1
LOOKUP FH=0x1 "b" --->
<--- FH=0x2
LOOKUP FH=0x2 "c" --->
<--- FH=0x3
relative to the public filehandle, those three LOOKUPs can be squished into one multi-component lookup:
LOOKUP FH=0x0 "a/b/c" --->
<--- FH=0x3
Lowkey the cleanest glow-up β¨ Just remember that multi-component lookup is only supported for LOOKUP requests relative to the public filehandle. No cap, that's the rule π
6.1. Canonical Path vs. Native Path
So if the pathname in a multi-component LOOKUP starts with an ASCII character, it must be a canonical path π A canonical path is a hierarchy written with slashes, looking like <directory>/<directory>/.../<name>. If a "/" shows up inside a component, it has to be escaped as %2f. Non-ASCII characters inside components also need escaping with "%" followed by a two digit hexadecimal code. And any "%" that isn't introducing an encoded character has to be encoded as %25 itself. Very particular, very important π
Now, if the first character of the path is a slash, the canonical path gets evaluated relative to the server's root directory πΈ If the first character isn't a slash, it gets evaluated relative to whatever directory the public filehandle is associated with π§
Not every WebNFS server can handle arbitrary absolute paths, ngl π Obviously the server can't return a filehandle if the path points at something that isn't exported by the server. Also, some servers won't return a filehandle if the path names a file or directory in an exported filesystem that's different from the one tied to the public filehandle. Not everyone gets the main character treatment π
If the first character of the path is 0x80 (non-ASCII), then the character right after it is the first one in a native path. A native path follows the server's normal pathname syntax. Like:
Lookup for Canonical Path:
LOOKUP FH=0x0 "/a/b/c"
Lookup for Native Path:
LOOKUP FH=0x0 0x80 "a:b:c"
6.2. Symbolic Links
On Unix servers, components inside a pathname can be symbolic links π¦ The server evaluates these as part of its normal pathname evaluation. If the final component is a symbolic link, though, the server just returns its filehandle instead of following it π
If the attributes returned with a filehandle say it refers to a symbolic link, then it's the client's job to deal with the link by fetching its contents using the READLINK procedure. Whatever happens next depends on what the link says β¨
Evaluating symbolic links on the client side is only defined if the symbolic link was retrieved through a multi-component lookup of a canonical path. Be a little picky about it, periodt π«Ά
6.2.1. Absolute Link
If the first character of the link text is a slash "/", the following path can be assumed to be absolute π The server must evaluate the entire path relative to the public filehandle:
LOOKUP FH=0x0 "a/b" --->
<--- FH=0x1 (symbolic link)
READLINK FH=0x1 --->
<--- "/x/y"
LOOKUP FH=0x0 "/x/y"
<--- FH=0x2
So in this case, the client just passes the link text back to the server for evaluation. Easy peasy π
6.2.2. Relative Link
If the first character of the link text is not a slash, the following path can be assumed to be relative to where the symbolic link lives π To evaluate it correctly, the client has to substitute the link text in place of the final pathname component that named the link, and then issue a another LOOKUP relative to the public filehandle.
LOOKUP FH=0x0 "a/b" --->
<--- FH=0x1 (symbolic link)
READLINK FH=0x1 --->
<--- "x/y"
LOOKUP FH=0x0 "a/x/y"
<--- FH=0x2
By swapping the link text into the link path and letting the server evaluate that new path, the server effectively gets to evaluate the link relative to the link's own location. Clever, right? π§ β¨
The client may also "clean up" the resulting pathname by removing redundant components, as described in Section 4. of RFC 1808.
6.3. Filesystem Spanning Pathnames
Normally, NFS LOOKUP requests do not cross from one filesystem to another on the server π§ For example, say the server has these exports and mounts:
/export (exported)
/export/bigdata (mountpoint)
Then an NFS LOOKUP for "bigdata" using the filehandle for "/export" returns a "no file" error, because the LOOKUP didn't cross the mountpoint on the server π There's a practical reason for this. If the server let the mountpoint crossing happen, a Unix client could get ambiguous fileid information that doesn't match its view of one single remote mount for "/export". It's expected that the client handles this by mirroring the extra server mount, like so:
Client Server
/mnt <--- mounted on --- /export
/mnt/bigdata <--- mounted on --- /export/bigdata
BUT, this changes if the client issues the filesystem spanning LOOKUP relative to the public filehandle π Say these filesystems are exported:
/export (exported public)
/export/bigdata (exported mountpoint)
Then an NFS LOOKUP for "bigdata" relative to the public filehandle will cross the mountpoint, just as if the client had sent a MOUNT request π But only if the new filesystem is exported, and only if the server supports Export Spanning Pathnames as described in Section 6.3 of RFC 2055 [RFC2055]. Both conditions, no exceptions, bestie π
β οΈ Quick reminder: crossing into a second export only happens through the public filehandle path. Regular LOOKUPs don't do it, even when the mount is right there. Don't get caught out!
7. Contacting the Server π
WebNFS clients should be optimistic and assume the server supports WebNFS π But they should also be ready to fall back to conventional methods for accessing the server if it doesn't. Main character confidence with a backup plan π
The client should start by assuming the server supports:
- NFS version 3.
- NFS TCP connections.
- Public Filehandles.
If those assumptions don't hold, the client should fall back gracefully, using as few messages as possible π«Ά The following steps are recommended:
- Try to create a TCP connection to the server's port 2049.
If that connection fails, then assume that a request sent over UDP will work, and use UDP port 2049.
Don't use the PORTMAP protocol to find the server's port unless the server doesn't respond on port 2049 for both TCP and UDP. Portmap is a last resort, not a first move π
- Assume WebNFS and V3 are supported, and send an NFS version 3 LOOKUP with the public filehandle for the requested pathname π¦
If the server returns an RPC PROG_MISMATCH error, then assume NFS version 3 isn't supported, and retry the LOOKUP with an NFS version 2 public filehandle π
Note: the first call doesn't necessarily have to be a LOOKUP. If the operation is aimed at the public filehandle itself, like a READDIR or READDIRPLUS of the directory associated with the public filehandle, that's totally fine π
If the server returns an NFS3ERR_STALE, NFS3ERR_INVAL, or NFS3ERR_BADHANDLE error, then assume the server doesn't support WebNFS, since it doesn't recognize the public filehandle π In that case the client MUST use the server's portmap service to locate and use the MOUNT protocol to get an initial filehandle for the requested path.
Okay, and here's the little glow-up tip the original gives: WebNFS clients can benefit by caching info about the server π§ That includes whether the server supports TCP connections (and if it does, the client should cache the TCP connection too), which protocol the server supports, and whether it supports public filehandles. If the server doesn't support public filehandles, the client may choose to cache the port assignment of the MOUNT service, plus previously used pathnames and their filehandles π
8. Mount Protocol β¨
okay so if the server replies with an error saying it doesn't do public filehandles, the client MUST use the MOUNT protocol to turn the pathname into a filehandle πΊοΈ Version 1 is in Appendix A of RFC 1094 and version 3 is in Appendix I of RFC 1813. Version 2 is basically version 1 with one extra procedure, MOUNTPROC_PATHCONF, which gets POSIX pathconf info from the server π§
by this point the client MUST already have some idea which NFS version the server supports π filehandles look different in NFS version 2 and version 3, so the client MUST pick the matching MOUNT version. MOUNT versions 1 and 2 only hand back NFS version 2 filehandles, while MOUNT version 3 hands back NFS version 3 filehandles. no mix-ups allowed π
here's the thing that's kind of iconic and kind of annoying: the MOUNT service isn't on a well-known port like NFS is. the client MUST use the PORTMAP service to find the server's MOUNT port before it can send a MOUNTPROC_MNT request for the filehandle of the path it wants π¦
Client Server
------ ------
-------------- MOUNT port ? --------------> Portmapper
<-------------- Port=984 ------------------
------- Filehandle for /export/foo ? ----> Mountd @ port 984
<--------- Filehandle=0xf82455ce0.. ------
servers often treat a successful MOUNTPROC_MNT request as "this client has mounted the filesystem" π they MAY keep that in a file listing which filesystems clients currently have mounted. that record gets removed when the client sends a MOUNTPROC_UMNT request. so after a successful MOUNTPROC_MNT reply, a WebNFS client SHOULD send a MOUNTPROC_UMNT request, so the server doesn't pile up "mounted" records forever π§Ή
also, heads up bestie: all that PORTMAP and MOUNT overhead is going to affect how long it takes the client to bind to the server, and MOUNT's dynamically assigned port might make it harder to get through firewalls or proxy servers π
the client MAY get some performance back by using a pathname prefix cache π for example, if the client already has a filehandle for "a/b", there's a really good chance it can get the filehandle for "a/b/c" just by doing a LOOKUP of "c" relative to the "a/b" filehandle. that skips the MOUNT translation entirely β¨ but there are risks, sis. a LOOKUP response doesn't tell you whether it crossed a filesystem mountpoint on the server, and NFS requests don't normally cross mountpoints on the server, so that relative LOOKUP MAY fail π the MOUNT service is the one you can trust to evaluate the pathname correctly, including crossing mountpoints when it needs to π
9. Exploiting Concurrency π₯
NFS servers are famous for being high capacity and for handling clients who send a bunch of concurrent requests at once πͺ so for the best performance, a WebNFS client SHOULD take advantage of that server concurrency. the RPC protocol NFS is built on gives you transport-independent concurrency through a unique transaction ID (XID) in every NFS request, which is so clean π«Ά
no need to open a pile of TCP connections to send requests at the same time π ββοΈ the RPC record marking protocol lets the client send and receive a whole stream of NFS requests and replies over one connection.
9.1 Read-ahead
to keep the number of READ requests low, a WebNFS client SHOULD use the biggest transfer size that both it and the server can handle π¦ the client can often squeeze more out of its link bandwidth by sending concurrent READ requests π the ideal number of READ requests has to be worked out on the fly, based on available bandwidth, link latency, and the I/O bandwidth of both the client and the server. for example, here's a client using one read-ahead to grab a 128k file from the server with 32k READ requests:
READ XID=77 offset=0 for 32k -->
READ XID=78 offset=32k for 32k -->
<-- Data for XID 77
READ XID=79 offset=64k for 32k -->
<-- Data for XID 78
READ XID=80 offset=96k for 32k -->
<-- Data for XID 79
<-- Data for XID 80
the client MUST be able to handle data coming back out of order π in that example, the data for XID 78 might show up before the data for XID 77, and that's totally fine.
the client SHOULD be careful not to read ahead more than the server, the network, or the client can handle π«§ one way to tell is a heuristic that measures throughput while the download is happening.
9.2 Concurrent File Download
a client MAY mix read-ahead with downloading several files at once π§ a super real example is a web page with a bunch of images, or a Java Applet pulling in multiple class files from the server.
leaving out read-ahead for clarity, downloading "file1", "file2", and "file3" might go something like this:
LOOKUP XID=77 0x0 "file1" -->
LOOKUP XID=78 0x0 "file2" -->
LOOKUP XID=79 0x0 "file3" -->
<-- FH=0x01 for XID 77
READ XID=80 0x01 offset=0 for 32k -->
<-- FH=0x02 for XID 78
READ XID=81 0x02 offset=0 for 32k -->
<-- FH=0x03 for XID 79
READ XID=82 0x03 offset=0 for 32k -->
<-- Data for XID 80
<-- Data for XID 81
<-- Data for XID 82
the replies MAY come back in a different order than the requests went out π that's not a problem at all, because RPC uses the XID to match each request to its reply. the best part is that a big file needing tons of READ requests won't hold up the concurrent download of smaller files, which is such a main character move π
but again, the client MUST be careful not to drown the server in download requests π
10.0 Timeout and Retransmission π
a WebNFS client SHOULD copy what regular NFS clients do and handle server or network outages gracefully π«Ά if a reply doesn't show up within a given timeout, the client SHOULD retransmit the request with its original XID (described in Section 8 of RFC 1831).
the server can use the XID to spot duplicate requests and skip doing the same work twice β¨
now, you'd think retransmitting over TCP is pointless, since TCP already detects and retransmits lost data π but at the RPC layer, retransmission is still needed to recover from a lost TCP connection, maybe because the server crashed or because the server closed the connection due to resource limits π when the TCP connection drops, the client MUST re-establish it and retransmit the pending requests.
the client SHOULD set the request timeout using these guidelines π
- A timeout that is too small may result in the wasteful transmission of duplicate requests. The server may be just slow to respond, either because it is heavily loaded, or because the link latency is high.
- A timeout that is too large may harm throughput if the request is lost and the connection is idle waiting for the retransmission to occur.
- The optimum timeout may vary with the server's responsiveness over time, and with the congestion and latency of the network.
- The optimum timeout will vary with the type of NFS request. For instance, the response to a LOOKUP request will be received more quickly than the response to a READ request.
- The timeout should be increased according to an exponential backoff until a limit is reached. For instance, if the timeout is 1 second, the first retransmitted request should have a timeout of two seconds, the second retransmission 4 seconds, and so on until the timeout reaches a limit, say 30 seconds. This avoids flooding the network with retransmission requests when the server is down, or overloaded.
and the rule of thumb π§ the client SHOULD start with a long timeout until it figures out how responsive the server is. after that, the timeout can be set to something that reflects how the server has responded to earlier requests π¦
11.0 Bibliography π
okay bestie, these are the receipts π§Ύ every source the spec leans on, with all the details so you can go find them yourself:
- [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC 1808, June 1995.
http://www.internic.net/rfc/rfc1808.txt - [RFC1831] Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification Version 2", RFC 1831, August 1995.
http://www.internic.net/rfc/rfc1831.txt - [RFC1832] Srinivasan, R, "XDR: External Data Representation Standard", RFC 1832, August 1995.
http://www.internic.net/rfc/rfc1832.txt - [RFC1833] Srinivasan, R., "Binding Protocols for ONC RPC Version 2", RFC 1833, August 1995.
http://www.internic.net/rfc/rfc1833.txt - [RFC1094] Sun Microsystems, Inc., "Network Filesystem Specification", RFC 1094, March 1989. NFS version 2 protocol specification.
http://www.internic.net/rfc/rfc1094.txt - [RFC1813] Sun Microsystems, Inc., "NFS Version 3 Protocol Specification," RFC 1813, June 1995. NFS version 3 protocol specification.
http://www.internic.net/rfc/rfc1813.txt - [RFC2055] Callaghan, B., "WebNFS Server Specification", RFC 2055, October 1996.
http://www.internic.net/rfc/rfc2055.txt - [Sandberg] Sandberg, R., D. Goldberg, S. Kleiman, D. Walsh, B. Lyon, "Design and Implementation of the Sun Network Filesystem," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Summer 1985. The basic paper describing the SunOS implementation of the NFS version 2 protocol, and discusses the goals, protocol specification and trade-offs. π
- [X/OpenNFS] X/Open Company, Ltd., X/Open CAE Specification: Protocols for X/Open Internetworking: XNFS, X/Open Company, Ltd., Apex Plaza, Forbury Road, Reading Berkshire, RG1 1AX, United Kingdom, 1991. This is an indispensable reference for NFS version 2 protocol and accompanying protocols, including the Lock Manager and the Portmapper. π
- [X/OpenPCNFS] X/Open Company, Ltd., X/Open CAE Specification: Protocols for X/Open Internetworking: (PC)NFS, Developer's Specification, X/Open Company, Ltd., Apex Plaza, Forbury Road, Reading Berkshire, RG1 1AX, United Kingdom, 1991. This is an indispensable reference for NFS version 2 protocol and accompanying protocols, including the Lock Manager and the Portmapper. π
12. Security Considerations π
bestie, this part is serious and I'm not going to be casual about it π Since the WebNFS server features are based on NFS protocol versions 2 and 3, the RPC based security considerations described in RFC 1094, RFC 1831, and RFC 1832 apply here also. So if you're reading this, those three documents are part of your security homework, no skipping π ββοΈ
Clients and servers may separately negotiate secure connection schemes for authentication, data integrity, and privacy. β¨
13. Acknowledgements π«Ά
This specification was extensively reviewed by the NFS group at SunSoft and brainstormed by Michael Eisler. Honestly the glow-up credit goes to them π
14. Author's Address π
Address comments related to this document to: nfs@eng.sun.com
Brent Callaghan
Sun Microsystems, Inc.
2550 Garcia Avenue
Mailstop Mpk17-201
Mountain View, CA 94043-1100
Phone: 1-415-786-5067
Fax: 1-415-786-5896
EMail: brent.callaghan@eng.sun.com
That's the whole spec, bestie π¦π you made it through all four parts!!
π¦ where this page comes from
- ietf: rfc2054 1996-10
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms