package com.frostnerd.smokescreen.util.proxy import com.frostnerd.dnstunnelproxy.AddressCreator import com.frostnerd.dnstunnelproxy.UpstreamAddress import com.frostnerd.encrypteddnstunnelproxy.QuicEngine import com.frostnerd.encrypteddnstunnelproxy.quic.AbstractQuicDnsHandle import com.frostnerd.encrypteddnstunnelproxy.quic.QuicUpstreamAddress import com.frostnerd.vpntunnelproxy.FutureAnswer import org.minidns.dnsmessage.DnsMessage import org.minidns.record.A import org.minidns.record.AAAA import org.minidns.record.Record import java.net.InetAddress /* * Copyright (C) 2020 Daniel Wolf (Ch4t4r) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * 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, see . * * You can contact the developer at daniel.wolf@frostnerd.com. */ class ProxyQuicHandler( private val ownAddresses:List, upstreamAddresses: List, connectTimeout: Int, val queryCountCallback: (() -> Unit)? = null, val mapQueryRefusedToHostBlock:Boolean, engine: QuicEngine ):AbstractQuicDnsHandle(upstreamAddresses, connectTimeout, engine) { override val handlesSpecificRequests: Boolean = ProxyBypassHandler.knownSearchDomains.isNotEmpty() private val dummyUpstreamAddress = UpstreamAddress(AddressCreator.fromHostAddress("0.0.0.0"), 1) override fun shouldHandleRequest(dnsMessage: DnsMessage): Boolean { return if(dnsMessage.questions.size > 0) { val name = dnsMessage.question.name return !ProxyBypassHandler.knownSearchDomains.any { name.endsWith(it) } } else true } override fun modifyUpstreamResponse(dnsMessage: DnsMessage): DnsMessage { return if(dnsMessage.responseCode == DnsMessage.RESPONSE_CODE.REFUSED) { if(dnsMessage.questions.isNotEmpty()) { val answer = if(dnsMessage.question.type == Record.TYPE.A) { A("0.0.0.0") } else AAAA("::") dnsMessage.asBuilder().setResponseCode(DnsMessage.RESPONSE_CODE.NO_ERROR).addAnswer( Record( dnsMessage.question.name, dnsMessage.question.type, Record.CLASS.IN.value, 50L, answer ) ).build() } else dnsMessage } else dnsMessage } override fun remapDestination(destinationAddress: InetAddress, port: Int): UpstreamAddress { queryCountCallback?.invoke() return dummyUpstreamAddress } override fun shouldHandleDestination(destinationAddress: InetAddress, port: Int): Boolean = ownAddresses.any { it.equals(destinationAddress.hostAddress, true) } override fun shouldModifyUpstreamResponse(dnsMessage: DnsMessage): Boolean = mapQueryRefusedToHostBlock && dnsMessage.responseCode == DnsMessage.RESPONSE_CODE.REFUSED override fun informFailedRequest(request: FutureAnswer, failureReason: Throwable?) { } override fun name(): String { return "ProxyQuicHandler" } }