Skip to content

Commit 8792f3b

Browse files
authored
Merge pull request #69 from gatewayd-io/fix-stale-connection-issue
Fix stale connection issue
2 parents 20365df + fd130da commit 8792f3b

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

network/proxy.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package network
22

33
import (
44
"context"
5-
"errors"
6-
"io"
75

86
gerr "github.com/gatewayd-io/gatewayd/errors"
97
"github.com/gatewayd-io/gatewayd/plugin"
@@ -262,7 +260,7 @@ func (pr *ProxyImpl) PassThrough(gconn gnet.Conn) *gerr.GatewayDError {
262260

263261
// The connection to the server is closed, so we MUST reconnect,
264262
// otherwise the client will be stuck.
265-
if received == 0 && err != nil && errors.Is(err.Unwrap(), io.EOF) {
263+
if IsConnClosed(received, err) || IsConnTimedOut(err) {
266264
pr.logger.Debug().Fields(
267265
map[string]interface{}{
268266
"function": "proxy.passthrough",
@@ -289,6 +287,17 @@ func (pr *ProxyImpl) PassThrough(gconn gnet.Conn) *gerr.GatewayDError {
289287
}
290288
}
291289

290+
// If the response is empty, don't send anything, instead just close the ingress connection.
291+
if received == 0 {
292+
pr.logger.Debug().Fields(
293+
map[string]interface{}{
294+
"function": "proxy.passthrough",
295+
"local": client.Conn.LocalAddr().String(),
296+
"remote": client.Conn.RemoteAddr().String(),
297+
}).Msg("No data to send to client")
298+
return err
299+
}
300+
292301
// Run the OnEgressTraffic hooks.
293302
result, err = pr.hookConfig.Run(
294303
context.Background(),

network/server.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,15 @@ func (s *Server) OnTraffic(gconn gnet.Conn) gnet.Action {
218218
// Pass the traffic from the client to server and vice versa.
219219
// If there is an error, log it and close the connection.
220220
if err := s.proxy.PassThrough(gconn); err != nil {
221-
s.logger.Error().Err(err).Msg("Failed to pass through traffic")
221+
s.logger.Warn().Err(err).Msg("Failed to pass through traffic")
222222
switch {
223-
case errors.Is(err, gerr.ErrPoolExhausted):
224-
case errors.Is(err, gerr.ErrCastFailed):
225-
case errors.Is(err, gerr.ErrClientNotFound):
226-
case errors.Is(err, gerr.ErrClientNotConnected):
227-
case errors.Is(err, gerr.ErrClientSendFailed):
228-
case errors.Is(err, gerr.ErrClientReceiveFailed):
229-
case errors.Is(err.Unwrap(), io.EOF):
223+
case errors.Is(err, gerr.ErrPoolExhausted),
224+
errors.Is(err, gerr.ErrCastFailed),
225+
errors.Is(err, gerr.ErrClientNotFound),
226+
errors.Is(err, gerr.ErrClientNotConnected),
227+
errors.Is(err, gerr.ErrClientSendFailed),
228+
errors.Is(err, gerr.ErrClientReceiveFailed),
229+
errors.Is(err.Unwrap(), io.EOF):
230230
return gnet.Close
231231
}
232232
}

network/utils.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"crypto/sha256"
55
"encoding/base64"
66
"encoding/hex"
7+
"errors"
78
"fmt"
9+
"io"
810
"net"
911
"syscall"
1012

@@ -118,3 +120,17 @@ func extractFieldValue(result map[string]interface{}, fieldName string) ([]byte,
118120
}
119121
return data, err, conversionErr
120122
}
123+
124+
func IsConnTimedOut(err *gerr.GatewayDError) bool {
125+
if err != nil && err.Unwrap() != nil {
126+
var netErr net.Error
127+
if ok := errors.As(err.Unwrap(), &netErr); ok && netErr.Timeout() {
128+
return true
129+
}
130+
}
131+
return false
132+
}
133+
134+
func IsConnClosed(received int, err *gerr.GatewayDError) bool {
135+
return received == 0 && err != nil && err.Unwrap() != nil && errors.Is(err.Unwrap(), io.EOF)
136+
}

0 commit comments

Comments
 (0)