mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
udptun: use routine to handle upstream connection
This commit is contained in:
parent
3dc02c246b
commit
4b0388a47d
@ -2,8 +2,6 @@
|
||||
|
||||
[](https://travis-ci.org/nadoo/glider)
|
||||
[](https://goreportcard.com/report/github.com/nadoo/glider)
|
||||
[](https://golang.org/dl/)
|
||||
[](https://github.com/nadoo/glider/blob/master/LICENSE)
|
||||
[](https://github.com/nadoo/glider/releases)
|
||||
[](https://github.com/nadoo/glider/releases)
|
||||
|
||||
@ -61,7 +59,7 @@ TODO:
|
||||
Binary:
|
||||
- [https://github.com/nadoo/glider/releases](https://github.com/nadoo/glider/releases)
|
||||
|
||||
Go Get (requires **Go 1.9 or newer**):
|
||||
Go Get (requires **Go 1.9+** ):
|
||||
```bash
|
||||
go get -u github.com/nadoo/glider
|
||||
```
|
||||
|
86
tproxy.go
86
tproxy.go
@ -1,10 +1,18 @@
|
||||
// +build linux
|
||||
|
||||
// ref: https://www.kernel.org/doc/Documentation/networking/tproxy.txt
|
||||
// @LiamHaworth: https://github.com/LiamHaworth/go-tproxy/blob/master/tproxy_udp.go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// TProxy struct
|
||||
@ -42,13 +50,13 @@ func (s *TProxy) ListenAndServeUDP() {
|
||||
return
|
||||
}
|
||||
|
||||
listener, err := net.ListenUDP("udp", laddr)
|
||||
lc, 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()
|
||||
fd, err := lc.File()
|
||||
if err != nil {
|
||||
logf("proxy-tproxy failed to get file descriptor: %v", err)
|
||||
return
|
||||
@ -68,4 +76,78 @@ func (s *TProxy) ListenAndServeUDP() {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
_, srcAddr, dstAddr, err := ReadFromUDP(lc, buf)
|
||||
if err != nil {
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
|
||||
logf("proxy-tproxy Temporary error while reading data: %s", netErr)
|
||||
}
|
||||
|
||||
logf("proxy-tproxy Unrecoverable error while reading data: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
logf("proxy-tproxy Accepting UDP connection from %s with destination of %s", srcAddr.String(), dstAddr.String())
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ReadFromUDP reads a UDP packet from c, copying the payload into b.
|
||||
// It returns the number of bytes copied into b and the return address
|
||||
// that was on the packet.
|
||||
//
|
||||
// Out-of-band data is also read in so that the original destination
|
||||
// address can be identified and parsed.
|
||||
func ReadFromUDP(conn *net.UDPConn, b []byte) (int, *net.UDPAddr, *net.UDPAddr, error) {
|
||||
oob := make([]byte, 1024)
|
||||
n, oobn, _, addr, err := conn.ReadMsgUDP(b, oob)
|
||||
if err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
|
||||
msgs, err := syscall.ParseSocketControlMessage(oob[:oobn])
|
||||
if err != nil {
|
||||
return 0, nil, nil, fmt.Errorf("parsing socket control message: %s", err)
|
||||
}
|
||||
|
||||
var originalDst *net.UDPAddr
|
||||
for _, msg := range msgs {
|
||||
if msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_RECVORIGDSTADDR {
|
||||
originalDstRaw := &syscall.RawSockaddrInet4{}
|
||||
if err = binary.Read(bytes.NewReader(msg.Data), binary.LittleEndian, originalDstRaw); err != nil {
|
||||
return 0, nil, nil, fmt.Errorf("reading original destination address: %s", err)
|
||||
}
|
||||
|
||||
switch originalDstRaw.Family {
|
||||
case syscall.AF_INET:
|
||||
pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(originalDstRaw))
|
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||
originalDst = &net.UDPAddr{
|
||||
IP: net.IPv4(pp.Addr[0], pp.Addr[1], pp.Addr[2], pp.Addr[3]),
|
||||
Port: int(p[0])<<8 + int(p[1]),
|
||||
}
|
||||
|
||||
case syscall.AF_INET6:
|
||||
pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(originalDstRaw))
|
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||
originalDst = &net.UDPAddr{
|
||||
IP: net.IP(pp.Addr[:]),
|
||||
Port: int(p[0])<<8 + int(p[1]),
|
||||
Zone: strconv.Itoa(int(pp.Scope_id)),
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, nil, nil, fmt.Errorf("original destination is an unsupported network family")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if originalDst == nil {
|
||||
return 0, nil, nil, fmt.Errorf("unable to obtain original destination: %s", err)
|
||||
}
|
||||
|
||||
return n, addr, originalDst, nil
|
||||
}
|
||||
|
32
uottun.go
32
uottun.go
@ -45,24 +45,26 @@ func (s *UoTTun) ListenAndServe() {
|
||||
continue
|
||||
}
|
||||
|
||||
// NOTE: acturally udp over tcp
|
||||
rc, err := s.sDialer.Dial("udp", s.raddr)
|
||||
if err != nil {
|
||||
logf("failed to connect to server %v: %v", s.raddr, err)
|
||||
continue
|
||||
}
|
||||
go func() {
|
||||
// NOTE: acturally udp over tcp
|
||||
rc, err := s.sDialer.Dial("udp", s.raddr)
|
||||
if err != nil {
|
||||
logf("failed to connect to server %v: %v", s.raddr, err)
|
||||
return
|
||||
}
|
||||
|
||||
rc.Write(buf[:n])
|
||||
rc.Write(buf[:n])
|
||||
|
||||
resp, err := ioutil.ReadAll(rc)
|
||||
if err != nil {
|
||||
logf("error in ioutil.ReadAll: %s\n", err)
|
||||
return
|
||||
}
|
||||
rc.Close()
|
||||
resp, err := ioutil.ReadAll(rc)
|
||||
if err != nil {
|
||||
logf("error in ioutil.ReadAll: %s\n", err)
|
||||
return
|
||||
}
|
||||
rc.Close()
|
||||
|
||||
c.WriteTo(resp, clientAddr)
|
||||
c.WriteTo(resp, clientAddr)
|
||||
|
||||
logf("proxy-uottun %s <-> %s", clientAddr, s.raddr)
|
||||
logf("proxy-uottun %s <-> %s", clientAddr, s.raddr)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user