Skip to content

Commit cb504ae

Browse files
authored
Fix request timeout handling (#388)
* Fix request timeout handling * Ensure 64-bit alignment
1 parent c4ad4d4 commit cb504ae

File tree

2 files changed

+30
-20
lines changed

2 files changed

+30
-20
lines changed

conn.go

+15-10
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const (
8787
type Conn struct {
8888
// requestTimeout is loaded atomically
8989
// so we need to ensure 64-bit alignment on 32-bit platforms.
90+
// https://github.com/go-ldap/ldap/pull/199
9091
requestTimeout int64
9192
conn net.Conn
9293
isTLS bool
@@ -281,9 +282,7 @@ func (l *Conn) Close() {
281282

282283
// SetTimeout sets the time after a request is sent that a MessageTimeout triggers
283284
func (l *Conn) SetTimeout(timeout time.Duration) {
284-
if timeout > 0 {
285-
atomic.StoreInt64(&l.requestTimeout, int64(timeout))
286-
}
285+
atomic.StoreInt64(&l.requestTimeout, int64(timeout))
287286
}
288287

289288
// Returns the next available messageID
@@ -486,20 +485,26 @@ func (l *Conn) processMessages() {
486485
l.messageContexts[message.MessageID] = message.Context
487486

488487
// Add timeout if defined
489-
requestTimeout := time.Duration(atomic.LoadInt64(&l.requestTimeout))
490-
if requestTimeout > 0 {
488+
if l.requestTimeout > 0 {
491489
go func() {
490+
timer := time.NewTimer(time.Duration(l.requestTimeout))
492491
defer func() {
493492
if err := recover(); err != nil {
494493
logger.Printf("ldap: recovered panic in RequestTimeout: %v", err)
495494
}
495+
496+
timer.Stop()
496497
}()
497-
time.Sleep(requestTimeout)
498-
timeoutMessage := &messagePacket{
499-
Op: MessageTimeout,
500-
MessageID: message.MessageID,
498+
499+
select {
500+
case <-timer.C:
501+
timeoutMessage := &messagePacket{
502+
Op: MessageTimeout,
503+
MessageID: message.MessageID,
504+
}
505+
l.sendProcessMessage(timeoutMessage)
506+
case <-message.Context.done:
501507
}
502-
l.sendProcessMessage(timeoutMessage)
503508
}()
504509
}
505510
case MessageResponse:

v3/conn.go

+15-10
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const (
8787
type Conn struct {
8888
// requestTimeout is loaded atomically
8989
// so we need to ensure 64-bit alignment on 32-bit platforms.
90+
// https://github.com/go-ldap/ldap/pull/199
9091
requestTimeout int64
9192
conn net.Conn
9293
isTLS bool
@@ -281,9 +282,7 @@ func (l *Conn) Close() {
281282

282283
// SetTimeout sets the time after a request is sent that a MessageTimeout triggers
283284
func (l *Conn) SetTimeout(timeout time.Duration) {
284-
if timeout > 0 {
285-
atomic.StoreInt64(&l.requestTimeout, int64(timeout))
286-
}
285+
atomic.StoreInt64(&l.requestTimeout, int64(timeout))
287286
}
288287

289288
// Returns the next available messageID
@@ -486,20 +485,26 @@ func (l *Conn) processMessages() {
486485
l.messageContexts[message.MessageID] = message.Context
487486

488487
// Add timeout if defined
489-
requestTimeout := time.Duration(atomic.LoadInt64(&l.requestTimeout))
490-
if requestTimeout > 0 {
488+
if l.requestTimeout > 0 {
491489
go func() {
490+
timer := time.NewTimer(time.Duration(l.requestTimeout))
492491
defer func() {
493492
if err := recover(); err != nil {
494493
logger.Printf("ldap: recovered panic in RequestTimeout: %v", err)
495494
}
495+
496+
timer.Stop()
496497
}()
497-
time.Sleep(requestTimeout)
498-
timeoutMessage := &messagePacket{
499-
Op: MessageTimeout,
500-
MessageID: message.MessageID,
498+
499+
select {
500+
case <-timer.C:
501+
timeoutMessage := &messagePacket{
502+
Op: MessageTimeout,
503+
MessageID: message.MessageID,
504+
}
505+
l.sendProcessMessage(timeoutMessage)
506+
case <-message.Context.done:
501507
}
502-
l.sendProcessMessage(timeoutMessage)
503508
}()
504509
}
505510
case MessageResponse:

0 commit comments

Comments
 (0)