aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/config.go225
1 files changed, 136 insertions, 89 deletions
diff --git a/src/config.go b/src/config.go
index 72a604f..e2d7f20 100644
--- a/src/config.go
+++ b/src/config.go
@@ -61,6 +61,7 @@ func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
send(fmt.Sprintf("persistent_keepalive_interval=%d",
atomic.LoadUint64(&peer.persistentKeepaliveInterval),
))
+
for _, ip := range device.routingTable.AllowedIPs(peer) {
send("allowed_ip=" + ip.String())
}
@@ -89,6 +90,9 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
logDebug := device.log.Debug
var peer *Peer
+
+ deviceConfig := true
+
for scanner.Scan() {
// parse line
@@ -99,86 +103,110 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
}
parts := strings.Split(line, "=")
if len(parts) != 2 {
- return &IPCError{Code: ipcErrorNoKeyValue}
+ return &IPCError{Code: ipcErrorProtocol}
}
key := parts[0]
value := parts[1]
- switch key {
+ /* device configuration */
- /* interface configuration */
+ if deviceConfig {
- case "private_key":
- var sk NoisePrivateKey
- if value == "" {
- device.SetPrivateKey(sk)
- } else {
- err := sk.FromHex(value)
- if err != nil {
- logError.Println("Failed to set private_key:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
+ switch key {
+ case "private_key":
+ var sk NoisePrivateKey
+ if value == "" {
+ device.SetPrivateKey(sk)
+ } else {
+ err := sk.FromHex(value)
+ if err != nil {
+ logError.Println("Failed to set private_key:", err)
+ return &IPCError{Code: ipcErrorInvalid}
+ }
+ device.SetPrivateKey(sk)
}
- device.SetPrivateKey(sk)
- }
- case "listen_port":
- port, err := strconv.ParseUint(value, 10, 16)
- if err != nil {
- logError.Println("Failed to set listen_port:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
- }
- netc := &device.net
- netc.mutex.Lock()
- if netc.addr.Port != int(port) {
- if netc.conn != nil {
- netc.conn.Close()
+ case "listen_port":
+ port, err := strconv.ParseUint(value, 10, 16)
+ if err != nil {
+ logError.Println("Failed to set listen_port:", err)
+ return &IPCError{Code: ipcErrorInvalid}
}
- netc.addr.Port = int(port)
- netc.conn, err = net.ListenUDP("udp", netc.addr)
- }
- netc.mutex.Unlock()
- if err != nil {
- logError.Println("Failed to create UDP listener:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
- }
+ netc := &device.net
+ netc.mutex.Lock()
+ if netc.addr.Port != int(port) {
+ if netc.conn != nil {
+ netc.conn.Close()
+ }
+ netc.addr.Port = int(port)
+ netc.conn, err = net.ListenUDP("udp", netc.addr)
+ }
+ netc.mutex.Unlock()
+ if err != nil {
+ logError.Println("Failed to create UDP listener:", err)
+ return &IPCError{Code: ipcErrorIO}
+ }
+ // TODO: Clear source address of all peers
- case "fwmark":
- logError.Println("FWMark not handled yet")
+ case "fwmark":
+ logError.Println("FWMark not handled yet")
+ // TODO: Clear source address of all peers
- case "public_key":
- var pubKey NoisePublicKey
- err := pubKey.FromHex(value)
- if err != nil {
- logError.Println("Failed to get peer by public_key:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
- }
- device.mutex.RLock()
- peer, _ = device.peers[pubKey]
- device.mutex.RUnlock()
- if peer == nil {
- peer = device.NewPeer(pubKey)
- }
+ case "public_key":
- case "replace_peers":
- if value == "true" {
- device.RemoveAllPeers()
- } else {
- logError.Println("Failed to set replace_peers, invalid value:", value)
- return &IPCError{Code: ipcErrorInvalidValue}
- }
+ // switch to peer configuration
- default:
+ deviceConfig = false
- /* peer configuration */
+ case "replace_peers":
+ if value != "true" {
+ logError.Println("Failed to set replace_peers, invalid value:", value)
+ return &IPCError{Code: ipcErrorInvalid}
+ }
+ device.RemoveAllPeers()
- if peer == nil {
- logError.Println("No peer referenced, before peer operation")
- return &IPCError{Code: ipcErrorNoPeer}
+ default:
+ logError.Println("Invalid UAPI key (device configuration):", key)
+ return &IPCError{Code: ipcErrorInvalid}
}
+ }
+
+ /* peer configuration */
+
+ if !deviceConfig {
switch key {
+ case "public_key":
+ var pubKey NoisePublicKey
+ err := pubKey.FromHex(value)
+ if err != nil {
+ logError.Println("Failed to get peer by public_key:", err)
+ return &IPCError{Code: ipcErrorInvalid}
+ }
+
+ // check if public key of peer equal to device
+
+ device.mutex.RLock()
+ if device.publicKey.Equals(pubKey) {
+ device.mutex.RUnlock()
+ logError.Println("Public key of peer matches private key of device")
+ return &IPCError{Code: ipcErrorInvalid}
+ }
+
+ // find peer referenced
+
+ peer, _ = device.peers[pubKey]
+ device.mutex.RUnlock()
+ if peer == nil {
+ peer = device.NewPeer(pubKey)
+ }
+
case "remove":
+ if value != "true" {
+ logError.Println("Failed to set remove, invalid value:", value)
+ return &IPCError{Code: ipcErrorInvalid}
+ }
device.RemovePeer(peer.handshake.remoteStatic)
logDebug.Println("Removing", peer.String())
peer = nil
@@ -191,50 +219,67 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
}()
if err != nil {
logError.Println("Failed to set preshared_key:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
+ return &IPCError{Code: ipcErrorInvalid}
}
case "endpoint":
+ // TODO: Only IP and port
addr, err := net.ResolveUDPAddr("udp", value)
if err != nil {
logError.Println("Failed to set endpoint:", value)
- return &IPCError{Code: ipcErrorInvalidValue}
+ return &IPCError{Code: ipcErrorInvalid}
}
peer.mutex.Lock()
peer.endpoint = addr
peer.mutex.Unlock()
case "persistent_keepalive_interval":
- secs, err := strconv.ParseInt(value, 10, 64)
- if secs < 0 || err != nil {
+
+ // update keep-alive interval
+
+ secs, err := strconv.ParseUint(value, 10, 16)
+ if err != nil {
logError.Println("Failed to set persistent_keepalive_interval:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
+ return &IPCError{Code: ipcErrorInvalid}
}
- atomic.StoreUint64(
+
+ old := atomic.SwapUint64(
&peer.persistentKeepaliveInterval,
- uint64(secs),
+ secs,
)
+ // send immediate keep-alive
+
+ if old == 0 && secs != 0 {
+ up, err := device.tun.IsUp()
+ if err != nil {
+ logError.Println("Failed to get tun device status:", err)
+ return &IPCError{Code: ipcErrorIO}
+ }
+ if up {
+ peer.SendKeepAlive()
+ }
+ }
+
case "replace_allowed_ips":
- if value == "true" {
- device.routingTable.RemovePeer(peer)
- } else {
+ if value != "true" {
logError.Println("Failed to set replace_allowed_ips, invalid value:", value)
- return &IPCError{Code: ipcErrorInvalidValue}
+ return &IPCError{Code: ipcErrorInvalid}
}
+ device.routingTable.RemovePeer(peer)
case "allowed_ip":
_, network, err := net.ParseCIDR(value)
if err != nil {
logError.Println("Failed to set allowed_ip:", err)
- return &IPCError{Code: ipcErrorInvalidValue}
+ return &IPCError{Code: ipcErrorInvalid}
}
ones, _ := network.Mask.Size()
device.routingTable.Insert(network.IP, uint(ones), peer)
default:
- logError.Println("Invalid UAPI key:", key)
- return &IPCError{Code: ipcErrorInvalidKey}
+ logError.Println("Invalid UAPI key (peer configuration):", key)
+ return &IPCError{Code: ipcErrorInvalid}
}
}
}
@@ -244,6 +289,8 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
func ipcHandle(device *Device, socket net.Conn) {
+ // create buffered read/writer
+
defer socket.Close()
buffered := func(s io.ReadWriter) *bufio.ReadWriter {
@@ -259,30 +306,30 @@ func ipcHandle(device *Device, socket net.Conn) {
return
}
- switch op {
+ // handle operation
+ var status *IPCError
+
+ switch op {
case "set=1\n":
device.log.Debug.Println("Config, set operation")
- err := ipcSetOperation(device, buffered)
- if err != nil {
- fmt.Fprintf(buffered, "errno=%d\n\n", err.ErrorCode())
- } else {
- fmt.Fprintf(buffered, "errno=0\n\n")
- }
- return
+ status = ipcSetOperation(device, buffered)
case "get=1\n":
device.log.Debug.Println("Config, get operation")
- err := ipcGetOperation(device, buffered)
- if err != nil {
- fmt.Fprintf(buffered, "errno=%d\n\n", err.ErrorCode())
- } else {
- fmt.Fprintf(buffered, "errno=0\n\n")
- }
- return
+ status = ipcGetOperation(device, buffered)
default:
device.log.Error.Println("Invalid UAPI operation:", op)
+ return
+ }
+
+ // write status
+ if status != nil {
+ device.log.Error.Println(status)
+ fmt.Fprintf(buffered, "errno=%d\n\n", status.ErrorCode())
+ } else {
+ fmt.Fprintf(buffered, "errno=0\n\n")
}
}