]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
device: allow pipelining UAPI requests
authorJason A. Donenfeld <Jason@zx2c4.com>
Mon, 25 Jan 2021 18:00:43 +0000 (19:00 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 25 Jan 2021 19:48:28 +0000 (20:48 +0100)
The original spec ends with \n\n especially for this reason.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
device/uapi.go

index c1ddb3857509b46cc1aceaeae2c22f4b2322028e..31fbdc7717c181fec6d144c1a79a56abd123c77e 100644 (file)
@@ -380,9 +380,6 @@ func (device *Device) IpcSet(uapiConf string) error {
 }
 
 func (device *Device) IpcHandle(socket net.Conn) {
-
-       // create buffered read/writer
-
        defer socket.Close()
 
        buffered := func(s io.ReadWriter) *bufio.ReadWriter {
@@ -391,34 +388,43 @@ func (device *Device) IpcHandle(socket net.Conn) {
                return bufio.NewReadWriter(reader, writer)
        }(socket)
 
-       defer buffered.Flush()
-
-       op, err := buffered.ReadString('\n')
-       if err != nil {
-               return
-       }
+       for {
+               op, err := buffered.ReadString('\n')
+               if err != nil {
+                       return
+               }
 
-       // handle operation
-       switch op {
-       case "set=1\n":
-               err = device.IpcSetOperation(buffered.Reader)
-       case "get=1\n":
-               err = device.IpcGetOperation(buffered.Writer)
-       default:
-               device.log.Error.Println("invalid UAPI operation:", op)
-               return
-       }
+               // handle operation
+               switch op {
+               case "set=1\n":
+                       err = device.IpcSetOperation(buffered.Reader)
+               case "get=1\n":
+                       nextByte, err := buffered.ReadByte()
+                       if err != nil {
+                               return
+                       }
+                       if nextByte != '\n' {
+                               err = ipcErrorf(ipc.IpcErrorInvalid, "trailing character in UAPI get: %c", nextByte, err)
+                               break
+                       }
+                       err = device.IpcGetOperation(buffered.Writer)
+               default:
+                       device.log.Error.Println("invalid UAPI operation:", op)
+                       return
+               }
 
-       // write status
-       var status *IPCError
-       if err != nil && !errors.As(err, &status) {
-               // shouldn't happen
-               status = ipcErrorf(ipc.IpcErrorUnknown, "other UAPI error: %w", err)
-       }
-       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")
+               // write status
+               var status *IPCError
+               if err != nil && !errors.As(err, &status) {
+                       // shouldn't happen
+                       status = ipcErrorf(ipc.IpcErrorUnknown, "other UAPI error: %w", err)
+               }
+               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")
+               }
+               buffered.Flush()
        }
 }