* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2017 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
return 0;
if (random_seed == 0)
{
- if (running_in_test_harness) random_seed = 42; else
+ if (f.running_in_test_harness) random_seed = 42; else
{
int p = (int)getpid();
random_seed = (int)time(NULL) ^ ((p << 16) | p);
first place.
Because this data may survive over more than one incoming SMTP message, it has
-to be in permanent store.
+to be in permanent store. However, STARTTLS has to be forgotten and redone
+on a multi-message conn, so this will be called once per message then. Hence
+we use malloc, so we can free.
Arguments: none
Returns: nothing
host_build_sender_fullhost(void)
{
BOOL show_helo = TRUE;
-uschar *address;
+uschar * address, * fullhost, * rcvhost, * reset_point;
int len;
-int old_pool = store_pool;
-if (sender_host_address == NULL) return;
+if (!sender_host_address) return;
-store_pool = POOL_PERM;
+reset_point = store_get(0);
/* Set up address, with or without the port. After discussion, it seems that
the only format that doesn't cause trouble is [aaaa]:pppp. However, we can't
/* If there's no EHLO/HELO data, we can't show it. */
-if (sender_helo_name == NULL) show_helo = FALSE;
+if (!sender_helo_name) show_helo = FALSE;
/* If HELO/EHLO was followed by an IP literal, it's messy because of two
features of IPv6. Firstly, there's the "IPv6:" prefix (Exim is liberal and
int adlen; /* Sun compiler doesn't like ++ in initializers */
adlen = portptr ? (++portptr - address) : Ustrlen(address);
- sender_fullhost = sender_helo_name
+ fullhost = sender_helo_name
? string_sprintf("(%s) %s", sender_helo_name, address)
: address;
g = string_catn(NULL, address, adlen);
- if (sender_ident != NULL || show_helo || portptr != NULL)
+ if (sender_ident || show_helo || portptr)
{
int firstptr;
g = string_catn(g, US" (", 2);
g = string_catn(g, US")", 1);
}
- sender_rcvhost = string_from_gstring(g);
-
- /* Release store, because string_cat allocated a minimum of 100 bytes that
- are rarely completely used. */
-
- store_reset(sender_rcvhost + g->ptr + 1);
+ rcvhost = string_from_gstring(g);
}
/* Host name is known and verified. Unless we've already found that the HELO
if (show_helo)
{
- sender_fullhost = string_sprintf("%s (%s) %s", sender_host_name,
+ fullhost = string_sprintf("%s (%s) %s", sender_host_name,
sender_helo_name, address);
- sender_rcvhost = (sender_ident == NULL)?
- string_sprintf("%s (%s helo=%s)", sender_host_name,
- address, sender_helo_name) :
- string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name,
- address, sender_helo_name, sender_ident);
+ rcvhost = sender_ident
+ ? string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name,
+ address, sender_helo_name, sender_ident)
+ : string_sprintf("%s (%s helo=%s)", sender_host_name,
+ address, sender_helo_name);
}
else
{
- sender_fullhost = string_sprintf("%s %s", sender_host_name, address);
- sender_rcvhost = (sender_ident == NULL)?
- string_sprintf("%s (%s)", sender_host_name, address) :
- string_sprintf("%s (%s ident=%s)", sender_host_name, address,
- sender_ident);
+ fullhost = string_sprintf("%s %s", sender_host_name, address);
+ rcvhost = sender_ident
+ ? string_sprintf("%s (%s ident=%s)", sender_host_name, address,
+ sender_ident)
+ : string_sprintf("%s (%s)", sender_host_name, address);
}
}
-store_pool = old_pool;
+if (sender_fullhost) store_free(sender_fullhost);
+sender_fullhost = string_copy_malloc(fullhost);
+if (sender_rcvhost) store_free(sender_rcvhost);
+sender_rcvhost = string_copy_malloc(rcvhost);
+
+store_reset(reset_point);
DEBUG(D_host_lookup) debug_printf("sender_fullhost = %s\n", sender_fullhost);
DEBUG(D_host_lookup) debug_printf("sender_rcvhost = %s\n", sender_rcvhost);
/* For testing the case when a lookup does not complete, we have a special
reserved IP address. */
-if (running_in_test_harness &&
+if (f.running_in_test_harness &&
Ustrcmp(sender_host_address, "99.99.99.99") == 0)
{
HDEBUG(D_host_lookup)
/* If we have failed to find a name, return FAIL and log when required.
NB host_lookup_msg must be in permanent store. */
-if (sender_host_name == NULL)
+if (!sender_host_name)
{
- if (host_checking || !log_testing_mode)
+ if (host_checking || !f.log_testing_mode)
log_write(L_host_lookup_failed, LOG_MAIN, "no host name found for IP "
"address %s", sender_host_address);
host_lookup_msg = US" (failed to find host name from IP address)";
{
int rc;
BOOL ok = FALSE;
- host_item h;
- dnssec_domains d;
-
- h.next = NULL;
- h.name = hname;
- h.mx = MX_NONE;
- h.address = NULL;
- d.request = sender_host_dnssec ? US"*" : NULL;;
- d.require = NULL;
+ host_item h = { .next = NULL, .name = hname, .mx = MX_NONE, .address = NULL };
+ dnssec_domains d =
+ { .request = sender_host_dnssec ? US"*" : NULL, .require = NULL };
if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA,
NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND
/* Initialize the flag that gets set for DNS syntax check errors, so that the
interface to this function can be similar to host_find_bydns. */
-host_find_failed_syntax = FALSE;
+f.host_find_failed_syntax = FALSE;
/* Loop to look up both kinds of address in an IPv6 world */
if (slow_lookup_log) time_msec = get_time_in_ms();
#if HAVE_IPV6
- if (running_in_test_harness)
+ if (f.running_in_test_harness)
hostdata = host_fake_gethostbyname(host->name, af, &error_num);
else
{
}
#else /* not HAVE_IPV6 */
- if (running_in_test_harness)
+ if (f.running_in_test_harness)
hostdata = host_fake_gethostbyname(host->name, AF_INET, &error_num);
else
{
HDEBUG(D_host_lookup) debug_printf("%s\n", msg);
if (temp_error) goto RETURN_AGAIN;
- if (host_checking || !log_testing_mode)
+ if (host_checking || !f.log_testing_mode)
log_write(L_host_lookup_failed, LOG_MAIN, "%s", msg);
return HOST_FIND_FAILED;
}
dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
(whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
dnssec_request);
-host_find_failed_syntax = FALSE;
+f.host_find_failed_syntax = FALSE;
/* First, if requested, look for SRV records. The service name is given; we
assume TCP protocol. DNS domain names are constrained to a maximum of 256
characters, so the code below should be safe. */
-if ((whichrrs & HOST_FIND_BY_SRV) != 0)
+if (whichrrs & HOST_FIND_BY_SRV)
{
uschar buffer[300];
uschar *temp_fully_qualified_name = buffer;
block. Otherwise, add a new block in the correct place; if it has to be
before the first block, copy the first block's data to a new second block. */
- if (last == NULL)
+ if (!last)
{
host->name = string_copy_dnsdomain(data);
host->address = NULL;
else if (Ustrcmp(buffer, "require_dnssec") == 0) require_dnssec = TRUE;
else if (Ustrcmp(buffer, "no_require_dnssec") == 0) require_dnssec = FALSE;
else if (Ustrcmp(buffer, "test_harness") == 0)
- running_in_test_harness = !running_in_test_harness;
+ f.running_in_test_harness = !f.running_in_test_harness;
else if (Ustrcmp(buffer, "ipv6") == 0) disable_ipv6 = !disable_ipv6;
else if (Ustrcmp(buffer, "res_debug") == 0)
{