112 lines
2.5 KiB
Go
112 lines
2.5 KiB
Go
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
package chirp
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type fakeBIRD struct {
|
|
net.Listener
|
|
protocolsEnabled map[string]bool
|
|
sock string
|
|
}
|
|
|
|
func newFakeBIRD(t *testing.T, protocols ...string) *fakeBIRD {
|
|
sock := filepath.Join(t.TempDir(), "sock")
|
|
l, err := net.Listen("unix", sock)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
pe := make(map[string]bool)
|
|
for _, p := range protocols {
|
|
pe[p] = false
|
|
}
|
|
return &fakeBIRD{
|
|
Listener: l,
|
|
protocolsEnabled: pe,
|
|
sock: sock,
|
|
}
|
|
}
|
|
|
|
func (fb *fakeBIRD) listen() error {
|
|
for {
|
|
c, err := fb.Accept()
|
|
if err != nil {
|
|
if errors.Is(err, net.ErrClosed) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
go fb.handle(c)
|
|
}
|
|
}
|
|
|
|
func (fb *fakeBIRD) handle(c net.Conn) {
|
|
fmt.Fprintln(c, "0001 BIRD 2.0.8 ready.")
|
|
sc := bufio.NewScanner(c)
|
|
for sc.Scan() {
|
|
cmd := sc.Text()
|
|
args := strings.Split(cmd, " ")
|
|
switch args[0] {
|
|
case "enable":
|
|
en, ok := fb.protocolsEnabled[args[1]]
|
|
if !ok {
|
|
fmt.Fprintln(c, "9001 syntax error, unexpected CF_SYM_UNDEFINED, expecting CF_SYM_KNOWN or TEXT or ALL")
|
|
} else if en {
|
|
fmt.Fprintf(c, "0010-%s: already enabled\n", args[1])
|
|
} else {
|
|
fmt.Fprintf(c, "0011-%s: enabled\n", args[1])
|
|
}
|
|
fmt.Fprintln(c, "0000 ")
|
|
fb.protocolsEnabled[args[1]] = true
|
|
case "disable":
|
|
en, ok := fb.protocolsEnabled[args[1]]
|
|
if !ok {
|
|
fmt.Fprintln(c, "9001 syntax error, unexpected CF_SYM_UNDEFINED, expecting CF_SYM_KNOWN or TEXT or ALL")
|
|
} else if !en {
|
|
fmt.Fprintf(c, "0008-%s: already disabled\n", args[1])
|
|
} else {
|
|
fmt.Fprintf(c, "0009-%s: disabled\n", args[1])
|
|
}
|
|
fmt.Fprintln(c, "0000 ")
|
|
fb.protocolsEnabled[args[1]] = false
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestChirp(t *testing.T) {
|
|
fb := newFakeBIRD(t, "tailscale")
|
|
defer fb.Close()
|
|
go fb.listen()
|
|
c, err := New(fb.sock)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := c.EnableProtocol("tailscale"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := c.EnableProtocol("tailscale"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := c.DisableProtocol("tailscale"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := c.DisableProtocol("tailscale"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := c.EnableProtocol("rando"); err == nil {
|
|
t.Fatalf("enabling %q succeded", "rando")
|
|
}
|
|
if err := c.DisableProtocol("rando"); err == nil {
|
|
t.Fatalf("disabling %q succeded", "rando")
|
|
}
|
|
}
|