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 }