Split host & port in the protocol, and make each domain resolves only once even when ACL is enabled, improving performance and ensuring consistency of connection destinations

This commit is contained in:
Toby
2021-04-19 00:20:22 -07:00
parent 7b841aa203
commit b09880a050
8 changed files with 196 additions and 136 deletions

View File

@@ -10,6 +10,7 @@ import (
"github.com/lucas-clemente/quic-go/congestion"
"github.com/lunixbochs/struc"
"net"
"strconv"
"sync"
"time"
)
@@ -187,14 +188,19 @@ func (c *Client) openStreamWithReconnect() (quic.Session, quic.Stream, error) {
}
func (c *Client) DialTCP(addr string) (net.Conn, error) {
host, port, err := splitHostPort(addr)
if err != nil {
return nil, err
}
session, stream, err := c.openStreamWithReconnect()
if err != nil {
return nil, err
}
// Send request
err = struc.Pack(stream, &clientRequest{
UDP: false,
Address: addr,
UDP: false,
Host: host,
Port: port,
})
if err != nil {
_ = stream.Close()
@@ -349,14 +355,19 @@ func (c *quicPktConn) ReadFrom() ([]byte, string, error) {
// Closed
return nil, "", ErrClosed
}
return msg.Data, msg.Address, nil
return msg.Data, net.JoinHostPort(msg.Host, strconv.Itoa(int(msg.Port))), nil
}
func (c *quicPktConn) WriteTo(p []byte, addr string) error {
host, port, err := splitHostPort(addr)
if err != nil {
return err
}
var msgBuf bytes.Buffer
_ = struc.Pack(&msgBuf, &udpMessage{
SessionID: c.UDPSessionID,
Address: addr,
Host: host,
Port: port,
Data: p,
})
return c.Session.SendMessage(msgBuf.Bytes())
@@ -366,3 +377,15 @@ func (c *quicPktConn) Close() error {
c.CloseFunc()
return c.Stream.Close()
}
func splitHostPort(hostport string) (string, uint16, error) {
host, port, err := net.SplitHostPort(hostport)
if err != nil {
return "", 0, err
}
portUint, err := strconv.ParseUint(port, 10, 16)
if err != nil {
return "", 0, err
}
return host, uint16(portUint), err
}