package gre import ( "math" "net" "log" "os" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/link/channel" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/transport/raw" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/waiter" ) var SIZE = 16 type Endpoint struct { channel.Endpoint } type writer Endpoint func New(mtu uint32) *Endpoint{ var linkAddress tcpip.LinkAddress ch := channel.New(SIZE, mtu, linkAddress) return &Endpoint{ Endpoint: *ch, } } func (e *Endpoint) GetChannel() *channel.Endpoint { return &e.Endpoint } func (e *Endpoint) Bind(s *stack.Stack, laddr tcpip.FullAddress) { log.Println("Bind begin") // Create TCP endpoint. var wq waiter.Queue ep, err := raw.NewEndpoint(s, ipv4.ProtocolNumber, header.GREProtocolNumber, &wq) if err != nil { log.Fatal(err) } log.Println("EP: %s", ep) raddr := tcpip.FullAddress{NIC: 1, Addr: tcpip.Address(net.ParseIP("10.0.0.1"))} log.Println("Remote:", raddr.Addr, raddr) if err := ep.Bind(tcpip.FullAddress{1, "", 0}); err != nil { log.Fatal("Bind failed: ", err) } // if err := ep.Connect(raddr); err != nil { // log.Fatal("Connect failed: ", err) // } // Issue connect request and wait for it to complete. waitEntry, notifyCh := waiter.NewChannelEntry(nil) // Read data and write to standard output until the peer closes the // connection from its side. wq.EventRegister(&waitEntry, waiter.EventIn) for { _, err := ep.Read(os.Stdout, math.MaxUint16, tcpip.ReadOptions{}) if err != nil { if err == tcpip.ErrClosedForReceive { break } if err == tcpip.ErrWouldBlock { <-notifyCh continue } log.Fatal("Read() failed:", err) } } wq.EventUnregister(&waitEntry) log.Println("Bind end") } // Attach saves the stack network-layer dispatcher for use later when packets // are injected. func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { log.Println("GRE: Attach") e.Endpoint.Attach(dispatcher) }