mirror of
https://github.com/apernet/hysteria.git
synced 2025-07-03 16:47:01 +00:00
Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
|
57c5164854 | ||
|
da63981d96 | ||
|
ca82106dc4 | ||
|
c2025fd8b0 | ||
|
4245f2df67 | ||
|
08a982ee91 | ||
|
716e9db691 | ||
|
aa7766b47e |
16 changed files with 70 additions and 23 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -157,6 +157,8 @@ func fakeFlags() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
openWinVT()
|
||||||
|
|
||||||
// compatible with old flag format
|
// compatible with old flag format
|
||||||
fakeFlags()
|
fakeFlags()
|
||||||
|
|
||||||
|
|
|
@ -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
22
app/cmd/winvt.go
Normal 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
7
app/cmd/winvt_stub.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func openWinVT() {
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue