Skip to content

Commit b05d573

Browse files
committed
Tidy up, improve logging and add missing error handling.
1 parent cf869ce commit b05d573

File tree

3 files changed

+194
-155
lines changed

3 files changed

+194
-155
lines changed

domain-proxy/common.go

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"os"
99
"strconv"
1010
"strings"
11-
"sync"
1211
"time"
1312
)
1413

@@ -20,7 +19,7 @@ const (
2019
ConnectionTimeoutKey = "CONNECTION_TIMEOUT"
2120
DefaultConnectionTimeout = 1000 * time.Millisecond
2221
IdleTimeoutKey = "IDLE_TIMEOUT"
23-
DefaultIdleTimeout = 30000 * time.Millisecond
22+
DefaultIdleTimeout = 10000 * time.Millisecond
2423
)
2524

2625
var Logger *log.Logger
@@ -29,53 +28,78 @@ func InitLogger(appName string) {
2928
Logger = log.New(os.Stdout, appName+" ", log.LstdFlags|log.Lshortfile)
3029
}
3130

32-
func BiDirectionalTransfer(leftConn, rightConn net.Conn, byteBufferSize int, idleTimeout time.Duration, executor *sync.WaitGroup) {
33-
defer executor.Done()
34-
defer CloseConnections(leftConn, rightConn)
31+
func BiDirectionalTransfer(leftConnection, rightConnection net.Conn, byteBufferSize int, idleTimeout time.Duration, connectionType string, connectionNo uint64) {
32+
defer CloseConnection(leftConnection, rightConnection, connectionType, connectionNo)
3533
done := make(chan struct{}, 2)
36-
leftConn.SetDeadline(time.Now().Add(idleTimeout))
37-
rightConn.SetDeadline(time.Now().Add(idleTimeout))
38-
go Transfer(leftConn, rightConn, done, byteBufferSize, idleTimeout)
39-
go Transfer(rightConn, leftConn, done, byteBufferSize, idleTimeout)
34+
if err := leftConnection.SetDeadline(time.Now().Add(idleTimeout)); err != nil {
35+
handleSetDeadlineError(leftConnection, err)
36+
return
37+
}
38+
if err := rightConnection.SetDeadline(time.Now().Add(idleTimeout)); err != nil {
39+
handleSetDeadlineError(rightConnection, err)
40+
return
41+
}
42+
go Transfer(leftConnection, rightConnection, done, byteBufferSize, idleTimeout, connectionType, connectionNo)
43+
go Transfer(rightConnection, leftConnection, done, byteBufferSize, idleTimeout, connectionType, connectionNo)
4044
<-done
4145
<-done
4246
}
4347

44-
func Transfer(sourceConn, targetConn net.Conn, done chan struct{}, bufferSize int, idleTimeout time.Duration) {
48+
func Transfer(sourceConnection, targetConnection net.Conn, done chan struct{}, bufferSize int, idleTimeout time.Duration, connectionType string, connectionNo uint64) {
4549
defer func() {
4650
done <- struct{}{}
4751
}()
4852
buf := make([]byte, bufferSize)
4953
for {
50-
n, err := io.CopyBuffer(sourceConn, targetConn, buf)
51-
if err != nil {
52-
handleConnectionError(err)
54+
if n, err := io.CopyBuffer(sourceConnection, targetConnection, buf); err != nil {
55+
handleConnectionError(err, connectionType, connectionNo)
5356
return
5457
} else if n > 0 {
55-
sourceConn.SetReadDeadline(time.Now().Add(idleTimeout))
56-
targetConn.SetWriteDeadline(time.Now().Add(idleTimeout))
57-
Logger.Printf("%d bytes transferred", n)
58+
if err = sourceConnection.SetReadDeadline(time.Now().Add(idleTimeout)); err != nil {
59+
handleSetDeadlineError(sourceConnection, err)
60+
return
61+
}
62+
if err = targetConnection.SetWriteDeadline(time.Now().Add(idleTimeout)); err != nil {
63+
handleSetDeadlineError(targetConnection, err)
64+
return
65+
}
66+
Logger.Printf("%d bytes transferred for %s connection %d", n, connectionType, connectionNo)
5867
}
5968
}
6069
}
6170

62-
func handleConnectionError(err error) {
71+
func handleSetDeadlineError(connection net.Conn, err error) {
72+
Logger.Printf("Failed to set deadline: %v", err)
73+
if err = connection.Close(); err != nil {
74+
HandleConnectionCloseError(err)
75+
}
76+
}
77+
78+
func HandleConnectionCloseError(err error) {
79+
Logger.Printf("Failed to close connection: %v", err)
80+
}
81+
82+
func HandleListenerCloseError(err error) {
83+
Logger.Printf("Failed to close listener: %v", err)
84+
}
85+
86+
func handleConnectionError(err error, connectionType string, connectionNo uint64) {
6387
var netErr net.Error
6488
if errors.As(err, &netErr) && netErr.Timeout() {
65-
Logger.Printf("Connection timed out")
89+
Logger.Printf("%s connection %d timed out", connectionType, connectionNo)
6690
} else if err != io.EOF {
67-
Logger.Printf("Error using connection: %v", err)
91+
Logger.Printf("Failed to transfer data using %s connection %d: %v", connectionType, connectionNo, err)
6892
}
6993
}
7094

71-
func CloseConnections(leftConn, rightConn net.Conn) {
72-
if leftConn != nil {
73-
leftConn.Close()
95+
func CloseConnection(leftConnection, rightConnection net.Conn, connectionType string, connectionNo uint64) {
96+
if err := leftConnection.Close(); err != nil {
97+
HandleConnectionCloseError(err)
7498
}
75-
if rightConn != nil {
76-
rightConn.Close()
99+
if err := rightConnection.Close(); err != nil {
100+
HandleConnectionCloseError(err)
77101
}
78-
Logger.Println("Connections closed")
102+
Logger.Printf("%s connection %d closed", connectionType, connectionNo)
79103
}
80104

81105
func GetEnvVariable(key, defaultValue string) string {

domain-proxy/domain_proxy_client.go

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"net"
66
"os"
77
"os/signal"
8-
"sync"
8+
"sync/atomic"
99
"syscall"
1010
"time"
1111
)
@@ -14,17 +14,18 @@ const (
1414
Localhost = "localhost"
1515
ServerHttpPortKey = "SERVER_HTTP_PORT"
1616
DefaultServerHttpPort = 8080
17+
HttpToDomainSocket = "HTTP <-> Domain Socket"
1718
)
1819

1920
type DomainProxyClient struct {
20-
domainSocket string
21-
serverHttpPort int
22-
byteBufferSize int
23-
connectionTimeout time.Duration
24-
idleTimeout time.Duration
25-
listener net.Listener
26-
executor *sync.WaitGroup
27-
shutdownChan chan struct{}
21+
domainSocket string
22+
serverHttpPort int
23+
byteBufferSize int
24+
connectionTimeout time.Duration
25+
idleTimeout time.Duration
26+
httpConnectionCounter atomic.Uint64
27+
listener net.Listener
28+
shutdownChan chan struct{}
2829
}
2930

3031
func NewDomainProxyClient(domainSocket string, serverHttpPort, byteBufferSize int, connectionTimeout, idleTimeout time.Duration) *DomainProxyClient {
@@ -34,7 +35,6 @@ func NewDomainProxyClient(domainSocket string, serverHttpPort, byteBufferSize in
3435
byteBufferSize: byteBufferSize,
3536
connectionTimeout: connectionTimeout,
3637
idleTimeout: idleTimeout,
37-
executor: &sync.WaitGroup{},
3838
shutdownChan: make(chan struct{}),
3939
}
4040
}
@@ -47,42 +47,49 @@ func (dpc *DomainProxyClient) Start() {
4747
if err != nil {
4848
Logger.Fatalf("Failed to start HTTP server: %v", err)
4949
}
50-
dpc.executor.Add(1)
5150
go dpc.startClient()
5251
}
5352

5453
func (dpc *DomainProxyClient) startClient() {
55-
defer dpc.executor.Done()
56-
Logger.Println("HTTP server listening on port", dpc.serverHttpPort)
54+
Logger.Printf("HTTP server listening on port %d", dpc.serverHttpPort)
5755
for {
58-
serverConn, err := dpc.listener.Accept()
59-
if err != nil {
56+
if serverConnection, err := dpc.listener.Accept(); err != nil {
6057
select {
6158
case <-dpc.shutdownChan:
6259
return
6360
default:
64-
Logger.Printf("Failed to accept connection: %v", err)
65-
continue
61+
Logger.Printf("Failed to accept server connection: %v", err)
6662
}
63+
} else {
64+
go dpc.handleConnectionRequest(serverConnection)
6765
}
68-
domainConn, err := net.DialTimeout("unix", dpc.domainSocket, dpc.connectionTimeout)
69-
if err != nil {
70-
Logger.Printf("Failed to connect to domain socket: %v", err)
71-
serverConn.Close()
72-
continue
66+
}
67+
}
68+
69+
func (dpc *DomainProxyClient) handleConnectionRequest(serverConnection net.Conn) {
70+
connectionNo := dpc.httpConnectionCounter.Add(1)
71+
Logger.Printf("Handling %s Connection %d", HttpToDomainSocket, connectionNo)
72+
startTime := time.Now()
73+
domainConnection, err := net.DialTimeout("unix", dpc.domainSocket, dpc.connectionTimeout)
74+
if err != nil {
75+
Logger.Printf("Failed to connect to domain socket: %v", err)
76+
if err = serverConnection.Close(); err != nil {
77+
HandleConnectionCloseError(err)
7378
}
74-
dpc.executor.Add(1)
75-
go BiDirectionalTransfer(serverConn, domainConn, dpc.byteBufferSize, dpc.idleTimeout, dpc.executor)
79+
return
7680
}
81+
go func() {
82+
BiDirectionalTransfer(serverConnection, domainConnection, dpc.byteBufferSize, dpc.idleTimeout, HttpToDomainSocket, connectionNo)
83+
Logger.Printf("%s Connection %d ended after %d ms", HttpToDomainSocket, connectionNo, time.Since(startTime).Milliseconds())
84+
}()
7785
}
7886

7987
func (dpc *DomainProxyClient) Stop() {
8088
Logger.Println("Shutting down domain proxy client...")
8189
close(dpc.shutdownChan)
8290
if err := dpc.listener.Close(); err != nil {
83-
Logger.Printf("Error closing listener: %v", err)
91+
HandleListenerCloseError(err)
8492
}
85-
//dpc.executor.Wait()
8693
}
8794

8895
func GetServerHttpPort() int {
@@ -93,8 +100,8 @@ func main() {
93100
InitLogger("Domain Proxy Client")
94101
client := NewDomainProxyClient(GetDomainSocket(), GetServerHttpPort(), GetByteBufferSize(), GetConnectionTimeout(), GetIdleTimeout())
95102
client.Start()
96-
sigs := make(chan os.Signal, 1)
97-
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
98-
<-sigs
103+
signals := make(chan os.Signal, 1)
104+
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
105+
<-signals
99106
client.Stop()
100107
}

0 commit comments

Comments
 (0)