+return OK;
+
+
+ {
+ int code;
+ uschar * set_message;
+
+ RESPONSE_FAILED:
+ {
+ save_errno = errno;
+ message = NULL;
+ sx->send_quit = check_response(sx->host, &save_errno, sx->addrlist->more_errno,
+ sx->buffer, &code, &message, &pass_message);
+ goto FAILED;
+ }
+
+ SEND_FAILED:
+ {
+ save_errno = errno;
+ code = '4';
+ message = US string_sprintf("send() to %s [%s] failed: %s",
+ sx->host->name, sx->host->address, strerror(save_errno));
+ sx->send_quit = FALSE;
+ goto FAILED;
+ }
+
+ /* This label is jumped to directly when a TLS negotiation has failed,
+ or was not done for a host for which it is required. Values will be set
+ in message and save_errno, and setting_up will always be true. Treat as
+ a temporary error. */
+
+#ifdef SUPPORT_TLS
+ TLS_FAILED:
+ code = '4';
+#endif
+
+ /* The failure happened while setting up the call; see if the failure was
+ a 5xx response (this will either be on connection, or following HELO - a 5xx
+ after EHLO causes it to try HELO). If so, fail all addresses, as this host is
+ never going to accept them. For other errors during setting up (timeouts or
+ whatever), defer all addresses, and yield DEFER, so that the host is not
+ tried again for a while. */
+
+ FAILED:
+ sx->ok = FALSE; /* For when reached by GOTO */
+ set_message = message;
+
+ yield = code == '5'
+#ifdef SUPPORT_I18N
+ || errno == ERRNO_UTF8_FWD
+#endif
+ ? FAIL : DEFER;
+
+ set_errno(sx->addrlist, save_errno, set_message, yield, pass_message, sx->host
+#ifdef EXPERIMENTAL_DSN_INFO
+ , sx->smtp_greeting, sx->helo_response
+#endif
+ );
+ }
+
+
+SEND_QUIT:
+
+if (sx->send_quit)
+ (void)smtp_write_command(&sx->outblock, FALSE, "QUIT\r\n");
+
+/*END_OFF:*/
+
+#ifdef SUPPORT_TLS
+tls_close(FALSE, TRUE);
+#endif
+
+/* Close the socket, and return the appropriate value, first setting
+works because the NULL setting is passed back to the calling process, and
+remote_max_parallel is forced to 1 when delivering over an existing connection,
+
+If all went well and continue_more is set, we shouldn't actually get here if
+there are further addresses, as the return above will be taken. However,
+writing RSET might have failed, or there may be other addresses whose hosts are
+specified in the transports, and therefore not visible at top level, in which
+case continue_more won't get set. */
+
+HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP(close)>>\n");
+if (sx->send_quit)
+ {
+ shutdown(sx->outblock.sock, SHUT_WR);
+ if (fcntl(sx->inblock.sock, F_SETFL, O_NONBLOCK) == 0)
+ for (rc = 16; read(sx->inblock.sock, sx->inbuffer, sizeof(sx->inbuffer)) > 0 && rc > 0;)
+ rc--; /* drain socket */
+ }
+(void)close(sx->inblock.sock);
+
+#ifndef DISABLE_EVENT
+(void) event_raise(sx->tblock->event_action, US"tcp:close", NULL);
+#endif
+
+continue_transport = NULL;
+continue_hostname = NULL;
+return yield;
+}
+
+
+/*************************************************
+* Deliver address list to given host *
+*************************************************/
+
+/* If continue_hostname is not null, we get here only when continuing to
+deliver down an existing channel. The channel was passed as the standard
+input. TLS is never active on a passed channel; the previous process always
+closes it down before passing the connection on.
+
+Otherwise, we have to make a connection to the remote host, and do the
+initial protocol exchange.
+
+When running as an MUA wrapper, if the sender or any recipient is rejected,
+temporarily or permanently, we force failure for all recipients.
+
+Arguments:
+ addrlist chain of potential addresses to deliver; only those whose
+ transport_return field is set to PENDING_DEFER are currently
+ being processed; others should be skipped - they have either
+ been delivered to an earlier host or IP address, or been
+ failed by one of them.
+ host host to deliver to
+ host_af AF_INET or AF_INET6
+ port default TCP/IP port to use, in host byte order
+ interface interface to bind to, or NULL
+ tblock transport instance block
+ message_defer set TRUE if yield is OK, but all addresses were deferred
+ because of a non-recipient, non-host failure, that is, a
+ 4xx response to MAIL FROM, DATA, or ".". This is a defer
+ that is specific to the message.
+ suppress_tls if TRUE, don't attempt a TLS connection - this is set for
+ a second attempt after TLS initialization fails
+
+Returns: OK - the connection was made and the delivery attempted;
+ the result for each address is in its data block.
+ DEFER - the connection could not be made, or something failed
+ while setting up the SMTP session, or there was a
+ non-message-specific error, such as a timeout.
+ ERROR - a filter command is specified for this transport,
+ and there was a problem setting it up; OR helo_data
+ or add_headers or authenticated_sender is specified
+ for this transport, and the string failed to expand
+*/
+
+static int
+smtp_deliver(address_item *addrlist, host_item *host, int host_af, int port,
+ uschar *interface, transport_instance *tblock,
+ BOOL *message_defer, BOOL suppress_tls)
+{
+address_item *addr;
+address_item *sync_addr;
+address_item *first_addr = addrlist;
+int yield = OK;
+int address_count;
+int save_errno;
+int rc;
+time_t start_delivery_time = time(NULL);
+
+BOOL completed_address = FALSE;
+
+
+BOOL pass_message = FALSE;
+uschar *message = NULL;
+uschar new_message_id[MESSAGE_ID_LENGTH + 1];
+uschar *p;
+
+smtp_context sx;
+
+suppress_tls = suppress_tls; /* stop compiler warning when no TLS support */
+
+sx.addrlist = addrlist;
+sx.host = host;
+sx.host_af = host_af,
+sx.port = port;
+sx.interface = interface;
+sx.tblock = tblock;
+
+if ((rc = smtp_setup_conn(&sx, message_defer, suppress_tls, FALSE)) != OK)
+ return rc;
+