1.摘要
本文主要定義了一種SMTP服務擴展,使用這種服務擴展服務器可以說明它在一個TCP發送操作中可以接收多少個指令。在一個TCP發送指令中使用多個操作可以大大提高系統的運行效率。
2.介紹
雖然SMTP服務已經廣泛使用了,效果也不錯,但是對它的擴展也是不可少的。如果某個網絡需要很長時間進行連接,那SMTP運行的效果可就比較差了。SMTP的時間就費在等待一個個的命令上了。如果能夠使SMTP客戶端進行命令流水,也就是一次發送許多指令,就會提高運行效率。但以前的協議中沒有說明這一條,客戶無法知道服務器能夠同時接收多少指令。因此產生了如下的一些問題:
連接過程中連接失控或緩沖區滿;
在SMTP命令失敗時清除TCP輸入緩沖區,有時這是沒有必要的;
對一些命令會不講道理地判斷它為失敗,例如一些服務器如果在上一個REPTTO失敗后會再不接收DATA命令,而不管RCPTTO之前的命令是不是成功,而有些服務器則可以在RCPTTO命令失敗后接收DATA命令。
3.命令流水擴展框架
它的定義如下:
此服務擴展的名稱為流水(Pipelining);
與EHLO相關聯的擴展值是PIPELINING;
PIPELININGEHLO不再參數;
MAILFROM或RCPTTO命令不附加其它參數;
沒有附加其它SMTP命令;
4.流水服務擴展
當客戶機希望使用流水時,它會發送EHLO命令到服務器,如果服務器以250響應(其中的響應包括PIPELINING)就表明服務器支持SMTP服務流水。
4.1.客戶使用流水
在客戶知道服務器可以支持流水的時候,客戶可以傳輸多個命令(稱為命令組)到服務器,不用發送一條等待一下然后再發一條,特別的RSET,MAILFROM,SENDFROM,SOMLFROM,SAMLFROM和RCPTTO可以出現在命令組的任何地方。EHLO,DATA,VRFY,EXPN,TURN,QUIT和NOOP只能出現在命令組中的最后位置,因為它們成功與否將改變SMTP命令所處的狀態。由其它SMTP擴展產生的命令只能出現在組中的最后位置。實際傳送的命令可以是組中的第一個命令。
客戶SMTP必須檢查與組中據有相關的狀態。如果RCPTTP接收地址未被接受,客戶端必須檢查DATA的狀態,客戶端不能假設因為沒有RCPTTO是成功的所以DATA就會失敗。如果DATA命令被正確拒絕,客戶端可以發出RSET,如果DATA命令沒有被正確拒絕,客戶端要發出一個點(dot)。命令所產生的狀態必須和分別發出每個命令時相同,必須支持多行(Multiline)響應??蛻鬝MTP可以選擇在非阻塞狀態運行,它在接收到服務器的響應時立即處理,即使還有數據需要發送也不能推遲對響應的處理。如果不支持非阻塞狀態,客戶端必須檢查TCP窗口的大小,TCP窗口的大小必須大于命令組的大小。窗口大小經常是4K,如果不能進行這樣的檢查,可能會導致死鎖。
4.2.服務器對流水的支持
服務器應該提供下面的服務擴展:
在任何情況下不行將TCP輸入緩沖區的內容丟棄;
當且僅當接收到一個或多個有效的RCPTTO命令時,才對DATA命令應該主動發出響應;
因為DATA命令沒有合法的接收者,結果接收到空信息時,不要再發出消息給任何人(當然對DATA命令還要做一個響應);
對成組的RSET,MAILFROM,SENDFROM,SOMLFROM,SAMLFROM和RCPTTO命令的響應先保存起來,然后一起發送;
不允許緩存對EHLO,DATA,VRFY,EXPN,TURN,QUIT和NOOP的響應;
不允許緩沖不可識別命令的響應;
在本地TCP輸入緩沖區為空時必須將據有未發出的響應全部發出;
不允許對未接收到的命令進行猜測;或假設它的存在;
在響應的文本信息中應該表時這是對哪個命令進行的響應;
5.例子
下面是一個不支持流水的SMTP會話:其中S代表服務器,C代表客戶端;
S:<等待打開連接>
C:<打開連接>
S:220innosoft.comSMTPserviceready
C:HELOdbc.mtview.ca.us
S:250innosoft.com
C:MAILFROM:
S:250sender
C:RCPTTO:
S:250recipient
C:RCPTTO:
S:250recipient
C:RCPTTO:
S:250recipient
C:DATA
S:354傳輸郵件內容,并以一個只有”.”的行結束郵件
...
C:.
S:250messagesent
C:QUIT
S:221goodbye
在上例中客戶需要9次等待服務器的響應,下面我們來看看在支持流水的情況下是什么樣子:其中S代表服務器,C代表客戶端;
S:<等待打開連接>
C:<打開連接>
S:220innosoft.comSMTPserviceready
C:EHLOdbc.mtview.ca.us
S:250-innosoft.com
S:250PIPELINING
C:MAILFROM:
C:RCPTTO:
C:RCPTTO:
C:RCPTTO:
C:DATA
S:250sender
S:250recipient
S:250recipient
S:250recipient
S:354傳輸郵件內容,并以一個只有”.”的行結束郵件
...
C:.
C:QUIT
S:250messagesent
S:221goodbye
現在等待的次數由9次變為了4次,下面我們看一下當據有接收者均被拒絕時會是什么情況:
S:<等待打開連接>
C:<打開連接>
S:220innosoft.comSMTPserviceready
C:EHLOdbc.mtview.ca.us
S:250-innosoft.com
S:250PIPELINING
C:MAILFROM:
C:RCPTTO:
C:RCPTTO:
C:DATA
S:250sender
S:550remotemailto
S:550remotemailto
S:554novalidrecipientsgiven//未給出合法的接收者
C:QUIT
S:221goodbye
客戶端也等待了4次,如果服務器在接收DATA命令當不檢查接收者的合法性,則是下面的情況:
S:<等待打開連接>
C:<打開連接>
S:220innosoft.comSMTPserviceready
C:EHLOdbc.mtview.ca.us
S:250-innosoft.com
S:250PIPELINING
C:MAILFROM:
C:RCPTTO:
C:RCPTTO:
C:DATA
S:250sender
S:550remotemailto
S:550remotemailto
S:354傳輸郵件內容,并以一個只有”.”的行結束郵件
C:.
C:QUIT
S:554novalidrecipients//未給出合法的接收者
S:221goodbye