diff --git a/weed/command/s3.go b/weed/command/s3.go index 5037da9cb..faedfe520 100644 --- a/weed/command/s3.go +++ b/weed/command/s3.go @@ -261,6 +261,9 @@ func (s3opt *S3Options) resolvePaths() { func (s3opt *S3Options) startS3Server() bool { + // Before the first filer dial below; gRPC caches conns and binds at dial time. + util.SetOutboundLocalIP(*s3opt.bindIp) + filerAddresses := pb.ServerAddresses(*s3opt.filer).ToAddresses() filerBucketsPath := "/buckets" @@ -324,7 +327,6 @@ func (s3opt *S3Options) startS3Server() bool { if *s3opt.bindIp == "" { *s3opt.bindIp = "0.0.0.0" } - util.SetOutboundLocalIP(*s3opt.bindIp) defaultFileMode, fileModeErr := s3opt.parseDefaultFileMode() if fileModeErr != nil { diff --git a/weed/pb/grpc_client_server.go b/weed/pb/grpc_client_server.go index c053e37f5..d7960255a 100644 --- a/weed/pb/grpc_client_server.go +++ b/weed/pb/grpc_client_server.go @@ -212,11 +212,14 @@ func GrpcDial(ctx context.Context, address string, waitForReady bool, opts ...gr var d net.Dialer return d.DialContext(ctx, "unix", socketPath) })) - } else if util.OutboundLocalAddr() != nil { - // Bind outbound gRPC connections to the configured -ip.bind source - // address. Only installed when a source address is set, so default - // deployments keep gRPC's stock dialer behavior. + } else { + // Always install so a conn cached before SetOutboundLocalIP binds once set; + // the stock net.Dialer until then preserves gRPC's default dial behavior. options = append(options, grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + if util.OutboundLocalAddr() == nil { + var d net.Dialer + return d.DialContext(ctx, "tcp", addr) + } return util.OutboundDialContext(ctx, "tcp", addr) })) }