summaryrefslogtreecommitdiff
path: root/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2021-04-14 16:54:42 +0200
committerkali kaneko (leap communications) <kali@leap.se>2021-04-14 16:54:42 +0200
commit67a0eb7111d3f89e4a0cb21e43aefe6d87d37e04 (patch)
treec9b18e0da6e06ac165a485ee957b7850adb12e86 /vendor/github.com/apparentlymart/go-openvpn-mgmt/demux
parent2e8f2a2e8e83fd89f956cdde886d5d9d808132da (diff)
[pkg] go mod vendor to build debian/ubuntu packages
Diffstat (limited to 'vendor/github.com/apparentlymart/go-openvpn-mgmt/demux')
-rw-r--r--vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/demuxer.go63
-rw-r--r--vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/doc.go12
2 files changed, 75 insertions, 0 deletions
diff --git a/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/demuxer.go b/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/demuxer.go
new file mode 100644
index 0000000..c57964e
--- /dev/null
+++ b/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/demuxer.go
@@ -0,0 +1,63 @@
+package demux
+
+import (
+ "bufio"
+ "io"
+)
+
+var readErrSynthEvent = []byte("FATAL:Error reading from OpenVPN")
+
+// Demultiplex reads from the given io.Reader, assumed to be the client
+// end of an OpenVPN Management Protocol connection, and splits it into
+// distinct messages from OpenVPN.
+//
+// It then writes the raw message buffers into either replyCh or eventCh
+// depending on whether each message is a reply to a client command or
+// an asynchronous event notification.
+//
+// The buffers written to replyCh are entire raw message lines (without the
+// trailing newlines), while the buffers written to eventCh are the raw
+// event strings with the prototcol's leading '>' indicator omitted.
+//
+// The caller should usually provide buffered channels of sufficient buffer
+// depth so that the reply channel will not be starved by slow event
+// processing.
+//
+// Once the io.Reader signals EOF, eventCh will be closed, then replyCh
+// will be closed, and then this function will return.
+//
+// As a special case, if a non-EOF error occurs while reading from the
+// io.Reader then a synthetic "FATAL" event will be written to eventCh
+// before the two buffers are closed and the function returns. This
+// synthetic message will have the error message "Error reading from OpenVPN".
+func Demultiplex(r io.Reader, replyCh, eventCh chan<- []byte) {
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ buf := scanner.Bytes()
+
+ if len(buf) < 1 {
+ // Should never happen but we'll be robust and ignore this,
+ // rather than crashing below.
+ continue
+ }
+
+ // Asynchronous messages always start with > to differentiate
+ // them from replies.
+ if buf[0] == '>' {
+ // Trim off the > when we post the message, since it's
+ // redundant after we've demuxed.
+ eventCh <- buf[1:]
+ } else {
+ replyCh <- buf
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ // Generate a synthetic FATAL event so that the caller can
+ // see that the connection was not gracefully closed.
+ eventCh <- readErrSynthEvent
+ }
+
+ close(eventCh)
+ close(replyCh)
+}
diff --git a/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/doc.go b/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/doc.go
new file mode 100644
index 0000000..263a267
--- /dev/null
+++ b/vendor/github.com/apparentlymart/go-openvpn-mgmt/demux/doc.go
@@ -0,0 +1,12 @@
+// Package demux implements low-level demultiplexing of the stream of
+// messages sent from OpenVPN on the management channel.
+//
+// OpenVPN's protocol includes two different kinds of message from the OpenVPN
+// process: replies to commands sent by the management client, and asynchronous
+// event notifications.
+//
+// This package's purpose is to split these messages into two separate streams,
+// so that functions executing command/response sequences can just block
+// on the reply channel while an event loop elsewhere deals with any async
+// events that might show up.
+package demux