Skip to content

Commit

Permalink
Resolve #5, an issue where having an invalid ESL password did not pro…
Browse files Browse the repository at this point in the history
…perly close the connection.

Also ensures we send the exit command where it logically makes sense to ensure that we try our best to inform FreeSWITCH of us stopping the connection.
  • Loading branch information
winsock committed Feb 16, 2021
1 parent 4b56517 commit 5aaee86
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 16 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ eslgo was written from the ground up in idiomatic Go for use in our production p
go get github.com/percipia/eslgo
```
```
github.com/percipia/eslgo v1.3.2
github.com/percipia/eslgo v1.3.3
```

## Overview
Expand Down Expand Up @@ -90,6 +90,6 @@ func main() {

// Close the connection after sleeping for a bit
time.Sleep(60 * time.Second)
conn.Close()
conn.ExitAndClose()
}
```
10 changes: 9 additions & 1 deletion connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func newConnection(c net.Conn, outbound bool) *Conn {
TypeEventPlain: make(chan *RawResponse),
TypeEventXML: make(chan *RawResponse),
TypeEventJSON: make(chan *RawResponse),
TypeAuthRequest: make(chan *RawResponse),
TypeAuthRequest: make(chan *RawResponse, 1), // Buffered to ensure we do not lose the initial auth request before we are setup to respond
TypeDisconnect: make(chan *RawResponse),
},
runningContext: runningContext,
Expand Down Expand Up @@ -124,6 +124,14 @@ func (c *Conn) SendCommand(ctx context.Context, command command.Command) (*RawRe
}
}

func (c *Conn) ExitAndClose() {
// Attempt a graceful closing of the connection with FreeSWITCH
ctx, cancel := context.WithTimeout(c.runningContext, time.Second)
_, _ = c.SendCommand(ctx, command.Exit{})
cancel()
c.Close()
}

func (c *Conn) Close() {
c.closeOnce.Do(c.close)
}
Expand Down
6 changes: 3 additions & 3 deletions example/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func main() {
})

// Ensure all events are enabled
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
_ = conn.EnableEvents(ctx)
cancel()

Expand All @@ -48,7 +48,7 @@ func main() {
}
}

// Remove the listener and close the connection
// Remove the listener and close the connection gracefully
conn.RemoveEventListener(eslgo.EventListenAll, listenerID)
conn.Close()
conn.ExitAndClose()
}
4 changes: 2 additions & 2 deletions example/inbound/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

func main() {
// Connect to FreeSWITCH
conn, err := eslgo.Dial("127.0.0.1:8021", "ClueCon", func() {
conn, err := eslgo.Dial("127.0.0.1:8021", "ClueCon1", func() {
fmt.Println("Inbound Connection Disconnected")
})
if err != nil {
Expand All @@ -37,5 +37,5 @@ func main() {

// Close the connection after sleeping for a bit
time.Sleep(60 * time.Second)
conn.Close()
conn.ExitAndClose()
}
18 changes: 12 additions & 6 deletions inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ func Dial(address, password string, onDisconnect func()) (*Conn, error) {
<-connection.responseChannels[TypeAuthRequest]
err = connection.doAuth(connection.runningContext, command.Auth{Password: password})
if err != nil {
// Try to gracefully disconnect
log.Printf("Failed to auth %e\n", err)
_, _ = connection.SendCommand(connection.runningContext, command.Exit{})
// Try to gracefully disconnect, we have the wrong password.
connection.ExitAndClose()
if onDisconnect != nil {
go onDisconnect()
}
return nil, err
} else {
log.Printf("Sucessfully authenticated %s\n", connection.conn.RemoteAddr())
}
Expand All @@ -47,7 +50,9 @@ func (c *Conn) disconnectLoop(onDisconnect func()) {
select {
case <-c.responseChannels[TypeDisconnect]:
c.Close()
defer onDisconnect()
if onDisconnect != nil {
onDisconnect()
}
return
case <-c.runningContext.Done():
return
Expand All @@ -60,9 +65,10 @@ func (c *Conn) authLoop(auth command.Auth) {
case <-c.responseChannels[TypeAuthRequest]:
err := c.doAuth(c.runningContext, auth)
if err != nil {
// Try to gracefully disconnect
log.Printf("Failed to auth %e\n", err)
_, _ = c.SendCommand(c.runningContext, command.Exit{})
// Close the connection, we have the wrong password
c.ExitAndClose()
return
} else {
log.Printf("Sucessfully authenticated %s\n", c.conn.RemoteAddr())
}
Expand Down
4 changes: 2 additions & 2 deletions outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (c *Conn) outboundHandle(handler OutboundHandler) {
if err != nil {
log.Printf("Error connecting to %s error %s", c.conn.RemoteAddr().String(), err.Error())
// Try closing cleanly first
c.Close()
c.Close() // Not ExitAndClose since this error connection is most likely from communication failure
return
}
handler(c.runningContext, c, response)
Expand All @@ -67,7 +67,7 @@ func (c *Conn) outboundHandle(handler OutboundHandler) {
ctx, cancel = context.WithTimeout(c.runningContext, 5*time.Second)
_, _ = c.SendCommand(ctx, command.Exit{})
cancel()
c.Close()
c.ExitAndClose()
}

func (c *Conn) dummyLoop() {
Expand Down

0 comments on commit 5aaee86

Please sign in to comment.