fixed v4 gateway resolution #616
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -27,7 +28,7 @@ type Client struct {
|
||||
}
|
||||
|
||||
// NewClient creates a new TRON gRPC client connected to the given endpoint.
|
||||
func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client, error) {
|
||||
func NewClient(grpcURL string, timeout time.Duration, authToken string, forceIPv4 bool) (*Client, error) {
|
||||
if grpcURL == "" {
|
||||
return nil, merrors.InvalidArgument("tronclient: grpc url is required")
|
||||
}
|
||||
@@ -50,6 +51,9 @@ func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client
|
||||
}
|
||||
|
||||
opts := []grpc.DialOption{transportCreds}
|
||||
if forceIPv4 {
|
||||
opts = append(opts, grpc.WithContextDialer(grpcForceIPv4Dialer))
|
||||
}
|
||||
if token := strings.TrimSpace(authToken); token != "" {
|
||||
opts = append(opts,
|
||||
grpc.WithUnaryInterceptor(grpcTokenUnaryInterceptor(token)),
|
||||
@@ -67,6 +71,40 @@ func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client
|
||||
}, nil
|
||||
}
|
||||
|
||||
func grpcForceIPv4Dialer(ctx context.Context, address string) (net.Conn, error) {
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Resolve IPv4 only
|
||||
ips, err := net.DefaultResolver.LookupIP(ctx, "ip4", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return nil, merrors.Internal(fmt.Sprintf("no IPv4 address found for %s", host))
|
||||
}
|
||||
|
||||
var dialer net.Dialer
|
||||
var lastErr error
|
||||
for _, ip := range ips {
|
||||
target := net.JoinHostPort(ip.String(), port)
|
||||
conn, err := dialer.DialContext(ctx, "tcp4", target)
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
lastErr = err
|
||||
if ctx.Err() != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if lastErr != nil {
|
||||
return nil, merrors.Internal(fmt.Sprintf("failed to dial any IPv4 address for %s: %v", host, lastErr))
|
||||
}
|
||||
return nil, merrors.Internal(fmt.Sprintf("failed to dial IPv4 address for %s", host))
|
||||
}
|
||||
|
||||
func normalizeGRPCAddress(grpcURL string) (string, bool, error) {
|
||||
target := strings.TrimSpace(grpcURL)
|
||||
useTLS := false
|
||||
|
||||
Reference in New Issue
Block a user