Я пытаюсь добавить DNS через HTTPS в приложение VPN. для справки по проекту VPN-Example. В этом проекте я пытаюсь добавить только DNS-запросы для передачи DNS через HTTPS (DoH) вместо простых DNS-запросов. Я могу сделать это и получить ответ для DoH. Проблема, с которой я в конечном итоге сталкиваюсь, заключается в том, что когда я обновляю пакет, я что-то упускаю или делаю что-то неправильно, что приводит к ошибкам расчета контрольной суммы. Я новичок в работе с сетями и не могу устранить эту проблему.
В методе VPN VPNRunnable Run я добавил следующий код, чтобы найти пакеты DNS-запросов, а затем разрешить DNS с помощью DoH.
data class Result(
@SerializedName("Status") val status: Int,
@SerializedName("TC") val tc: Boolean?,
@SerializedName("RD") val rd: Boolean?,
@SerializedName("RA") val ra: Boolean?,
@SerializedName("AD") val ad: Boolean?,
@SerializedName("CD") val cd: Boolean?,
@SerializedName("Question") val question: List?,
@SerializedName("Answer") val answer: List?,
@SerializedName("Authority") val authority: List?,
@SerializedName("edns_client_subnet") val ednsClientSubnet: String?
)
data class Question(
@SerializedName("name") val name: String,
@SerializedName("type") val type: Int
)
data class Answer(
@SerializedName("name") val name: String,
@SerializedName("type") val type: Int,
@SerializedName("TTL") val ttl: Int,
@SerializedName("Expires") val expires: String,
@SerializedName("data") val data: String
)
data class Authority(
@SerializedName("name") val name: String,
@SerializedName("type") val type: Int,
@SerializedName("TTL") val ttl: Int,
@SerializedName("Expires") val expires: String,
@SerializedName("data") val data: String
)
// Perform a synchronous DNS lookup
fun lookup(domain: String, type: Int): Result? {
for (resolver in resolvers) {
val url = "${resolver.url}?name=$domain&type=$type"
val request = Request.Builder()
.url(url)
.apply {
if (resolver.method == Method.POST) post(RequestBody.create(null, ByteArray(0)))
}
.addHeader("Content-Type", "application/dns-json")
.build()
try {
val response = client.newCall(request).execute()
if (response.isSuccessful) {
response.body?.let { responseBody ->
return gson.fromJson(responseBody.string(), Result::class.java)
}
}
} catch (e: IOException) {
// Log or handle exception
e.printStackTrace()
}
}
return null
}
Проблема начинается после того, как я пытаюсь использовать этот код для обновления пакета и отправки его обратно на устройство. Код обновления моего пакета после того, как я передал его. Результат ответа DNS:
Я пытаюсь добавить DNS через HTTPS в приложение VPN. для справки по проекту VPN-Example. В этом проекте я пытаюсь добавить только DNS-запросы для передачи DNS через HTTPS (DoH) вместо простых DNS-запросов. Я могу сделать это и получить ответ для DoH. Проблема, с которой я в конечном итоге сталкиваюсь, заключается в том, что когда я обновляю пакет, я что-то упускаю или делаю что-то неправильно, что приводит к ошибкам расчета контрольной суммы. Я новичок в работе с сетями и не могу устранить эту проблему. В методе VPN VPNRunnable Run я добавил следующий код, чтобы найти пакеты DNS-запросов, а затем разрешить DNS с помощью DoH. [code]private static class VPNRunnable implements Runnable { //... @Override public void run() { //... if (packet.isDNSQuery()) { String domain = packet.getDomainName(); Result resolvedResult = resolveDomainOverDoH(domain); Log.i(TAG, "DNS Packet Before: " + packet.toString()); if (resolvedResult != null && !Objects.requireNonNull(resolvedResult.getAnswer()).isEmpty()) { Packet dnsResponsePacket = buildDNSResponse(packet, resolvedResult); if (dnsResponsePacket != null) { Log.i(TAG, "DNS Packet After: " + dnsResponsePacket.toString());
networkToDeviceQueue.offer(dnsResponsePacket.toByteBuffer()); Log.i(TAG, "DNS response created for domain: " + domain); } else { Log.e(TAG, "Failed to create DNS response for domain: " + domain); } } else { Log.e(TAG, "Failed to resolve DNS query for domain: " + domain); } } else if (packet.isUDP()) { Log.i(TAG, "read udp" + readBytes); // Logs UDP read operation deviceToNetworkUDPQueue.offer(packet); // Adds packet to UDP queue } //... [/code] В приведенном выше коде я могу получить правильный ответ DNS через HTTPS через [code] data class Result( @SerializedName("Status") val status: Int, @SerializedName("TC") val tc: Boolean?, @SerializedName("RD") val rd: Boolean?, @SerializedName("RA") val ra: Boolean?, @SerializedName("AD") val ad: Boolean?, @SerializedName("CD") val cd: Boolean?, @SerializedName("Question") val question: List?, @SerializedName("Answer") val answer: List?, @SerializedName("Authority") val authority: List?, @SerializedName("edns_client_subnet") val ednsClientSubnet: String? ) data class Question( @SerializedName("name") val name: String, @SerializedName("type") val type: Int )
data class Answer( @SerializedName("name") val name: String, @SerializedName("type") val type: Int, @SerializedName("TTL") val ttl: Int, @SerializedName("Expires") val expires: String, @SerializedName("data") val data: String )
data class Authority( @SerializedName("name") val name: String, @SerializedName("type") val type: Int, @SerializedName("TTL") val ttl: Int, @SerializedName("Expires") val expires: String, @SerializedName("data") val data: String ) [/code] и код поиска DNS через HTTPs: [code] // Perform a synchronous DNS lookup fun lookup(domain: String, type: Int): Result? { for (resolver in resolvers) { val url = "${resolver.url}?name=$domain&type=$type" val request = Request.Builder() .url(url) .apply { if (resolver.method == Method.POST) post(RequestBody.create(null, ByteArray(0))) } .addHeader("Content-Type", "application/dns-json") .build()
try { val response = client.newCall(request).execute() if (response.isSuccessful) { response.body?.let { responseBody -> return gson.fromJson(responseBody.string(), Result::class.java) } } } catch (e: IOException) { // Log or handle exception e.printStackTrace() } } return null } [/code] Проблема начинается после того, как я пытаюсь использовать этот код для обновления пакета и отправки его обратно на устройство. Код обновления моего пакета после того, как я передал его. Результат ответа DNS: [code] public static Packet buildDNSResponse(Packet queryPacket, Result responseInfo) { try { // Create a new response packet based on the query packet ByteBuffer responseBuffer = ByteBuffer.allocate(1500); // Allocate a large enough buffer responseBuffer.put(queryPacket.backingBuffer.array(), 0, queryPacket.backingBuffer.limit()); responseBuffer.clear();
Packet responsePacket = new Packet(responseBuffer);
// Swap source and destination IP addresses byte[] tempIp = responsePacket.ip4Header.sourceAddress.getAddress(); responsePacket.ip4Header.sourceAddress = responsePacket.ip4Header.destinationAddress; responsePacket.ip4Header.destinationAddress = InetAddress.getByAddress(tempIp);
// Swap source and destination ports int tempPort = responsePacket.udpHeader.sourcePort; responsePacket.udpHeader.sourcePort = responsePacket.udpHeader.destinationPort; responsePacket.udpHeader.destinationPort = tempPort;
// Modify DNS header int dnsStart = Packet.IP4_HEADER_SIZE + Packet.UDP_HEADER_SIZE; responsePacket.backingBuffer.putShort(dnsStart + 2, (short) 0x8180); // DNS flags: Standard query response, No error responsePacket.backingBuffer.putShort(dnsStart + 6, (short) responseInfo.getAnswer().size()); // Answer RRs
// Find the end of the question section int questionEnd = findQuestionEnd(responsePacket.backingBuffer, dnsStart);
// Add answer section int answerStart = questionEnd; for (Answer answer : responseInfo.getAnswer()) { answerStart = addAnswerRecord(responsePacket.backingBuffer, answerStart, answer); }
// Adjust the limit of the backing buffer responsePacket.backingBuffer.limit(totalLength);
return responsePacket; } catch (Exception e) { Log.e(TAG, "Error building DNS response", e); return null; } }
private static int findQuestionEnd(ByteBuffer buffer, int dnsStart) { int position = dnsStart + 12; // Start after DNS header while (buffer.get(position) != 0) { position += buffer.get(position) + 1; } return position + 5; // +1 for null byte, +4 for QTYPE and QCLASS }
private static int addAnswerRecord(ByteBuffer buffer, int start, Answer answer) throws UnknownHostException { buffer.putShort(start, (short) 0xC00C); // Pointer to question name buffer.putShort(start + 2, (short) answer.getType()); buffer.putShort(start + 4, (short) 1); // CLASS IN buffer.putInt(start + 6, answer.getTtl());
private static byte[] parseRDATA(int type, String data) throws UnknownHostException { switch (type) { case 1: // A record return InetAddress.getByName(data).getAddress(); case 28: // AAAA record return InetAddress.getByName(data).getAddress(); case 5: // CNAME record case 16: // TXT record default: return data.getBytes(); } } [/code] Поэтому полученный пакет от buildDNSResponse() неверен, и я не уверен, в чем заключается проблема.
Я пытаюсь добавить DNS через HTTPS в приложение VPN. для справки по проекту VPN-Example. В этом проекте я пытаюсь добавить только DNS-запросы для передачи DNS через HTTPS (DoH) вместо простых DNS-запросов. Я могу сделать это и получить ответ для...
В настоящее время получает приведенную ниже ошибку из моего кода (я пытаюсь вызвать прогноз из моей пользовательской конечной точки Vertex AI). Не уверен, что происходит. Ниже приведены кое -что, что я пытался сделать:
Я пытаюсь назвать прогноз из моей пользовательской конечной точки Vertex AI, но я получаю ошибку ниже. Не уверен, что происходит. Ниже приведены некоторые вещи, которые я пробовал сделать:
Идентификатор конечной точки двойной проверки и номер...
Я пытаюсь назвать прогноз из моей пользовательской конечной точки Vertex AI, но я получаю ошибку ниже. Не уверен, что происходит. Ниже приведены некоторые вещи, которые я пробовал сделать:
Идентификатор конечной точки двойной проверки и номер...
Я пытаюсь назвать прогноз из моей пользовательской конечной точки Vertex AI, но я получаю ошибку ниже. Не уверен, что происходит. Ниже приведены некоторые вещи, которые я пробовал сделать:
Идентификатор конечной точки двойной проверки и номер...