Skip to content

Commit 248a318

Browse files
jlhawnliggitt
authored andcommitted
Use Message Context (#69)
This patch introduces a new type called `messageContext` which is now the return value of `(*Conn).sendMessage()`. The message context object still contains a channel from which methods like, Add(), Bind(), Search(), etc., will receive response packets. It also has a field which holds the message ID as well as a `done` channel which is used to prevent deadlock in the `processMessages()` goroutine. This is accomplished by also changing the `(*Conn).finishMessage()` method to take a message context and close this `done` channel before sending a `MessageFinish` packet to the `processMessages()` goroutine. The `processMessages()` goroutine now has a `messageContexts` map which replaces the `chanResults` map. Now, rather than sending response packets only on the response channels, the `messageContext` has its own `sendResponse()` method which uses a switch that blocks on sending a response packet *or* waiting for its `done` channel to be closed by `finishMessage()`. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
1 parent 8a8cb05 commit 248a318

9 files changed

Lines changed: 416 additions & 147 deletions

File tree

add.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ type Attribute struct {
2121
Vals []string
2222
}
2323

24-
25-
2624
func (a *Attribute) encode() *ber.Packet {
2725
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
2826
seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.Type, "Type"))
@@ -39,7 +37,6 @@ type AddRequest struct {
3937
Attributes []Attribute
4038
}
4139

42-
4340
func (a AddRequest) encode() *ber.Packet {
4441
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
4542
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.DN, "DN"))
@@ -63,29 +60,25 @@ func NewAddRequest(dn string) *AddRequest {
6360
}
6461

6562
func (l *Conn) Add(addRequest *AddRequest) error {
66-
messageID := l.nextMessageID()
6763
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
68-
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
64+
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
6965
packet.AppendChild(addRequest.encode())
7066

7167
l.Debug.PrintPacket(packet)
7268

73-
channel, err := l.sendMessage(packet)
69+
msgCtx, err := l.sendMessage(packet)
7470
if err != nil {
7571
return err
7672
}
77-
if channel == nil {
78-
return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
79-
}
80-
defer l.finishMessage(messageID)
73+
defer l.finishMessage(msgCtx)
8174

82-
l.Debug.Printf("%d: waiting for response", messageID)
83-
packetResponse, ok := <-channel
75+
l.Debug.Printf("%d: waiting for response", msgCtx.id)
76+
packetResponse, ok := <-msgCtx.responses
8477
if !ok {
85-
return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
78+
return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
8679
}
8780
packet, err = packetResponse.ReadPacket()
88-
l.Debug.Printf("%d: got response %p", messageID, packet)
81+
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
8982
if err != nil {
9083
return err
9184
}
@@ -106,6 +99,6 @@ func (l *Conn) Add(addRequest *AddRequest) error {
10699
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
107100
}
108101

109-
l.Debug.Printf("%d: returning", messageID)
102+
l.Debug.Printf("%d: returning", msgCtx.id)
110103
return nil
111104
}

bind.go

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,32 +40,27 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
4040
}
4141

4242
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
43-
messageID := l.nextMessageID()
44-
4543
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
46-
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
44+
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
4745
encodedBindRequest := simpleBindRequest.encode()
4846
packet.AppendChild(encodedBindRequest)
4947

5048
if l.Debug {
5149
ber.PrintPacket(packet)
5250
}
5351

54-
channel, err := l.sendMessage(packet)
52+
msgCtx, err := l.sendMessage(packet)
5553
if err != nil {
5654
return nil, err
5755
}
58-
if channel == nil {
59-
return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
60-
}
61-
defer l.finishMessage(messageID)
56+
defer l.finishMessage(msgCtx)
6257

63-
packetResponse, ok := <-channel
58+
packetResponse, ok := <-msgCtx.responses
6459
if !ok {
65-
return nil, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
60+
return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
6661
}
6762
packet, err = packetResponse.ReadPacket()
68-
l.Debug.Printf("%d: got response %p", messageID, packet)
63+
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
6964
if err != nil {
7065
return nil, err
7166
}
@@ -96,10 +91,8 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
9691
}
9792

9893
func (l *Conn) Bind(username, password string) error {
99-
messageID := l.nextMessageID()
100-
10194
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
102-
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
95+
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
10396
bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
10497
bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
10598
bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name"))
@@ -110,21 +103,18 @@ func (l *Conn) Bind(username, password string) error {
110103
ber.PrintPacket(packet)
111104
}
112105

113-
channel, err := l.sendMessage(packet)
106+
msgCtx, err := l.sendMessage(packet)
114107
if err != nil {
115108
return err
116109
}
117-
if channel == nil {
118-
return NewError(ErrorNetwork, errors.New("ldap: could not send message"))
119-
}
120-
defer l.finishMessage(messageID)
110+
defer l.finishMessage(msgCtx)
121111

122-
packetResponse, ok := <-channel
112+
packetResponse, ok := <-msgCtx.responses
123113
if !ok {
124-
return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
114+
return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
125115
}
126116
packet, err = packetResponse.ReadPacket()
127-
l.Debug.Printf("%d: got response %p", messageID, packet)
117+
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
128118
if err != nil {
129119
return err
130120
}

compare.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ import (
3333
// Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise
3434
// false with any error that occurs if any.
3535
func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
36-
messageID := l.nextMessageID()
3736
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
38-
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID"))
37+
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
3938

4039
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request")
4140
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN"))
@@ -48,22 +47,19 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
4847

4948
l.Debug.PrintPacket(packet)
5049

51-
channel, err := l.sendMessage(packet)
50+
msgCtx, err := l.sendMessage(packet)
5251
if err != nil {
5352
return false, err
5453
}
55-
if channel == nil {
56-
return false, NewError(ErrorNetwork, errors.New("ldap: could not send message"))
57-
}
58-
defer l.finishMessage(messageID)
54+
defer l.finishMessage(msgCtx)
5955

60-
l.Debug.Printf("%d: waiting for response", messageID)
61-
packetResponse, ok := <-channel
56+
l.Debug.Printf("%d: waiting for response", msgCtx.id)
57+
packetResponse, ok := <-msgCtx.responses
6258
if !ok {
63-
return false, NewError(ErrorNetwork, errors.New("ldap: channel closed"))
59+
return false, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
6460
}
6561
packet, err = packetResponse.ReadPacket()
66-
l.Debug.Printf("%d: got response %p", messageID, packet)
62+
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
6763
if err != nil {
6864
return false, err
6965
}

0 commit comments

Comments
 (0)