Skip to content

Commit

Permalink
new: add tunnel service
Browse files Browse the repository at this point in the history
  • Loading branch information
hiddify-com committed Jan 29, 2024
1 parent 25d5b8a commit 5fa2822
Show file tree
Hide file tree
Showing 28 changed files with 352 additions and 219 deletions.
74 changes: 74 additions & 0 deletions admin_service/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package admin_service

import (
"log"

"github.com/hiddify/libcore/global"
"github.com/kardianos/service"
)

var logger service.Logger

type hiddifyNext struct{}

var port int = 18020

func (m *hiddifyNext) Start(s service.Service) error {
go m.run()
return nil
}
func (m *hiddifyNext) Stop(s service.Service) error {
err := global.StopService()
if err != nil {
return err
}
// Stop should not block. Return with a few seconds.
// <-time.After(time.Second * 1)
return nil
}
func (m *hiddifyNext) run() {
StartWebServer(port, false)
}

func StartService(goArg string) {
svcConfig := &service.Config{
Name: "Hiddify Tunnel Service",
DisplayName: "Hiddify Tunnel Service",
Description: "This is a bridge for tunnel",
}

prg := &hiddifyNext{}
s, err := service.New(prg, svcConfig)
if err != nil {
log.Fatal(err)
}
if len(goArg) > 0 {
if goArg == "uninstall" {
err = s.Stop()
if err != nil {
log.Fatal(err)
}
}
err = service.Control(s, goArg)
if err != nil {
log.Fatal(err)
}
if goArg == "install" {
err = s.Start()
if err != nil {
log.Fatal(err)
}
}

return
}

logger, err = s.Logger(nil)
if err != nil {
log.Fatal(err)
}
err = s.Run()
if err != nil {
logger.Error(err)
}
}
79 changes: 39 additions & 40 deletions web/web.go → admin_service/web.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package web
package admin_service

import (
"crypto/tls"
"fmt"
"github.com/hiddify/libcore/global"
"github.com/hiddify/libcore/utils"
"net/http"
"strconv"

"github.com/hiddify/libcore/global"
"github.com/hiddify/libcore/utils"
)

const (
Expand All @@ -16,65 +17,61 @@ const (
clientKeyPath = "cert/client-key.pem"
)

func StartWebServer(Port int) {
func StartWebServer(Port int, TLS bool) {
http.HandleFunc("/start", startHandler)
http.HandleFunc("/stop", StopHandler)
server := &http.Server{
Addr: "127.0.0.1:" + fmt.Sprintf("%d", Port),
TLSConfig: &tls.Config{
}
var err error
if TLS {
server.TLSConfig = &tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{utils.LoadCertificate(serverCertPath, serverKeyPath)},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: utils.LoadClientCA(clientCertPath),
},
}
err = server.ListenAndServeTLS(serverCertPath, serverKeyPath)
} else {
err = server.ListenAndServe()
}
err := server.ListenAndServeTLS(serverCertPath, serverKeyPath)
if err != nil {
panic("Error: " + err.Error())
}
}
func startHandler(w http.ResponseWriter, r *http.Request) {
queryParams := r.URL.Query()
Ipv6 := queryParams.Get("Ipv6")
ServerPort := queryParams.Get("ServerPort")
StrictRoute := queryParams.Get("StrictRoute")
EndpointIndependentNat := queryParams.Get("EndpointIndependentNat")
TheStack := queryParams.Get("Stack")

ipv6, err := strconv.ParseBool(Ipv6)
ipv6, err := strconv.ParseBool(queryParams.Get("Ipv6"))
if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
fmt.Printf("ipv6 Error: %v ==>using false\n", err)
ipv6 = false
}
serverPort, err := strconv.Atoi(ServerPort)
serverPort, err := strconv.Atoi(queryParams.Get("ServerPort"))
if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
fmt.Printf("serverPort Error: %v ==>using 2334\n", err)
serverPort = 2334
}
strictRoute, err := strconv.ParseBool(StrictRoute)
strictRoute, err := strconv.ParseBool(queryParams.Get("StrictRoute"))
if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
fmt.Printf("strictRoute Error: %v ==>using false\n", err)
strictRoute = false
}
endpointIndependentNat, err := strconv.ParseBool(EndpointIndependentNat)
endpointIndependentNat, err := strconv.ParseBool(queryParams.Get("EndpointIndependentNat"))
if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
}
theStack := GetStack(TheStack)
if theStack == "UNKNOWN" {
http.Error(w, fmt.Sprintf("Error: %s", "Stack is not valid"), http.StatusBadRequest)
return
fmt.Printf("endpointIndependentNat Error: %v ==>using false\n", err)
endpointIndependentNat = false
}
theStack := GetStack(queryParams.Get("Stack"))

parameters := global.Parameters{Ipv6: ipv6, ServerPort: serverPort, StrictRoute: strictRoute, EndpointIndependentNat: endpointIndependentNat, Stack: GetStack(TheStack)}
parameters := global.Parameters{Ipv6: ipv6, ServerPort: serverPort, StrictRoute: strictRoute, EndpointIndependentNat: endpointIndependentNat, Stack: theStack}

