Support kcptun.

This commit is contained in:
Charlie Qiu
2017-01-11 20:49:37 +08:00
parent 6d4cbedcfa
commit f7cca35948
8 changed files with 196 additions and 23 deletions

View File

@ -11,11 +11,11 @@ import Foundation
class KcptunProfile: NSObject {
var mode: String = "normal"
var mode: String = "fast"
var key: String = "it's a secrect"
var crypt: String = "aes"
var nocomp: Bool = true
var nocomp: Bool = false
var datashard: uint = 10
var parityshard: uint = 3
@ -57,7 +57,7 @@ class KcptunProfile: NSObject {
func toJsonConfig() -> [String: AnyObject] {
let defaults = UserDefaults.standard
let localHost = defaults.string(forKey: "Kcptun.LocalHost")
let localHost = defaults.string(forKey: "Kcptun.LocalHost")! as String
let localPort = defaults.integer(forKey: "Kcptun.LocalPort")
let conf: [String: AnyObject] = [

View File

@ -15,6 +15,7 @@ let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NG/"
let LAUNCH_AGENT_DIR = "/Library/LaunchAgents/"
let LAUNCH_AGENT_CONF_SSLOCAL_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist"
let LAUNCH_AGENT_CONF_PRIVOXY_NAME = "com.qiuyuzhou.shadowsocksX-NG.http.plist"
let LAUNCH_AGENT_CONF_KCPTUN_NAME = "com.qiuyuzhou.shadowsocksX-NG.kcptun.plist"
func getFileSHA1Sum(_ filepath: String) -> String {
@ -129,23 +130,6 @@ func InstallSSLocal() {
}
}
func InstallKcptunClient() {
let fileMgr = FileManager.default
let homeDir = NSHomeDirectory()
let appSupportDir = homeDir+APP_SUPPORT_DIR
if !fileMgr.fileExists(atPath: appSupportDir + "kcptun_\(KCPTUN_CLIENT_VERSION)/kcptun_client") {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "install_kcptun", ofType: "sh")
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Install kcptun succeeded.")
} else {
NSLog("Install kcptun failed.")
}
}
}
func writeSSLocalConfFile(_ conf:[String:AnyObject]) -> Bool {
do {
let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "ss-local-config.json"
@ -193,8 +177,10 @@ func SyncSSLocal() {
}
SyncPac()
SyncPrivoxy()
SyncKcptun()
}
// --------------------------------------------------------------------------------
// MARK: privoxy
func generatePrivoxyLauchAgentPlist() -> Bool {
@ -339,3 +325,144 @@ func SyncPrivoxy() {
}
}
}
// --------------------------------------------------------------------------------
// kcptun
func generateKcptunLauchAgentPlist() -> Bool {
let sslocalPath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun_client"
let logFilePath = NSHomeDirectory() + "/Library/Logs/kcptun_client.log"
let launchAgentDirPath = NSHomeDirectory() + LAUNCH_AGENT_DIR
let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_KCPTUN_NAME
// Ensure launch agent directory is existed.
let fileMgr = FileManager.default
if !fileMgr.fileExists(atPath: launchAgentDirPath) {
try! fileMgr.createDirectory(atPath: launchAgentDirPath, withIntermediateDirectories: true, attributes: nil)
}
let oldSha1Sum = getFileSHA1Sum(plistFilepath)
let arguments = [sslocalPath, "-c", "kcptun-config.json"]
// For a complete listing of the keys, see the launchd.plist manual page.
let dict: NSMutableDictionary = [
"Label": "com.qiuyuzhou.shadowsocksX-NG.kcptun",
"WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR,
"KeepAlive": true,
"StandardOutPath": logFilePath,
"StandardErrorPath": logFilePath,
"ProgramArguments": arguments,
"EnvironmentVariables": ["DYLD_LIBRARY_PATH": NSHomeDirectory() + APP_SUPPORT_DIR]
]
dict.write(toFile: plistFilepath, atomically: true)
let Sha1Sum = getFileSHA1Sum(plistFilepath)
if oldSha1Sum != Sha1Sum {
return true
} else {
return false
}
}
func InstallKcptunClient() {
let fileMgr = FileManager.default
let homeDir = NSHomeDirectory()
let appSupportDir = homeDir+APP_SUPPORT_DIR
if !fileMgr.fileExists(atPath: appSupportDir + "kcptun_\(KCPTUN_CLIENT_VERSION)/kcptun_client") {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "install_kcptun", ofType: "sh")
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Install kcptun succeeded.")
} else {
NSLog("Install kcptun failed.")
}
}
}
func writeKcptunConfFile(_ conf:[String:AnyObject]) -> Bool {
do {
let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun-config.json"
let data: Data = try JSONSerialization.data(withJSONObject: conf, options: .prettyPrinted)
let oldSum = getFileSHA1Sum(filepath)
try data.write(to: URL(fileURLWithPath: filepath), options: .atomic)
let newSum = getFileSHA1Sum(filepath)
if oldSum == newSum {
return false
}
return true
} catch {
NSLog("Write kcptun config file failed.")
}
return false
}
func removeKcptunConfFile() {
do {
let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun-config.json"
try FileManager.default.removeItem(atPath: filepath)
} catch {
}
}
func ReloadConfKcptun() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "reload_conf_kcptun.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Start kcptun succeeded.")
} else {
NSLog("Start kcptun failed.")
}
}
func StartKcptun() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "start_kcptun.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Start kcptun succeeded.")
} else {
NSLog("Start kcptun failed.")
}
}
func StopKcptun() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "stop_kcptun.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Stop kcptun succeeded.")
} else {
NSLog("Stop kcptun failed.")
}
}
func SyncKcptun() {
var changed: Bool = false
changed = changed || generateKcptunLauchAgentPlist()
let mgr = ServerProfileManager.instance
if let profile = mgr.getActiveProfile() {
if profile.enabledKcptun {
changed = changed || writeKcptunConfFile(profile.toKcptunJsonConfig())
let on = UserDefaults.standard.bool(forKey: "ShadowsocksOn")
if on {
StartKcptun()
ReloadConfKcptun()
return
}
}
}
StopKcptun()
removeKcptunConfFile()
}

