diff options
Diffstat (limited to 'pkg/tcpip/sample/tun_tcp_connect')
-rw-r--r-- | pkg/tcpip/sample/tun_tcp_connect/main.go | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 05b879543..2bbb7ffcc 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -57,8 +57,11 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/sniffer" "gvisor.dev/gvisor/pkg/tcpip/link/tun" + "gvisor.dev/gvisor/pkg/tcpip/link/tunnel" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" + "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" + "gvisor.dev/gvisor/pkg/tcpip/transport/gre" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" "gvisor.dev/gvisor/pkg/waiter" ) @@ -89,9 +92,29 @@ func writer(ch chan struct{}, ep tcpip.Endpoint) { } } +func parseIP(s string) tcpip.Address { + addr := tcpip.Address(net.ParseIP(s)) + ip4addr := addr.To4(); if ip4addr != "" { + return ip4addr + } else { + return addr + } +} + +func addAddress(s *stack.Stack, id tcpip.NICID, addr tcpip.Address) *tcpip.Error { + var proto tcpip.NetworkProtocolNumber + if addr.To4() == "" { + proto = ipv6.ProtocolNumber + } else { + proto = ipv4.ProtocolNumber + } + + return s.AddAddress(id, proto, addr) +} + func main() { - if len(os.Args) != 6 { - log.Fatal("Usage: ", os.Args[0], " <tun-device> <local-ipv4-address> <local-port> <remote-ipv4-address> <remote-port>") + if len(os.Args) != 8 { + log.Fatal("Usage: ", os.Args[0], " <tun-device> <local-ipv4-address> <local-port> <remote-ipv4-address> <remote-port> <local-gre-address> <remote-gre-address>") } tunName := os.Args[1] @@ -99,15 +122,21 @@ func main() { portName := os.Args[3] remoteAddrName := os.Args[4] remotePortName := os.Args[5] + greAddrName := os.Args[6] + greRemoteAddrName := os.Args[7] rand.Seed(time.Now().UnixNano()) - addr := tcpip.Address(net.ParseIP(addrName).To4()) + addr := parseIP(addrName) + greAddr := parseIP(greAddrName) + greRemoteAddr := parseIP(greRemoteAddrName) remote := tcpip.FullAddress{ - NIC: 1, - Addr: tcpip.Address(net.ParseIP(remoteAddrName).To4()), + NIC: 0, + Addr: parseIP(remoteAddrName), } + log.Printf("local:%v remote:%v", addr, remote) + var localPort uint16 if v, err := strconv.Atoi(portName); err != nil { log.Fatalf("Unable to convert port %v: %v", portName, err) @@ -124,8 +153,8 @@ func main() { // Create the stack with ipv4 and tcp protocols, then add a tun-based // NIC and ipv4 address. s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol}, + NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, + TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, gre.NewProtocol}, }) mtu, err := rawfile.GetMTU(tunName) @@ -146,21 +175,42 @@ func main() { log.Fatal(err) } - protocolAddr := tcpip.ProtocolAddress{ - Protocol: ipv4.ProtocolNumber, - AddressWithPrefix: addr.WithPrefix(), + if err := addAddress(s, 1, greAddr); err != nil { + log.Fatal(err) + } + + greEP := tunnel.New(mtu - 24) + if err := s.CreateNIC(2, sniffer.New(greEP)); err != nil { + log.Fatal(err) } - if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil { - log.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err) + if err := addAddress(s, 2, addr); err != nil { + log.Fatal(err) } // Add default route. + subnet, err := tcpip.NewSubnet( + tcpip.Address(parseIP("10.0.0.0")), + tcpip.AddressMask(parseIP("255.255.255.0"))) + if err != nil { + panic(err) + } s.SetRouteTable([]tcpip.Route{ { + Destination: subnet, + NIC: 1, + }, + { Destination: header.IPv4EmptySubnet, + NIC: 2, + }, + { + Destination: header.IPv6EmptySubnet, NIC: 1, }, }) + log.Printf("Nics enabled 1:%v 2:%v 3:%v", s.CheckNIC(1), s.CheckNIC(2), s.CheckNIC(3)) + + greEP.Start(s, &greAddr, &greRemoteAddr) // Create TCP endpoint. var wq waiter.Queue @@ -193,6 +243,9 @@ func main() { fmt.Println("Connected") + payload := tcpip.SlicePayload([]byte("GET / HTTP/1.0\r\nHost: www.m7n.se\r\n\r\n")) + ep.Write(payload, tcpip.WriteOptions{}) + // Start the writer in its own goroutine. writerCompletedCh := make(chan struct{}) go writer(writerCompletedCh, ep) // S/R-SAFE: sample code. |