mirror of
https://github.com/containers/gvisor-tap-vsock.git
synced 2026-04-23 00:27:09 +08:00
372f660354
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
57 lines
1.5 KiB
Go
57 lines
1.5 KiB
Go
package forwarder
|
|
|
|
import (
|
|
"net"
|
|
"strconv"
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"gvisor.dev/gvisor/pkg/tcpip"
|
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
|
"gvisor.dev/gvisor/pkg/tcpip/header"
|
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
|
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
|
|
"gvisor.dev/gvisor/pkg/waiter"
|
|
)
|
|
|
|
func UDP(s *stack.Stack, nat map[tcpip.Address]tcpip.Address, natLock *sync.Mutex) *udp.Forwarder {
|
|
return udp.NewForwarder(s, func(r *udp.ForwarderRequest) bool {
|
|
localAddress := r.ID().LocalAddress
|
|
|
|
if linkLocal().Contains(localAddress) || localAddress == header.IPv4Broadcast {
|
|
return true
|
|
}
|
|
|
|
natLock.Lock()
|
|
if replaced, ok := nat[localAddress]; ok {
|
|
localAddress = replaced
|
|
}
|
|
natLock.Unlock()
|
|
|
|
var wq waiter.Queue
|
|
ep, tcpErr := r.CreateEndpoint(&wq)
|
|
if tcpErr != nil {
|
|
if _, ok := tcpErr.(*tcpip.ErrConnectionRefused); ok {
|
|
// transient error
|
|
log.Debugf("r.CreateEndpoint() = %v", tcpErr)
|
|
} else {
|
|
log.Errorf("r.CreateEndpoint() = %v", tcpErr)
|
|
}
|
|
return false
|
|
}
|
|
|
|
p, _ := NewUDPProxy(&autoStoppingListener{underlying: gonet.NewUDPConn(&wq, ep)}, func() (net.Conn, error) {
|
|
return net.Dial("udp", net.JoinHostPort(localAddress.String(), strconv.Itoa(int(r.ID().LocalPort))))
|
|
})
|
|
go func() {
|
|
p.Run()
|
|
|
|
// note that at this point packets that are sent to the current forwarder session
|
|
// will be dropped. We will start processing the packets again when we get a new
|
|
// forwarder request.
|
|
ep.Close()
|
|
}()
|
|
return true
|
|
})
|
|
}
|