Skip to content

Commit

Permalink
add TCPUserTimeout param to s3 driver
Browse files Browse the repository at this point in the history
customizes `TCP_USER_TIMEOUT` value for S3 client connections.
  • Loading branch information
wjordan committed May 8, 2024
1 parent d58e3ff commit 306cb1e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
38 changes: 38 additions & 0 deletions registry/storage/driver/s3-aws/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import (
"fmt"
"io"
"math"
"net"
"net/http"
"path/filepath"
"reflect"
"sort"
"strconv"
"strings"
"sync"
"syscall"
"time"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -120,6 +122,7 @@ type DriverParameters struct {
UseDualStack bool
Accelerate bool
LogLevel aws.LogLevelType
TCPUserTimeout time.Duration
}

func init() {
Expand Down Expand Up @@ -440,6 +443,21 @@ func FromParameters(ctx context.Context, parameters map[string]interface{}) (*Dr
return nil, fmt.Errorf("the accelerate parameter should be a boolean")
}

tcpUserTimeout := parameters["tcpusertimeout"]
tcpUserTimeoutDuration := time.Duration(0)
switch tcpUserTimeout := tcpUserTimeout.(type) {
case string:
d, err := time.ParseDuration(tcpUserTimeout)
if err != nil {
return nil, fmt.Errorf("the tcpusertimeout parameter should be a duration")
}
tcpUserTimeoutDuration = d
case nil:
// do nothing
default:
return nil, fmt.Errorf("the tcpusertimeout parameter should be a duration")
}

params := DriverParameters{
fmt.Sprint(accessKey),
fmt.Sprint(secretKey),
Expand All @@ -465,6 +483,7 @@ func FromParameters(ctx context.Context, parameters map[string]interface{}) (*Dr
useDualStackBool,
accelerateBool,
getS3LogLevelFromParam(parameters["loglevel"]),
tcpUserTimeoutDuration,
}

return New(ctx, params)
Expand Down Expand Up @@ -561,6 +580,25 @@ func New(ctx context.Context, params DriverParameters) (*Driver, error) {
httpTransportModified := false
httpTransport := http.DefaultTransport.(*http.Transport).Clone()

if params.TCPUserTimeout > 0 {
dialer := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}
dialer.Control = func(network, address string, c syscall.RawConn) error {
var err error
controlErr := c.Control(func(fd uintptr) {
err = setTCPUserTimeout(fd, params.TCPUserTimeout)
})
if controlErr != nil {
return controlErr
}
return err
}
httpTransport.DialContext = dialer.DialContext
httpTransportModified = true
}

if params.SkipVerify {
httpTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
httpTransportModified = true
Expand Down
12 changes: 12 additions & 0 deletions registry/storage/driver/s3-aws/tcp_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build !linux
// +build !linux

package s3

import (
"time"
)

func setTCPUserTimeout(fd uintptr, timeout time.Duration) error {
return nil
}
12 changes: 12 additions & 0 deletions registry/storage/driver/s3-aws/tcp_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package s3

import (
"syscall"
"time"

"golang.org/x/sys/unix"
)

func setTCPUserTimeout(fd uintptr, timeout time.Duration) error {
return syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout.Milliseconds()))
}

0 comments on commit 306cb1e

Please sign in to comment.