SMTP Pipelining Command Format?

EricMartello

Senior member
Apr 17, 2003
910
0
0
SMTP Pipelining is a common feature supported on most modern email servers. It allows the client to send commands in a group without having to wait for a response to each command, thus making for a quicker transaction. I've read the RFC but it does not get into technical detail about implementation of pipelining.

My question is: How do you send the commands to the server as a "batch" vs one-by-one to take advantage of pipelining if you are trying to program an email client?

For example:

You start with EHLO, the client sees '250 PIPELINING' as one of the supported features. At this point you could initiate the email sending process. Below, you are sending the same email to 3 recipients.

MAIL FROM: <email> \r\n
RCPT TO: <email> \r\n
RCPT TO: <email> \r\n
RCPT TO: <email> \r\n
DATA \r\n

The problem I am having is sending those commands as a batch - in other words, all in one shot without having the server ack each command. Right now, because of the \r\n required after each command, the server sends a response immediately after receiving each command and I am pretty sure that is not how pipelining is supposed to work. How do I send the commands from within my program so that the server accepts them as a batch and does not respond until I send the DATA command as per RFC?

 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
Pipelining != to batching. Pipelining means that you can have multiple instructions 'in-flight' as opposed to waiting for each instruction to be processed separately. Reading up on the Wikipedia, it looks like the server is supposed to respond after each command received with a received ok sort of response. Just send each command as fast as you can, and keep track of the servers responses as they come in.

(Disclaimer, Im not a Networking protocols guy, I just know what pipelining is/means :))
 

EricMartello

Senior member
Apr 17, 2003
910
0
0
Yes, pipelining is in fact a form of batch processing since you send the commands in a batch, and receive a batch of responses in the order the commands were sent. That is how it should work according to RFC. Wikipedia is not the best place to look for information about this kind of thing.

I did try sending the commands without waiting, and it doesn't work. I did not get any response from the server when doing it that way so it leads me to believe there is a correct way to send them. It would be nice if they just made it easier by giving us the option to indicate that the client is going to pipeline the commands, thus the server will expect a batch of commands and not reply until it receives the data command.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Everything I can find says it should work exactly as you've described. Is it possible the server doesn't implement it correctly?
 

EricMartello

Senior member
Apr 17, 2003
910
0
0
Sending the commands in one bunch works, ending with DATA. I get 354 which means OK to send email body...I do that, and after that nothing happens. No errors or anything and the mail does not get sent. The same code works fine if I check for a response between each command.

Edit: The mail server is running Exim 4, which is a common server.
 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
Sounds like you're not terminating the SMTP session correctly.

Sending mail to postfix requires the final line of the body to be a single . and then the next line QUIT
 

EricMartello

Senior member
Apr 17, 2003
910
0
0
OK guys, I got it working, but I had to sidestep RFC a little. For future reference, if you want to pipeline SMTP commands, here is how:

Start Session:
EHLO

<Logon if necessary>

Send to server as one call:
"MAIL FROM: <email>\r\nRCPT TO: <email>\r\nDATA\r\nEMAIL_CONTENT\r\n.\r\n"

You will receive a response to each command as a list, in the order you sent them. I just check the last response line for 250 as the last command to verify that the message was sent. If there was an error in the batch, you can then check the remaining lines to find out where it occurred.

Notice how I had to include the email body as part of the pipeline...according to RFC, the pipelining should stop with DATA because it is considered a "state change" on the server...but whatever works is good enough for me. :)