feat: fast open

This commit is contained in:
Toby 2022-11-23 21:19:52 +00:00
parent 536fa24595
commit 80faa4aaf8
4 changed files with 38 additions and 13 deletions

2
.gitignore vendored
View File

@ -184,3 +184,5 @@ hy_linux
.vscode .vscode
/build/ /build/
config*.json

View File

@ -134,7 +134,7 @@ func client(config *clientConfig) {
up, down, _ := config.Speed() up, down, _ := config.Speed()
for { for {
try += 1 try += 1
c, err := core.NewClient(config.Server, auth, tlsConfig, quicConfig, pktConnFunc, up, down, c, err := core.NewClient(config.Server, auth, tlsConfig, quicConfig, pktConnFunc, up, down, config.FastOpen,
func(err error) { func(err error) {
if config.QuitOnDisconnect { if config.QuitOnDisconnect {
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{

View File

@ -223,6 +223,7 @@ type clientConfig struct {
ReceiveWindowConn uint64 `json:"recv_window_conn"` ReceiveWindowConn uint64 `json:"recv_window_conn"`
ReceiveWindow uint64 `json:"recv_window"` ReceiveWindow uint64 `json:"recv_window"`
DisableMTUDiscovery bool `json:"disable_mtu_discovery"` DisableMTUDiscovery bool `json:"disable_mtu_discovery"`
FastOpen bool `json:"fast_open"`
Resolver string `json:"resolver"` Resolver string `json:"resolver"`
ResolvePreference string `json:"resolve_preference"` ResolvePreference string `json:"resolve_preference"`
} }

View File

@ -29,6 +29,7 @@ type Client struct {
sendBPS, recvBPS uint64 sendBPS, recvBPS uint64
auth []byte auth []byte
fastOpen bool
tlsConfig *tls.Config tlsConfig *tls.Config
quicConfig *quic.Config quicConfig *quic.Config
@ -48,7 +49,8 @@ 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, quicReconnectFunc func(err error), pktConnFunc pktconns.ClientPacketConnFunc, sendBPS uint64, recvBPS uint64, fastOpen bool,
quicReconnectFunc func(err error),
) (*Client, error) { ) (*Client, error) {
quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery
c := &Client{ c := &Client{
@ -56,6 +58,7 @@ func NewClient(serverAddr string, auth []byte, tlsConfig *tls.Config, quicConfig
sendBPS: sendBPS, sendBPS: sendBPS,
recvBPS: recvBPS, recvBPS: recvBPS,
auth: auth, auth: auth,
fastOpen: fastOpen,
tlsConfig: tlsConfig, tlsConfig: tlsConfig,
quicConfig: quicConfig, quicConfig: quicConfig,
pktConnFunc: pktConnFunc, pktConnFunc: pktConnFunc,
@ -221,6 +224,9 @@ func (c *Client) DialTCP(addr string) (net.Conn, error) {
_ = stream.Close() _ = stream.Close()
return nil, err return nil, err
} }
// If fast open is enabled, we return the stream immediately
// and defer the response handling to the first Read() call
if !c.fastOpen {
// Read response // Read response
var sr serverResponse var sr serverResponse
err = struc.Unpack(stream, &sr) err = struc.Unpack(stream, &sr)
@ -232,10 +238,12 @@ func (c *Client) DialTCP(addr string) (net.Conn, error) {
_ = stream.Close() _ = stream.Close()
return nil, fmt.Errorf("connection rejected: %s", sr.Message) return nil, fmt.Errorf("connection rejected: %s", sr.Message)
} }
}
return &hyTCPConn{ return &hyTCPConn{
Orig: stream, Orig: stream,
PseudoLocalAddr: session.LocalAddr(), PseudoLocalAddr: session.LocalAddr(),
PseudoRemoteAddr: session.RemoteAddr(), PseudoRemoteAddr: session.RemoteAddr(),
Established: !c.fastOpen,
}, nil }, nil
} }
@ -306,9 +314,23 @@ type hyTCPConn struct {
Orig quic.Stream Orig quic.Stream
PseudoLocalAddr net.Addr PseudoLocalAddr net.Addr
PseudoRemoteAddr net.Addr PseudoRemoteAddr net.Addr
Established bool
} }
func (w *hyTCPConn) Read(b []byte) (n int, err error) { func (w *hyTCPConn) Read(b []byte) (n int, err error) {
if !w.Established {
var sr serverResponse
err := struc.Unpack(w.Orig, &sr)
if err != nil {
_ = w.Close()
return 0, err
}
if !sr.OK {
_ = w.Close()
return 0, fmt.Errorf("connection rejected: %s", sr.Message)
}
w.Established = true
}
return w.Orig.Read(b) return w.Orig.Read(b)
} }