mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 09:25:41 +08:00
tproxy: add base udp tproxy listener codes
This commit is contained in:
parent
4fe5eb97bb
commit
fdbb9a5034
@ -42,7 +42,7 @@ General:
|
||||
|
||||
TODO:
|
||||
- [x] UDP over TCP Tunnel (client <-udp-> uottun <-tcp-> ss <-udp-> target)
|
||||
- [ ] Linux tproxy support
|
||||
- [ ] Transparent UDP proxy (linux tproxy)
|
||||
- [ ] TUN/TAP device support
|
||||
- [ ] Code refactoring: support proxy registering so it can be pluggable
|
||||
- [ ] Conditional compilation so we can abandon needless proxy type and get a smaller binary size
|
||||
|
@ -43,7 +43,7 @@ dns://53
|
||||
# global remote dns server (you can specify different dns server in rule file)
|
||||
dnsserver=8.8.8.8:53
|
||||
|
||||
# Create and mange ipset on linux based on destinations in rule files
|
||||
# Create and manage ipset on linux based on destinations in rule files
|
||||
# - add ip/cidrs in rule files on startup
|
||||
# - add resolved ips for domains in rule files by dns forwarder server
|
||||
# Usually used in transparent proxy mode on linux
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shadowsocks/go-shadowsocks2/socks"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -32,7 +30,7 @@ func NewRedirProxy(addr string, sDialer Dialer) (*RedirProxy, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ListenAndServe redirected requests as a server.
|
||||
// ListenAndServe .
|
||||
func (s *RedirProxy) ListenAndServe() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
@ -84,7 +82,7 @@ func (s *RedirProxy) ListenAndServe() {
|
||||
}
|
||||
|
||||
// Get the original destination of a TCP connection.
|
||||
func getOrigDst(conn net.Conn, ipv6 bool) (socks.Addr, error) {
|
||||
func getOrigDst(conn net.Conn, ipv6 bool) (Addr, error) {
|
||||
c, ok := conn.(*net.TCPConn)
|
||||
if !ok {
|
||||
return nil, errors.New("only work with TCP connection")
|
||||
@ -112,7 +110,7 @@ func getOrigDst(conn net.Conn, ipv6 bool) (socks.Addr, error) {
|
||||
}
|
||||
|
||||
// Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
|
||||
func getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
func getorigdst(fd uintptr) (Addr, error) {
|
||||
raw := syscall.RawSockaddrInet4{}
|
||||
siz := unsafe.Sizeof(raw)
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
@ -120,7 +118,7 @@ func getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
}
|
||||
|
||||
addr := make([]byte, 1+net.IPv4len+2)
|
||||
addr[0] = socks.AtypIPv4
|
||||
addr[0] = socks5IP4
|
||||
copy(addr[1:1+net.IPv4len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv4len], addr[1+net.IPv4len+1] = port[0], port[1]
|
||||
@ -129,7 +127,7 @@ func getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
|
||||
// Call ipv6_getorigdst() from linux/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
|
||||
// NOTE: I haven't tried yet but it should work since Linux 3.8.
|
||||
func ipv6_getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
func ipv6_getorigdst(fd uintptr) (Addr, error) {
|
||||
raw := syscall.RawSockaddrInet6{}
|
||||
siz := unsafe.Sizeof(raw)
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
@ -137,7 +135,7 @@ func ipv6_getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
}
|
||||
|
||||
addr := make([]byte, 1+net.IPv6len+2)
|
||||
addr[0] = socks.AtypIPv6
|
||||
addr[0] = socks5IP6
|
||||
copy(addr[1:1+net.IPv6len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv6len], addr[1+net.IPv6len+1] = port[0], port[1]
|
||||
|
@ -15,7 +15,7 @@ func NewRedirProxy(addr string, sDialer Dialer) (*RedirProxy, error) {
|
||||
return nil, errors.New("redir not supported on this os")
|
||||
}
|
||||
|
||||
// ListenAndServe redirected requests as a server.
|
||||
// ListenAndServe .
|
||||
func (s *RedirProxy) ListenAndServe() {
|
||||
log.Fatal("redir not supported on this os")
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func NewSOCKS5(addr, user, pass string, cDialer Dialer, sDialer Dialer) (*SOCKS5
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ListenAndServe connects to the address addr on the network net via the SOCKS5 proxy.
|
||||
// ListenAndServe .
|
||||
func (s *SOCKS5) ListenAndServe() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
|
@ -21,7 +21,7 @@ func NewTCPTun(addr, raddr string, sDialer Dialer) (*TCPTun, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ListenAndServe redirected requests as a server.
|
||||
// ListenAndServe .
|
||||
func (s *TCPTun) ListenAndServe() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
|
68
tproxy.go
Normal file
68
tproxy.go
Normal file
@ -0,0 +1,68 @@
|
||||
// +build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
func (s *TProxy) ListenAndServeTCP() {
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
20
tproxy_other.go
Normal file
20
tproxy_other.go
Normal file
@ -0,0 +1,20 @@
|
||||
// +build !linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
)
|
||||
|
||||
type TProxy struct{}
|
||||
|
||||
// NewTProxy returns a tproxy.
|
||||
func NewTProxy(addr string, sDialer Dialer) (*TProxy, error) {
|
||||
return nil, errors.New("tproxy not supported on this os")
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *TProxy) ListenAndServe() {
|
||||
log.Fatal("tproxy not supported on this os")
|
||||
}
|
Loading…
Reference in New Issue
Block a user