Recent updates: Changes to handling partial print jobs

Introduction

RPM Remote Print Manager® ("RPM") is not my first LPD print server. That honor goes to a program called "wslpd" which I wrote for a US government agency in the early nineties.

The LPD print protocol is not that hard to understand. There is a reference document for it available on the Internet to anyone who wants to know. You can track it down with a search for "rfc 1179". The conversation essentially goes something like this: 

Print requestor RPM
I want you to print something on this queue OK
This is the name of the data file I'm using and how big it is OK
Here's the data file <reading> OK
This is the name of the file of meta data I want to send about this job, and how many bytes OK
Here's the meta data I want you to know about this job <reading> OK
I'm done Gotcha

If you can imagine this conversation, allowing some room for flexibility, then you have a pretty good idea how LPD printing works. It's not elegant but it gets the job done. There are many more options, of course.

Using LPD as a test

A customer told us they had dozens of empty queues in RPM. It seems a Linux print program created these queues when it sent "test print requests" to RPM. Obviously the print program wanted to see if RPM was listening, which it was, and if these queues existed. RPM by defaults creates a queue if it doesn't already exist.

Our philosophy is that it is better to get a print job you don't know what to do with, then to not get the print job at all. That is why RPM by default does not reject print jobs. Besides, you can always decide later how you want to process that job. You can't do that if you have no idea there ever was a job.

Issue #1: "Captain, we're being probed"

I started to refer to these episodes with odd queue names as "probes" since the end result was an empty print job. A zero byte job is not very useful. RPM has an option to ignore jobs under a certain size so it was easy to erase the empty jobs using that setting.

Up to now the whole episode reminded me of classic Star Trek where something unpleasant happens without a good reason. Everyone on the bridge tenses up. Is it a problem?

Issue #2: the "exception" to the rule

Empty jobs are annoying. Once you determine that they were deliberate, and not part of a network error or software bug, it's easy to make them go away.

However, we started to encounter "probes" which were more serious in that they left error messages. In the RPM event log in the user interface, we started seeing messages like the following:

LpdProto::OnRead - 2016-11-24 19:05:43.398
error: unknown exception
message: get command: \x04ITINVDOM\x0a

and

LpdProto::Close - 2016-11-21 13:49:06.124 
error: unknown exception 
message: close socket

When we investigated further we found two problems.

Problem #1: handling incomplete transactions

Based on where the error messages were coming from in RPM, I determined that we had not received all the parts of the print request one would expect. In all this time I had not personally seen incomplete transfers, nor did I expect to.

I had reasoned before that if there was an incomplete transfer then it was due to a network problem. The correct course of action would be to let someone know. I admit the error messsages above do not say "hey there's a network problem" so that's on me.

Once I fixed those issues, we continued to get reports.

Problem #2: the "tear down"

If we go back to the sample LPD print request I mocked up earlier, you'll notice that the conversation follows a simple "send / response" pattern. Like a real conversation, one person says something with the expectation that the other person will respond some way.

We discovered that some print programs send the request, then immediately close the connection.

It's a lot like a phone conversation which is cut off at the beginning: "I have something important I need you to do" "OK, what?" "Go outside and " <click>

After I made changes to RPM's diagnostic logging we determined that we were getting a "close" event from the print client at the same time as a "read" event. This is like the conversation above. The connection was abruptly severed.

The present solution

  1. Since I know we're going to have partial messages I've accounted for that in RPM, so no more exception messages.
  2. I've made allowances in the networking code that we may get a close message. RPM will read all the available data first. This will ensure that if we can complete the transaction, we will.

Conclusion

These updates are included in RPM as of version 6.1.0.453 available on July 12, 2017. You can check for updates in the Help menu of the RPM user interface, or contact your sales person with your questions.