diff options
author | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2018-02-04 16:08:26 +0100 |
---|---|---|
committer | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2018-02-04 16:08:26 +0100 |
commit | a0f54cbe5ac2cd8b8296c2c57c30029dd349cff0 (patch) | |
tree | 64574090d79ff3899c5c18e5268e450028e4656b /src/uapi.go | |
parent | 5871ec04deb8f4715cab37146940baa35c08cbee (diff) |
Align with go library layout
Diffstat (limited to 'src/uapi.go')
-rw-r--r-- | src/uapi.go | 437 |
1 files changed, 0 insertions, 437 deletions
diff --git a/src/uapi.go b/src/uapi.go deleted file mode 100644 index caaa498..0000000 --- a/src/uapi.go +++ /dev/null @@ -1,437 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "io" - "net" - "strconv" - "strings" - "sync/atomic" - "time" -) - -type IPCError struct { - Code int64 -} - -func (s *IPCError) Error() string { - return fmt.Sprintf("IPC error: %d", s.Code) -} - -func (s *IPCError) ErrorCode() int64 { - return s.Code -} - -func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError { - - device.log.Debug.Println("UAPI: Processing get operation") - - // create lines - - lines := make([]string, 0, 100) - send := func(line string) { - lines = append(lines, line) - } - - func() { - - // lock required resources - - device.net.mutex.RLock() - defer device.net.mutex.RUnlock() - - device.noise.mutex.RLock() - defer device.noise.mutex.RUnlock() - - device.routing.mutex.RLock() - defer device.routing.mutex.RUnlock() - - device.peers.mutex.Lock() - defer device.peers.mutex.Unlock() - - // serialize device related values - - if !device.noise.privateKey.IsZero() { - send("private_key=" + device.noise.privateKey.ToHex()) - } - - if device.net.port != 0 { - send(fmt.Sprintf("listen_port=%d", device.net.port)) - } - - if device.net.fwmark != 0 { - send(fmt.Sprintf("fwmark=%d", device.net.fwmark)) - } - - // serialize each peer state - - for _, peer := range device.peers.keyMap { - peer.mutex.RLock() - defer peer.mutex.RUnlock() - - send("public_key=" + peer.handshake.remoteStatic.ToHex()) - send("preshared_key=" + peer.handshake.presharedKey.ToHex()) - if peer.endpoint != nil { - send("endpoint=" + peer.endpoint.DstToString()) - } - - nano := atomic.LoadInt64(&peer.stats.lastHandshakeNano) - secs := nano / time.Second.Nanoseconds() - nano %= time.Second.Nanoseconds() - - send(fmt.Sprintf("last_handshake_time_sec=%d", secs)) - send(fmt.Sprintf("last_handshake_time_nsec=%d", nano)) - send(fmt.Sprintf("tx_bytes=%d", peer.stats.txBytes)) - send(fmt.Sprintf("rx_bytes=%d", peer.stats.rxBytes)) - send(fmt.Sprintf("persistent_keepalive_interval=%d", - atomic.LoadUint64(&peer.persistentKeepaliveInterval), - )) - - for _, ip := range device.routing.table.AllowedIPs(peer) { - send("allowed_ip=" + ip.String()) - } - - } - }() - - // send lines (does not require resource locks) - - for _, line := range lines { - _, err := socket.WriteString(line + "\n") - if err != nil { - return &IPCError{ - Code: ipcErrorIO, - } - } - } - - return nil -} - -func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError { - scanner := bufio.NewScanner(socket) - logError := device.log.Error - logDebug := device.log.Debug - - var peer *Peer - - dummy := false - deviceConfig := true - - for scanner.Scan() { - - // parse line - - line := scanner.Text() - if line == "" { - return nil - } - parts := strings.Split(line, "=") - if len(parts) != 2 { - return &IPCError{Code: ipcErrorProtocol} - } - key := parts[0] - value := parts[1] - - /* device configuration */ - - if deviceConfig { - - switch key { - case "private_key": - var sk NoisePrivateKey - err := sk.FromHex(value) - if err != nil { - logError.Println("Failed to set private_key:", err) - return &IPCError{Code: ipcErrorInvalid} - } - logDebug.Println("UAPI: Updating device private key") - device.SetPrivateKey(sk) - - case "listen_port": - - // parse port number - - port, err := strconv.ParseUint(value, 10, 16) - if err != nil { - logError.Println("Failed to parse listen_port:", err) - return &IPCError{Code: ipcErrorInvalid} - } - - // update port and rebind - - logDebug.Println("UAPI: Updating listen port") - - device.net.mutex.Lock() - device.net.port = uint16(port) - device.net.mutex.Unlock() - - if err := device.BindUpdate(); err != nil { - logError.Println("Failed to set listen_port:", err) - return &IPCError{Code: ipcErrorPortInUse} - } - - case "fwmark": - - // parse fwmark field - - fwmark, err := func() (uint32, error) { - if value == "" { - return 0, nil - } - mark, err := strconv.ParseUint(value, 10, 32) - return uint32(mark), err - }() - - if err != nil { - logError.Println("Invalid fwmark", err) - return &IPCError{Code: ipcErrorInvalid} - } - - logDebug.Println("UAPI: Updating fwmark") - - device.net.mutex.Lock() - device.net.fwmark = uint32(fwmark) - device.net.mutex.Unlock() - - if err := device.BindUpdate(); err != nil { - logError.Println("Failed to update fwmark:", err) - return &IPCError{Code: ipcErrorPortInUse} - } - - case "public_key": - // switch to peer configuration - logDebug.Println("UAPI: Transition to peer configuration") - deviceConfig = false - - case "replace_peers": - if value != "true" { - logError.Println("Failed to set replace_peers, invalid value:", value) - return &IPCError{Code: ipcErrorInvalid} - } - logDebug.Println("UAPI: Removing all peers") - device.RemoveAllPeers() - - default: - logError.Println("Invalid UAPI key (device configuration):", key) - return &IPCError{Code: ipcErrorInvalid} - } - } - - /* peer configuration */ - - if !deviceConfig { - - switch key { - - case "public_key": - var publicKey NoisePublicKey - err := publicKey.FromHex(value) - if err != nil { - logError.Println("Failed to get peer by public_key:", err) - return &IPCError{Code: ipcErrorInvalid} - } - - // ignore peer with public key of device - - device.noise.mutex.RLock() - equals := device.noise.publicKey.Equals(publicKey) - device.noise.mutex.RUnlock() - - if equals { - peer = &Peer{} - dummy = true - } - - // find peer referenced - - peer = device.LookupPeer(publicKey) - - if peer == nil { - peer, err = device.NewPeer(publicKey) - if err != nil { - logError.Println("Failed to create new peer:", err) - return &IPCError{Code: ipcErrorInvalid} - } - logDebug.Println("UAPI: Created new peer:", peer.String()) - } - - peer.mutex.Lock() - peer.timer.handshakeDeadline.Reset(RekeyAttemptTime) - peer.mutex.Unlock() - - case "remove": - - // remove currently selected peer from device - - if value != "true" { - logError.Println("Failed to set remove, invalid value:", value) - return &IPCError{Code: ipcErrorInvalid} - } - if !dummy { - logDebug.Println("UAPI: Removing peer:", peer.String()) - device.RemovePeer(peer.handshake.remoteStatic) - } - peer = &Peer{} - dummy = true - - case "preshared_key": - - // update PSK - - logDebug.Println("UAPI: Updating pre-shared key for peer:", peer.String()) - - peer.handshake.mutex.Lock() - err := peer.handshake.presharedKey.FromHex(value) - peer.handshake.mutex.Unlock() - - if err != nil { - logError.Println("Failed to set preshared_key:", err) - return &IPCError{Code: ipcErrorInvalid} - } - - case "endpoint": - - // set endpoint destination - - logDebug.Println("UAPI: Updating endpoint for peer:", peer.String()) - - err := func() error { - peer.mutex.Lock() - defer peer.mutex.Unlock() - endpoint, err := CreateEndpoint(value) - if err != nil { - return err - } - peer.endpoint = endpoint - peer.timer.handshakeDeadline.Reset(RekeyAttemptTime) - return nil - }() - - if err != nil { - logError.Println("Failed to set endpoint:", value) - return &IPCError{Code: ipcErrorInvalid} - } - - case "persistent_keepalive_interval": - - // update keep-alive interval - - logDebug.Println("UAPI: Updating persistent_keepalive_interval for peer:", peer.String()) - - secs, err := strconv.ParseUint(value, 10, 16) - if err != nil { - logError.Println("Failed to set persistent_keepalive_interval:", err) - return &IPCError{Code: ipcErrorInvalid} - } - - old := atomic.SwapUint64( - &peer.persistentKeepaliveInterval, - secs, - ) - - // send immediate keep-alive - - if old == 0 && secs != 0 { - if err != nil { - logError.Println("Failed to get tun device status:", err) - return &IPCError{Code: ipcErrorIO} - } - if device.isUp.Get() && !dummy { - peer.SendKeepAlive() - } - } - - case "replace_allowed_ips": - - logDebug.Println("UAPI: Removing all allowed IPs for peer:", peer.String()) - - if value != "true" { - logError.Println("Failed to set replace_allowed_ips, invalid value:", value) - return &IPCError{Code: ipcErrorInvalid} - } - - if dummy { - continue - } - - device.routing.mutex.Lock() - device.routing.table.RemovePeer(peer) - device.routing.mutex.Unlock() - - case "allowed_ip": - - logDebug.Println("UAPI: Adding allowed_ip to peer:", peer.String()) - - _, network, err := net.ParseCIDR(value) - if err != nil { - logError.Println("Failed to set allowed_ip:", err) - return &IPCError{Code: ipcErrorInvalid} - } - - if dummy { - continue - } - - ones, _ := network.Mask.Size() - device.routing.mutex.Lock() - device.routing.table.Insert(network.IP, uint(ones), peer) - device.routing.mutex.Unlock() - - default: - logError.Println("Invalid UAPI key (peer configuration):", key) - return &IPCError{Code: ipcErrorInvalid} - } - } - } - - return nil -} - -func ipcHandle(device *Device, socket net.Conn) { - - // create buffered read/writer - - defer socket.Close() - - buffered := func(s io.ReadWriter) *bufio.ReadWriter { - reader := bufio.NewReader(s) - writer := bufio.NewWriter(s) - return bufio.NewReadWriter(reader, writer) - }(socket) - - defer buffered.Flush() - - op, err := buffered.ReadString('\n') - if err != nil { - return - } - - // handle operation - - var status *IPCError - - switch op { - case "set=1\n": - device.log.Debug.Println("Config, set operation") - status = ipcSetOperation(device, buffered) - - case "get=1\n": - device.log.Debug.Println("Config, get operation") - 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") - } -} |