err = global.WriteParameters(parameters.Ipv6, parameters.ServerPort, parameters.StrictRoute, parameters.EndpointIndependentNat, GetStringFromStack(parameters.Stack))
if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
}
err = global.SetupC("./", "./work", "./tmp", false)
err = global.SetupC("./", "./", "./tmp", false)

if err != nil {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
Expand All @@ -84,7 +81,7 @@ func startHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("Error: %v", err), http.StatusBadRequest)
return
}

http.Error(w, fmt.Sprintf("Ok"), http.StatusOK)
}
func StopHandler(w http.ResponseWriter, r *http.Request) {
err := global.StopService()
Expand All @@ -94,29 +91,31 @@ func StopHandler(w http.ResponseWriter, r *http.Request) {
}
}
func GetStack(stack string) global.Stack {

switch stack {
case "system":
return global.System
case "gVisor":
case "gvisor":
return global.GVisor
case "mixed":
return global.Mixed
case "LWIP":
return global.LWIP
// case "LWIP":
// return global.LWIP
default:
return "UNKNOWN"
fmt.Printf("Stack Error: %s is not valid==> using GVisor\n", stack)
return global.GVisor
}
}
func GetStringFromStack(stack global.Stack) string {
switch stack {
case global.System:
return "system"
case global.GVisor:
return "gVisor"
return "gvisor"
case global.Mixed:
return "mixed"
case global.LWIP:
return "LWIP"
// case global.LWIP:
// return "LWIP"
default:
return "UNKNOWN"
}
Expand Down
17 changes: 17 additions & 0 deletions admin_service_cmd/admin_service.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<!-- <assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="hiddify-service.exe"
type="win32"
/> -->
<description>Hiddify Tunnel Service</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Binary file added admin_service_cmd/admin_service.syso
Binary file not shown.
33 changes: 33 additions & 0 deletions admin_service_cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

/*
#cgo LDFLAGS: bin/libcore.dll
#include <stdlib.h>
#include <stdint.h>
// Import the function from the DLL
extern void AdminServiceStart(char *arg);
*/
import "C"
import (
"os"
)

func main() {
args := os.Args
// Check if there is at least one command-line argument
if len(args) < 2 {
println("Usage: hiddify-service.exe empty/start/stop/uninstall/install")
// os.Exit(1)
args = append(args, "")
}
// fmt.Printf("os.Args: %+v", args)
os.Chdir(os.Args[0])
// Convert the Go string to a C string
arg := C.CString(args[1])
// defer C.free(unsafe.Pointer(arg))

// Call AdminServiceStart with the C string
C.AdminServiceStart(arg)
}
4 changes: 4 additions & 0 deletions build_windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ set GOARCH=amd64
set CC=x86_64-w64-mingw32-gcc
set CGO_ENABLED=1
go build -trimpath -tags with_gvisor,with_quic,with_wireguard,with_ech,with_utls,with_clash_api,with_grpc -ldflags="-w -s" -buildmode=c-shared -o bin/libcore.dll ./custom

rsrc -manifest admin_service_cmd\admin_service.manifest -ico ..\assets\images\tray_icon_connected.ico -o admin_service_cmd\admin_service.syso
go build -o bin/hiddify-service.exe ./admin_service_cmd
@REM copy .\admin_service_cmd\admin_service.manifest bin\hiddify-service.exe.manifest
19 changes: 19 additions & 0 deletions cmd/cmd_admin_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"github.com/hiddify/libcore/admin_service"

"github.com/spf13/cobra"
)

var commandService = &cobra.Command{
Use: "admin-service",
Short: "Sign box service start/stop/install/uninstall",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 2 {
admin_service.StartService("")
}
admin_service.StartService(args[1])
},
}
2 changes: 1 addition & 1 deletion cmd/cmd_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func build(path string, optionsPath string) error {
}
if commandBuildOutputPath != "" {
outputPath, _ := filepath.Abs(filepath.Join(workingDir, commandBuildOutputPath))
err = os.WriteFile(outputPath, []byte(config), 0777)
err = os.WriteFile(outputPath, []byte(config), 0644)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/cmd_gen_cert.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package main

import (
"os"

"github.com/hiddify/libcore/utils"
"github.com/spf13/cobra"
"os"
)

var commandGenerateCertification = &cobra.Command{
Use: "gen-cert",
Short: "Generate certification for web server",
Run: func(cmd *cobra.Command, args []string) {
err := os.MkdirAll("cert", 600)
err := os.MkdirAll("cert", 0644)
if err != nil {
panic("Error: " + err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cmd_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func parse(path string) error {
}
if commandParseOutputPath != "" {
outputPath, _ := filepath.Abs(filepath.Join(workingDir, commandParseOutputPath))
err = os.WriteFile(outputPath, config, 0777)
err = os.WriteFile(outputPath, config, 0644)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 5fa2822

Please sign in to comment.