X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/0539a19dc27efcfc77713a87aba6b61fef947249..584e96c65f12aca9414450b656504af6e3f7a399:/src/src/host.c diff --git a/src/src/host.c b/src/src/host.c index 643900b21..7fda13d3c 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or @@ -257,7 +257,7 @@ else count++; yield = store_get(sizeof(struct hostent)); - alist = store_get((count + 1) * sizeof(char **)); + alist = store_get((count + 1) * sizeof(char *)); adds = store_get(count *alen); yield->h_name = CS name; @@ -544,7 +544,7 @@ use this directly as the first item for Received: because it ain't an RFC 2822 domain. Sigh. */ address = string_sprintf("[%s]:%d", sender_host_address, sender_host_port); -if ((log_extra_selector & LX_incoming_port) == 0 || sender_host_port <= 0) +if (!LOGGING(incoming_port) || sender_host_port <= 0) *(Ustrrchr(address, ':')) = 0; /* If there's no EHLO/HELO data, we can't show it. */ @@ -597,12 +597,12 @@ if (sender_host_name == NULL) sender_fullhost = (sender_helo_name == NULL)? address : string_sprintf("(%s) %s", sender_helo_name, address); - sender_rcvhost = string_cat(NULL, &size, &ptr, address, adlen); + sender_rcvhost = string_catn(NULL, &size, &ptr, address, adlen); if (sender_ident != NULL || show_helo || portptr != NULL) { int firstptr; - sender_rcvhost = string_cat(sender_rcvhost, &size, &ptr, US" (", 2); + sender_rcvhost = string_catn(sender_rcvhost, &size, &ptr, US" (", 2); firstptr = ptr; if (portptr != NULL) @@ -617,7 +617,7 @@ if (sender_host_name == NULL) sender_rcvhost = string_append(sender_rcvhost, &size, &ptr, 2, (firstptr == ptr)? US"ident=" : US" ident=", sender_ident); - sender_rcvhost = string_cat(sender_rcvhost, &size, &ptr, US")", 1); + sender_rcvhost = string_catn(sender_rcvhost, &size, &ptr, US")", 1); } sender_rcvhost[ptr] = 0; /* string_cat() always leaves room */ @@ -695,8 +695,7 @@ else { uschar *flag = useflag? US"H=" : US""; uschar *iface = US""; - if ((log_extra_selector & LX_incoming_interface) != 0 && - interface_address != NULL) + if (LOGGING(incoming_interface) && interface_address != NULL) iface = string_sprintf(" I=[%s]:%d", interface_address, interface_port); if (sender_ident == NULL) (void)string_format(big_buffer, big_buffer_size, "%s%s%s", @@ -1068,7 +1067,7 @@ if (Ustrchr(address, ':') != NULL) /* Handle IPv4 address */ (void)sscanf(CS address, "%d.%d.%d.%d", x, x+1, x+2, x+3); -bin[v4offset] = (x[0] << 24) + (x[1] << 16) + (x[2] << 8) + x[3]; +bin[v4offset] = ((uint)x[0] << 24) + (x[1] << 16) + (x[2] << 8) + x[3]; return v4offset+1; } @@ -1099,7 +1098,7 @@ for (i = 0; i < count; i++) if (mask == 0) wordmask = 0; else if (mask < 32) { - wordmask = (-1) << (32 - mask); + wordmask = (uint)(-1) << (32 - mask); mask = 0; } else @@ -1147,20 +1146,14 @@ if (count == 1) { j = binary[0]; for (i = 24; i >= 0; i -= 8) - { - sprintf(CS tt, "%d.", (j >> i) & 255); - while (*tt) tt++; - } + tt += sprintf(CS tt, "%d.", (j >> i) & 255); } else - { for (i = 0; i < 4; i++) { j = binary[i]; - sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep); - while (*tt) tt++; + tt += sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep); } - } tt--; /* lose final separator */ @@ -1176,6 +1169,63 @@ return tt - buffer; } +/* Like host_nmtoa() but: ipv6-only, canonical output, no mask + +Arguments: + binary points to the ints + buffer big enough to hold the result + +Returns: the number of characters placed in buffer, not counting + the final nul. +*/ + +int +ipv6_nmtoa(int * binary, uschar * buffer) +{ +int i, j, k; +uschar * c = buffer; +uschar * d = NULL; /* shut insufficiently "clever" compiler up */ + +for (i = 0; i < 4; i++) + { /* expand to text */ + j = binary[i]; + c += sprintf(CS c, "%x:%x:", (j >> 16) & 0xffff, j & 0xffff); + } + +for (c = buffer, k = -1, i = 0; i < 8; i++) + { /* find longest 0-group sequence */ + if (*c == '0') /* must be "0:" */ + { + uschar * s = c; + j = i; + while (c[2] == '0') i++, c += 2; + if (i-j > k) + { + k = i-j; /* length of sequence */ + d = s; /* start of sequence */ + } + } + while (*++c != ':') ; + c++; + } + +c[-1] = '\0'; /* drop trailing colon */ + +/* debug_printf("%s: D k %d <%s> <%s>\n", __FUNCTION__, k, d, d + 2*(k+1)); */ +if (k >= 0) + { /* collapse */ + c = d + 2*(k+1); + if (d == buffer) c--; /* need extra colon */ + *d++ = ':'; /* 1st 0 */ + while ((*d++ = *c++)) ; + } +else + d = c; + +return d - buffer; +} + + /************************************************* * Check port for tls_on_connect * @@ -1271,7 +1321,7 @@ for (i = 0; i < size; i++) if (mlen == 0) mask = 0; else if (mlen < 32) { - mask = (-1) << (32 - mlen); + mask = (uint)(-1) << (32 - mlen); mlen = 0; } else @@ -1471,7 +1521,7 @@ int len; uschar *s, *t; struct hostent *hosts; struct in_addr addr; -unsigned long time_msec; +unsigned long time_msec = 0; /* init to quieten dumb static analysis */ if (slow_lookup_log) time_msec = get_time_in_ms(); @@ -1928,16 +1978,6 @@ BOOL temp_error = FALSE; int af; #endif -/* If we are in the test harness, a name ending in .test.again.dns always -forces a temporary error response, unless the name is in -dns_again_means_nonexist. */ - -if (running_in_test_harness) - { - const uschar *endname = host->name + Ustrlen(host->name); - if (Ustrcmp(endname - 14, "test.again.dns") == 0) goto RETURN_AGAIN; - } - /* Make sure DNS options are set as required. This appears to be necessary in some circumstances when the get..byname() function actually calls the DNS. */ @@ -2368,10 +2408,7 @@ for (; i >= 0; i--) { if (rr->type == type) { - /* dns_address *da = dns_address_from_rr(&dnsa, rr); */ - - dns_address *da; - da = dns_address_from_rr(&dnsa, rr); + dns_address *da = dns_address_from_rr(&dnsa, rr); DEBUG(D_host_lookup) if (!da) debug_printf("no addresses extracted from A6 RR for %s\n", @@ -2631,7 +2668,7 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) if (dnssec_request) { if (dns_is_secure(&dnsa)) - { + { DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name); dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; } @@ -2883,6 +2920,12 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); NEXT_MX_RR: continue; } +if (!last) /* No rr of correct type; give up */ + { + yield = HOST_FIND_FAILED; + goto out; + } + /* If the list of hosts was obtained from SRV records, there are two things to do. First, if there is only one host, and it's name is ".", it means there is no SMTP service at this domain. Otherwise, we have to sort the hosts of equal @@ -2909,7 +2952,7 @@ if (ind_type == T_SRV) debug_printf(" %s P=%d W=%d\n", h->name, h->mx, h->sort_key % 1000); } - for (pptr = &host, h = host; h != last; pptr = &(h->next), h = h->next) + for (pptr = &host, h = host; h != last; pptr = &h->next, h = h->next) { int sum = 0; host_item *hh; @@ -3014,7 +3057,8 @@ dns_init(FALSE, FALSE, /* Disable qualify_single and search_parents */ for (h = host; h != last->next; h = h->next) { - if (h->address != NULL) continue; /* Inserted by a multihomed host */ + if (h->address) continue; /* Inserted by a multihomed host */ + rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, NULL, dnssec_request, dnssec_require); if (rc != HOST_FOUND) @@ -3026,7 +3070,7 @@ for (h = host; h != last->next; h = h->next) h->why = hwhy_deferred; } else - h->why = (rc == HOST_IGNORED)? hwhy_ignored : hwhy_failed; + h->why = rc == HOST_IGNORED ? hwhy_ignored : hwhy_failed; } } @@ -3222,7 +3266,7 @@ while (Ufgets(buffer, 256, stdin) != NULL) else { int flags = whichrrs; - dnssec d; + dnssec_domains d; h.name = buffer; h.next = NULL;