Skip to content

Commit

Permalink
connection timeout handling
Browse files Browse the repository at this point in the history
  • Loading branch information
glaslos committed Oct 20, 2023
1 parent 3fdc39a commit 3de2326
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 45 deletions.
11 changes: 9 additions & 2 deletions glutton.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ func (g *Glutton) Start() error {
return err
}

if err := g.UpdateConnectionTimeout(g.ctx, conn); err != nil {
g.Logger.Error("failed to set connection timeout", zap.Error(err))
}

if hfunc, ok := g.tcpProtocolHandlers[rule.Target]; ok {
go func() {
if err := hfunc(g.ctx, conn); err != nil {
Expand Down Expand Up @@ -243,10 +247,13 @@ func (g *Glutton) makeID() error {
}

// UpdateConnectionTimeout increase connection timeout limit on connection I/O operation
func (g *Glutton) UpdateConnectionTimeout(ctx context.Context, conn net.Conn) {
func (g *Glutton) UpdateConnectionTimeout(ctx context.Context, conn net.Conn) error {
if timeout, ok := ctx.Value("timeout").(time.Duration); ok {
conn.SetDeadline(time.Now().Add(timeout))
if err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {
return err
}
}
return nil
}

// ConnectionByFlow returns connection metadata by connection key
Expand Down
2 changes: 1 addition & 1 deletion protocols/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ type Honeypot interface {
ProduceTCP(protocol string, conn net.Conn, md *connection.Metadata, payload []byte, decoded interface{}) error
ProduceUDP(handler string, srcAddr, dstAddr *net.UDPAddr, md *connection.Metadata, payload []byte, decoded interface{}) error
ConnectionByFlow([2]uint64) *connection.Metadata
UpdateConnectionTimeout(ctx context.Context, conn net.Conn)
UpdateConnectionTimeout(ctx context.Context, conn net.Conn) error
MetadataByConnection(net.Conn) (*connection.Metadata, error)
}
70 changes: 37 additions & 33 deletions protocols/tcp/bittorrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,44 +50,48 @@ func HandleBittorrent(ctx context.Context, conn net.Conn, logger interfaces.Logg

logger.Info("new bittorrent connection")

buffer := make([]byte, 1024)
for {
buffer := make([]byte, 1024)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err == nil || n > 0 {
msg := bittorrentMsg{}
if err := binary.Read(bytes.NewReader(buffer[:n]), binary.BigEndian, &msg); err != nil {
logger.Error("failed to read message", zap.Error(err), zap.String("handler", "bittorrent"))
break
}
if err != nil {
logger.Error("failed to read data", zap.Error(err), zap.String("handler", "bittorrent"))
break
}

if n <= 0 {
break
}

msg := bittorrentMsg{}
if err := binary.Read(bytes.NewReader(buffer[:n]), binary.BigEndian, &msg); err != nil {
logger.Error("failed to read message", zap.Error(err), zap.String("handler", "bittorrent"))
break
}

server.events = append(server.events, parsedBittorrent{
Direction: "read",
Message: msg,
Payload: buffer[:n],
})
server.events = append(server.events, parsedBittorrent{
Direction: "read",
Message: msg,
Payload: buffer[:n],
})

logger.Info(
"bittorrent received",
zap.String("handler", "bittorrent"),
zap.Uint8s("peer_id", msg.PeerID[:]),
zap.Uint8s("inf_hash", msg.InfoHash[:]),
)
logger.Info(
"bittorrent received",
zap.String("handler", "bittorrent"),
zap.Uint8s("peer_id", msg.PeerID[:]),
zap.Uint8s("inf_hash", msg.InfoHash[:]),
)

server.events = append(server.events, parsedBittorrent{
Direction: "write",
Message: msg,
Payload: buffer[:n],
})
if err = binary.Write(conn, binary.BigEndian, msg); err != nil {
logger.Error("failed to write message", zap.Error(err), zap.String("handler", "bittorrent"))
break
}
} else {
logger.Info("failed to read from connection", zap.String("handler", "bittorrent"))
if err != nil {
logger.Error("failed to read data", zap.Error(err), zap.String("handler", "bittorrent"))
break
}
server.events = append(server.events, parsedBittorrent{
Direction: "write",
Message: msg,
Payload: buffer[:n],
})
if err = binary.Write(conn, binary.BigEndian, msg); err != nil {
logger.Error("failed to write message", zap.Error(err), zap.String("handler", "bittorrent"))
break
}
}
return nil
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/ftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ func HandleFTP(ctx context.Context, conn net.Conn, logger interfaces.Logger, h i
return err
}
for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
msg, err := server.read(logger, h)
if len(msg) < 4 || err != nil {
return err
Expand Down
6 changes: 4 additions & 2 deletions protocols/tcp/memcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import (

func HandleMemcache(ctx context.Context, conn net.Conn, logger interfaces.Logger, h interfaces.Honeypot) error {
var dataMap = map[string]string{}
buffer := make([]byte, 1024)
for {
buffer := make([]byte, 1024)
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/mqtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ func HandleMQTT(ctx context.Context, conn net.Conn, logger interfaces.Logger, h
}()
buffer := make([]byte, 1024)
for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err == nil || n > 0 {
msg := mqttMsg{}
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/rdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ func HandleRDP(ctx context.Context, conn net.Conn, logger interfaces.Logger, h i

buffer := make([]byte, 1024)
for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err != nil && n <= 0 {
logger.Error(fmt.Sprintf("rdp error: %v", err))
Expand Down
3 changes: 3 additions & 0 deletions protocols/tcp/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ func HandleSIP(ctx context.Context, conn net.Conn, logger interfaces.Logger, h i
pp := parser.NewPacketParser(l)

for {
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ func HandleSMB(ctx context.Context, conn net.Conn, logger interfaces.Logger, h i

buffer := make([]byte, 1024)
for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err != nil && n <= 0 {
return err
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/smtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ func HandleSMTP(ctx context.Context, conn net.Conn, logger interfaces.Logger, h
client.w("220 Welcome!")

for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
data, err := client.read()
if err != nil {
break
Expand Down
5 changes: 4 additions & 1 deletion protocols/tcp/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ func HandleTCP(ctx context.Context, conn net.Conn, logger interfaces.Logger, h i

msgLength := 0
data := []byte{}
buffer := make([]byte, 1024)
for {
buffer := make([]byte, 1024)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
n, err := conn.Read(buffer)
if err != nil {
logger.Error("read error", zap.String("handler", "tcp"), zap.Error(err))
Expand Down
4 changes: 3 additions & 1 deletion protocols/tcp/telnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ func HandleTelnet(ctx context.Context, conn net.Conn, logger interfaces.Logger,
}

for {
h.UpdateConnectionTimeout(ctx, conn)
if err := h.UpdateConnectionTimeout(ctx, conn); err != nil {
return err
}
msg, err := s.read(conn)
if err != nil {
return err
Expand Down
14 changes: 14 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package glutton

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestServer(t *testing.T) {
server := NewServer(1234, 1235)
require.NotNil(t, server)
err := server.Shutdown()
require.NoError(t, err)
}

0 comments on commit 3de2326

Please sign in to comment.