File: rfc1179ref.htm

package info (click to toggle)
lprng 3.8.10-1.2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 13,076 kB
  • ctags: 4,348
  • sloc: ansic: 35,394; sh: 10,756; perl: 2,210; makefile: 1,046
file content (373 lines) | stat: -rw-r--r-- 16,544 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta name="generator" content="HTML Tidy, see www.w3.org">
    <title>RFC 1179 - Line Printer Daemon Protocol</title>
    <meta name="GENERATOR" content=
    "Modular DocBook HTML Stylesheet Version 1.71 ">
    <link rel="HOME" title=" LPRng-HOWTO" href="index.htm">
    <link rel="PREVIOUS" title="\LPRng accounting.pl Utility" href=
    "x9588.htm">
    <link rel="NEXT" title="Protocol Requests and Replies " href=
    "remotesupport.htm">
  </head>

  <body class="CHAPTER" bgcolor="#FFFFFF" text="#000000" link=
  "#0000FF" vlink="#840084" alink="#0000FF">
    <div class="NAVHEADER">
      <table summary="Header navigation table" width="100%" border=
      "0" cellpadding="0" cellspacing="0">
        <tr>
          <th colspan="3" align="center">LPRng-HOWTO: 1 Apr 2002
          (For LPRng-3.8.10)</th>
        </tr>

        <tr>
          <td width="10%" align="left" valign="bottom"><a href=
          "x9588.htm" accesskey="P">Prev</a></td>

          <td width="80%" align="center" valign="bottom">
          </td>

          <td width="10%" align="right" valign="bottom"><a href=
          "remotesupport.htm" accesskey="N">Next</a></td>
        </tr>
      </table>
      <hr align="LEFT" width="100%">
    </div>

    <div class="CHAPTER">
      <h1><a name="RFC1179REF">Chapter 19. RFC 1179 - Line Printer
      Daemon Protocol</a></h1>

      <div class="TOC">
        <dl>
          <dt><b>Table of Contents</b></dt>

          <dt>19.1. <a href="rfc1179ref.htm#LPDPORT">Ports and
          Connections</a></dt>

          <dt>19.2. <a href="remotesupport.htm">Protocol Requests
          and Replies</a></dt>

          <dt>19.3. <a href="jobtransfer.htm">Job Transfer</a></dt>

          <dt>19.4. <a href="x9971.htm">Data File Transfer</a></dt>

          <dt>19.5. <a href="x10007.htm">Control File
          Contents</a></dt>

          <dt>19.6. <a href="x10210.htm"><b class=
          "APPLICATION">lpq</b> Requests</a></dt>

          <dt>19.7. <a href="x10233.htm"><b class=
          "APPLICATION">lprm</b> Requests</a></dt>

          <dt>19.8. <a href="lpcreread.htm">LPC Requests</a></dt>

          <dt>19.9. <a href="sendblockformat.htm">Block Job
          Transfer</a></dt>

          <dt>19.10. <a href="x10436.htm">Authenticated
          Transfer</a></dt>
        </dl>
      </div>

      <p>RFC1179 can be obtained from the <b class=
      "APPLICATION">LPRng</b> distribution, in the
      LPRng_DOC/rfc1179 directory, or from one of many sites which
      mirror the RFCs.</p>

      <p>This RFC is an <i class="EMPHASIS">informational</i> RFC,
      which means that the information in it is meant as a guide to
      users, and not as a fixed standard. In addition, the RFC
      tried to document the behavior of the BSD <b class=
      "APPLICATION">lpd</b> print server, and left out many details
      dealing with error recover, error messages, extensions to the
      protocol, etc.</p>

      <p>In this section, I will try to explain what RFC1179
      specifies as a protocol, and many of the problems encountered
      in trying to use it.</p>

      <div class="SECT1">
        <h1 class="SECT1"><a name="LPDPORT">19.1. Ports and
        Connections</a></h1>

        <p>Options used:</p>

        <ul>
          <li>
            <p><tt class="LITERAL">lpd_port=</tt><i class=
            "EMPHASIS">Port for <b class="APPLICATION">lpd</b> to
            accept connection</i></p>
          </li>

          <li>
            <p><tt class="LITERAL">originate_port=</tt><i class=
            "EMPHASIS">Ports to originate connections on</i></p>
          </li>

          <li>
            <p><tt class="LITERAL">reuse_addr</tt> FLAG <i class=
            "EMPHASIS">Set SO_REUSEADDR flag on connection</i></p>
          </li>

          <li>
            <p><tt class="LITERAL">retry_econnrefused</tt> FLAG <i
            class="EMPHASIS">Retry on connect ECONNREFUSED
            error</i></p>
          </li>

          <li>
            <p><tt class="LITERAL">retry_nolink</tt> FLAG <i class=
            "EMPHASIS">Retry on device open or connection
            ffailure</i></p>
          </li>

          <li>
            <p><tt class="LITERAL">socket_linger=</tt><i class=
            "EMPHASIS">socket linger timeout</i></p>
          </li>
        </ul>
        <br>
        <br>

        <p>RFC1179 requires that the <b class="APPLICATION">lpd</b>
        server listen for TCP/IP connections on port 515. This port
        is registered with the Internet Naming Authority, and the
        <tt class="FILENAME">/etc/services</tt> file or TCP/IP
        services database usually has an entry:</p>

        <div class="INFORMALEXAMPLE">
          <a name="AEN9672"></a>
