storj.io/uplink@v1.13.0/config.go (about)

     1  // Copyright (C) 2020 Storj Labs, Inc.
     2  // See LICENSE for copying information.
     3  
     4  package uplink
     5  
     6  import (
     7  	"context"
     8  	"net"
     9  	"time"
    10  	_ "unsafe" // for go:linkname
    11  
    12  	"storj.io/common/rpc"
    13  	"storj.io/common/rpc/rpcpool"
    14  	"storj.io/common/useragent"
    15  )
    16  
    17  const defaultDialTimeout = 10 * time.Second
    18  
    19  // Config defines configuration for using uplink library.
    20  type Config struct {
    21  	// UserAgent defines a registered partner's Value Attribution Code, and is used by the satellite to associate
    22  	// a bucket with the partner at the time of bucket creation.
    23  	// See https://docs.storj.io/dcs/how-tos/configure-tools-for-the-partner-program for info on the Partner Program.
    24  	// UserAgent should follow https://tools.ietf.org/html/rfc7231#section-5.5.3.
    25  	UserAgent string
    26  
    27  	// DialTimeout defines how long client should wait for establishing
    28  	// a connection to peers.
    29  	// No explicit value or 0 means default 20s will be used. Value lower than 0 means there is no timeout.
    30  	// DialTimeout is ignored if DialContext is provided.
    31  	//
    32  	// Deprecated: with the advent of Noise and TCP_FASTOPEN use, traditional dialing
    33  	// doesn't necessarily happen anymore. This is already ignored for certain
    34  	// connections and will be removed in a future release.
    35  	DialTimeout time.Duration
    36  
    37  	// DialContext is an extremely low level concern. It should almost certainly
    38  	// remain unset so that this library can make informed choices about how to
    39  	// talk to each node.
    40  	// DialContext is how sockets are opened to nodes of all kinds and is called to
    41  	// establish a connection. If DialContext is nil, it'll try to use the implementation
    42  	// best suited for each node.
    43  	//
    44  	// Deprecated: this will be removed in a future release. All analyzed uses of
    45  	// setting this value in open source projects are attempting to solve some more
    46  	// nuanced problem (like QoS) which can only be handled for some types of
    47  	// connections. This value is a hammer where we need a scalpel.
    48  	DialContext func(ctx context.Context, network, address string) (net.Conn, error)
    49  
    50  	// satellitePool is a connection pool dedicated for satellite connections.
    51  	// If not set, the normal pool / default will be used.
    52  	satellitePool *rpcpool.Pool
    53  
    54  	// pool is a connection pool for everything else (mainly for storagenode). Or everything if satellitePool is not set.
    55  	// If nil, a default pool will be created.
    56  	pool *rpcpool.Pool
    57  
    58  	// maximumBufferSize is used to set the maximum buffer size for DRPC
    59  	// connections/streams.
    60  	maximumBufferSize int
    61  
    62  	// disableObjectKeyEncryption disables the encryption of object keys for newly
    63  	// uploaded objects.
    64  	//
    65  	// Disabling the encryption of object keys means that the object keys are
    66  	// stored in plain text in the satellite database. This allows object listings
    67  	// to be returned in lexicographically sorted order.
    68  	//
    69  	// Object content is still encrypted as usual.
    70  	disableObjectKeyEncryption bool
    71  
    72  	// disableBackgroundQoS tells the uplink library to not try setting background
    73  	// QoS flags on the network sockets. This will impact the congestion control
    74  	// profile as well.
    75  	disableBackgroundQoS bool
    76  }
    77  
    78  // getDialer returns a new rpc.Dialer corresponding to the config.
    79  func (config Config) getDialer(ctx context.Context) (_ rpc.Dialer, err error) {
    80  	return config.getDialerForPool(ctx, nil)
    81  }
    82  
    83  // getDialerForPool returns a new rpc.Dialer corresponding to the config, using the chosen pool (or config.pool if pool is nil).
    84  func (config Config) getDialerForPool(ctx context.Context, pool *rpcpool.Pool) (_ rpc.Dialer, err error) {
    85  	tlsOptions, err := getProcessTLSOptions(ctx)
    86  	if err != nil {
    87  		return rpc.Dialer{}, packageError.Wrap(err)
    88  	}
    89  
    90  	dialer := rpc.NewDefaultDialer(tlsOptions)
    91  	if pool != nil {
    92  		dialer.Pool = pool
    93  	} else if config.pool != nil {
    94  		dialer.Pool = config.pool
    95  	} else {
    96  		dialer.Pool = rpc.NewDefaultConnectionPool()
    97  	}
    98  
    99  	dialer.DialTimeout = config.DialTimeout
   100  	dialer.AttemptBackgroundQoS = !config.disableBackgroundQoS
   101  
   102  	if config.DialContext != nil {
   103  		// N.B.: It is okay to use NewDefaultTCPConnector here because we explicitly don't want
   104  		// NewHybridConnector. NewHybridConnector would not be able to use the user-provided
   105  		// DialContext.
   106  		//lint:ignore SA1019 deprecated okay,
   107  		//nolint:staticcheck // deprecated okay.
   108  		dialer.Connector = rpc.NewDefaultTCPConnector(config.DialContext)
   109  	}
   110  
   111  	dialer.ConnectionOptions.Manager.Stream.MaximumBufferSize = config.maximumBufferSize
   112  
   113  	return dialer, nil
   114  }
   115  
   116  // NB: this is used with linkname in internal/expose.
   117  // It needs to be updated when this is updated.
   118  //
   119  //lint:ignore U1000, used with linkname
   120  //nolint:unused,revive
   121  //go:linkname config_getDialer
   122  func config_getDialer(config Config, ctx context.Context) (_ rpc.Dialer, err error) {
   123  	return config.getDialer(ctx)
   124  }
   125  
   126  // setConnectionPool exposes setting connection pool.
   127  //
   128  // NB: this is used with linkname in internal/expose.
   129  // It needs to be updated when this is updated.
   130  //
   131  //lint:ignore U1000, used with linkname
   132  //nolint:unused
   133  //go:linkname config_setConnectionPool
   134  func config_setConnectionPool(config *Config, pool *rpcpool.Pool) { config.pool = pool }
   135  
   136  // setSatelliteConnectionPool exposes setting connection pool for satellite.
   137  //
   138  // NB: this is used with linkname in internal/expose.
   139  // It needs to be updated when this is updated.
   140  //
   141  //lint:ignore U1000, used with linkname
   142  //nolint:unused
   143  //go:linkname config_setSatelliteConnectionPool
   144  func config_setSatelliteConnectionPool(config *Config, pool *rpcpool.Pool) {
   145  	config.satellitePool = pool
   146  }
   147  
   148  // setMaximumBufferSize exposes setting maximumBufferSize.
   149  //
   150  // NB: this is used with linkname in internal/expose.
   151  // It needs to be updated when this is updated.
   152  //
   153  //lint:ignore U1000, used with linkname
   154  //nolint:unused
   155  //go:linkname config_setMaximumBufferSize
   156  func config_setMaximumBufferSize(config *Config, maximumBufferSize int) {
   157  	config.maximumBufferSize = maximumBufferSize
   158  }
   159  
   160  // disableObjectKeyEncryption exposes setting disableObjectKeyEncryption.
   161  //
   162  // NB: this is used with linkname in internal/expose.
   163  // It needs to be updated when this is updated.
   164  //
   165  //lint:ignore U1000, used with linkname
   166  //nolint:unused
   167  //go:linkname config_disableObjectKeyEncryption
   168  func config_disableObjectKeyEncryption(config *Config) {
   169  	config.disableObjectKeyEncryption = true
   170  }
   171  
   172  func (config Config) validateUserAgent(ctx context.Context) error {
   173  	if len(config.UserAgent) == 0 {
   174  		return nil
   175  	}
   176  
   177  	if _, err := useragent.ParseEntries([]byte(config.UserAgent)); err != nil {
   178  		return err
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  // disableBackgroundQoS exposes setting Config.disableBackgroundQoS.
   185  //
   186  // NB: this is used with linkname in internal/expose.
   187  // It needs to be updated when this is updated.
   188  //
   189  //lint:ignore U1000, used with linkname
   190  //nolint:unused
   191  //go:linkname config_disableBackgroundQoS
   192  func config_disableBackgroundQoS(config *Config, disabled bool) {
   193  	config.disableBackgroundQoS = disabled
   194  }