undid some redundant code and removed most work setting up a tun device

This commit is contained in:
james ryan 2024-06-09 14:08:30 -04:00
parent 84d8f580b3
commit 2b31fa8749

169
main.go
View File

@ -1,16 +1,21 @@
package main package main
import ( import (
"bufio" // "bufio"
"fmt" "fmt"
"log" "log"
"os" "os"
// "time" "net"
"strconv" "strconv"
"io"
"context"
"time"
"math/rand" "math/rand"
"bytes"
"github.com/songgao/packets/ethernet" "golang.org/x/crypto/ssh"
// "github.com/songgao/packets/ethernet"
"github.com/songgao/water" "github.com/songgao/water"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
@ -20,6 +25,7 @@ type Client struct {
ifce *water.Interface ifce *water.Interface
hostname string hostname string
addr *netlink.Addr addr *netlink.Addr
addr_str string
} }
// -- funcs -- // -- funcs --
@ -47,6 +53,17 @@ type Client struct {
// used to verify collisions // used to verify collisions
var client_leases = make(map[string]string) var client_leases = make(map[string]string)
var mode string
func detectMode() {
mode = os.Getenv("LAZYVPN_MODE")
if len(mode) == 0 {
fmt.Println("Mode not set! assuming CLIENT")
mode = "CLIENT"
}
fmt.Printf("Running in mode %s\n", mode)
return
}
func generateClientTUN(hn string) Client { func generateClientTUN(hn string) Client {
// configure TUN interface // configure TUN interface
@ -63,32 +80,37 @@ func generateClientTUN(hn string) Client {
// Generate a free address to assign // Generate a free address to assign
var cl_Addr_str string var cl_Addr_str string
if mode == "CLIENT" {
// This is a bad way of doing it, and only accounts for local conflicts
// theres definitely a way to find if it conflicts somewhere else
// ideally, it shouldnt be locked to this 16 block, either. eventually,
// the allowed range (CIDR included) should be defined.
// this is an alpha for now, just to get *something* nice working
r := rand.New(rand.NewSource(255))
for {
var b1 int = int(r.Int31n(255))
var b2 int = int(r.Int31n(255))
cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2)
// This is a bad way of doing it, and only accounts for local conflicts fmt.Println(cl_Addr_str)
// theres definitely a way to find if it conflicts somewhere else
// ideally, it shouldnt be locked to this 16 block, either. eventually,
// the allowed range (CIDR included) should be defined.
// this is an alpha for now, just to get *something* nice working
r := rand.New(rand.NewSource(255))
for {
var b1 int = int(r.Int31n(255))
var b2 int = int(r.Int31n(255))
cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2)
fmt.Println(cl_Addr_str) _, isLeased := client_leases[cl_Addr_str]
if !isLeased {
_, isLeased := client_leases[cl_Addr_str] break
if !isLeased { }
break
} }
} else {
// its the server
cl_Addr_str = ".0.1"
} }
cl_Link, err := netlink.LinkByName(config.Name) cl_Link, err := netlink.LinkByName(config.Name)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
cl_Addr, err := netlink.ParseAddr("169.254"+cl_Addr_str+"/16") cl_Addr_str = "169.254"+cl_Addr_str
cl_Addr, err := netlink.ParseAddr(cl_Addr_str+"/16")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -100,40 +122,87 @@ func generateClientTUN(hn string) Client {
ifce: cl_ifce, ifce: cl_ifce,
hostname: hn, hostname: hn,
addr: cl_Addr, addr: cl_Addr,
addr_str: cl_Addr_str,
}
}
func StartListener(addr string) {
// listen on port 28173
l, err := net.Listen("tcp", addr+":28173")
if err != nil {
log.Fatal(err)
}
defer l.Close()
fmt.Printf("Listening on %s port 28173", addr)
for {
// Wait for a connection.
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
// Handle the connection in a new goroutine.
// The loop then returns to accepting, so that
// multiple connections may be served concurrently.
go func(c net.Conn) {
// Echo all incoming data.
io.Copy(c, c)
// Shut down the connection.
c.Close()
}(conn)
}
}
func StartDialer() {
var d net.Dialer
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
fmt.Printf("Attempting autodiscovery")
conn, err := d.DialContext(ctx, "tcp", "169.254.0.1:28173")
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
if _, err := conn.Write([]byte("Hello, World!")); err != nil {
log.Fatal(err)
} }
} }
func main() { func main() {
var desired_hostname string // Detect if we are in CLIENT or SERVER mode
fmt.Printf("your nosthanem is ") detectMode()
hn, _ := os.Hostname()
fmt.Println(hn) // Zeroth stage - gather info
fmt.Printf("Please enter a desired hostname for the new client: ") var hostKey ssh.PublicKey
scanner := bufio.NewScanner(os.Stdin) config := &ssh.ClientConfig {
scanner.Scan() User: os.Getenv("LAZYUSER"),
err := scanner.Err() Auth: []ssh.authmethod {
if err != nil { ssh.Password(os.Getenv("LAZYPASS")),
log.Fatal(err) },
} HostKeyCallback: ssh.FixedHostKey(hostKey),
desired_hostname = scanner.Text()
var registered_client Client = generateClientTUN(desired_hostname)
log.Printf("interface name: %s\n", registered_client.ifce.Name())
var frame ethernet.Frame
ifce := registered_client.ifce
for {
frame.Resize(1500)
n, err := ifce.Read([]byte(frame))
if err != nil {
log.Fatal(err)
}
frame = frame[:n]
log.Printf("Dst: %s\n", frame.Destination())
log.Printf("Src: %s\n", frame.Source())
log.Printf("Ethertype: % x\n", frame.Ethertype())
log.Printf("Payload: % x\n", frame.Payload())
} }
// generateNewClient() // First stage - attempt to connect to public host
var host string = "192.168.122.1"
fmt.Printf("Dialing host %s....\n", host)
client, err := ssh.Dial("tcp", host+":22278", config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
defer client.Close()
// Final stage
if mode == "SERVER" {
// open, listen and wait
StartListener(registered_client.addr_str)
} else {
// connect to far end
StartDialer()
}
} }