WIP: URI Parser and TLS
Signed-off-by: Vasiliy Doylov <nekocwd@mainlining.org>
This commit is contained in:
parent
e432987032
commit
95e1c233e7
7 changed files with 221 additions and 5 deletions
3
src/logic/error.vala
Normal file
3
src/logic/error.vala
Normal file
|
@ -0,0 +1,3 @@
|
|||
errordomain ParseError {
|
||||
NOT_IMPLEMENTED,
|
||||
}
|
|
@ -13,4 +13,6 @@ singularity_sources += [
|
|||
outbounds_sources,
|
||||
transports_sources,
|
||||
config_sources,
|
||||
'logic/tls.vala',
|
||||
'logic/error.vala',
|
||||
]
|
||||
|
|
|
@ -2,4 +2,5 @@ outbounds_sources = [
|
|||
'logic/outbounds/outbound.vala',
|
||||
'logic/outbounds/dial.vala',
|
||||
'logic/outbounds/trojan.vala',
|
||||
'logic/outbounds/vless.vala',
|
||||
]
|
||||
|
|
|
@ -17,8 +17,120 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
class Singularity.Outbound.Outbound : Object, Json.Serializable {
|
||||
// We can't use name `type` in vala
|
||||
public string type_name { get; construct set; default = ""; }
|
||||
public string tag { get; set; default = ""; }
|
||||
public string tag { get; set; default = "proxy"; }
|
||||
|
||||
public static Outbound parse_uri (string profile) throws UriError, ParseError {
|
||||
Uri uri = null;
|
||||
uri = Uri.parse (profile, UriFlags.HAS_PASSWORD | UriFlags.NON_DNS | UriFlags.PARSE_RELAXED);
|
||||
|
||||
var scheme = uri.get_scheme ();
|
||||
if (!(scheme == "trojan" || scheme == "vless"))// Stupid check for now
|
||||
throw new ParseError.NOT_IMPLEMENTED ("Protocol %s not implemented yet", scheme);
|
||||
|
||||
var host = uri.get_host ();
|
||||
var port = uri.get_port ();
|
||||
var user = uri.get_user ();
|
||||
var name = uri.get_fragment ();
|
||||
HashTable<string, string> params = null;
|
||||
|
||||
if (uri.get_query () != null) {
|
||||
params = Uri.parse_params (uri.get_query ());
|
||||
} else {
|
||||
params = new HashTable<string, string> (null, null);
|
||||
}
|
||||
|
||||
|
||||
Outbound outbound = null;
|
||||
TLS tls = null;
|
||||
Transport.Transport transport = null;
|
||||
tls = new TLS (){
|
||||
enabled = true,
|
||||
insecure = true,
|
||||
server_name = params["sni"]
|
||||
};
|
||||
|
||||
params["type"] = params["headerType"] ?? params["type"];
|
||||
switch (params["type"] ?? "none") {
|
||||
case "ws":
|
||||
var ws = new Transport.WebSocket () {
|
||||
path = params["path"],
|
||||
};
|
||||
ws.headers["Host"] = params["host"];
|
||||
transport = ws;
|
||||
break;
|
||||
case "grpc":
|
||||
transport = new Transport.GRPC () {
|
||||
service_name = params["serviceName"],
|
||||
};
|
||||
break;
|
||||
case "httpupgrade":
|
||||
transport = new Transport.HttpUpgrade () {
|
||||
path = params["path"],
|
||||
host = params["host"],
|
||||
};
|
||||
break;
|
||||
case "http":
|
||||
var t = new Transport.Http () {
|
||||
path = params["path"],
|
||||
method = "GET",
|
||||
};
|
||||
t.headers["Host"] = params["host"];
|
||||
transport = t;
|
||||
break;
|
||||
case "xhttp":
|
||||
throw new ParseError.NOT_IMPLEMENTED ("Transport %s not implemented yet", params["type"]);
|
||||
case "tcp":
|
||||
case "none":
|
||||
case "raw":
|
||||
break;
|
||||
default:
|
||||
warning ("Unknown transport type %s", params["type"]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (params["pbk"] != null) {
|
||||
tls.reality = new TLS.Reality ();
|
||||
tls.reality.enabled = true;
|
||||
tls.reality.public_key = params["pbk"] ?? "";
|
||||
tls.reality.short_id = params["sid"] ?? "";
|
||||
}
|
||||
|
||||
|
||||
if (params["fp"] != null || tls.reality != null) {
|
||||
tls.utls = new TLS.UTLS ();
|
||||
tls.utls.enabled = true;
|
||||
tls.utls.fingerprint = params["fp"];
|
||||
}
|
||||
|
||||
switch (scheme) {
|
||||
case "vless":
|
||||
outbound = new Vless () {
|
||||
uuid = user,
|
||||
server = host,
|
||||
server_port = port,
|
||||
transport = transport,
|
||||
tls = tls,
|
||||
packet_encoding = params["packetEncoding"]
|
||||
};
|
||||
break;
|
||||
case "trojan":
|
||||
outbound = new Trojan () {
|
||||
password = user,
|
||||
server = host,
|
||||
server_port = port,
|
||||
transport = transport,
|
||||
tls = tls,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
warning ("Unknown scheme %s", scheme);
|
||||
break;
|
||||
}
|
||||
|
||||
return outbound;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,10 +29,7 @@ class Singularity.Outbound.Trojan : Dial, Json.Serializable {
|
|||
public string network { get; set; default = null; }
|
||||
public Transport.Transport transport { get; set; default = null; }
|
||||
|
||||
/*
|
||||
* public TLS tls { get; set; default = null; }
|
||||
* TODO: Implement TLS
|
||||
*/
|
||||
public TLS tls { get; set; default = null; }
|
||||
/*
|
||||
* public Multiplex multiplex { get; set; default = null; }
|
||||
* TODO: Implement Multiplex
|
||||
|
@ -48,6 +45,9 @@ class Singularity.Outbound.Trojan : Dial, Json.Serializable {
|
|||
Utils.fix_type (ref node);
|
||||
Utils.fix_dash (ref node);
|
||||
}
|
||||
if (property_name == "tls" && tls != null) {
|
||||
Utils.fix_dash (ref node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
|
54
src/logic/outbounds/vless.vala
Normal file
54
src/logic/outbounds/vless.vala
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* vless.vala
|
||||
*
|
||||
* Copyright 2025 Vasiliy Doylov (NekoCWD) <nekocwd@mainlining.org>
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* Vless outbound.
|
||||
* DASH and TYPE FIX REQUIRED
|
||||
*/
|
||||
class Singularity.Outbound.Vless : Dial, Json.Serializable {
|
||||
public string server { get; set; default = null; }
|
||||
public int64 server_port { get; set; default = 1080; }
|
||||
public string uuid { get; set; default = null; }
|
||||
public string flow { get; set; default = null; }
|
||||
public string network { get; set; default = null; }
|
||||
public TLS tls { get; set; default = null; }
|
||||
public string packet_encoding { get; set; default = null; }
|
||||
public Transport.Transport transport { get; set; default = null; }
|
||||
/*
|
||||
* public Multiplex multiplex { get; set; default = null; }
|
||||
* TODO: Implement Multiplex
|
||||
*/
|
||||
|
||||
construct {
|
||||
type_name = "vless";
|
||||
}
|
||||
|
||||
public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
|
||||
var node = default_serialize_property (property_name, value, pspec);
|
||||
if (property_name == "transport" && transport != null) {
|
||||
Utils.fix_type (ref node);
|
||||
Utils.fix_dash (ref node);
|
||||
}
|
||||
if (property_name == "tls" && tls != null) {
|
||||
Utils.fix_dash (ref node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
44
src/logic/tls.vala
Normal file
44
src/logic/tls.vala
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* tls.vala
|
||||
*
|
||||
* Copyright 2025 Vasiliy Doylov (NekoCWD) <nekocwd@mainlining.org>
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
class Singularity.TLS : Object, Json.Serializable {
|
||||
public class Reality : Object, Json.Serializable {
|
||||
public bool enabled { get; set; default = false; }
|
||||
public string public_key { get; set; default = null; }
|
||||
public string short_id { get; set; default = null; }
|
||||
}
|
||||
|
||||
public class UTLS : Object, Json.Serializable {
|
||||
public bool enabled { get; set; }
|
||||
public string fingerprint { get; set; default = ""; }
|
||||
}
|
||||
public bool enabled { get; construct set; }
|
||||
public bool insecure { get; construct set; }
|
||||
public string server_name { get; set; default = null; }
|
||||
public Reality reality { get; set; default = null; }
|
||||
public UTLS utls { get; set; default = null; }
|
||||
|
||||
public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
|
||||
var node = default_serialize_property (property_name, value, pspec);
|
||||
if (property_name == "reality" && reality != null) {
|
||||
Utils.fix_dash (ref node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue