mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2024-12-30 02:37:01 +00:00
Compare commits
3
Commits
v2.0.0-rc.3
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcf9d280b8 | ||
|
|
f18362714d | ||
|
|
95dc93cb41 |
@@ -21,9 +21,7 @@ PLATFORM_LIST = \
|
||||
openbsd-amd64 \
|
||||
openbsd-arm64 \
|
||||
|
||||
.PHONY: all docker $(PLATFORM_LIST)
|
||||
|
||||
all: $(PLATFORM_LIST)
|
||||
all: linux-amd64 darwin-amd64
|
||||
|
||||
docker:
|
||||
$(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
@@ -54,6 +52,8 @@ zip_releases=$(addsuffix .zip, $(PLATFORM_LIST))
|
||||
$(zip_releases): %.zip : %
|
||||
zip -m -j $(DIR)/$(NAME)-$(basename $@).zip $(DIR)/$(NAME)-$(basename $@)
|
||||
|
||||
all-arch: $(PLATFORM_LIST)
|
||||
|
||||
releases: $(zip_releases)
|
||||
|
||||
clean:
|
||||
|
||||
@@ -71,7 +71,7 @@ $ docker build -t tun2socks .
|
||||
or
|
||||
|
||||
```text
|
||||
$ docker build -t tun2socks -f ./docker/Dockerfile.aarch64 .
|
||||
$ docker build -t tun2socks -f .Dockerfile.aarch64 .
|
||||
```
|
||||
|
||||
## QuickStart
|
||||
|
||||
+18
-59
@@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
_ "unsafe"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
@@ -103,7 +104,7 @@ func (p *udpPacket) WriteBack(b []byte, addr net.Addr) (int, error) {
|
||||
data := v.ToVectorisedView()
|
||||
// if addr is not provided, write back use original dst Addr as src Addr.
|
||||
if addr == nil {
|
||||
return sendUDP(p.r, data, p.id.LocalPort, p.id.RemotePort, udpNoChecksum)
|
||||
return _sendUDP(p.r, data, p.id.LocalPort, p.id.RemotePort, udpNoChecksum)
|
||||
}
|
||||
|
||||
udpAddr, ok := addr.(*net.UDPAddr)
|
||||
@@ -113,75 +114,33 @@ func (p *udpPacket) WriteBack(b []byte, addr net.Addr) (int, error) {
|
||||
|
||||
r := p.r.Clone()
|
||||
defer r.Release()
|
||||
|
||||
if ipv4 := udpAddr.IP.To4(); ipv4 != nil {
|
||||
r.LocalAddress = tcpip.Address(ipv4)
|
||||
} else {
|
||||
r.LocalAddress = tcpip.Address(udpAddr.IP)
|
||||
}
|
||||
return sendUDP(&r, data, uint16(udpAddr.Port), p.id.RemotePort, udpNoChecksum)
|
||||
return _sendUDP(&r, data, uint16(udpAddr.Port), p.id.RemotePort, udpNoChecksum)
|
||||
}
|
||||
|
||||
// _sendUDP wraps sendUDP with some default parameters.
|
||||
func _sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, noChecksum bool) (int, error) {
|
||||
if err := sendUDP(r, data, localPort, remotePort, 0 /* ttl */, true /* useDefaultTTL */, 0 /* tos */, nil /* owner */, noChecksum); err != nil {
|
||||
return 0, fmt.Errorf("%s", err)
|
||||
}
|
||||
return data.Size(), nil
|
||||
}
|
||||
|
||||
// sendUDP sends a UDP segment via the provided network endpoint and under the
|
||||
// provided identity.
|
||||
func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, noChecksum bool) (int, error) {
|
||||
// Allocate a buffer for the UDP header.
|
||||
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: header.UDPMinimumSize + int(r.MaxHeaderLength()),
|
||||
Data: data,
|
||||
})
|
||||
|
||||
// Initialize the UDP header.
|
||||
udpHdr := header.UDP(pkt.TransportHeader().Push(header.UDPMinimumSize))
|
||||
pkt.TransportProtocolNumber = udp.ProtocolNumber
|
||||
|
||||
length := uint16(pkt.Size())
|
||||
udpHdr.Encode(&header.UDPFields{
|
||||
SrcPort: localPort,
|
||||
DstPort: remotePort,
|
||||
Length: length,
|
||||
})
|
||||
|
||||
// Set the checksum field unless TX checksum offload is enabled.
|
||||
// On IPv4, UDP checksum is optional, and a zero value indicates the
|
||||
// transmitter skipped the checksum generation (RFC768).
|
||||
// On IPv6, UDP checksum is not optional (RFC2460 Section 8.1).
|
||||
if r.RequiresTXTransportChecksum() &&
|
||||
(!noChecksum || r.NetProto == header.IPv6ProtocolNumber) {
|
||||
xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, length)
|
||||
for _, v := range data.Views() {
|
||||
xsum = header.Checksum(v, xsum)
|
||||
}
|
||||
udpHdr.SetChecksum(^udpHdr.CalculateChecksum(xsum))
|
||||
}
|
||||
|
||||
ttl := r.DefaultTTL()
|
||||
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{
|
||||
Protocol: udp.ProtocolNumber,
|
||||
TTL: ttl,
|
||||
TOS: 0, /* default */
|
||||
}, pkt); err != nil {
|
||||
r.Stats().UDP.PacketSendErrors.Increment()
|
||||
return 0, fmt.Errorf("%s", err)
|
||||
}
|
||||
|
||||
// Track count of packets sent.
|
||||
r.Stats().UDP.PacketsSent.Increment()
|
||||
return data.Size(), nil
|
||||
}
|
||||
//
|
||||
//go:linkname sendUDP gvisor.dev/gvisor/pkg/tcpip/transport/udp.sendUDP
|
||||
func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8, useDefaultTTL bool, tos uint8, owner tcpip.PacketOwner, noChecksum bool) *tcpip.Error
|
||||
|
||||
// verifyChecksum verifies the checksum unless RX checksum offload is enabled.
|
||||
// On IPv4, UDP checksum is optional, and a zero value means the transmitter
|
||||
// omitted the checksum generation (RFC768).
|
||||
// On IPv6, UDP checksum is not optional (RFC2460 Section 8.1).
|
||||
func verifyChecksum(hdr header.UDP, pkt *stack.PacketBuffer) bool {
|
||||
if !pkt.RXTransportChecksumValidated &&
|
||||
(hdr.Checksum() != 0 || pkt.NetworkProtocolNumber == header.IPv6ProtocolNumber) {
|
||||
netHdr := pkt.Network()
|
||||
xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, netHdr.DestinationAddress(), netHdr.SourceAddress(), hdr.Length())
|
||||
for _, v := range pkt.Data.Views() {
|
||||
xsum = header.Checksum(v, xsum)
|
||||
}
|
||||
return hdr.CalculateChecksum(xsum) == 0xffff
|
||||
}
|
||||
return true
|
||||
}
|
||||
//
|
||||
//go:linkname verifyChecksum gvisor.dev/gvisor/pkg/tcpip/transport/udp.verifyChecksum
|
||||
func verifyChecksum(hdr header.UDP, pkt *stack.PacketBuffer) bool
|
||||
|
||||
@@ -4,9 +4,15 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/xjasonlyu/clash/component/dialer"
|
||||
"github.com/xjasonlyu/clash/component/resolver"
|
||||
)
|
||||
|
||||
func init() { /* use bound dialer to resolve DNS */
|
||||
func init() {
|
||||
|
||||
// enable ipv6
|
||||
resolver.DisableIPv6 = false
|
||||
|
||||
// use bound dialer to resolve DNS
|
||||
net.DefaultResolver.PreferGo = true
|
||||
net.DefaultResolver.Dial = dialer.DialContext
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ func Start(dnsURL string, rawHosts []string) error {
|
||||
return errors.New("unsupported scheme")
|
||||
}
|
||||
|
||||
var serverAddr = u.Host
|
||||
serverAddr := u.Host
|
||||
if serverAddr == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
fakeIPRange := u.Query().Get("fake-ip-range")
|
||||
if fakeIPRange == "" {
|
||||
|
||||
@@ -92,7 +92,7 @@ func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
|
||||
// zeros. RFC1928
|
||||
var targetAddr socks5.Addr = []byte{socks5.AtypIPv4, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
bindAddr, err := socks5.ClientHandshake(c, targetAddr, socks5.CmdUDPAssociate, user)
|
||||
addr, err := socks5.ClientHandshake(c, targetAddr, socks5.CmdUDPAssociate, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("client hanshake: %w", err)
|
||||
}
|
||||
@@ -110,7 +110,17 @@ func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
return &socksPacketConn{PacketConn: pc, rAddr: bindAddr.UDPAddr(), tcpConn: c}, nil
|
||||
bindAddr := addr.UDPAddr()
|
||||
if bindAddr.IP.IsUnspecified() {
|
||||
udpAddr, err := resolveUDPAddr("udp", ss.Addr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bindAddr.IP = udpAddr.IP
|
||||
}
|
||||
|
||||
return &socksPacketConn{PacketConn: pc, rAddr: bindAddr, tcpConn: c}, nil
|
||||
}
|
||||
|
||||
type socksPacketConn struct {
|
||||
|
||||
Reference in New Issue
Block a user