Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support to new version vmess link #516

Merged
merged 3 commits into from
Jul 25, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.v2ray.ang.util

import android.graphics.Bitmap
import android.text.TextUtils
import android.util.Log
import com.google.gson.Gson
import com.v2ray.ang.AngApplication
import com.v2ray.ang.AppConfig
Expand All @@ -16,12 +15,9 @@ import com.v2ray.ang.AppConfig.VMESS_PROTOCOL
import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.dto.VmessQRCode
import com.v2ray.ang.extension.defaultDPreference
import org.jetbrains.anko.toast
import java.net.URI
import java.net.URLDecoder
import java.util.*
import java.net.*
import java.math.BigInteger

object AngConfigManager {
private lateinit var app: AngApplication
Expand Down Expand Up @@ -256,7 +252,11 @@ object AngConfigManager {
if (server.startsWith(VMESS_PROTOCOL)) {

val indexSplit = server.indexOf("?")
if (indexSplit > 0) {
val newVmess = tryParseNewVmess(server)
if (newVmess != null) {
vmess = newVmess
vmess.subid = subid
} else if (indexSplit > 0) {
vmess = ResolveVmess4Kitsunebi(server)
} else {

Expand Down Expand Up @@ -378,6 +378,60 @@ object AngConfigManager {
return 0
}

fun tryParseNewVmess(uri: String): AngConfig.VmessBean? {
return runCatching {
val uri = URI(uri)
check(uri.scheme == "vmess")
val (_, protocol, tlsStr, uuid, alterId) =
Regex("(tcp|http|ws|kcp|quic)(\\+tls)?:([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})-([0-9]+)")
.matchEntire(uri.userInfo)?.groupValues
?: error("parse user info fail.")
val tls = tlsStr.isNotBlank()
val queryParam = uri.rawQuery.split("&")
.map { it.split("=").let { (k, v) -> k to URLDecoder.decode(v, "utf-8")!! } }
.toMap()
val vmess = AngConfig.VmessBean()
vmess.address = uri.host
vmess.port = uri.port
vmess.guid = uuid
vmess.alterId = alterId.toInt()
vmess.streamSecurity = if (tls) "tls" else ""
vmess.remarks = uri.fragment

// TODO: allowInsecure not supported

when (protocol) {
"tcp" -> {
vmess.network = "tcp"
vmess.headerType = queryParam["type"] ?: "none"
vmess.requestHost = queryParam["host"] ?: ""
}
"http" -> {
vmess.network = "h2"
vmess.path = queryParam["path"]?.takeIf { it.trim() != "/" } ?: ""
vmess.requestHost = queryParam["host"]?.split("|")?.get(0) ?: ""
}
"ws" -> {
vmess.network = "ws"
vmess.path = queryParam["path"]?.takeIf { it.trim() != "/" } ?: ""
vmess.requestHost = queryParam["host"]?.split("|")?.get(0) ?: ""
}
"kcp" -> {
vmess.network = "kcp"
vmess.headerType = queryParam["type"] ?: "none"
vmess.path = queryParam["seed"] ?: ""
}
"quic" -> {
vmess.network = "quic"
vmess.security = queryParam["security"] ?: "none"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently quic security should be put as vmess.requestHost.
This brings a question.. how does the new format carry vmess.securiity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现阶段,vmess的security取消,默认auto

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the new format finalised? If not I'd suggest we should add security.

Copy link
Contributor Author

@iseki0 iseki0 Jul 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until now, looks there is no plan for it. And I don't think we should add this feature. Because it can auto negotiation.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no matter which encryption has been choosed, client can always connect to server, so I don't think security option is necessary.

Copy link

@ghost ghost Jul 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello.
As far as I could tell, VMess could perform auto-negotiation and they suggest setting it to auto. So this is not required anymore.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it is not mandatory but it would be a convenient setting. "none" is a common choice with tls. Also user would expect to transfer basic settings with export-and-then-import. For instance..
#356
dalao @RPRX was surprised by it :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That only happens when using the old standard. It's your parser's fault not to work correctly.
The new standard obsoletes this setting, so they are irrelevant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version scheme has removed the paramter. I think it's viable to user, because of we don't use base64. So that user will understand what's happeded.

vmess.headerType = queryParam["type"] ?: "none"
vmess.path = queryParam["key"] ?: ""
}
}
vmess
}.getOrNull()
}

private fun ResolveVmess4Kitsunebi(server: String): AngConfig.VmessBean {

val vmess = AngConfig.VmessBean()
Expand Down