mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-23 11:00:25 +00:00
proxy: prepare to encapsulate UDP datagrams over a vsock connection
A net.UDPListener is the datagram equivalent of a net.Conn. This patch accepts at most one connection from vsock and attempts to read and write UDP datagrams along it. Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
parent
abbafd82f1
commit
3870705eaf
@ -28,22 +28,16 @@ type Proxy interface {
|
|||||||
|
|
||||||
|
|
||||||
// NewProxy creates a Proxy according to the specified frontendAddr and backendAddr.
|
// NewProxy creates a Proxy according to the specified frontendAddr and backendAddr.
|
||||||
func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
|
func NewProxy(frontendAddr *vsock.VsockAddr, backendAddr net.Addr) (Proxy, error) {
|
||||||
switch frontendAddr.(type) {
|
switch backendAddr.(type) {
|
||||||
case *net.UDPAddr:
|
case *net.UDPAddr:
|
||||||
listener, err := net.ListenUDP("udp", frontendAddr.(*net.UDPAddr))
|
listener, err := vsock.Listen(frontendAddr.Port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewUDPProxy(frontendAddr, listener, backendAddr.(*net.UDPAddr))
|
return NewUDPProxy(frontendAddr, NewUDPListener(listener), backendAddr.(*net.UDPAddr))
|
||||||
case *net.TCPAddr:
|
case *net.TCPAddr:
|
||||||
listener, err := net.Listen("tcp", frontendAddr.String())
|
listener, err := vsock.Listen(frontendAddr.Port)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewTCPProxy(listener, backendAddr.(*net.TCPAddr))
|
|
||||||
case *vsock.VsockAddr:
|
|
||||||
listener, err := vsock.Listen(frontendAddr.(*vsock.VsockAddr).Port)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
100
alpine/packages/proxy/libproxy/udp_encapsulation.go
Normal file
100
alpine/packages/proxy/libproxy/udp_encapsulation.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package libproxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
//"strings"
|
||||||
|
"sync"
|
||||||
|
//"syscall"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type udpListener interface {
|
||||||
|
ReadFromUDP(b []byte) (int, *net.UDPAddr, error)
|
||||||
|
WriteToUDP(b []byte, addr *net.UDPAddr) (int, error)
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type udpEncapsulator struct {
|
||||||
|
conn *net.Conn
|
||||||
|
listener net.Listener
|
||||||
|
m *sync.Mutex
|
||||||
|
r *sync.Mutex
|
||||||
|
w *sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpEncapsulator) getConn() (net.Conn, error) {
|
||||||
|
u.m.Lock()
|
||||||
|
defer u.m.Unlock()
|
||||||
|
if u.conn != nil {
|
||||||
|
return *u.conn, nil
|
||||||
|
}
|
||||||
|
conn, err := u.listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Printf("Failed to accept connection: %#v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.conn = &conn
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpEncapsulator) ReadFromUDP(b []byte) (int, *net.UDPAddr, error) {
|
||||||
|
conn, err := u.getConn()
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
u.r.Lock()
|
||||||
|
defer u.r.Unlock()
|
||||||
|
datagram := &udpDatagram{payload: b}
|
||||||
|
err = datagram.Unmarshal(conn)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
return len(datagram.payload), &net.UDPAddr{IP: *datagram.IP, Port: datagram.Port, Zone: datagram.Zone}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpEncapsulator) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
|
||||||
|
conn, err := u.getConn()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
u.w.Lock()
|
||||||
|
defer u.w.Unlock()
|
||||||
|
datagram := &udpDatagram{payload: b, IP: &addr.IP, Port: addr.Port, Zone: addr.Zone}
|
||||||
|
return len(b), datagram.Marshal(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpEncapsulator) Close() error {
|
||||||
|
if u.conn != nil {
|
||||||
|
conn := *u.conn
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
u.listener.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUDPListener(listener net.Listener) udpListener {
|
||||||
|
var m sync.Mutex;
|
||||||
|
return &udpEncapsulator{
|
||||||
|
conn: nil,
|
||||||
|
listener: listener,
|
||||||
|
m: &m,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type udpDatagram struct {
|
||||||
|
payload []byte
|
||||||
|
IP *net.IP
|
||||||
|
Port int
|
||||||
|
Zone string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpDatagram) Marshal(conn net.Conn) error {
|
||||||
|
return errors.New("Marshal unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *udpDatagram) Unmarshal(conn net.Conn) error {
|
||||||
|
return errors.New("Unmarshal unimplemented")
|
||||||
|
}
|
@ -18,12 +18,6 @@ const (
|
|||||||
UDPBufSize = 65507
|
UDPBufSize = 65507
|
||||||
)
|
)
|
||||||
|
|
||||||
type udpListener interface {
|
|
||||||
ReadFromUDP(b []byte) (int, *net.UDPAddr, error)
|
|
||||||
WriteToUDP(b []byte, addr *net.UDPAddr) (int, error)
|
|
||||||
Close() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// A net.Addr where the IP is split into two fields so you can use it as a key
|
// A net.Addr where the IP is split into two fields so you can use it as a key
|
||||||
// in a map:
|
// in a map:
|
||||||
type connTrackKey struct {
|
type connTrackKey struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user