<pre class="SCREEN">
    printer     515/tcp     spooler     # line printer spooler
</pre>
        </div>
        <br>
        <br>

        <p>RFC1179 explicitly states that all connections to port
        515 must originate from ports 721-731. The reason for this
        restriction is due to the UNIX concept of <i class=
        "EMPHASIS">reserved</i> and <i class=
        "EMPHASIS">privileged</i> ports. By convention, ports in
        the range 1-1023 can only <i class="EMPHASIS">bound</i> by
        processes whose Effective User ID (EUID) is 0 (root). This,
        ordinary users could not originate a connection from the
        reserved or privileged port range.</p>

        <p>In a UNIX environment, this means that the user programs
        <b class="APPLICATION">lpr</b>, <b class=
        "APPLICATION">lpq</b>, <b class="APPLICATION">lprm</b>, and
        <b class="APPLICATION">lpc</b> would have to be SETUID
        root.</p>

        <p>As experience has shown, for security purposes, the
        fewer programs that need to have privileged status, the
        better. <b class="APPLICATION">LPRng</b> uses the <tt
        class="LITERAL">lpd_port=printer</tt> configuration option
        to set the actual port to be use. By default, this is port
        515, but can be set to other values.</p>

        <p>The restriction of originating ports to 721-731 causes
        another set of problems. Part of the TCP/IP protocol is
        concerned with avoiding communications problems resulting
        from the arrival of old or <i class="EMPHASIS">stale</i>
        packets. When a connection between <tt class=
        "LITERAL">sourcehost, sourceport</tt> and <tt class=
        "LITERAL">desthost, destport</tt> is made, a set of
        sequence numbers is established and used for sending and
        acknowledgement of data. When the connection terminates,
        the TCP/IP protocol restricts the establishment of a new
        connection between <tt class="LITERAL">sourcehost,
        sourceport</tt> and <tt class="LITERAL">desthost,
        destport</tt> for a period long enough for all <i class=
        "EMPHASIS">stale</i> packets to be removed from the system.
        This is approximately 10 minutes long.</p>

        <p>In order to simplify assignments of ports, timing out
        connections, and other matters, many TCP/IP packages do
        keep track of explicit connections <i class=
        "EMPHASIS">originating</i> from a port, but simply prevent
        the port from being reused for either origination or
        reception of a connection. They do, however, keep track of
        the active connections <i class="EMPHASIS">to</i> a port,
        and perform timeouts on these. This is usually much simpler
        to implement, as it can be done with a list attached to the
        port.</p>

        <p>This implementation method creates some problems when a
        large number of connections must be originated from a
        relatively small number of port numbers. Observe what
        happens when host 1 tries to send a large number of jobs to
        a server 2. The following connections are established and
        terminated: <tt class="LITERAL">host 1, port 721</tt> and
        <tt class="LITERAL">host 2, port 515</tt> <tt class=
        "LITERAL">host 1, port 722</tt> and <tt class=
        "LITERAL">host 2, port 515</tt> <tt class="LITERAL">host 1,
        port 723</tt> and <tt class="LITERAL">host 2, port 515</tt>
        <tt class="LITERAL">host 1, port 724</tt> and <tt class=
        "LITERAL">host 2, port 515</tt> <tt class="LITERAL">host 1,
        port 725</tt> and <tt class="LITERAL">host 2, port 515</tt>
        <tt class="LITERAL">host 1, port 726</tt> and <tt class=
        "LITERAL">host 2, port 515</tt> <tt class="LITERAL">host 1,
        port 727</tt> and <tt class="LITERAL">host 2, port 515</tt>
        <tt class="LITERAL">host 1, port 728</tt> and <tt class=
        "LITERAL">host 2, port 515</tt> <tt class="LITERAL">host 1,
        port 729</tt> and <tt class="LITERAL">host 2, port 515</tt>
        <tt class="LITERAL">host 1, port 730</tt> and <tt class=
        "LITERAL">host 2, port 515</tt> <tt class="LITERAL">host 1,
        port 731</tt> and <tt class="LITERAL">host 2, port
        515</tt></p>

        <p>Now according to the RFC1179 rules and the TCP/IP
        protocol, we will have to wait until one of these
        connections terminates before we can make another. On the
        originating system, if the TCP/IP implementation does
        timeouts on the originating port, we will have to wait for
        the timeout to elapse before we can make a new connection.
        Unfortunately, there is no way to find out what the status
        of the port is, so we will have to try them each in turn
        until we get a successful connection.</p>

        <p>The <b class="APPLICATION">LPRng</b> code has tried to
        provide several methods to deal with these problems.
        Firstly, the <tt class="LITERAL">originate_port=512
        1023</tt> option specifies the range of ports used to
        originate connections when the software is running either
        as ROOT or SETUID root. By strict RFC1179 rules, this
        should be <tt class="LITERAL">originate_port=721 731</tt>,
        but it turns out that most BSD <b class=
        "APPLICATION">lpd</b> based implementations only check for
        a <i class="EMPHASIS">reserved</i> originating port. By
        using 512 ports we get a greatly reduced rate of errors due
        to lack of ports due to pending timeouts.</p>

        <p>However, on some systems which are acting as servers for
        a large number of printers even increasing this port range
        is insufficient, and steps need to be taken use the
        originating port numbers more efficiently. The Berkeley
        TCP/IP implementation <tt class=
        "FUNCTION">getsockopt()</tt> and <tt class=
        "FUNCTION">setsockopt()</tt> allows the user to manipulate
        some of the underlying timeouts and options of the TCP/IP
        network. When a TCP/IP connection is established, the <tt
        class="FUNCTION">setsockopt()</tt> facility can be used to
        set the <tt class="LITERAL">SO_REUSEADDR</tt> flag on the
        connection. This flag effectively sets the timeout value on
        the ports and connections to 0, allowing immediate reuse of
        the ports. When done on an originating end of a connection,
        this will allow the originating port number to be reused
        immediately.</p>

        <p>It would appear that by setting <tt class=
        "LITERAL">SO_REUSEADDR</tt> on the originating end that we
        have solved our problems. However, unless the destination
        end of the connection sets its <tt class=
        "LITERAL">SO_REUSEADDR</tt> flag on the connection, it will
        still do a timeout. Thus when we try to make a connection
        from a port that was active within a short period of time
        to the same host, then it will reject the connection until
        the timeout is over.</p>

        <p>The <tt class="LITERAL">reuse_addr</tt> flag (default
        off) forces the <b class="APPLICATION">LPRng</b> software
        to set the <tt class="LITERAL">SO_REUSEADDR</tt> flag on
        originating connections. As indicated, this will allow
        ports to be reused immediately for outgoing connections,
        rather than waiting for a timeout.</p>

        <p>While the <tt class="LITERAL">reuse_addr</tt> flag
        usually allows us to reuse ports, there is still the
        problem of dealing with connections failing due to the
        remote site rejecting the connection due to a pending
        timeout from a previous connection. A careful study of the
        original BSD TCP/IP network code and of some others
        indicates that when a connection fails due to a pending
        timeout, an ECONNREFUSED error code is returned to a <tt
        class="FUNCTION">connect()</tt> system call. If this
        happens and we suspect that the remote site is rejecting
        the connection due to a timeout problem, then we should
        retry making the connection but from a new port, and
        continue retrying until all possible ports are used.</p>

        <p>The <tt class="LITERAL">retry_econnrefused</tt> (default
        on) flag is used to specify that we retry connections in
        this manner. When this is set, a <tt class=
        "LITERAL">connection refused</tt> error causes the
        connection to be retried using a new port. This will be
        repeated until all available ports have been tried.</p>

        <p>When printing a job and the <b class=
        "APPLICATION">lpd</b> server connection to a remote site or
        device open fails, the <tt class=
        "LITERAL">retry_nolink</tt> (default on) will cause the
        attempt to be retried indefinitely. The combination of <tt
        class="LITERAL">retry_econnrefused</tt> and <tt class=
        "LITERAL">retry_nolink</tt> will provide robust connection
        attempts to remote systems.</p>

        <p>While the above problems cause difficulties when making
        connections, there are also problems when terminating
        connections. After closing a socket, the TCP/IP software
        will try to flush any pending data to the destination.
        Unfortunately, on some systems it will only do this while
        the process is active. This has caused problems on systems
        which terminate a process it has received an abnormal
        (signal caused) termination.</p>

        <p>The <tt class="FUNCTION">setsockopt()</tt> SO_LINGER
        option allows the user to specify that when a socket is
        closed normally, that the process should block until
        pending data is flushed or for the <tt class=
        "LITERAL">socket_linger</tt> period. If <tt class=
        "LITERAL">socket_linger</tt> is 0, then no SO_LINGER
        operation is done.</p>

        <p>In summary, if you experience problems with connection
        failures due to port exhaustion, first try setting the <tt
        class="LITERAL">reuse_port</tt> flag, and you should see a
        reduction. Check to ensure that the <tt class=
        "LITERAL">retry_econnrefused</tt> and <tt class=
        "LITERAL">retry_nolink</tt> flags are set, and the error
        code in the log and status files. If the failures continue,
        then the problem is caused by the remote end having timeout
        limitations and there is little you can do except to set a
        very long <tt class="LITERAL">connect_retry</tt> interval,
        say <tt class="LITERAL">connect_retry=120</tt> (2
        minutes).</p>
      </div>
    </div>

    <div class="NAVFOOTER">
      <hr align="LEFT" width="100%">

      <table summary="Footer navigation table" width="100%" border=
      "0" cellpadding="0" cellspacing="0">
        <tr>
          <td width="33%" align="left" valign="top"><a href=
          "x9588.htm" accesskey="P">Prev</a></td>

          <td width="34%" align="center" valign="top"><a href=
          "index.htm" accesskey="H">Home</a></td>

          <td width="33%" align="right" valign="top"><a href=
          "remotesupport.htm" accesskey="N">Next</a></td>
        </tr>

        <tr>
          <td width="33%" align="left" valign="top">\<b class=
          "APPLICATION">LPRng</b> accounting.pl Utility</td>

          <td width="34%" align="center" valign="top">&nbsp;</td>

          <td width="33%" align="right" valign="top">Protocol
          Requests and Replies</td>
        </tr>
      </table>
    </div>
  </body>
</html>