mirror of
https://github.com/cedar2025/hysteria.git
synced 2025-06-08 13:29:56 +00:00
120 lines
3.4 KiB
Go
120 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"github.com/lucas-clemente/quic-go"
|
|
"github.com/lucas-clemente/quic-go/congestion"
|
|
"github.com/sirupsen/logrus"
|
|
hyCongestion "github.com/tobyxdd/hysteria/pkg/congestion"
|
|
"github.com/tobyxdd/hysteria/pkg/core"
|
|
"github.com/tobyxdd/hysteria/pkg/obfs"
|
|
"github.com/tobyxdd/hysteria/pkg/utils"
|
|
"io/ioutil"
|
|
"net"
|
|
"os/user"
|
|
)
|
|
|
|
func relayClient(args []string) {
|
|
var config relayClientConfig
|
|
err := loadConfig(&config, args)
|
|
if err != nil {
|
|
logrus.WithField("error", err).Fatal("Unable to load configuration")
|
|
}
|
|
if err := config.Check(); err != nil {
|
|
logrus.WithField("error", err).Fatal("Configuration error")
|
|
}
|
|
if len(config.Name) == 0 {
|
|
usr, err := user.Current()
|
|
if err == nil {
|
|
config.Name = usr.Name
|
|
}
|
|
}
|
|
logrus.WithField("config", config.String()).Info("Configuration loaded")
|
|
|
|
tlsConfig := &tls.Config{
|
|
InsecureSkipVerify: config.Insecure,
|
|
NextProtos: []string{relayTLSProtocol},
|
|
MinVersion: tls.VersionTLS13,
|
|
}
|
|
// Load CA
|
|
if len(config.CustomCAFile) > 0 {
|
|
bs, err := ioutil.ReadFile(config.CustomCAFile)
|
|
if err != nil {
|
|
logrus.WithFields(logrus.Fields{
|
|
"error": err,
|
|
"file": config.CustomCAFile,
|
|
}).Fatal("Unable to load CA file")
|
|
}
|
|
cp := x509.NewCertPool()
|
|
if !cp.AppendCertsFromPEM(bs) {
|
|
logrus.WithFields(logrus.Fields{
|
|
"file": config.CustomCAFile,
|
|
}).Fatal("Unable to parse CA file")
|
|
}
|
|
tlsConfig.RootCAs = cp
|
|
}
|
|
|
|
quicConfig := &quic.Config{
|
|
MaxReceiveStreamFlowControlWindow: config.ReceiveWindowConn,
|
|
MaxReceiveConnectionFlowControlWindow: config.ReceiveWindow,
|
|
KeepAlive: true,
|
|
}
|
|
if quicConfig.MaxReceiveStreamFlowControlWindow == 0 {
|
|
quicConfig.MaxReceiveStreamFlowControlWindow = DefaultMaxReceiveStreamFlowControlWindow
|
|
}
|
|
if quicConfig.MaxReceiveConnectionFlowControlWindow == 0 {
|
|
quicConfig.MaxReceiveConnectionFlowControlWindow = DefaultMaxReceiveConnectionFlowControlWindow
|
|
}
|
|
|
|
var obfuscator core.Obfuscator
|
|
if len(config.Obfs) > 0 {
|
|
obfuscator = obfs.XORObfuscator(config.Obfs)
|
|
}
|
|
|
|
client, err := core.NewClient(config.ServerAddr, config.Name, "", tlsConfig, quicConfig,
|
|
uint64(config.UpMbps)*mbpsToBps, uint64(config.DownMbps)*mbpsToBps,
|
|
func(refBPS uint64) congestion.ExternalSendAlgorithm {
|
|
return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS))
|
|
}, obfuscator)
|
|
if err != nil {
|
|
logrus.WithField("error", err).Fatal("Client initialization failed")
|
|
}
|
|
defer client.Close()
|
|
logrus.WithField("addr", config.ServerAddr).Info("Connected")
|
|
|
|
listener, err := net.Listen("tcp", config.ListenAddr)
|
|
if err != nil {
|
|
logrus.WithField("error", err).Fatal("TCP listen failed")
|
|
}
|
|
defer listener.Close()
|
|
logrus.WithField("addr", listener.Addr().String()).Info("TCP server listening")
|
|
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
logrus.WithField("error", err).Fatal("TCP accept failed")
|
|
}
|
|
go relayClientHandleConn(conn, client)
|
|
}
|
|
}
|
|
|
|
func relayClientHandleConn(conn net.Conn, client *core.Client) {
|
|
logrus.WithField("src", conn.RemoteAddr().String()).Debug("New connection")
|
|
var closeErr error
|
|
defer func() {
|
|
_ = conn.Close()
|
|
logrus.WithFields(logrus.Fields{
|
|
"error": closeErr,
|
|
"src": conn.RemoteAddr().String(),
|
|
}).Debug("Connection closed")
|
|
}()
|
|
rwc, err := client.Dial(false, "")
|
|
if err != nil {
|
|
closeErr = err
|
|
return
|
|
}
|
|
defer rwc.Close()
|
|
closeErr = utils.PipePair(conn, rwc, nil, nil)
|
|
}
|