* End-To-End Arguments in System Design * Authors: J.H. Saltzer, D.P. Reed, and D.D. Clark * Field: OS/Structure Functionality is provided by applications at endpoints, and only with the help and knowledge of the endpoints can the functionality be implemented "completely and correctly." Therefore it is futile to attempt to provide the complete functionality at lower levels (e.g. part of the communication system); providing functionality at these levels can at best improve performance. Example: file transfer. At a high level five steps must be performed: 1) read data from disk 2) package data for the network 3) transfer across the network 4) unpackage received data 5) write to disk Lots of things might go wrong: 1) errors in data read from the disk 2) software error when performing buffering/copying at either host 3) processor or memory hardware error while buffering/copying 4) communication system might change bits, change order of packets, lose packets, or deliver a packet more than once. 5) hosts may crash at any point before, during, or after the transfer End-to-end solution: Keep a CRC with each file. After receiving host finishes writing the data to disk, read it back and perform a CRC to ensure that it is the same. Making the communication system more reliable only helps #4, but the application will need to do the end-to-end check in any case because of the other potential issues. Performance: time for successful copy grows exponentially with the size of the file, so the error rates for each step should be low for good performance. Recently it seems that use of TCP has been declining in favor of UDP. What applications are behind this shift? Is the end-to-end argument applicable? Another thing that might go wrong in the file transfer is that someone else intercepts the packets and replaces them with something else. They can manipulate the CRC packet(s) or just ensure that the data comes out with the same CRC. End-to-end solution: encryption? Lesson: the application of end-to-end depends on how you define the functionality. Is the end-to-end argument ever really applied in its purest form? For example do file transfer applications really read back the data from disk and do a CRC? Perhaps the right answer is: the more you care about the correctness and completeness of the functionality, the more the end-to-end argument applies.