summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/sample/tun_tcp_connect/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/sample/tun_tcp_connect/main.go')
-rw-r--r--pkg/tcpip/sample/tun_tcp_connect/main.go77
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.