Add support for daemon locks for better process removal

This commit is contained in:
Alec Scott
2022-01-31 16:44:06 -07:00
parent 39b23f4e91
commit 275eb18ca8
3 changed files with 66 additions and 18 deletions

View File

@@ -2,6 +2,9 @@ package cli
import (
"fmt"
"os"
"path/filepath"
"strconv"
"github.com/DataDrake/cli-ng/v2/cmd"
"github.com/hyprspace/hyprspace/tun"
@@ -26,8 +29,34 @@ func DownRun(r *cmd.Root, c *cmd.Sub) {
// Parse Command Args
args := c.Args.(*DownArgs)
err := tun.Delete(args.InterfaceName)
// Parse Global Config Flag for Custom Config Path
configPath := r.Flags.(*GlobalFlags).Config
if configPath == "" {
configPath = "/etc/hyprspace/" + args.InterfaceName + ".yaml"
}
// Read lock from file system to stop process.
lockPath := filepath.Join(filepath.Dir(configPath), args.InterfaceName+".lock")
out, err := os.ReadFile(lockPath)
checkErr(err)
pid, err := strconv.Atoi(string(out))
checkErr(err)
process, err := os.FindProcess(pid)
checkErr(err)
err0 := process.Signal(os.Interrupt)
err1 := tun.Delete(args.InterfaceName)
// Different types of systems may need the tun devices destroyed first or
// the process to exit first don't worry as long as one of these two has
// suceeded.
if err0 != nil && err1 != nil {
checkErr(err0)
checkErr(err1)
}
fmt.Println("[+] deleted hyprspace " + args.InterfaceName + " daemon")
}

View File

@@ -9,6 +9,7 @@ import (
"net"
"os"
"os/signal"
"path/filepath"
"runtime"
"strconv"
"strings"
@@ -158,6 +159,9 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
go p2p.Discover(ctx, host, dht, peerTable)
go prettyDiscovery(ctx, host, peerTable)
// Configure path for lock
lockPath := filepath.Join(filepath.Dir(cfg.Path), cfg.Interface.Name+".lock")
go func() {
// Wait for a SIGINT or SIGTERM signal
ch := make(chan os.Signal, 1)
@@ -169,9 +173,19 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
if err := host.Close(); err != nil {
panic(err)
}
// Remove daemon lock from file system.
err = os.Remove(lockPath)
checkErr(err)
// Exit the application.
os.Exit(0)
}()
// Write lock to filesystem to indicate an existing running daemon.
err = os.WriteFile(lockPath, []byte(fmt.Sprint(os.Getpid())), os.ModePerm)
checkErr(err)
// Bring Up TUN Device
err = tunDev.Up()
if err != nil {
@@ -182,18 +196,14 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
// Listen For New Packets on TUN Interface
activeStreams = make(map[string]network.Stream)
var packet = make([]byte, 1420)
var stream network.Stream
var ok bool
var plen int
var dst string
for {
plen, err = tunDev.Iface.Read(packet)
plen, err := tunDev.Iface.Read(packet)
if err != nil {
log.Println(err)
continue
}
dst = net.IPv4(packet[16], packet[17], packet[18], packet[19]).String()
stream, ok = activeStreams[dst]
dst := net.IPv4(packet[16], packet[17], packet[18], packet[19]).String()
stream, ok := activeStreams[dst]
if ok {
_, err = stream.Write(packet[:plen])
if err == nil {
@@ -203,8 +213,8 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
delete(activeStreams, dst)
ok = false
}
if _, ok := peerTable[dst]; ok {
stream, err = host.NewStream(ctx, peerTable[dst], p2p.Protocol)
if peer, ok := peerTable[dst]; ok {
stream, err = host.NewStream(ctx, peer, p2p.Protocol)
if err != nil {
log.Println(err)
continue
@@ -215,7 +225,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
}
}
func createDaemon(cfg config.Config, out chan<- error) {
func createDaemon(cfg *config.Config, out chan<- error) {
path, err := os.Executable()
checkErr(err)
// Create Pipe to monitor for daemon output.
@@ -238,6 +248,8 @@ func createDaemon(cfg config.Config, out chan<- error) {
count++
}
}
// Release the created daemon
err = process.Release()
checkErr(err)
if count < len(cfg.Peers) {
@@ -252,11 +264,9 @@ func streamHandler(stream network.Stream) {
stream.Reset()
return
}
var err error
var packet = make([]byte, 1420)
var plen int
for {
plen, err = stream.Read(packet)
plen, err := stream.Read(packet)
if err != nil {
stream.Close()
delete(activeStreams, RevLookup[stream.Conn().RemotePeer().Pretty()])

View File

@@ -8,6 +8,7 @@ import (
// Config is the main Configuration Struct for Hyprspace.
type Config struct {
Path string `yaml:"path,omitempty"`
Interface Interface `yaml:"interface"`
Peers map[string]Peer `yaml:"peers"`
}
@@ -27,12 +28,12 @@ type Peer struct {
}
// Read initializes a config from a file.
func Read(path string) (result Config, err error) {
func Read(path string) (*Config, error) {
in, err := os.ReadFile(path)
if err != nil {
return
return nil, err
}
result = Config{
result := Config{
Interface: Interface{
Name: "hs0",
ListenPort: 8001,
@@ -41,6 +42,14 @@ func Read(path string) (result Config, err error) {
PrivateKey: "",
},
}
// Read in config settings from file.
err = yaml.Unmarshal(in, &result)
return
if err != nil {
return nil, err
}
// Overwrite path of config to input.
result.Path = path
return &result, nil
}