diff --git a/include/xpldns.h b/include/xpldns.h
index bd78abc..f9de130 100644
--- a/include/xpldns.h
+++ b/include/xpldns.h
@@ -93,6 +93,7 @@ typedef struct{
typedef struct {
XplDns_ResultCode status;
int preference;
+ int null_mx;
char current_mx[XPLDNS_NAMELEN + 1];
XplDns_Result *_mx_result;
XplDns_RecordList *_mx_current;
@@ -101,6 +102,7 @@ typedef struct {
int XplDnsInit(void);
void XplDnsResultFree(XplDns_Result *result);
XplDns_Result * XplDnsLookupIP(const char *domain);
+int XplDnsMxRecordsAreNull(const XplDns_RecordList *records);
XplDns_MxLookup *XplDnsNewMxLookup(const char *domain);
XplDns_IpList * XplDnsNextMxLookupIpList(XplDns_MxLookup *mx);
void XplDnsFreeMxLookup(XplDns_MxLookup *mx);
diff --git a/src/agents/smtp/smtpc.c b/src/agents/smtp/smtpc.c
index 4bbe9aa..60fbccc 100755
--- a/src/agents/smtp/smtpc.c
+++ b/src/agents/smtp/smtpc.c
@@ -494,6 +494,10 @@ Connection *LookupRemoteMX(RecipStruct *Recipient, char *hostname,
break;
}
}
+ if (mx->null_mx) {
+ Recipient->Result = DELIVER_HOST_UNKNOWN;
+ goto finish;
+ }
while ((list = XplDnsNextMxLookupIpList(mx)) != NULL) {
int x;
diff --git a/src/agents/smtp/smtpd.c b/src/agents/smtp/smtpd.c
index 386ef4c..1a83b82 100644
--- a/src/agents/smtp/smtpd.c
+++ b/src/agents/smtp/smtpd.c
@@ -3601,6 +3601,9 @@ DeliverRemoteMessage (ConnectionStruct * Client, char *Sender,
DELIVER_ERROR(RetVal);
goto finish;
}
+ if (mx->null_mx) {
+ DELIVER_ERROR(DELIVER_HOST_UNKNOWN);
+ }
while ((list = XplDnsNextMxLookupIpList(mx)) != NULL) {
int x;
diff --git a/src/libs/xpl/CMakeLists.txt b/src/libs/xpl/CMakeLists.txt
index 932346c..187b591 100644
--- a/src/libs/xpl/CMakeLists.txt
+++ b/src/libs/xpl/CMakeLists.txt
@@ -30,4 +30,8 @@ if(BUILD_TESTING)
add_executable(xpl-init-test tests/init-test.c)
target_link_libraries(xpl-init-test PRIVATE bongoxpl Threads::Threads)
add_test(NAME xpl-init COMMAND xpl-init-test)
+
+ add_executable(xpl-dns-mx-test tests/dns-mx-test.c)
+ target_link_libraries(xpl-dns-mx-test PRIVATE bongoxpl)
+ add_test(NAME xpl-dns-mx COMMAND xpl-dns-mx-test)
endif()
diff --git a/src/libs/xpl/dns.c b/src/libs/xpl/dns.c
index ea92ead..7e5693a 100644
--- a/src/libs/xpl/dns.c
+++ b/src/libs/xpl/dns.c
@@ -192,6 +192,22 @@ XplDnsResultFree(XplDns_Result *result)
MemFree(result);
}
+int
+XplDnsMxRecordsAreNull(const XplDns_RecordList *records)
+{
+ const XplDns_RecordList *record;
+ const XplDns_MxRecord *only_mx = NULL;
+ unsigned int mx_count = 0U;
+
+ for (record = records; record != NULL; record = record->next) {
+ if (record->type != XPLDNS_RR_MX) continue;
+ only_mx = &record->record.MX;
+ mx_count++;
+ }
+ return mx_count == 1U && only_mx->preference == 0 &&
+ only_mx->mxname[0] == '\0';
+}
+
XplDns_MxLookup *
XplDnsNewMxLookup(const char *domain)
{
@@ -248,7 +264,9 @@ restart_query:
result->status = mx_query->status;
result->_mx_result = mx_query;
- result->_mx_current = mx_query->list;
+ result->null_mx = mx_query->status == XPLDNS_SUCCESS &&
+ XplDnsMxRecordsAreNull(mx_query->list);
+ result->_mx_current = result->null_mx ? NULL : mx_query->list;
return result;
}
diff --git a/src/libs/xpl/tests/dns-mx-test.c b/src/libs/xpl/tests/dns-mx-test.c
new file mode 100644
index 0000000..8ff8ad9
--- /dev/null
+++ b/src/libs/xpl/tests/dns-mx-test.c
@@ -0,0 +1,53 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2001 Novell, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you
+ * may find current contact information at www.novell.com.
+ *
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+int
+main(void)
+{
+ XplDns_RecordList null_mx;
+ XplDns_RecordList regular_mx;
+
+ memset(&null_mx, 0, sizeof(null_mx));
+ null_mx.type = XPLDNS_RR_MX;
+ null_mx.record.MX.preference = 0;
+ assert(XplDnsMxRecordsAreNull(&null_mx));
+
+ null_mx.record.MX.preference = 10;
+ assert(!XplDnsMxRecordsAreNull(&null_mx));
+ null_mx.record.MX.preference = 0;
+ strcpy(null_mx.record.MX.mxname, "mail.example.test.");
+ assert(!XplDnsMxRecordsAreNull(&null_mx));
+
+ null_mx.record.MX.mxname[0] = '\0';
+ memset(®ular_mx, 0, sizeof(regular_mx));
+ regular_mx.type = XPLDNS_RR_MX;
+ regular_mx.record.MX.preference = 10;
+ strcpy(regular_mx.record.MX.mxname, "backup.example.test.");
+ null_mx.next = ®ular_mx;
+ assert(!XplDnsMxRecordsAreNull(&null_mx));
+ assert(!XplDnsMxRecordsAreNull(NULL));
+ return 0;
+}