default:
}
- deadline, _ := ctx.Deadline()
- partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
- if err != nil {
- // Ran out of time.
- if firstErr == nil {
- firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
- }
- break
- }
dialCtx := ctx
- if partialDeadline.Before(deadline) {
- var cancel context.CancelFunc
- dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
- defer cancel()
+ if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
+ partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
+ if err != nil {
+ // Ran out of time.
+ if firstErr == nil {
+ firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
+ }
+ break
+ }
+ if partialDeadline.Before(deadline) {
+ var cancel context.CancelFunc
+ dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
+ defer cancel()
+ }
}
c, err := sd.dialSingle(dialCtx, ra)
testenv.MustHaveExternalNetwork(t)
}
}
+
+type contextWithNonZeroDeadline struct {
+ context.Context
+}
+
+func (contextWithNonZeroDeadline) Deadline() (time.Time, bool) {
+ // Return non-zero time.Time value with false indicating that no deadline is set.
+ return time.Unix(0, 0), false
+}
+
+func TestDialWithNonZeroDeadline(t *testing.T) {
+ ln, err := newLocalListener("tcp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer ln.Close()
+ _, port, err := SplitHostPort(ln.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ctx := contextWithNonZeroDeadline{Context: context.Background()}
+ var dialer Dialer
+ c, err := dialer.DialContext(ctx, "tcp", JoinHostPort("", port))
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+}
if err := fd.pfd.Init(fd.net, true); err != nil {
return nil, err
}
- if deadline, _ := ctx.Deadline(); !deadline.IsZero() {
+ if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
fd.pfd.SetWriteDeadline(deadline)
defer fd.pfd.SetWriteDeadline(noDeadline)
}