Compare commits

...

8 commits

Author SHA1 Message Date
tobyxdd
57c5164854 docs: 1.3.5 changelog 2023-06-11 16:46:29 -07:00
tobyxdd
da63981d96 fix: socks5 udp listen addr when omitting address & udp domain 2023-06-11 16:22:42 -07:00
tobyxdd
ca82106dc4 chore: code format 2023-06-11 16:01:55 -07:00
Toby
c2025fd8b0
Merge pull request #614 from hellodword/reproducible
feat: reproducible building
2023-06-11 14:53:22 -07:00
Toby
4245f2df67
Merge pull request #610 from KsaNL/patch-1
Add Win32 VT mode support
2023-06-05 16:47:17 -07:00
hellodword
08a982ee91
feat: reproducible building 2023-05-30 17:14:58 +08:00
Haruue Icymoon
716e9db691
fix: build failed on linux 2023-05-17 22:16:01 +08:00
KsaNL
aa7766b47e
Add Win32 VT mode support 2023-05-17 18:41:47 +08:00
16 changed files with 70 additions and 23 deletions

View file

@ -1,5 +1,12 @@
# Changelog # Changelog
## 1.3.5
- Add VT color support for Windows
- Fix a bug where UDP did not work when using only port in SOCKS5 listen address (e.g. ":1080")
- Fix a bug in handling SOCKS5 UDP packets with domain address
- Updated quic-go to v0.34.0
## 1.3.4 ## 1.3.4
- Eliminate unnecessary DNS lookups when using SOCKS5 outbound with ACL disabled - Eliminate unnecessary DNS lookups when using SOCKS5 outbound with ACL disabled
@ -57,7 +64,8 @@
## 1.1.0 ## 1.1.0
- Super major CPU performance improvements (~30% to several times faster, depending on the circumstances) by optimizing several data structures in quic-go (changes upstreamed) - Super major CPU performance improvements (~30% to several times faster, depending on the circumstances) by optimizing
several data structures in quic-go (changes upstreamed)
## 1.0.5 ## 1.0.5

View file

