mirror of
https://github.com/yggdrasil-network/yggstack.git
synced 2025-04-28 14:15:07 +03:00
Refactor UDP port forwarding and document usage
This commit is contained in:
parent
0783b429fd
commit
f529064aa0
4 changed files with 52 additions and 43 deletions
33
README.md
33
README.md
|
@ -72,7 +72,8 @@ other configuration such as listen addresses or multicast addresses, etc.
|
||||||
|
|
||||||
### Run Yggstack
|
### Run Yggstack
|
||||||
|
|
||||||
To run SOCKS proxy server listening on local port 1080 using generated configuration:
|
To run SOCKS proxy server listening on local port 1080 using generated
|
||||||
|
configuration (like `ssh -D`):
|
||||||
|
|
||||||
```
|
```
|
||||||
./yggstack -useconffile /path/to/yggdrasil.conf -socks 127.0.0.1:1080
|
./yggstack -useconffile /path/to/yggdrasil.conf -socks 127.0.0.1:1080
|
||||||
|
@ -84,11 +85,35 @@ To run SOCKS proxy server listening on UNIX socket file `/tmp/yggstack.sock`:
|
||||||
./yggstack -useconffile /path/to/yggdrasil.conf -socks /tmp/yggstack.sock
|
./yggstack -useconffile /path/to/yggdrasil.conf -socks /tmp/yggstack.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
To expose network services (like a Web server) listening on local port 8080 to Yggdrasil
|
To expose network services (like a Web server) listening on local port 8080
|
||||||
network address at port 80:
|
to Yggdrasil network address at port 80 (like `ssh -R`):
|
||||||
|
|
||||||
|
TCP:
|
||||||
|
|
||||||
```
|
```
|
||||||
./yggstack -useconffile /path/to/yggdrasil.conf -exposetcp 80:127.0.0.1:8080
|
./yggstack -useconffile /path/to/yggdrasil.conf -remote-tcp 80:127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
UDP:
|
||||||
|
|
||||||
|
```
|
||||||
|
./yggstack -useconffile /path/to/yggdrasil.conf -remote-udp 53:127.0.0.1:53
|
||||||
|
```
|
||||||
|
|
||||||
|
To forward remote port on some other Yggdrasil node to local machine (like `ssh -L`):
|
||||||
|
|
||||||
|
TCP:
|
||||||
|
|
||||||
|
```
|
||||||
|
./yggstack -useconffile /path/to/yggdrasil.conf -local-tcp 127.0.0.1:8080:<remote-yggdrasil-ipv6>:8080
|
||||||
|
./yggstack -useconffile /path/to/yggdrasil.conf -local-tcp [::1]:8080:<remote-yggdrasil-ipv6>:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
UDP:
|
||||||
|
|
||||||
|
```
|
||||||
|
./yggstack -useconffile /path/to/yggdrasil.conf -local-udp 127.0.0.1:5353:<remote-yggdrasil-ipv6>:53
|
||||||
|
./yggstack -useconffile /path/to/yggdrasil.conf -local-udp [::1]:5353:<remote-yggdrasil-ipv6>:53
|
||||||
```
|
```
|
||||||
|
|
||||||
To run as a standalone node without SOCKS server or TCP port forwarding:
|
To run as a standalone node without SOCKS server or TCP port forwarding:
|
||||||
|
|
|
@ -31,6 +31,8 @@ import (
|
||||||
|
|
||||||
"github.com/yggdrasil-network/yggstack/src/netstack"
|
"github.com/yggdrasil-network/yggstack/src/netstack"
|
||||||
"github.com/yggdrasil-network/yggstack/src/types"
|
"github.com/yggdrasil-network/yggstack/src/types"
|
||||||
|
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
)
|
)
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
|
@ -40,13 +42,8 @@ type node struct {
|
||||||
socks5Listener net.Listener
|
socks5Listener net.Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
type UDPConnSession struct {
|
type UDPSession struct {
|
||||||
conn *net.UDPConn
|
conn interface{}
|
||||||
remoteAddr net.Addr
|
|
||||||
}
|
|
||||||
|
|
||||||
type UDPPacketConnSession struct {
|
|
||||||
conn *net.PacketConn
|
|
||||||
remoteAddr net.Addr
|
remoteAddr net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,22 +393,23 @@ func main() {
|
||||||
logger.Errorf("Failed to connect to %s: %s", mapping.Mapped, err)
|
logger.Errorf("Failed to connect to %s: %s", mapping.Mapped, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
udpSession := &UDPPacketConnSession{
|
udpSession := &UDPSession{
|
||||||
conn: &udpFwdConn,
|
conn: udpFwdConn,
|
||||||
remoteAddr: remoteUdpAddr,
|
remoteAddr: remoteUdpAddr,
|
||||||
}
|
}
|
||||||
localUdpConnections.Store(remoteUdpAddrStr, udpSession)
|
localUdpConnections.Store(remoteUdpAddrStr, udpSession)
|
||||||
go types.ReverseProxyUDPPacketConn(mtu, udpListenConn, remoteUdpAddr, udpFwdConn)
|
go types.ReverseProxyUDP(mtu, udpListenConn, remoteUdpAddr, udpFwdConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
udpSession, ok := connVal.(*UDPPacketConnSession)
|
udpSession, ok := connVal.(*UDPSession)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
udpFwdConn := *udpSession.conn
|
udpFwdConnPtr := udpSession.conn.(*gonet.UDPConn)
|
||||||
|
udpFwdConn := *udpFwdConnPtr
|
||||||
|
|
||||||
_, err = udpFwdConn.WriteTo(udpBuffer[:bytesRead], mapping.Mapped)
|
_, err = udpFwdConn.Write(udpBuffer[:bytesRead])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debugf("Cannot write from yggdrasil to udp listener: %q", err)
|
logger.Debugf("Cannot write from yggdrasil to udp listener: %q", err)
|
||||||
udpFwdConn.Close()
|
udpFwdConn.Close()
|
||||||
|
@ -482,23 +480,26 @@ func main() {
|
||||||
logger.Errorf("Failed to connect to %s: %s", mapping.Mapped, err)
|
logger.Errorf("Failed to connect to %s: %s", mapping.Mapped, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
udpSession := &UDPConnSession{
|
udpSession := &UDPSession{
|
||||||
conn: udpFwdConn,
|
conn: udpFwdConn,
|
||||||
remoteAddr: remoteUdpAddr,
|
remoteAddr: remoteUdpAddr,
|
||||||
}
|
}
|
||||||
remoteUdpConnections.Store(remoteUdpAddrStr, udpSession)
|
remoteUdpConnections.Store(remoteUdpAddrStr, udpSession)
|
||||||
go types.ReverseProxyUDPConn(mtu, udpListenConn, remoteUdpAddr, *udpFwdConn)
|
go types.ReverseProxyUDP(mtu, udpListenConn, remoteUdpAddr, udpFwdConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
udpSession, ok := connVal.(*UDPConnSession)
|
udpSession, ok := connVal.(*UDPSession)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = udpSession.conn.Write(udpBuffer[:bytesRead])
|
udpFwdConnPtr := udpSession.conn.(*net.UDPConn)
|
||||||
|
udpFwdConn := *udpFwdConnPtr
|
||||||
|
|
||||||
|
_, err = udpFwdConn.Write(udpBuffer[:bytesRead])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debugf("Cannot write from yggdrasil to udp listener: %q", err)
|
logger.Debugf("Cannot write from yggdrasil to udp listener: %q", err)
|
||||||
udpSession.conn.Close()
|
udpFwdConn.Close()
|
||||||
remoteUdpConnections.Delete(remoteUdpAddrStr)
|
remoteUdpConnections.Delete(remoteUdpAddrStr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,12 +86,12 @@ func (s *YggdrasilNetstack) DialContext(ctx context.Context, network, address st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *YggdrasilNetstack) DialTCP(addr *net.TCPAddr) (net.Conn, error) {
|
func (s *YggdrasilNetstack) DialTCP(addr *net.TCPAddr) (*gonet.TCPConn, error) {
|
||||||
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
||||||
return gonet.DialTCP(s.stack, fa, pn)
|
return gonet.DialTCP(s.stack, fa, pn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *YggdrasilNetstack) DialUDP(addr *net.UDPAddr) (net.PacketConn, error) {
|
func (s *YggdrasilNetstack) DialUDP(addr *net.UDPAddr) (*gonet.UDPConn, error) {
|
||||||
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
||||||
return gonet.DialUDP(s.stack, nil, &fa, pn)
|
return gonet.DialUDP(s.stack, nil, &fa, pn)
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func (s *YggdrasilNetstack) ListenTCP(addr *net.TCPAddr) (net.Listener, error) {
|
||||||
return gonet.ListenTCP(s.stack, fa, pn)
|
return gonet.ListenTCP(s.stack, fa, pn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *YggdrasilNetstack) ListenUDP(addr *net.UDPAddr) (net.PacketConn, error) {
|
func (s *YggdrasilNetstack) ListenUDP(addr *net.UDPAddr) (*gonet.UDPConn, error) {
|
||||||
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
fa, pn, _ := convertToFullAddr(addr.IP, addr.Port)
|
||||||
return gonet.DialUDP(s.stack, &fa, nil, pn)
|
return gonet.DialUDP(s.stack, &fa, nil, pn)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReverseProxyUDPConn(mtu uint64, dst net.PacketConn, dstAddr net.Addr, src net.UDPConn) error {
|
func ReverseProxyUDP(mtu uint64, dst net.PacketConn, dstAddr net.Addr, src net.Conn) error {
|
||||||
buf := make([]byte, mtu)
|
buf := make([]byte, mtu)
|
||||||
for {
|
for {
|
||||||
n, err := src.Read(buf[:])
|
n, err := src.Read(buf[:])
|
||||||
|
@ -20,20 +20,3 @@ func ReverseProxyUDPConn(mtu uint64, dst net.PacketConn, dstAddr net.Addr, src n
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReverseProxyUDPPacketConn(mtu uint64, dst net.PacketConn, dstAddr net.Addr, src net.PacketConn) error {
|
|
||||||
buf := make([]byte, mtu)
|
|
||||||
for {
|
|
||||||
n, _, err := src.ReadFrom(buf[:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n > 0 {
|
|
||||||
n, err = dst.WriteTo(buf[:n], dstAddr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue