Handling DNS resolution exception (#67)
Closed
wojciech.kapcia@tigase.net opened 2 years ago

When trying to establish connection to locally deployed server (using localhost hostname) there is an exception because Halcyon tries to resolve it (and DNS should not resolve localhost) instead of connecting to it:

dic 14, 2022 1:00:01 P. M. tigase.halcyon.core.AbstractHalcyon connect
INFORMACIÓN: Connecting
dic 14, 2022 1:00:01 P. M. tigase.halcyon.core.connector.AbstractSocketSessionController start
INFORMACIÓN: Started session controller
dic 14, 2022 1:00:02 P. M. org.minidns.DnsClient query
ADVERTENCIA: The DNS server /1.1.1.1 returned a response without the "recursion available" (RA) flag set. This likely indicates a misconfiguration because the server is not suitable for DNS resolution
dic 14, 2022 1:00:02 P. M. org.minidns.DnsClient query
ADVERTENCIA: The DNS server /8.8.8.8 returned a response without the "recursion available" (RA) flag set. This likely indicates a misconfiguration because the server is not suitable for DNS resolution
org.minidns.util.MultipleIoException: No route to host, No route to host, Did not receive an authoritative answer, nor did the result contain any glue records, No route to host, No route to host
	at org.minidns.util.MultipleIoException.throwIfRequired(MultipleIoException.java:57)
	at org.minidns.iterative.ReliableDnsClient.query(ReliableDnsClient.java:139)
	at org.minidns.AbstractDnsClient.query(AbstractDnsClient.java:188)
	at org.minidns.dnssec.DnssecClient.queryDnssec(DnssecClient.java:104)
	at org.minidns.hla.DnssecResolverApi.resolve(DnssecResolverApi.java:65)
	at org.minidns.hla.ResolverApi.resolve(ResolverApi.java:114)
	at org.minidns.hla.ResolverApi.resolveSrv(ResolverApi.java:214)
	at org.minidns.hla.ResolverApi.resolveSrv(ResolverApi.java:141)
	at org.minidns.hla.ResolverApi.resolveSrv(ResolverApi.java:136)
	at org.minidns.hla.ResolverApi.resolveSrv(ResolverApi.java:124)
	at tigase.halcyon.core.connector.socket.DnsResolverMiniDns.resolve(DnsResolverMiniDns.kt:12)
	at tigase.halcyon.core.connector.socket.SocketConnector.createSocket(SocketConnector.kt:205)
	at tigase.halcyon.core.connector.socket.SocketConnector.start(SocketConnector.kt:233)
	at tigase.halcyon.core.AbstractHalcyon.startConnector(AbstractHalcyon.kt:312)
	at tigase.halcyon.core.AbstractHalcyon.connect(AbstractHalcyon.kt:369)
	at tigase.halcyon.core.Halcyon.connectAndWait(Halcyon.kt:100)
	at tigase.tests.Sasl2Bind2Test.test_sasl1_connection(TestSasl2Bind2.kt:45)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
	at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
	at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
	at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
	at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.testng.TestRunner.privateRun(TestRunner.java:808)
	at org.testng.TestRunner.run(TestRunner.java:603)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
	at org.testng.SuiteRunner.run(SuiteRunner.java:326)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
	at org.testng.TestNG.runSuites(TestNG.java:1092)
	at org.testng.TestNG.run(TestNG.java:1060)
	at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:135)
	at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeSingleClass(TestNGDirectoryTestSuite.java:112)
	at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
	at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:146)
	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
dic 14, 2022 1:00:05 P. M. tigase.halcyon.core.connector.AbstractSocketSessionController stop

There is code that handles failure case of DNS resolution (https://github.com/tigase/halcyon/blob/a08238019cc6a8000fd23399614e014ee089ac41/halcyon-core/src/jvmMain/kotlin/tigase/halcyon/core/connector/socket/SocketConnector.kt#L205-L205) but it doesn't work when the exception happens (thrown by https://github.com/tigase/halcyon/blob/a08238019cc6a8000fd23399614e014ee089ac41/halcyon-core/src/jvmMain/kotlin/tigase/halcyon/core/connector/socket/DnsResolverMiniDns.kt#L12-L12) thus connection fail.

Possible naive solution would involve yielding failure when exception is thrown (tested it and it works fine):

lass DnsResolverMiniDns : DnsResolver {

	override fun resolve(domain: String, completionHandler: (Result<List<SrvRecord>>) -> Unit) {
		try {
			val res = DnssecResolverApi.INSTANCE.resolveSrv(SrvType.xmpp_client, domain)

			if (!res.wasSuccessful()) {
				completionHandler.invoke(Result.failure(HalcyonException("Cannot retrieve domain $domain. responseCode=${res.responseCode}")))
			} else {
				res.answers.map {
					SrvRecord(
						port = it.port.toUInt(),
						weight = it.weight.toUInt(),
						priority = it.priority.toUInt(),
						target = it.target.toString()
					)
				}
					.let { completionHandler.invoke(Result.success(it)) }
			}
		} catch (e: IOException) {
			completionHandler.invoke(Result.failure(HalcyonException("Cannot retrieve domain $domain. Exception ${e} ")))
		}
	}
}
issue 1 of 1
Type
Bug
Priority
Normal
Assignee
Version
0.0.24
Issue Votes (0)
Watchers (0)
Reference
tigase/_libraries/halcyon#67
Please wait...
Page is in error, reload to recover