@ -17,7 +17,7 @@ type CmdAuthProvider struct {
Cmd string Cmd string
} }
func (p *CmdAuthProvider) Auth(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) { func (p *CmdAuthProvider) Auth(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string) {
cmd := exec.Command(p.Cmd, addr.String(), string(auth), strconv.Itoa(int(sSend)), strconv.Itoa(int(sRecv))) cmd := exec.Command(p.Cmd, addr.String(), string(auth), strconv.Itoa(int(sSend)), strconv.Itoa(int(sRecv)))
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
@ -51,7 +51,7 @@ type authResp struct {
Msg string `json:"msg"` Msg string `json:"msg"`
} }
func (p *HTTPAuthProvider) Auth(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) { func (p *HTTPAuthProvider) Auth(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string) {
jbs, err := json.Marshal(&authReq{ jbs, err := json.Marshal(&authReq{
Addr: addr.String(), Addr: addr.String(),
Payload: auth, Payload: auth,

View file

@ -24,7 +24,7 @@ func PasswordAuthFunc(rawMsg json5.RawMessage) (cs.ConnectFunc, error) {
// yes it is // yes it is
pwds = []string{pwdConfig["password"]} pwds = []string{pwdConfig["password"]}
} }
return func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) { return func(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string) {
for _, pwd := range pwds { for _, pwd := range pwds {
if string(auth) == pwd { if string(auth) == pwd {
return true, "Welcome" return true, "Welcome"

View file

@ -12,8 +12,8 @@ import (
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
) )
func acmeTLSConfig(domains []string, email string, disableHTTP bool, disableTLSALPN bool, func acmeTLSConfig(domains []string, email string, disableHTTP, disableTLSALPN bool,
altHTTPPort int, altTLSALPNPort int, altHTTPPort, altTLSALPNPort int,
) (*tls.Config, error) { ) (*tls.Config, error) {
cfg := &certmagic.Config{ cfg := &certmagic.Config{
RenewalWindowRatio: certmagic.DefaultRenewalWindowRatio, RenewalWindowRatio: certmagic.DefaultRenewalWindowRatio,

View file

@ -157,6 +157,8 @@ func fakeFlags() {
} }
func init() { func init() {
openWinVT()
// compatible with old flag format // compatible with old flag format
fakeFlags() fakeFlags()

View file

@ -99,7 +99,7 @@ func server(config *serverConfig) {
logrus.Warn("Neither authentication nor obfuscation is turned on. " + logrus.Warn("Neither authentication nor obfuscation is turned on. " +
"Your server could be used by anyone! Are you sure this is what you want?") "Your server could be used by anyone! Are you sure this is what you want?")
} }
authFunc = func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) { authFunc = func(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string) {
return true, "Welcome" return true, "Welcome"
} }
case "password", "passwords": case "password", "passwords":
@ -123,7 +123,7 @@ func server(config *serverConfig) {
default: default:
logrus.WithField("mode", config.Auth.Mode).Fatal("Unsupported authentication mode") logrus.WithField("mode", config.Auth.Mode).Fatal("Unsupported authentication mode")
} }
connectFunc := func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) { connectFunc := func(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string) {
ok, msg := authFunc(addr, auth, sSend, sRecv) ok, msg := authFunc(addr, auth, sSend, sRecv)
if !ok { if !ok {
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{

22
app/cmd/winvt.go Normal file
View file

@ -0,0 +1,22 @@
//go:build windows
// +build windows
package main
import (
"os"
"golang.org/x/sys/windows"
)
// Add console VT color mode
func openWinVT() {
stdout := windows.Handle(os.Stdout.Fd())
var mode uint32
windows.GetConsoleMode(stdout, &mode)
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING // Add VT Color Support
windows.SetConsoleMode(stdout, mode)
}

7
app/cmd/winvt_stub.go Normal file
View file

@ -0,0 +1,7 @@
//go:build !windows
// +build !windows
package main
func openWinVT() {
}

View file

@ -8,7 +8,7 @@ import (
"unsafe" "unsafe"
) )
func getsockopt(s uintptr, level uintptr, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) { func getsockopt(s, level, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) {
_, _, e := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) _, _, e := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
if e != 0 { if e != 0 {
err = e err = e

View file

@ -13,7 +13,7 @@ const (
// we have to call syscall.socketcall with this trick. // we have to call syscall.socketcall with this trick.
func syscall_socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno) func syscall_socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func getsockopt(s uintptr, level uintptr, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) { func getsockopt(s, level, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) {
_, e := syscall_socketcall(SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) _, e := syscall_socketcall(SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
if e != 0 { if e != 0 {
err = e err = e

View file

@ -254,9 +254,11 @@ func (s *Server) handleUDP(c *net.TCPConn, r *socks5.Request) error {
s.UDPErrorFunc(c.RemoteAddr(), closeErr) s.UDPErrorFunc(c.RemoteAddr(), closeErr)
}() }()
// Start local UDP server // Start local UDP server
// Bind to the same address that the incoming TCP connection is sending to
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{ udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
IP: s.TCPAddr.IP, IP: c.LocalAddr().(*net.TCPAddr).IP,
Zone: s.TCPAddr.Zone, Zone: c.LocalAddr().(*net.TCPAddr).Zone,
Port: 0, // Random port
}) })
if err != nil { if err != nil {
_ = sendReply(c, socks5.RepServerFailure) _ = sendReply(c, socks5.RepServerFailure)
@ -320,7 +322,7 @@ func (s *Server) handleUDP(c *net.TCPConn, r *socks5.Request) error {
return nil return nil
} }
func (s *Server) udpServer(clientConn *net.UDPConn, localRelayConn *net.UDPConn, hyUDP cs.HyUDPConn) { func (s *Server) udpServer(clientConn, localRelayConn *net.UDPConn, hyUDP cs.HyUDPConn) {
var clientAddr *net.UDPAddr var clientAddr *net.UDPAddr
buf := make([]byte, udpBufferSize) buf := make([]byte, udpBufferSize)
// Local to remote // Local to remote
@ -348,6 +350,9 @@ func (s *Server) udpServer(clientConn *net.UDPConn, localRelayConn *net.UDPConn,
if err != nil { if err != nil {
continue continue
} }
if atyp == socks5.ATYPDomain {
addr = addr[1:] // Remove the leading length byte
}
d := socks5.NewDatagram(atyp, addr, port, bs) d := socks5.NewDatagram(atyp, addr, port, bs)
_, _ = clientConn.WriteToUDP(d.Bytes(), clientAddr) _, _ = clientConn.WriteToUDP(d.Bytes(), clientAddr)
} }
@ -362,6 +367,9 @@ func (s *Server) udpServer(clientConn *net.UDPConn, localRelayConn *net.UDPConn,
if err != nil { if err != nil {
continue continue
} }
if atyp == socks5.ATYPDomain {
addr = addr[1:] // Remove the leading length byte
}
d := socks5.NewDatagram(atyp, addr, port, buf[:n]) d := socks5.NewDatagram(atyp, addr, port, buf[:n])
_, _ = clientConn.WriteToUDP(d.Bytes(), clientAddr) _, _ = clientConn.WriteToUDP(d.Bytes(), clientAddr)
} }

View file

@ -71,7 +71,7 @@ platform_to_env() {
} }
make_ldflags() { make_ldflags() {
local ldflags="-s -w -X 'main.appDate=$(date -u '+%F %T')'" local ldflags="-buildid= -s -w -X 'main.appDate=$(date -u '+%F %T')'"
if [ -n "$HY_APP_VERSION" ]; then if [ -n "$HY_APP_VERSION" ]; then
ldflags="$ldflags -X 'main.appVersion=$HY_APP_VERSION'" ldflags="$ldflags -X 'main.appVersion=$HY_APP_VERSION'"
else else

View file

@ -49,7 +49,7 @@ type Client struct {
} }
func NewClient(serverAddr string, auth []byte, tlsConfig *tls.Config, quicConfig *quic.Config, func NewClient(serverAddr string, auth []byte, tlsConfig *tls.Config, quicConfig *quic.Config,
pktConnFunc pktconns.ClientPacketConnFunc, sendBPS uint64, recvBPS uint64, fastOpen bool, lazyStart bool, pktConnFunc pktconns.ClientPacketConnFunc, sendBPS, recvBPS uint64, fastOpen, lazyStart bool,
quicReconnectFunc func(err error), quicReconnectFunc func(err error),
) (*Client, error) { ) (*Client, error) {
quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery

View file

@ -17,7 +17,7 @@ import (
) )
type ( type (
ConnectFunc func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) ConnectFunc func(addr net.Addr, auth []byte, sSend, sRecv uint64) (bool, string)
DisconnectFunc func(addr net.Addr, auth []byte, err error) DisconnectFunc func(addr net.Addr, auth []byte, err error)
TCPRequestFunc func(addr net.Addr, auth []byte, reqAddr string, action acl.Action, arg string) TCPRequestFunc func(addr net.Addr, auth []byte, reqAddr string, action acl.Action, arg string)
TCPErrorFunc func(addr net.Addr, auth []byte, reqAddr string, err error) TCPErrorFunc func(addr net.Addr, auth []byte, reqAddr string, err error)
@ -53,7 +53,7 @@ type Server struct {
func NewServer(tlsConfig *tls.Config, quicConfig *quic.Config, func NewServer(tlsConfig *tls.Config, quicConfig *quic.Config,
pktConn net.PacketConn, transport *transport.ServerTransport, pktConn net.PacketConn, transport *transport.ServerTransport,
sendBPS uint64, recvBPS uint64, disableUDP bool, aclEngine *acl.Engine, sendBPS, recvBPS uint64, disableUDP bool, aclEngine *acl.Engine,
connectFunc ConnectFunc, disconnectFunc DisconnectFunc, connectFunc ConnectFunc, disconnectFunc DisconnectFunc,
tcpRequestFunc TCPRequestFunc, tcpErrorFunc TCPErrorFunc, tcpRequestFunc TCPRequestFunc, tcpErrorFunc TCPErrorFunc,
udpRequestFunc UDPRequestFunc, udpErrorFunc UDPErrorFunc, udpRequestFunc UDPRequestFunc, udpErrorFunc UDPErrorFunc,

View file

@ -8,8 +8,8 @@ import (
) )
type Obfuscator interface { type Obfuscator interface {
Deobfuscate(in []byte, out []byte) int Deobfuscate(in, out []byte) int
Obfuscate(in []byte, out []byte) int Obfuscate(in, out []byte) int
} }
const xpSaltLen = 16 const xpSaltLen = 16
@ -30,7 +30,7 @@ func NewXPlusObfuscator(key []byte) *XPlusObfuscator {
} }
} }
func (x *XPlusObfuscator) Deobfuscate(in []byte, out []byte) int { func (x *XPlusObfuscator) Deobfuscate(in, out []byte) int {
outLen := len(in) - xpSaltLen outLen := len(in) - xpSaltLen
if outLen <= 0 || len(out) < outLen { if outLen <= 0 || len(out) < outLen {
return 0 return 0
@ -42,7 +42,7 @@ func (x *XPlusObfuscator) Deobfuscate(in []byte, out []byte) int {
return outLen return outLen
} }
func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int { func (x *XPlusObfuscator) Obfuscate(in, out []byte) int {
outLen := len(in) + xpSaltLen outLen := len(in) + xpSaltLen
if len(out) < outLen { if len(out) < outLen {
return 0 return 0

View file

@ -21,7 +21,7 @@ type SOCKS5Client struct {
Password string Password string
} }
func NewSOCKS5Client(serverAddr string, username string, password string) *SOCKS5Client { func NewSOCKS5Client(serverAddr, username, password string) *SOCKS5Client {
return &SOCKS5Client{ return &SOCKS5Client{
Dialer: &net.Dialer{ Dialer: &net.Dialer{
Timeout: 8 * time.Second, Timeout: 8 * time.Second,
@ -215,7 +215,7 @@ func (c *socks5UDPConn) Close() error {
return nil return nil
} }
func socks5AddrToUDPAddr(atyp byte, addr []byte, port []byte) (*net.UDPAddr, error) { func socks5AddrToUDPAddr(atyp byte, addr, port []byte) (*net.UDPAddr, error) {
clone := func(b []byte) []byte { clone := func(b []byte) []byte {
c := make([]byte, len(b)) c := make([]byte, len(b))
copy(c, b) copy(c, b)