arblant
FoxyVPN-MultiAcc / app / src / main / java / com / vauth / foxyvpn / vpn / tun / HevSocks5TunnelConfig.kt
HevSocks5TunnelConfig.kt100 lines · 3.1 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
package com.vauth.foxyvpn.vpn.tun

import android.content.Context
import java.io.File

object HevSocks5TunnelConfig {
    const val FILE_NAME = "hev-socks5-tunnel.yaml"

    const val TUN_ADDRESS = "10.8.0.2"

    const val TUN_MTU = 8500

    private const val TUNNEL_ICMP_MODE = "reply"

    const val MAPDNS_ADDRESS = "198.18.0.2"
    private const val MAPDNS_PORT = 53

    private const val MAPDNS_NETWORK = "100.64.0.0"
    private const val MAPDNS_NETMASK = "255.192.0.0"

    private const val MAPDNS_NETWORK_BITS = 100L shl 24 or (64L shl 16)
    private const val MAPDNS_NETMASK_BITS = 255L shl 24 or (192L shl 16)

    private const val MAPDNS_CACHE_SIZE = 10_000

    private const val CONNECT_TIMEOUT_MS = 20_000

    private const val TCP_READ_WRITE_TIMEOUT_MS = 300_000

    private const val UDP_READ_WRITE_TIMEOUT_MS = 60_000

    private const val TCP_BUFFER_SIZE_BYTES = 65_536

    private const val TASK_STACK_SIZE_BYTES = 86_016

    private const val UDP_RECV_BUFFER_SIZE_BYTES = 524_288

    private const val UDP_COPY_BUFFER_NUMS = 16

    private const val MAX_SESSION_COUNT = 0

    private const val LIMIT_NOFILE = 65_535

    fun isFakeDnsAddress(host: String): Boolean {
        val parts = host.split('.')
        if (parts.size != 4) return false
        var packed = 0L
        for (part in parts) {
            if (part.isEmpty() || part.length > 3) return false
            val octet = part.toIntOrNull() ?: return false
            if (octet !in 0..255) return false
            packed = (packed shl 8) or octet.toLong()
        }
        return (packed and MAPDNS_NETMASK_BITS) == MAPDNS_NETWORK_BITS
    }

    fun write(context: Context, socksPort: Int, useMapDns: Boolean = true): String {

        val mapdnsBlock = if (useMapDns) {
            """
            mapdns:
              address: '$MAPDNS_ADDRESS'
              port: $MAPDNS_PORT
              network: '$MAPDNS_NETWORK'
              netmask: '$MAPDNS_NETMASK'
              cache-size: $MAPDNS_CACHE_SIZE
            """.trimIndent() + "\n"
        } else {
            ""
        }

        val yaml = """
            tunnel:
              mtu: $TUN_MTU
              ipv4: '$TUN_ADDRESS'
              icmp: '$TUNNEL_ICMP_MODE'
            socks5:
              port: $socksPort
              address: '127.0.0.1'
              udp: 'udp'
            """.trimIndent() + "\n" + mapdnsBlock +
            """
            misc:
              task-stack-size: $TASK_STACK_SIZE_BYTES
              connect-timeout: $CONNECT_TIMEOUT_MS
              tcp-read-write-timeout: $TCP_READ_WRITE_TIMEOUT_MS
              udp-read-write-timeout: $UDP_READ_WRITE_TIMEOUT_MS
              tcp-buffer-size: $TCP_BUFFER_SIZE_BYTES
              udp-recv-buffer-size: $UDP_RECV_BUFFER_SIZE_BYTES
              udp-copy-buffer-nums: $UDP_COPY_BUFFER_NUMS
              max-session-count: $MAX_SESSION_COUNT
              limit-nofile: $LIMIT_NOFILE
              log-level: 'warn'
            """.trimIndent() + "\n"

        val file = File(context.filesDir, FILE_NAME)
        file.writeText(yaml)
        return file.absolutePath
    }
}