glider/tproxy.go

72 lines
1.6 KiB
Go
Raw Normal View History

// +build linux
package main
import (
"net"
"syscall"
)
// TProxy struct
type TProxy struct {
*Forwarder // as client
sDialer Dialer // dialer for server
}
// NewTProxy returns a tproxy.
func NewTProxy(addr string, sDialer Dialer) (*TProxy, error) {
s := &TProxy{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
}
return s, nil
}
// ListenAndServe .
func (s *TProxy) ListenAndServe() {
// go s.ListenAndServeTCP()
s.ListenAndServeUDP()
}
// ListenAndServeTCP .
func (s *TProxy) ListenAndServeTCP() {
logf("proxy-tproxy tcp mode not supported now, please use 'redir' instead")
}
// ListenAndServeUDP .
func (s *TProxy) ListenAndServeUDP() {
laddr, err := net.ResolveUDPAddr("udp", s.addr)
if err != nil {
logf("proxy-tproxy failed to resolve addr %s: %v", s.addr, err)
return
}
listener, err := net.ListenUDP("udp", laddr)
if err != nil {
logf("proxy-tproxy failed to listen on %s: %v", s.addr, err)
return
}
fd, err := listener.File()
if err != nil {
logf("proxy-tproxy failed to get file descriptor: %v", err)
return
}
defer fd.Close()
fileDescriptor := int(fd.Fd())
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
syscall.Close(fileDescriptor)
logf("proxy-tproxy failed to set socket option IP_TRANSPARENT: %v", err)
return
}
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_IP, syscall.IP_RECVORIGDSTADDR, 1); err != nil {
syscall.Close(fileDescriptor)
logf("proxy-tproxy failed to set socket option IP_RECVORIGDSTADDR: %v", err)
return
}
}