558
559
* XXX No need to do this before and after STARTTLS, but it's not a big deal
562
* XXX This critically depends on VSTREAM buffers to never be smaller than
561
565
if (session->features & SMTP_FEATURE_PIPELINING) {
562
optlen = sizeof(session->sndbufsize);
566
optlen = sizeof(sndbufsize);
563
567
if (getsockopt(vstream_fileno(session->stream), SOL_SOCKET,
564
SO_SNDBUF, (char *) &session->sndbufsize, &optlen) < 0)
568
SO_SNDBUF, (char *) &sndbufsize, &optlen) < 0)
565
569
msg_fatal("%s: getsockopt: %m", myname);
566
if (session->sndbufsize > VSTREAM_BUFSIZE)
567
session->sndbufsize = VSTREAM_BUFSIZE;
568
if (session->sndbufsize == 0) {
569
session->sndbufsize = VSTREAM_BUFSIZE;
570
if (sndbufsize > VSTREAM_BUFSIZE)
571
sndbufsize = VSTREAM_BUFSIZE;
572
if (sndbufsize < VSTREAM_BUFSIZE) {
573
sndbufsize = VSTREAM_BUFSIZE;
570
574
if (setsockopt(vstream_fileno(session->stream), SOL_SOCKET,
571
SO_SNDBUF, (char *) &session->sndbufsize, optlen) < 0)
575
SO_SNDBUF, (char *) &sndbufsize, optlen) < 0)
572
576
msg_fatal("%s: setsockopt: %m", myname);
575
579
msg_info("Using %s PIPELINING, TCP send buffer size is %d",
576
580
(state->misc_flags &
577
581
SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
578
session->sndbufsize);
580
session->sndbufsize = 0;
1132
1132
(session->features |= SMTP_FEATURE_RSET_REJECTED)
1135
* Sanity check. We don't want smtp_chat() to inadvertently flush the
1136
* output buffer. That means someone broke pipelining support.
1138
if (session->sndbufsize > VSTREAM_BUFSIZE)
1139
msg_panic("bad sndbufsize %d > VSTREAM_BUFSIZE %d",
1140
session->sndbufsize, VSTREAM_BUFSIZE);
1143
* Miscellaneous initialization. Some of this might be done in
1144
* smtp_xfer() but that just complicates interfaces and data structures.
1146
sndbuffree = session->sndbufsize;
1149
1135
* Pipelining support requires two loops: one loop for sending and one
1150
1136
* for receiving. Each loop has its own independent state. Most of the
1151
1137
* time the sender can run ahead of the receiver by as much as the TCP
1222
1208
case SMTP_STATE_XFORWARD_NAME_ADDR:
1223
1209
vstring_strcpy(next_command, XFORWARD_CMD);
1224
if (session->features & SMTP_FEATURE_XFORWARD_NAME) {
1210
if ((session->features & SMTP_FEATURE_XFORWARD_NAME)
1211
&& DEL_REQ_ATTR_AVAIL(request->client_name)) {
1225
1212
vstring_strcat(next_command, " " XFORWARD_NAME "=");
1226
xtext_quote_append(next_command,
1227
DEL_REQ_ATTR_AVAIL(request->client_name) ?
1228
request->client_name : XFORWARD_UNAVAILABLE, "");
1213
xtext_quote_append(next_command, request->client_name, "");
1230
if (session->features & SMTP_FEATURE_XFORWARD_ADDR) {
1215
if ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
1216
&& DEL_REQ_ATTR_AVAIL(request->client_addr)) {
1231
1217
vstring_strcat(next_command, " " XFORWARD_ADDR "=");
1232
xtext_quote_append(next_command,
1233
DEL_REQ_ATTR_AVAIL(request->client_addr) ?
1234
request->client_addr : XFORWARD_UNAVAILABLE, "");
1218
xtext_quote_append(next_command, request->client_addr, "");
1236
if (session->features & SMTP_FEATURE_XFORWARD_PORT) {
1220
if ((session->features & SMTP_FEATURE_XFORWARD_PORT)
1221
&& DEL_REQ_ATTR_AVAIL(request->client_port)) {
1237
1222
vstring_strcat(next_command, " " XFORWARD_PORT "=");
1238
xtext_quote_append(next_command,
1239
DEL_REQ_ATTR_AVAIL(request->client_port) ?
1240
request->client_port : XFORWARD_UNAVAILABLE, "");
1223
xtext_quote_append(next_command, request->client_port, "");
1242
1225
if (session->send_proto_helo)
1243
1226
next_state = SMTP_STATE_XFORWARD_PROTO_HELO;
1248
1231
case SMTP_STATE_XFORWARD_PROTO_HELO:
1249
1232
vstring_strcpy(next_command, XFORWARD_CMD);
1250
if (session->features & SMTP_FEATURE_XFORWARD_PROTO) {
1233
if ((session->features & SMTP_FEATURE_XFORWARD_PROTO)
1234
&& DEL_REQ_ATTR_AVAIL(request->client_proto)) {
1251
1235
vstring_strcat(next_command, " " XFORWARD_PROTO "=");
1252
xtext_quote_append(next_command,
1253
DEL_REQ_ATTR_AVAIL(request->client_proto) ?
1254
request->client_proto : XFORWARD_UNAVAILABLE, "");
1236
xtext_quote_append(next_command, request->client_proto, "");
1256
if (session->features & SMTP_FEATURE_XFORWARD_HELO) {
1238
if ((session->features & SMTP_FEATURE_XFORWARD_HELO)
1239
&& DEL_REQ_ATTR_AVAIL(request->client_helo)) {
1257
1240
vstring_strcat(next_command, " " XFORWARD_HELO "=");
1258
xtext_quote_append(next_command,
1259
DEL_REQ_ATTR_AVAIL(request->client_helo) ?
1260
request->client_helo : XFORWARD_UNAVAILABLE, "");
1241
xtext_quote_append(next_command, request->client_helo, "");
1262
if (session->features & SMTP_FEATURE_XFORWARD_DOMAIN) {
1243
if ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
1244
&& DEL_REQ_ATTR_AVAIL(request->rewrite_context)) {
1263
1245
vstring_strcat(next_command, " " XFORWARD_DOMAIN "=");
1264
1246
xtext_quote_append(next_command,
1265
DEL_REQ_ATTR_AVAIL(request->rewrite_context) == 0 ?
1266
XFORWARD_UNAVAILABLE :
1267
1247
strcmp(request->rewrite_context, MAIL_ATTR_RWR_LOCAL) ?
1268
1248
XFORWARD_DOM_REMOTE : XFORWARD_DOM_LOCAL, "");
1439
1419
if (SENDER_IN_WAIT_STATE
1440
1420
|| (SENDER_IS_AHEAD
1441
&& (VSTRING_LEN(next_command) + 2 > sndbuffree
1442
|| time((time_t *) 0) - vstream_ftime(session->stream) > 10))) {
1421
&& ((session->features & SMTP_FEATURE_PIPELINING) == 0
1422
|| (VSTRING_LEN(next_command) + 2
1423
+ vstream_bufstat(session->stream, VSTREAM_BST_OUT_PEND)
1425
|| time((time_t *) 0)
1426
- vstream_ftime(session->stream) > 10))) {
1443
1427
while (SENDER_IS_AHEAD) {
1716
* At this point, the sender and receiver are fully synchronized,
1717
* so that the entire TCP send buffer becomes available again.
1700
* At this point, the sender and receiver are fully synchronized.
1719
sndbuffree = session->sndbufsize;
1722
1704
* We know the server response to every command that was sent.
1771
1753
* XXX Don't downgrade just because generic_maps is turned
1774
if (downgrading || smtp_generic_maps || smtp_header_checks
1775
|| smtp_body_checks)
1756
#define SMTP_ANY_CHECKS (smtp_header_checks || smtp_body_checks)
1758
if (downgrading || smtp_generic_maps || SMTP_ANY_CHECKS)
1776
1759
session->mime_state = mime_state_alloc(downgrading ?
1777
1760
MIME_OPT_DOWNGRADE
1778
1761
| MIME_OPT_REPORT_NESTING :
1779
MIME_OPT_DISABLE_MIME,
1762
SMTP_ANY_CHECKS == 0 ?
1763
MIME_OPT_DISABLE_MIME :
1780
1765
smtp_generic_maps
1781
1766
|| smtp_header_checks ?
1782
1767
smtp_header_rewrite :
1934
* Use the XFORWARD command to forward client attributes only when a
1935
* minimal amount of information is available.
1917
* Use XFORWARD to forward the origin of this email message across an
1918
* SMTP-based content filter. Send client attribute information only if
1919
* it exists (i.e. remote submission). Local submissions have no client
1920
* attributes; the mail will appear to originate from the content filter
1921
* which is acceptable.
1937
1923
send_name_addr =
1938
1924
var_smtp_send_xforward
1939
1925
&& (((session->features & SMTP_FEATURE_XFORWARD_NAME)
1940
1926
&& DEL_REQ_ATTR_AVAIL(request->client_name))
1941
1927
|| ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
1942
&& DEL_REQ_ATTR_AVAIL(request->client_addr)));
1928
&& DEL_REQ_ATTR_AVAIL(request->client_addr))
1929
|| ((session->features & SMTP_FEATURE_XFORWARD_PORT)
1930
&& DEL_REQ_ATTR_AVAIL(request->client_port)));
1943
1931
session->send_proto_helo =
1944
1932
var_smtp_send_xforward
1945
1933
&& (((session->features & SMTP_FEATURE_XFORWARD_PROTO)
1946
1934
&& DEL_REQ_ATTR_AVAIL(request->client_proto))
1947
1935
|| ((session->features & SMTP_FEATURE_XFORWARD_HELO)
1948
&& DEL_REQ_ATTR_AVAIL(request->client_helo)));
1936
&& DEL_REQ_ATTR_AVAIL(request->client_helo))
1937
|| ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
1938
&& DEL_REQ_ATTR_AVAIL(request->rewrite_context)));
1949
1939
if (send_name_addr)
1950
1940
recv_state = send_state = SMTP_STATE_XFORWARD_NAME_ADDR;
1951
1941
else if (session->send_proto_helo)