From 059111f02049da2f01fb91e2067a325555e9d406 Mon Sep 17 00:00:00 2001 From: Vasiliy Doylov Date: Mon, 23 Jun 2025 15:22:31 +0300 Subject: [PATCH] Outbounds: Shadowsocks: initial implementation Signed-off-by: Vasiliy Doylov --- src/logic/error.vala | 1 + src/logic/outbounds/meson.build | 1 + src/logic/outbounds/outbound.vala | 16 +++++++++-- src/logic/outbounds/shadowsocks.vala | 43 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 src/logic/outbounds/shadowsocks.vala diff --git a/src/logic/error.vala b/src/logic/error.vala index 1f32898..828b73d 100644 --- a/src/logic/error.vala +++ b/src/logic/error.vala @@ -1,3 +1,4 @@ errordomain ParseError { NOT_IMPLEMENTED, + WRONG_FORMATING, } diff --git a/src/logic/outbounds/meson.build b/src/logic/outbounds/meson.build index 6a3a140..ca7c986 100644 --- a/src/logic/outbounds/meson.build +++ b/src/logic/outbounds/meson.build @@ -3,4 +3,5 @@ outbounds_sources = [ 'logic/outbounds/dial.vala', 'logic/outbounds/trojan.vala', 'logic/outbounds/vless.vala', + 'logic/outbounds/shadowsocks.vala', ] diff --git a/src/logic/outbounds/outbound.vala b/src/logic/outbounds/outbound.vala index 8d90119..8806f81 100644 --- a/src/logic/outbounds/outbound.vala +++ b/src/logic/outbounds/outbound.vala @@ -29,8 +29,6 @@ class Singularity.Outbound.Outbound : Object, Json.Serializable { 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 (); @@ -127,8 +125,20 @@ class Singularity.Outbound.Outbound : Object, Json.Serializable { tls = tls, }; break; + case "ss": + string creds = (string) Base64.decode (user); + var temp = creds.split (":", 2); + if (temp.length != 2) + throw new ParseError.WRONG_FORMATING ("Shadowsocks formating fail. Failed to parse creditants ?%s?", creds); + outbound = new ShadowSocks () { + method = temp[0], + password = temp[1], + server = host, + server_port = port, + }; + break; default: - warning ("Unknown scheme %s", scheme); + throw new ParseError.NOT_IMPLEMENTED ("Protocol %s not implemented yet", scheme); break; } outbound.name = name; diff --git a/src/logic/outbounds/shadowsocks.vala b/src/logic/outbounds/shadowsocks.vala new file mode 100644 index 0000000..cf4af61 --- /dev/null +++ b/src/logic/outbounds/shadowsocks.vala @@ -0,0 +1,43 @@ +/* shadowsocks.vala + * + * Copyright 2025 Vasiliy Doylov (NekoCWD) + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/* + * ShadowSocks outbound. + * DASH and TYPE FIX REQUIRED + */ +class Singularity.Outbound.ShadowSocks : Dial, Json.Serializable { + public string server { get; set; default = null; } + public int64 server_port { get; set; default = 1080; } + public string method { get; set; default = null; } + public string password { get; set; default = null; } + public string plugin { get; set; default = null; } + public string plugin_opts { get; set; default = null; } + public string network { get; set; default = null; } + public bool udp_over_tcp { get; set; default = false; } + + /* + * public Multiplex multiplex { get; set; default = null; } + * TODO: Implement Multiplex + */ + + construct { + type_name = "shadowsocks"; + } +}