Skip to content

Commit

Permalink
feat: be more aggressive to close conn (dmachard#308)
Browse files Browse the repository at this point in the history
* be more aggressive to close conn

* fix race

* fix for windows
  • Loading branch information
dmachard authored May 12, 2023
1 parent 74bc92d commit 92bc00c
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 29 deletions.
30 changes: 2 additions & 28 deletions collectors/dnstap.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package collectors
import (
"bufio"
"crypto/tls"
"io"
"net"
"os"
"strconv"
Expand All @@ -15,25 +14,6 @@ import (
"github.com/dmachard/go-logger"
)

// thanks to https://stackoverflow.com/questions/28967701/golang-tcp-socket-cant-close-after-get-file,
// call conn.CloseRead() before calling conn.Close()
func Close(conn io.Closer) error {
type ReadCloser interface {
CloseRead() error
}
var errs []error
if closer, ok := conn.(ReadCloser); ok {
errs = append(errs, closer.CloseRead())
}
errs = append(errs, conn.Close())
for _, err := range errs {
if err != nil {
return err
}
}
return nil
}

type Dnstap struct {
done chan bool
listen net.Listener
Expand Down Expand Up @@ -147,7 +127,7 @@ func (c *Dnstap) Stop() {
for _, conn := range c.conns {
peer := conn.RemoteAddr().String()
c.LogInfo("%s - closing connection...", peer)
Close(conn)
netlib.Close(conn, c.config.Collectors.Dnstap.ResetConn)
}
// Finally close the listener to unblock accept
c.LogInfo("stop listening...")
Expand Down Expand Up @@ -226,13 +206,7 @@ func (c *Dnstap) Run() {
}

if (c.connMode == "tls" || c.connMode == "tcp") && c.config.Collectors.Dnstap.RcvBufSize > 0 {

var is_tls bool
if c.config.Collectors.Dnstap.TlsSupport {
is_tls = true
}

before, actual, err := netlib.SetSock_RCVBUF(conn, c.config.Collectors.Dnstap.RcvBufSize, is_tls)
before, actual, err := netlib.SetSock_RCVBUF(conn, c.config.Collectors.Dnstap.RcvBufSize, c.config.Collectors.Dnstap.TlsSupport)
if err != nil {
c.logger.Fatal("Unable to set SO_RCVBUF: ", err)
}
Expand Down
14 changes: 13 additions & 1 deletion collectors/powerdns.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/dmachard/go-dnscollector/dnsutils"
"github.com/dmachard/go-dnscollector/netlib"
"github.com/dmachard/go-logger"
powerdns_protobuf "github.com/dmachard/go-powerdns-protobuf"
)
Expand Down Expand Up @@ -97,7 +98,7 @@ func (c *ProtobufPowerDNS) Stop() {
for _, conn := range c.conns {
peer := conn.RemoteAddr().String()
c.LogInfo("%s - closing connection...", peer)
conn.Close()
netlib.Close(conn, c.config.Collectors.PowerDNS.ResetConn)
}
// Finally close the listener to unblock accept
c.LogInfo("stop listening...")
Expand Down Expand Up @@ -160,6 +161,17 @@ func (c *ProtobufPowerDNS) Run() {
break
}

if c.config.Collectors.Dnstap.RcvBufSize > 0 {
before, actual, err := netlib.SetSock_RCVBUF(conn, c.config.Collectors.Dnstap.RcvBufSize, c.config.Collectors.Dnstap.TlsSupport)
if err != nil {
c.logger.Fatal("Unable to set SO_RCVBUF: ", err)
}
c.LogInfo("set SO_RCVBUF option, value before: %d, desired: %d, actual: %d",
before,
c.config.Collectors.Dnstap.RcvBufSize,
actual)
}

c.conns = append(c.conns, conn)
go c.HandleConn(conn)

Expand Down
4 changes: 4 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ multiplexer:
# key-file: ""
# # Sets the socket receive buffer in bytes SO_RCVBUF, set to zero to use the default system value
# sock-rcvbuf: 0
# # Reset TCP connection on exit
# reset-conn: true

# # dnstap proxifier with no protobuf decoding.
# dnstap-proxifier:
Expand Down Expand Up @@ -182,6 +184,8 @@ multiplexer:
# cert-file: ""
# # private key server file
# key-file: ""
# # Reset TCP connection on exit
# reset-conn: true

# # ztsp (TaZmen Sniffer Protocol)
# ztsp:
Expand Down
6 changes: 6 additions & 0 deletions dnsutils/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ type Config struct {
CertFile string `yaml:"cert-file"`
KeyFile string `yaml:"key-file"`
RcvBufSize int `yaml:"sock-rcvbuf"`
ResetConn bool `yaml:"reset-conn"`
} `yaml:"dnstap"`
DnstapProxifier struct {
Enable bool `yaml:"enable"`
Expand Down Expand Up @@ -213,6 +214,8 @@ type Config struct {
TlsMinVersion string `yaml:"tls-min-version"`
CertFile string `yaml:"cert-file"`
KeyFile string `yaml:"key-file"`
RcvBufSize int `yaml:"sock-rcvbuf"`
ResetConn bool `yaml:"reset-conn"`
} `yaml:"powerdns"`
FileIngestor struct {
Enable bool `yaml:"enable"`
Expand Down Expand Up @@ -479,6 +482,7 @@ func (c *Config) SetDefault() {
c.Collectors.Dnstap.CertFile = ""
c.Collectors.Dnstap.KeyFile = ""
c.Collectors.Dnstap.RcvBufSize = 0
c.Collectors.Dnstap.ResetConn = true

c.Collectors.DnstapProxifier.Enable = false
c.Collectors.DnstapProxifier.ListenIP = ANY_IP
Expand All @@ -503,6 +507,8 @@ func (c *Config) SetDefault() {
c.Collectors.PowerDNS.TlsMinVersion = TLS_v12
c.Collectors.PowerDNS.CertFile = ""
c.Collectors.PowerDNS.KeyFile = ""
c.Collectors.PowerDNS.RcvBufSize = 0
c.Collectors.PowerDNS.ResetConn = true

c.Collectors.FileIngestor.Enable = false
c.Collectors.FileIngestor.WatchDir = ""
Expand Down
6 changes: 6 additions & 0 deletions doc/collectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Options:
- `cert-file`: (string) certificate server file
- `key-file`: (string) private key server file
- `sock-rcvbuf`: (integer) sets the socket receive buffer in bytes SO_RCVBUF, set to zero to use the default system value
- `reset-conn`: (bool) Reset TCP connection on exit

Default values:

Expand All @@ -37,6 +38,7 @@ dnstap:
cert-file: ""
key-file: ""
sock-rcvbuf: 0
reset-conn: true
```
### DNS tap Proxifier
Expand Down Expand Up @@ -159,6 +161,8 @@ Options:
- `tls-min-version`: (string) min tls version
- `cert-file`: (string) certificate server file
- `key-file`: (string) private key server file
- `sock-rcvbuf`: (integer) sets the socket receive buffer in bytes SO_RCVBUF, set to zero to use the default system value
- `reset-conn`: (bool) Reset TCP connection on exit

Default values:

Expand All @@ -170,6 +174,8 @@ powerdns:
tls-min-version: 1.2
cert-file: ""
key-file: ""
sock-rcvbuf: 0
reset-conn: true
```

### File Ingestor
Expand Down
33 changes: 33 additions & 0 deletions netlib/conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package netlib

import (
"io"
"net"
)

// thanks to https://stackoverflow.com/questions/28967701/golang-tcp-socket-cant-close-after-get-file,
// call conn.CloseRead() before calling conn.Close()
func Close(conn io.Closer, reset bool) error {
type ReadCloser interface {
CloseRead() error
}

// Agressive closing, send TCP RESET instead of FIN
if reset {
if tcpConn, ok := conn.(*net.TCPConn); ok {
tcpConn.SetLinger(0)
}
}

var errs []error
if closer, ok := conn.(ReadCloser); ok {
errs = append(errs, closer.CloseRead())
}
errs = append(errs, conn.Close())
for _, err := range errs {
if err != nil {
return err
}
}
return nil
}
File renamed without changes.
File renamed without changes.

0 comments on commit 92bc00c

Please sign in to comment.