1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
package args
import (
"flag"
"os"
"strings"
)
type Arguments struct {
DatabasePath string
TemplatePath string
StaticPath string
Migrate bool
Scheduler bool
Port int
Server bool
// Dns runs the authoritative DNS server for the LAN. DnsZone is the suffix
// it owns (e.g. penguins.lan); queries outside it are forwarded to
// DnsResolvers (empty = no forwarding, since the LAN has no outside
// internet). ServerIP (env SERVER_IP) answers the zone apex so the website
// itself resolves; empty leaves the apex unanswered.
Dns bool
DnsPort int
DnsResolvers []string
DnsZone string
ServerIP string
// DevMAC (env DEV_MAC) forces every client's MAC, for testing auth from
// loopback where the browser never appears in the ARP table.
DevMAC string
// Minecraft RCON, for the server status panel. Empty address disables it.
RconAddress string
RconPassword string
// LanSubnet (env LAN_SUBNET, e.g. 192.168.8.0/24) is swept to populate the
// ARP table for idle devices. Empty disables the sweep.
LanSubnet string
}
func GetArgs() (*Arguments, error) {
databasePath := flag.String("database-path", "./db/penguins.db", "Path to the SQLite database")
templatePath := flag.String("template-path", "./templates", "Path to the template directory")
staticPath := flag.String("static-path", "./static", "Path to the static directory")
migrate := flag.Bool("migrate", false, "Run the migrations on startup")
scheduler := flag.Bool("scheduler", false, "Run the background scheduler (ARP refresh, session cleanup)")
port := flag.Int("port", 8080, "Port to listen on")
server := flag.Bool("server", false, "Run the HTTP server")
dns := flag.Bool("dns", false, "Run the authoritative DNS server")
dnsPort := flag.Int("dns-port", 8053, "Port for the DNS server to listen on")
dnsZone := flag.String("dns-zone", "penguins.lan", "DNS zone this server is authoritative for")
dnsResolvers := flag.String("dns-resolvers", "", "Comma-separated upstream resolvers for non-zone queries (empty disables forwarding)")
flag.Parse()
resolvers := []string{}
for _, r := range strings.Split(*dnsResolvers, ",") {
if r = strings.TrimSpace(r); r != "" {
resolvers = append(resolvers, r)
}
}
return &Arguments{
DatabasePath: *databasePath,
TemplatePath: *templatePath,
StaticPath: *staticPath,
Migrate: *migrate,
Scheduler: *scheduler,
Port: *port,
Server: *server,
Dns: *dns,
DnsPort: *dnsPort,
DnsResolvers: resolvers,
DnsZone: *dnsZone,
ServerIP: os.Getenv("SERVER_IP"),
DevMAC: os.Getenv("DEV_MAC"),
RconAddress: os.Getenv("RCON_ADDRESS"),
RconPassword: os.Getenv("RCON_PASSWORD"),
LanSubnet: os.Getenv("LAN_SUBNET"),
}, nil
}
|