mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
package bind
|
|
|
|
import (
|
|
"net"
|
|
"net/netip"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/amnezia-vpn/amneziawg-go/v3/conn"
|
|
|
|
"github.com/samosvalishe/free-turn-proxy/internal/tunnel"
|
|
)
|
|
|
|
// SinglePeerBind подключает WireGuard к каналу net.PacketConn вместо сокета.
|
|
type SinglePeerBind struct {
|
|
pc net.PacketConn
|
|
closed atomic.Bool
|
|
}
|
|
|
|
type peerEndpoint struct{}
|
|
|
|
func (peerEndpoint) ClearSrc() {}
|
|
func (peerEndpoint) SrcToString() string { return "" }
|
|
func (peerEndpoint) DstToString() string { return tunnel.EndpointSinglePeer }
|
|
func (peerEndpoint) DstToBytes() []byte { return []byte{} }
|
|
func (peerEndpoint) DstIP() netip.Addr { return netip.Addr{} }
|
|
func (peerEndpoint) SrcIP() netip.Addr { return netip.Addr{} }
|
|
|
|
var theEndpoint conn.Endpoint = peerEndpoint{}
|
|
|
|
func NewSinglePeerBind(pc net.PacketConn) *SinglePeerBind {
|
|
return &SinglePeerBind{pc: pc}
|
|
}
|
|
|
|
// Open инициализирует функции приёма пакетов и сбрасывает дедлайны.
|
|
func (b *SinglePeerBind) Open(uint16) ([]conn.ReceiveFunc, uint16, error) {
|
|
b.closed.Store(false)
|
|
if err := b.pc.SetReadDeadline(time.Time{}); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return []conn.ReceiveFunc{b.receive}, 0, nil
|
|
}
|
|
|
|
func (b *SinglePeerBind) receive(packets [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
|
|
n, _, err := b.pc.ReadFrom(packets[0])
|
|
if err != nil {
|
|
// При закрытом Bind возвращаем net.ErrClosed для корректного выхода из цикла чтения.
|
|
if b.closed.Load() {
|
|
return 0, net.ErrClosed
|
|
}
|
|
return 0, err
|
|
}
|
|
sizes[0] = n
|
|
eps[0] = theEndpoint
|
|
return 1, nil
|
|
}
|
|
|
|
func (b *SinglePeerBind) Send(bufs [][]byte, _ conn.Endpoint) error {
|
|
for _, buf := range bufs {
|
|
if _, err := b.pc.WriteTo(buf, nil); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (*SinglePeerBind) ParseEndpoint(string) (conn.Endpoint, error) {
|
|
return theEndpoint, nil
|
|
}
|
|
|
|
func (*SinglePeerBind) BatchSize() int { return 1 }
|
|
|
|
func (*SinglePeerBind) SetMark(uint32) error { return nil }
|
|
|
|
// Close прерывает текущие операции чтения без закрытия нижележащего PacketConn.
|
|
func (b *SinglePeerBind) Close() error {
|
|
if !b.closed.CompareAndSwap(false, true) {
|
|
return nil
|
|
}
|
|
return b.pc.SetReadDeadline(time.Unix(1, 0))
|
|
}
|