dialer: add bind device

This commit is contained in:
ginuerzh
2022-03-02 21:36:27 +08:00
parent ffdf11e89e
commit b96d37d4cc
29 changed files with 348 additions and 225 deletions

View File

@ -2,14 +2,16 @@ package http3
import (
"context"
"crypto/tls"
"net"
"net/http"
"sync"
"github.com/go-gost/gost/pkg/dialer"
pht_util "github.com/go-gost/gost/pkg/internal/util/pht"
"github.com/go-gost/gost/pkg/logger"
md "github.com/go-gost/gost/pkg/metadata"
"github.com/go-gost/gost/pkg/registry"
"github.com/lucas-clemente/quic-go"
"github.com/lucas-clemente/quic-go/http3"
)
@ -19,10 +21,10 @@ func init() {
}
type http3Dialer struct {
client *pht_util.Client
md metadata
logger logger.Logger
options dialer.Options
clients map[string]*pht_util.Client
clientMutex sync.Mutex
md metadata
options dialer.Options
}
func NewDialer(opts ...dialer.Option) dialer.Dialer {
@ -32,7 +34,7 @@ func NewDialer(opts ...dialer.Option) dialer.Dialer {
}
return &http3Dialer{
logger: options.Logger,
clients: make(map[string]*pht_util.Client),
options: options,
}
}
@ -42,23 +44,64 @@ func (d *http3Dialer) Init(md md.Metadata) (err error) {
return
}
tr := &http3.RoundTripper{
TLSClientConfig: d.options.TLSConfig,
}
d.client = &pht_util.Client{
Client: &http.Client{
// Timeout: 60 * time.Second,
Transport: tr,
},
AuthorizePath: d.md.authorizePath,
PushPath: d.md.pushPath,
PullPath: d.md.pullPath,
TLSEnabled: true,
Logger: d.options.Logger,
}
return nil
}
func (d *http3Dialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOption) (net.Conn, error) {
return d.client.Dial(ctx, addr)
d.clientMutex.Lock()
defer d.clientMutex.Unlock()
client, ok := d.clients[addr]
if !ok {
var options dialer.DialOptions
for _, opt := range opts {
opt(&options)
}
host := d.md.host
if host == "" {
host = options.Host
}
if h, _, _ := net.SplitHostPort(host); h != "" {
host = h
}
client = &pht_util.Client{
Host: host,
Client: &http.Client{
// Timeout: 60 * time.Second,
Transport: &http3.RoundTripper{
TLSClientConfig: d.options.TLSConfig,
Dial: func(network, adr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error) {
// d.options.Logger.Infof("dial: %s/%s, %s", addr, network, host)
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
udpConn, err := options.NetDialer.Dial(context.Background(), "udp", "")
if err != nil {
return nil, err
}
return quic.DialEarly(udpConn.(net.PacketConn), udpAddr, host, tlsCfg, cfg)
},
},
},
AuthorizePath: d.md.authorizePath,
PushPath: d.md.pushPath,
PullPath: d.md.pullPath,
TLSEnabled: true,
Logger: d.options.Logger,
}
d.clients[addr] = client
}
return client.Dial(ctx, addr)
}
// Multiplex implements dialer.Multiplexer interface.
func (d *http3Dialer) Multiplex() bool {
return true
}