mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
tstest/integration/vms: end-to-end UDP test (#2361)
This tests incoming and outgoing UDP traffic. It would test incoming UDP traffic however our socks server doesn't seem to allow for connecting to destinations over UDP. When the socks server gets that support the incoming test should pass without issue. Signed-off-by: Christine Dodrill <xe@tailscale.com>
This commit is contained in:
parent
a19eea965f
commit
dc78be12c5
80
tstest/integration/vms/udp_tester.go
Normal file
80
tstest/integration/vms/udp_tester.go
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2021 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// Command udp_tester exists because all of these distros being tested don't
|
||||
// have a consistent tool for doing UDP traffic. This is a very hacked up tool
|
||||
// that does that UDP traffic so these tests can be done.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
client = flag.String("client", "", "host:port to connect to for sending UDP")
|
||||
server = flag.String("server", "", "host:port to bind to for receiving UDP")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *client == "" && *server == "" {
|
||||
log.Fatal("specify -client or -server")
|
||||
}
|
||||
|
||||
if *client != "" {
|
||||
conn, err := net.Dial("udp", *client)
|
||||
if err != nil {
|
||||
log.Fatalf("can't dial %s: %v", *client, err)
|
||||
}
|
||||
log.Printf("dialed to %s", conn.RemoteAddr())
|
||||
defer conn.Close()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, err := os.Stdin.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
log.Fatalf("can't read from stdin: %v", err)
|
||||
}
|
||||
|
||||
nn, err := conn.Write(buf[:n])
|
||||
if err != nil {
|
||||
log.Fatalf("can't write to %s: %v", conn.RemoteAddr(), err)
|
||||
}
|
||||
|
||||
if n != nn {
|
||||
log.Fatalf("wanted to write %d bytes, wrote %d bytes", n, nn)
|
||||
}
|
||||
}
|
||||
|
||||
if *server != "" {
|
||||
addr, err := net.ResolveUDPAddr("udp", *server)
|
||||
if err != nil {
|
||||
log.Fatalf("can't resolve %s: %v", *server, err)
|
||||
}
|
||||
ln, err := net.ListenUDP("udp", addr)
|
||||
if err != nil {
|
||||
log.Fatalf("can't listen %s: %v", *server, err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
n, _, err := ln.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if n == 0 {
|
||||
log.Fatal("got nothing")
|
||||
}
|
||||
|
||||
fmt.Print(string(buf[:n]))
|
||||
}
|
||||
}
|
@ -859,6 +859,122 @@ func (h Harness) testDistro(t *testing.T, d Distro, ipm ipMapping) {
|
||||
t.Fatalf("wanted reported ip to be %q, got: %q", string(ipBytes), string(testIPBytes))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("outgoing-udp-ipv4", func(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("can't get working directory: %v", err)
|
||||
}
|
||||
dir := t.TempDir()
|
||||
run(t, cwd, "go", "build", "-o", filepath.Join(dir, "udp_tester"), "./udp_tester.go")
|
||||
|
||||
sftpCli, err := sftp.NewClient(cli)
|
||||
if err != nil {
|
||||
t.Fatalf("can't connect over sftp to copy binaries: %v", err)
|
||||
}
|
||||
defer sftpCli.Close()
|
||||
|
||||
copyFile(t, sftpCli, filepath.Join(dir, "udp_tester"), "/udp_tester")
|
||||
|
||||
uaddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort("::", "0"))
|
||||
if err != nil {
|
||||
t.Fatalf("can't resolve udp listener addr: %v", err)
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
ln, err := net.ListenUDP("udp", uaddr)
|
||||
if err != nil {
|
||||
t.Fatalf("can't listen for UDP traffic: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
sess, err := cli.NewSession()
|
||||
if err != nil {
|
||||
t.Fatalf("can't open session: %v", err)
|
||||
}
|
||||
defer sess.Close()
|
||||
|
||||
sess.Stdin = strings.NewReader("hi")
|
||||
sess.Stdout = logger.FuncWriter(t.Logf)
|
||||
sess.Stderr = logger.FuncWriter(t.Logf)
|
||||
|
||||
_, port, _ := net.SplitHostPort(ln.LocalAddr().String())
|
||||
|
||||
go func() {
|
||||
cmd := fmt.Sprintf("/udp_tester -client %s\n", net.JoinHostPort("100.64.0.1", port))
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
t.Logf("sending packet: %s", cmd)
|
||||
err := sess.Run(cmd)
|
||||
if err != nil {
|
||||
t.Errorf("can't send UDP packet: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
t.Log("listening for packet")
|
||||
n, _, err := ln.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
t.Fatal("got nothing")
|
||||
}
|
||||
|
||||
if !bytes.Contains(buf, []byte("hi")) {
|
||||
t.Fatal("did not get UDP message")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("incoming-udp-ipv4", func(t *testing.T) {
|
||||
// vms_test.go:947: can't dial: socks connect udp 127.0.0.1:36497->100.64.0.2:33409: network not implemented
|
||||
t.Skip("can't make outgoing sockets over UDP with our socks server")
|
||||
|
||||
sess, err := cli.NewSession()
|
||||
if err != nil {
|
||||
t.Fatalf("can't open session: %v", err)
|
||||
}
|
||||
defer sess.Close()
|
||||
|
||||
ip, err := sess.Output("tailscale ip -4")
|
||||
if err != nil {
|
||||
t.Fatalf("can't nab ipv4 address: %v", err)
|
||||
}
|
||||
|
||||
port, err := getProbablyFreePortNumber()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to fetch port number: %v", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
conn, err := h.testerDialer.Dial("udp", net.JoinHostPort(string(bytes.TrimSpace(ip)), strconv.Itoa(port)))
|
||||
if err != nil {
|
||||
t.Errorf("can't dial: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprint(conn, securePassword)
|
||||
}()
|
||||
|
||||
sess, err = cli.NewSession()
|
||||
if err != nil {
|
||||
t.Fatalf("can't open session: %v", err)
|
||||
}
|
||||
defer sess.Close()
|
||||
sess.Stderr = logger.FuncWriter(t.Logf)
|
||||
|
||||
msg, err := sess.Output(
|
||||
fmt.Sprintf(
|
||||
"/udp_tester -server %s",
|
||||
net.JoinHostPort(string(bytes.TrimSpace(ip)), strconv.Itoa(port)),
|
||||
),
|
||||
)
|
||||
|
||||
if msg := string(bytes.TrimSpace(msg)); msg != securePassword {
|
||||
t.Fatalf("wanted %q from vm, got: %q", securePassword, msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func runTestCommands(t *testing.T, timeout time.Duration, cli *ssh.Client, batch []expect.Batcher) {
|
||||
|
Loading…
Reference in New Issue
Block a user