summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2021-08-05 10:32:13 -0700
committerBrad Fitzpatrick <bradfitz@tailscale.com>2021-08-05 10:32:13 -0700
commit129d9e397a418dd47a54e465579a8288f202d083 (patch)
tree5fd39ea8f7ddb4c16471f5b1637b82c6254e28ae
parenta7290702526463e60e25ad126f569c858002a3fc (diff)
downloadtailscale-jknodt/portmap_test.tar.xz
tailscale-jknodt/portmap_test.zip
net/portmapper: add sketch of a TestIGD for portmapper testingjknodt/portmap_testbradfitz/portmap_test
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
-rw-r--r--net/portmapper/igd_test.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/net/portmapper/igd_test.go b/net/portmapper/igd_test.go
new file mode 100644
index 000000000..bdda9d9d3
--- /dev/null
+++ b/net/portmapper/igd_test.go
@@ -0,0 +1,78 @@
+// 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.
+
+package portmapper
+
+import (
+ "net"
+ "net/http"
+ "net/http/httptest"
+)
+
+// TestIGD is an IGD (Intenet Gateway Device) for testing. It supports fake
+// implementations of NAT-PMP, PCP, and/or UPnP to test clients against.
+type TestIGD struct {
+ upnpConn net.PacketConn // for UPnP discovery
+ pxpConn net.PacketConn // for NAT-PMP and/or PCP
+ ts *httptest.Server
+
+ doPMP bool
+ doPCP bool
+ doUPnP bool // TODO: more options for 3 flavors of UPnP services
+}
+
+func NewTestIGD() (*TestIGD, error) {
+ d := &TestIGD{
+ doPMP: true,
+ doPCP: true,
+ doUPnP: true,
+ }
+ var err error
+ if d.upnpConn, err = net.ListenPacket("udp", "127.0.0.1:1900"); err != nil {
+ return nil, err
+ }
+ if d.pxpConn, err = net.ListenPacket("udp", "127.0.0.1:5351"); err != nil {
+ return nil, err
+ }
+ d.ts = httptest.NewServer(http.HandlerFunc(d.serveUPnPHTTP))
+ go d.serveUPnPDiscovery()
+ go d.servePxP()
+ return d, nil
+}
+
+func (d *TestIGD) Close() error {
+ d.ts.Close()
+ d.upnpConn.Close()
+ d.pxpConn.Close()
+ return nil
+}
+
+func (d *TestIGD) serveUPnPHTTP(w http.ResponseWriter, r *http.Request) {
+ http.NotFound(w, r) // TODO
+}
+
+func (d *TestIGD) serveUPnPDiscovery() {
+ buf := make([]byte, 1500)
+ for {
+ n, addr, err := d.upnpConn.ReadFrom(buf)
+ if err != nil {
+ return
+ }
+ pkt := buf[:n]
+ _, _ = pkt, addr // TODO
+ }
+}
+
+// servePxP serves NAT-PMP and PCP, which share a port number.
+func (d *TestIGD) servePxP() {
+ buf := make([]byte, 1500)
+ for {
+ n, addr, err := d.pxpConn.ReadFrom(buf)
+ if err != nil {
+ return
+ }
+ pkt := buf[:n]
+ _, _ = pkt, addr // TODO
+ }
+}