hysteria/cmd/relay_server.go
2021-01-26 21:34:49 -08:00

121 lines
4 KiB
Go

package main
import (
"crypto/tls"
"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"
"io"
"net"
)
func relayServer(args []string) {
var config relayServerConfig
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")
}
logrus.WithField("config", config.String()).Info("Configuration loaded")
// Load cert
cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
"cert": config.CertFile,
"key": config.KeyFile,
}).Fatal("Unable to load the certificate")
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
NextProtos: []string{relayTLSProtocol},
MinVersion: tls.VersionTLS13,
}
quicConfig := &quic.Config{
MaxReceiveStreamFlowControlWindow: config.ReceiveWindowConn,
MaxReceiveConnectionFlowControlWindow: config.ReceiveWindowClient,
MaxIncomingStreams: int64(config.MaxConnClient),
KeepAlive: true,
}
if quicConfig.MaxReceiveStreamFlowControlWindow == 0 {
quicConfig.MaxReceiveStreamFlowControlWindow = DefaultMaxReceiveStreamFlowControlWindow
}
if quicConfig.MaxReceiveConnectionFlowControlWindow == 0 {
quicConfig.MaxReceiveConnectionFlowControlWindow = DefaultMaxReceiveConnectionFlowControlWindow
}
if quicConfig.MaxIncomingStreams == 0 {
quicConfig.MaxIncomingStreams = DefaultMaxIncomingStreams
}
var obfuscator core.Obfuscator
if len(config.Obfs) > 0 {
obfuscator = obfs.XORObfuscator(config.Obfs)
}
server, err := core.NewServer(config.ListenAddr, tlsConfig, quicConfig,
uint64(config.UpMbps)*mbpsToBps, uint64(config.DownMbps)*mbpsToBps,
func(refBPS uint64) congestion.CongestionControl {
return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS))
},
obfuscator,
func(addr net.Addr, username string, password string, sSend uint64, sRecv uint64) (core.AuthResult, string) {
// No authentication logic in relay, just log username and speed
logrus.WithFields(logrus.Fields{
"addr": addr.String(),
"username": username,
"up": sSend / mbpsToBps,
"down": sRecv / mbpsToBps,
}).Info("Client connected")
return core.AuthResultSuccess, ""
},
func(addr net.Addr, username string, err error) {
logrus.WithFields(logrus.Fields{
"error": err.Error(),
"addr": addr.String(),
"username": username,
}).Info("Client disconnected")
},
func(addr net.Addr, username string, id int, reqType core.ConnectionType, reqAddr string) (core.ConnectResult, string, io.ReadWriteCloser) {
packet := reqType == core.ConnectionTypePacket
logrus.WithFields(logrus.Fields{
"username": username,
"src": addr.String(),
"id": id,
}).Debug("New stream")
if packet {
return core.ConnectResultBlocked, "unsupported", nil
}
conn, err := net.DialTimeout("tcp", config.RemoteAddr, dialTimeout)
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
"dst": config.RemoteAddr,
}).Error("TCP error")
return core.ConnectResultFailed, err.Error(), nil
}
return core.ConnectResultSuccess, "", conn
},
func(addr net.Addr, username string, id int, reqType core.ConnectionType, reqAddr string, err error) {
logrus.WithFields(logrus.Fields{
"error": err,
"username": username,
"src": addr.String(),
"id": id,
}).Debug("Stream closed")
},
)
if err != nil {
logrus.WithField("error", err).Fatal("Server initialization failed")
}
defer server.Close()
logrus.WithField("addr", config.ListenAddr).Info("Server up and running")
err = server.Serve()
logrus.WithField("error", err).Fatal("Server shutdown")
}