Files
wireguard-go/src/config.go
T

289 lines
6.5 KiB
Go
Raw Normal View History

2017-05-30 22:36:49 +02:00
package main
import (
"bufio"
"fmt"
"io"
2017-06-01 21:31:30 +02:00
"net"
2017-06-04 21:48:15 +02:00
"strconv"
2017-06-29 14:39:21 +02:00
"strings"
2017-07-17 16:16:18 +02:00
"sync/atomic"
2017-07-18 15:22:56 +02:00
"time"
2017-05-30 22:36:49 +02:00
)
type IPCError struct {
Code int64
2017-05-30 22:36:49 +02:00
}
func (s *IPCError) Error() string {
return fmt.Sprintf("IPC error: %d", s.Code)
}
func (s *IPCError) ErrorCode() int64 {
return s.Code
2017-05-30 22:36:49 +02:00
}
2017-07-17 16:16:18 +02:00
func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
2017-06-28 23:45:45 +02:00
// create lines
2017-07-17 16:16:18 +02:00
device.mutex.RLock()
2017-06-28 23:45:45 +02:00
lines := make([]string, 0, 100)
send := func(line string) {
lines = append(lines, line)
}
if !device.privateKey.IsZero() {
send("private_key=" + device.privateKey.ToHex())
}
2017-06-30 14:41:08 +02:00
send(fmt.Sprintf("listen_port=%d", device.net.addr.Port))
2017-06-28 23:45:45 +02:00
for _, peer := range device.peers {
func() {
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.String())
}
2017-07-18 15:22:56 +02:00
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))
2017-07-17 16:16:18 +02:00
send(fmt.Sprintf("persistent_keepalive_interval=%d",
atomic.LoadUint64(&peer.persistentKeepaliveInterval),
))
2017-06-28 23:45:45 +02:00
for _, ip := range device.routingTable.AllowedIPs(peer) {
send("allowed_ip=" + ip.String())
}
}()
}
2017-07-17 16:16:18 +02:00
device.mutex.RUnlock()
2017-06-28 23:45:45 +02:00
// send lines
for _, line := range lines {
_, err := socket.WriteString(line + "\n")
if err != nil {
2017-07-17 16:16:18 +02:00
return &IPCError{
Code: ipcErrorIO,
}
2017-06-28 23:45:45 +02:00
}
}
return nil
2017-05-30 22:36:49 +02:00
}
2017-06-04 21:48:15 +02:00
func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
2017-05-30 22:36:49 +02:00
scanner := bufio.NewScanner(socket)
2017-07-17 16:16:18 +02:00
logError := device.log.Error
logDebug := device.log.Debug
2017-05-30 22:36:49 +02:00
2017-06-29 14:39:21 +02:00
var peer *Peer
2017-05-30 22:36:49 +02:00
for scanner.Scan() {
2017-07-17 16:16:18 +02:00
// parse line
2017-05-30 22:36:49 +02:00
line := scanner.Text()
2017-06-29 14:39:21 +02:00
if line == "" {
return nil
2017-05-30 22:36:49 +02:00
}
2017-06-29 14:39:21 +02:00
parts := strings.Split(line, "=")
if len(parts) != 2 {
2017-05-30 22:36:49 +02:00
return &IPCError{Code: ipcErrorNoKeyValue}
}
2017-06-29 14:39:21 +02:00
key := parts[0]
value := parts[1]
2017-05-30 22:36:49 +02:00
switch key {
2017-07-17 16:16:18 +02:00
/* interface configuration */
2017-05-30 22:36:49 +02:00
case "private_key":
2017-07-21 15:17:43 +02:00
var sk NoisePrivateKey
2017-05-30 22:36:49 +02:00
if value == "" {
2017-07-21 15:17:43 +02:00
device.SetPrivateKey(sk)
2017-05-30 22:36:49 +02:00
} else {
2017-06-30 14:41:08 +02:00
err := sk.FromHex(value)
2017-05-30 22:36:49 +02:00
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set private_key:", err)
2017-06-29 14:39:21 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-05-30 22:36:49 +02:00
}
2017-06-30 14:41:08 +02:00
device.SetPrivateKey(sk)
2017-05-30 22:36:49 +02:00
}
case "listen_port":
port, err := strconv.ParseUint(value, 10, 16)
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set listen_port:", err)
2017-06-29 14:39:21 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-05-30 22:36:49 +02:00
}
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()
2017-07-17 16:16:18 +02:00
if err != nil {
logError.Println("Failed to create UDP listener:", err)
return &IPCError{Code: ipcErrorInvalidValue}
}
2017-05-30 22:36:49 +02:00
case "fwmark":
2017-07-17 16:16:18 +02:00
logError.Println("FWMark not handled yet")
2017-05-30 22:36:49 +02:00
case "public_key":
var pubKey NoisePublicKey
err := pubKey.FromHex(value)
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to get peer by public_key:", err)
2017-06-29 14:39:21 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-05-30 22:36:49 +02:00
}
2017-06-29 14:39:21 +02:00
device.mutex.RLock()
peer, _ := device.peers[pubKey]
2017-06-29 14:39:21 +02:00
device.mutex.RUnlock()
if peer == nil {
peer = device.NewPeer(pubKey)
2017-06-29 14:39:21 +02:00
}
2017-05-30 22:36:49 +02:00
case "replace_peers":
2017-06-29 14:39:21 +02:00
if value == "true" {
2017-06-04 21:48:15 +02:00
device.RemoveAllPeers()
} else {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set replace_peers, invalid value:", value)
2017-06-04 21:48:15 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-06-01 21:31:30 +02:00
}
2017-05-30 22:36:49 +02:00
default:
2017-07-17 16:16:18 +02:00
/* peer configuration */
2017-05-30 22:36:49 +02:00
if peer == nil {
2017-07-17 16:16:18 +02:00
logError.Println("No peer referenced, before peer operation")
2017-05-30 22:36:49 +02:00
return &IPCError{Code: ipcErrorNoPeer}
}
switch key {
case "remove":
2017-06-29 14:39:21 +02:00
device.RemovePeer(peer.handshake.remoteStatic)
2017-07-17 16:16:18 +02:00
logDebug.Println("Removing", peer.String())
2017-05-30 22:36:49 +02:00
peer = nil
case "preshared_key":
2017-06-01 21:31:30 +02:00
err := func() error {
2017-05-30 22:36:49 +02:00
peer.mutex.Lock()
defer peer.mutex.Unlock()
2017-06-24 15:34:17 +02:00
return peer.handshake.presharedKey.FromHex(value)
2017-05-30 22:36:49 +02:00
}()
2017-06-01 21:31:30 +02:00
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set preshared_key:", err)
2017-06-29 14:39:21 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-06-01 21:31:30 +02:00
}
2017-05-30 22:36:49 +02:00
case "endpoint":
2017-06-30 14:41:08 +02:00
addr, err := net.ResolveUDPAddr("udp", value)
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set endpoint:", value)
2017-06-29 14:39:21 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
2017-06-01 21:31:30 +02:00
}
peer.mutex.Lock()
2017-06-30 14:41:08 +02:00
peer.endpoint = addr
2017-06-01 21:31:30 +02:00
peer.mutex.Unlock()
2017-05-30 22:36:49 +02:00
case "persistent_keepalive_interval":
2017-06-04 21:48:15 +02:00
secs, err := strconv.ParseInt(value, 10, 64)
if secs < 0 || err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set persistent_keepalive_interval:", err)
2017-06-04 21:48:15 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
}
2017-07-17 16:16:18 +02:00
atomic.StoreUint64(
&peer.persistentKeepaliveInterval,
uint64(secs),
)
2017-05-30 22:36:49 +02:00
case "replace_allowed_ips":
2017-06-29 14:39:21 +02:00
if value == "true" {
2017-06-04 21:48:15 +02:00
device.routingTable.RemovePeer(peer)
} else {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set replace_allowed_ips, invalid value:", value)
2017-06-04 21:48:15 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
}
2017-05-30 22:36:49 +02:00
case "allowed_ip":
2017-06-04 21:48:15 +02:00
_, network, err := net.ParseCIDR(value)
if err != nil {
2017-07-17 16:16:18 +02:00
logError.Println("Failed to set allowed_ip:", err)
2017-06-04 21:48:15 +02:00
return &IPCError{Code: ipcErrorInvalidValue}
}
ones, _ := network.Mask.Size()
device.routingTable.Insert(network.IP, uint(ones), peer)
2017-05-30 22:36:49 +02:00
default:
2017-07-17 16:16:18 +02:00
logError.Println("Invalid UAPI key:", key)
2017-05-30 22:36:49 +02:00
return &IPCError{Code: ipcErrorInvalidKey}
}
}
}
return nil
}
2017-06-29 14:39:21 +02:00
func ipcHandle(device *Device, socket net.Conn) {
2017-05-30 22:36:49 +02:00
2017-07-17 16:16:18 +02:00
defer socket.Close()
2017-05-30 22:36:49 +02:00
2017-07-17 16:16:18 +02:00
buffered := func(s io.ReadWriter) *bufio.ReadWriter {
reader := bufio.NewReader(s)
writer := bufio.NewWriter(s)
return bufio.NewReadWriter(reader, writer)
}(socket)
2017-06-28 23:45:45 +02:00
2017-07-17 16:16:18 +02:00
defer buffered.Flush()
op, err := buffered.ReadString('\n')
if err != nil {
return
}
switch op {
case "set=1\n":
device.log.Debug.Println("Config, set operation")
err := ipcSetOperation(device, buffered)
2017-05-30 22:36:49 +02:00
if err != nil {
2017-07-17 16:16:18 +02:00
fmt.Fprintf(buffered, "errno=%d\n\n", err.ErrorCode())
} else {
fmt.Fprintf(buffered, "errno=0\n\n")
2017-05-30 22:36:49 +02:00
}
2017-07-17 16:16:18 +02:00
return
2017-05-30 22:36:49 +02:00
2017-07-17 16:16:18 +02:00
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")
2017-05-30 22:36:49 +02:00
}
2017-07-17 16:16:18 +02:00
return
2017-05-30 22:36:49 +02:00
2017-07-17 16:16:18 +02:00
default:
device.log.Error.Println("Invalid UAPI operation:", op)
}
2017-05-30 22:36:49 +02:00
}