Fix UDP TPROXY incorrect src addr bug & build master action

This commit is contained in:
Toby 2021-05-09 14:53:30 -07:00
parent 0719e8980e
commit faabd094fd
2 changed files with 74 additions and 16 deletions

44
.github/workflows/build-master.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Build master
on:
push:
branches:
- 'master'
tags-ignore:
- 'v*'
jobs:
build:
name: Build
runs-on: ubuntu-latest
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
steps:
- name: Check out
uses: actions/checkout@v2
- name: Get time
uses: gerred/actions/current-time@master
id: current-time
- name: Build
uses: crazy-max/ghaction-xgo@v1
env:
TIME: "${{ steps.current-time.outputs.time }}"
with:
xgo_version: latest
go_version: latest
dest: dist
prefix: hysteria
targets: linux/amd64,linux/386,linux/arm-5,linux/arm-7,linux/arm64,linux/mipsle,darwin-10.12/amd64,darwin-10.12/arm64,windows-6.0/amd64,windows-6.0/386
ldflags: -w -s -X main.appCommit=${{ github.sha }} -X main.appDate=${{ env.TIME }}
pkg: cmd
- name: Archive
uses: actions/upload-artifact@v2
with:
name: dist
path: dist

View File

@ -52,8 +52,9 @@ func NewUDPTProxy(hyClient *core.Client, transport transport.Transport, listen s
} }
type connEntry struct { type connEntry struct {
HyConn core.UDPConn
LocalConn *net.UDPConn LocalConn *net.UDPConn
HyConn core.UDPConn
DirectConn *net.UDPConn
Deadline atomic.Value Deadline atomic.Value
} }
@ -66,7 +67,7 @@ func (r *UDPTProxy) sendPacket(entry *connEntry, dstAddr *net.UDPAddr, data []by
action, arg := acl.ActionProxy, "" action, arg := acl.ActionProxy, ""
var ipAddr *net.IPAddr var ipAddr *net.IPAddr
var resErr error var resErr error
if r.ACLEngine != nil && entry.LocalConn != nil { if r.ACLEngine != nil && entry.DirectConn != nil {
action, arg, ipAddr, resErr = r.ACLEngine.ResolveAndMatch(host) action, arg, ipAddr, resErr = r.ACLEngine.ResolveAndMatch(host)
// Doesn't always matter if the resolution fails, as we may send it through HyClient // Doesn't always matter if the resolution fails, as we may send it through HyClient
} }
@ -75,7 +76,7 @@ func (r *UDPTProxy) sendPacket(entry *connEntry, dstAddr *net.UDPAddr, data []by
if resErr != nil { if resErr != nil {
return resErr return resErr
} }
_, err = entry.LocalConn.WriteToUDP(data, &net.UDPAddr{ _, err = entry.DirectConn.WriteToUDP(data, &net.UDPAddr{
IP: ipAddr.IP, IP: ipAddr.IP,
Port: int(port), Port: int(port),
Zone: ipAddr.Zone, Zone: ipAddr.Zone,
@ -92,7 +93,7 @@ func (r *UDPTProxy) sendPacket(entry *connEntry, dstAddr *net.UDPAddr, data []by
if err != nil { if err != nil {
return err return err
} }
_, err = entry.LocalConn.WriteToUDP(data, rAddr) _, err = entry.DirectConn.WriteToUDP(data, rAddr)
return err return err
default: default:
// Do nothing // Do nothing
@ -123,21 +124,33 @@ func (r *UDPTProxy) ListenAndServe() error {
} else { } else {
// New // New
r.ConnFunc(srcAddr) r.ConnFunc(srcAddr)
hyConn, err := r.HyClient.DialUDP() localConn, err := tproxy.DialUDP("udp", dstAddr, srcAddr)
if err != nil { if err != nil {
r.ErrorFunc(srcAddr, err) r.ErrorFunc(srcAddr, err)
continue continue
} }
var localConn *net.UDPConn hyConn, err := r.HyClient.DialUDP()
if r.ACLEngine != nil {
localConn, err = r.Transport.LocalListenUDP(nil)
if err != nil { if err != nil {
r.ErrorFunc(srcAddr, err) r.ErrorFunc(srcAddr, err)
_ = localConn.Close()
continue
}
var directConn *net.UDPConn
if r.ACLEngine != nil {
directConn, err = r.Transport.LocalListenUDP(nil)
if err != nil {
r.ErrorFunc(srcAddr, err)
_ = localConn.Close()
_ = hyConn.Close()
continue continue
} }
} }
// Send // Send
entry := &connEntry{HyConn: hyConn, LocalConn: localConn} entry := &connEntry{
LocalConn: localConn,
HyConn: hyConn,
DirectConn: directConn,
}
_ = r.sendPacket(entry, dstAddr, buf[:n]) _ = r.sendPacket(entry, dstAddr, buf[:n])
// Add it to the map // Add it to the map
connMapMutex.Lock() connMapMutex.Lock()
@ -151,17 +164,17 @@ func (r *UDPTProxy) ListenAndServe() error {
break break
} }
entry.Deadline.Store(time.Now().Add(r.Timeout)) entry.Deadline.Store(time.Now().Add(r.Timeout))
_, _ = conn.WriteToUDP(bs, srcAddr) _, _ = localConn.Write(bs)
} }
}() }()
if localConn != nil { if directConn != nil {
go func() { go func() {
buf := make([]byte, udpBufferSize) buf := make([]byte, udpBufferSize)
for { for {
n, _, err := localConn.ReadFrom(buf) n, _, err := directConn.ReadFrom(buf)
if n > 0 { if n > 0 {
entry.Deadline.Store(time.Now().Add(r.Timeout)) entry.Deadline.Store(time.Now().Add(r.Timeout))
_, _ = conn.WriteToUDP(buf[:n], srcAddr) _, _ = localConn.Write(buf[:n])
} }
if err != nil { if err != nil {
break break
@ -176,9 +189,10 @@ func (r *UDPTProxy) ListenAndServe() error {
if ttl <= 0 { if ttl <= 0 {
// Time to die // Time to die
connMapMutex.Lock() connMapMutex.Lock()
_ = hyConn.Close()
if localConn != nil {
_ = localConn.Close() _ = localConn.Close()
_ = hyConn.Close()
if directConn != nil {
_ = directConn.Close()
} }
delete(connMap, srcAddr.String()) delete(connMap, srcAddr.String())
connMapMutex.Unlock() connMapMutex.Unlock()