View File

@ -90,6 +90,7 @@ class PreferencesWindowController: NSWindowController
"normal",
"fast",
"fast2",
"fast3",
])
profilesTableView.reloadData()

View File

@ -107,6 +107,9 @@ class ServerProfile: NSObject, NSCopying {
if let ota = data["OTA"] {
profile.ota = ota as! Bool
}
if let enabledKcptun = data["EnabledKcptun"] {
profile.enabledKcptun = enabledKcptun as! Bool
}
if let kcptunData = data["KcptunProfile"] {
profile.kcptunProfile = KcptunProfile.fromDictionary(kcptunData as! [String:Any?])
}
@ -132,7 +135,7 @@ class ServerProfile: NSObject, NSCopying {
d["Password"] = password as AnyObject?
d["Remark"] = remark as AnyObject?
d["OTA"] = ota as AnyObject?
d["EnabledKcptun"] = enabledKcptun as AnyObject
d["EnabledKcptun"] = NSNumber(value: enabledKcptun)
d["KcptunProfile"] = kcptunProfile.toDictionary() as AnyObject
return d
}

View File

@ -0,0 +1,10 @@
#!/bin/sh
# reload_conf_kcptun.sh
# ShadowsocksX-NG
#
# Created by 邱宇舟 on 2017/1/11.
# Copyright © 2017年 qiuyuzhou. All rights reserved.
launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist"
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist"

View File

@ -0,0 +1,9 @@
#!/bin/sh
# start_kcptun.sh
# ShadowsocksX-NG
#
# Created by 邱宇舟 on 2017/1/11.
# Copyright © 2017年 qiuyuzhou. All rights reserved.
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist"

9
ShadowsocksX-NG/stop_kcptun.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
# stop_kcptun.sh
# ShadowsocksX-NG
#
# Created by 邱宇舟 on 2017/1/11.
# Copyright © 2017年 qiuyuzhou. All rights reserved.
launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist"