Skip to content

Commit

Permalink
feat: implement basic IPC mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
bilalcaliskan committed Jan 19, 2024
1 parent 51c38a8 commit 3c4ceb1
Showing 1 changed file with 135 additions and 9 deletions.
144 changes: 135 additions & 9 deletions cmd/root/root.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package root

import (
"context"
"bufio"
"errors"
"fmt"
"github.com/rs/zerolog"
"io"
"net"
"os"
"os/signal"
"strings"
"syscall"

"github.com/bilalcaliskan/split-the-tunnel/cmd/root/options"

Expand All @@ -27,21 +35,24 @@ var rootCmd = &cobra.Command{
Short: "",
Long: ``,
Version: ver.GitVersion,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, args []string) error {
logger := logging.GetLogger()
logger.Info().Str("appVersion", ver.GitVersion).Str("goVersion", ver.GoVersion).Str("goOS", ver.GoOs).
Str("goArch", ver.GoArch).Str("gitCommit", ver.GitCommit).Str("buildDate", ver.BuildDate).
Msg("split-the-tunnel is started!")

logger.Info().Msg(opts.Domain)
logger.Info().Msg(opts.DnsServers)
// Setup signal handling for a graceful shutdown
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

cmd.SetContext(context.WithValue(cmd.Context(), options.LoggerKey{}, logger))
cmd.SetContext(context.WithValue(cmd.Context(), options.OptsKey{}, opts))
// Initialize IPC mechanism
if err := initIPC(logger); err != nil {
logger.Fatal().Err(err).Msg("failed to initialize IPC")
}

<-sigs
logger.Info().Msg("received termination signal, shutting down...")

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}
Expand All @@ -53,3 +64,118 @@ func Execute() {
os.Exit(1)
}
}

const socketPath = "/tmp/mydaemon.sock"

func initIPC(logger zerolog.Logger) error {
// Check and remove the socket file if it already exists
if _, err := os.Stat(socketPath); err == nil {
if err := os.Remove(socketPath); err != nil {
return err
}
}

// Listen on the UNIX domain socket
listener, err := net.Listen("unix", socketPath)
if err != nil {
return err
}

go func() {
defer listener.Close()
for {
// Accept new connections
conn, err := listener.Accept()
if err != nil {
logger.Error().Err(err).Msg("failed to accept connection")
continue
}

// Handle the connection in a new goroutine
go handleConnection(conn, logger)
}
}()

return nil
}

func handleConnection(conn net.Conn, logger zerolog.Logger) {
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadString('\n')
if err != nil {
if err != io.EOF {
logger.Error().Err(err).Msg("failed to read from IPC connection")
continue
}
}

// Process the received command
if err := processCommand(strings.TrimSpace(message), conn); err != nil {
logger.Error().Err(err).Msg("failed to process command")
break
}
}
}

func processCommand(command string, conn net.Conn) error {
parts := strings.Fields(command)
if len(parts) == 0 {
return errors.New("not enough arguments")
}

switch parts[0] {
case "add":
if len(parts) < 2 {
err := errors.New("add command requires a domain name")

Check failure on line 130 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)

Check failure on line 130 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / Analyze (go)

ineffectual assignment to err (ineffassign)

Check failure on line 130 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / staticcheck

this value of err is never used (SA4006)

Check failure on line 130 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / staticcheck

New is a pure function but its return value is ignored (SA4017)
_, err = conn.Write([]byte("Error: 'add' command requires a domain name\n"))
return err
}
return handleAddCommand(parts[1], conn)
case "remove":
if len(parts) < 2 {
err := errors.New("remove command requires a domain name")

Check failure on line 137 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)

Check failure on line 137 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / Analyze (go)

ineffectual assignment to err (ineffassign)

Check failure on line 137 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / staticcheck

this value of err is never used (SA4006)

Check failure on line 137 in cmd/root/root.go

View workflow job for this annotation

GitHub Actions / staticcheck

New is a pure function but its return value is ignored (SA4017)
_, err = conn.Write([]byte("Error: 'remove' command requires a domain name\n"))
return err
}
return handleRemoveCommand(parts[1], conn)
case "list":
return handleListCommand(conn)
default:
_, err := conn.Write([]byte("Error: Unknown command\n"))
return err
}
}

func handleAddCommand(domain string, conn net.Conn) error {
// Add logic to handle adding route for domain
// Placeholder for adding functionality

//_, err := conn.Write([]byte("Added route for " + domain + "\n"))
//return err

fmt.Println("handling add command for domain: " + domain)
return nil
}

func handleRemoveCommand(domain string, conn net.Conn) error {
// Add logic to handle removing route for domain
// Placeholder for removing functionality

//_, err := conn.Write([]byte("Removed route for " + domain + "\n"))
//return err

fmt.Println("handling remove command for domain: " + domain)
return nil
}

func handleListCommand(conn net.Conn) error {
// Add logic to list all routes
// Placeholder for listing functionality

//_, err := conn.Write([]byte("List of all routes\n"))
//return err

fmt.Println("handling list command")
return nil
}

0 comments on commit 3c4ceb1

Please sign in to comment.