Skip to content

Commit

Permalink
switch to internal package
Browse files Browse the repository at this point in the history
  • Loading branch information
shueybubbles committed Jun 12, 2023
1 parent 41cfbff commit 7c4207d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ require (
github.com/golang-sql/sqlexp v0.1.0
github.com/jcmturner/gokrb5/v8 v8.4.4
golang.org/x/crypto v0.9.0
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
)

replace gopkg.in/natefinch/nvpipe.v2 => ./internal/gopkg.in/natefinch/nvpipe.v2
40 changes: 30 additions & 10 deletions internal/gopkg.in/natefinch/npipe.v2/npipe_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,38 @@ func (e PipeError) Temporary() bool {
// Dial will return a PipeError if you pass in a badly formatted pipe name.
//
// Examples:
// // local pipe
// conn, err := Dial(`\\.\pipe\mypipename`)
//
// // remote pipe
// conn, err := Dial(`\\othercomp\pipe\mypipename`)
// // local pipe
// conn, err := Dial(`\\.\pipe\mypipename`)
//
// // remote pipe
// conn, err := Dial(`\\othercomp\pipe\mypipename`)
func Dial(address string) (*PipeConn, error) {
return dialImpl(address, true)
}

// DialExisting acts like Dial but fails right away if the pipe doesn't exist
func DialExisting(address string) (*PipeConn, error) {
return dialImpl(address, false)
}

// DialTimeout acts like Dial, but will time out after the duration of timeout
func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) {
return dialTimeoutImpl(address, timeout, true)
}

// DialTimeoutExisting acts like DialTimeout but fails right away if the pipe doesn't exist
func DialTimeoutExisting(address string, timeout time.Duration) (*PipeConn, error) {
return dialTimeoutImpl(address, timeout, false)
}

func dialImpl(address string, waitForPipe bool) (*PipeConn, error) {
for {
conn, err := dial(address, nmpwait_wait_forever)
if err == nil {
return conn, nil
}
if isPipeNotReady(err) {
if isPipeNotReady(err, waitForPipe) {
<-time.After(100 * time.Millisecond)
continue
}
Expand All @@ -123,7 +143,7 @@ func Dial(address string) (*PipeConn, error) {
}

// DialTimeout acts like Dial, but will time out after the duration of timeout
func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) {
func dialTimeoutImpl(address string, timeout time.Duration, waitForPipe bool) (*PipeConn, error) {
deadline := time.Now().Add(timeout)

now := time.Now()
Expand All @@ -138,7 +158,7 @@ func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) {
return nil, PipeError{fmt.Sprintf(
"Timed out waiting for pipe '%s' to come available", address), true}
}
if isPipeNotReady(err) {
if isPipeNotReady(err, waitForPipe) {
left := deadline.Sub(time.Now())
retry := 100 * time.Millisecond
if left > retry {
Expand All @@ -156,13 +176,13 @@ func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) {
}

// isPipeNotReady checks the error to see if it indicates the pipe is not ready
func isPipeNotReady(err error) bool {
func isPipeNotReady(err error, waitForPipe bool) bool {
// Pipe Busy means another client just grabbed the open pipe end,
// and the server hasn't made a new one yet.
// File Not Found means the server hasn't created the pipe yet.
// Neither is a fatal error.
// If waitForPipe is false, File Not Found is treated as fatal

return err == syscall.ERROR_FILE_NOT_FOUND || err == error_pipe_busy
return (waitForPipe && err == syscall.ERROR_FILE_NOT_FOUND) || err == error_pipe_busy
}

// newOverlapped creates a structure used to track asynchronous
Expand Down
6 changes: 3 additions & 3 deletions internal/np/namedpipe_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import (
"os"
"time"

"gopkg.in/natefinch/npipe.v2"
"github.com/microsoft/go-mssqldb/internal/gopkg.in/natefinch/npipe.v2"
)

func DialConnection(ctx context.Context, pipename string, host string, instanceName string, inputServerSPN string) (conn net.Conn, serverSPN string, err error) {
dl, ok := ctx.Deadline()
if ok {
duration := time.Until(dl)
conn, err = npipe.DialTimeout(pipename, duration)
conn, err = npipe.DialTimeoutExisting(pipename, duration)
} else {
conn, err = npipe.Dial(pipename)
conn, err = npipe.DialExisting(pipename)
}
serverSPN = inputServerSPN
if err == nil && inputServerSPN == "" {
Expand Down

0 comments on commit 7c4207d

Please sign in to comment.