Skip to content

Commit

Permalink
[Feature]: Add UDP SO_REUSEADDR Support
Browse files Browse the repository at this point in the history
  • Loading branch information
ihipop committed Apr 9, 2023
1 parent f130472 commit d7afe4f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 1 deletion.
3 changes: 3 additions & 0 deletions coremain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ type ServerListenerConfig struct {
ProxyProtocol bool `yaml:"proxy_protocol"` // accepting the PROXYProtocol

IdleTimeout uint `yaml:"idle_timeout"` // (sec) used by tcp, dot, doh as connection idle timeout.

// see issue: https://github.com/IrineSistiana/mosdns/issues/
ReuseAddr bool `yaml:"reuse_addr"` // used by udp on unix alike systems.
}

type APIConfig struct {
Expand Down
9 changes: 8 additions & 1 deletion coremain/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package coremain

import (
"context"
"errors"
"fmt"
"github.com/IrineSistiana/mosdns/v4/pkg/server"
Expand All @@ -28,6 +29,7 @@ import (
"github.com/pires/go-proxyproto"
"go.uber.org/zap"
"net"
"syscall"
"time"
)

Expand Down Expand Up @@ -115,7 +117,12 @@ func (m *Mosdns) startServerListener(cfg *ServerListenerConfig, dnsHandler dns_h
var run func() error
switch cfg.Protocol {
case "", "udp":
conn, err := net.ListenPacket("udp", cfg.Addr)
var lc net.ListenConfig
lc.Control = func(network, address string, c syscall.RawConn) error {
return serverSocketOption(c, cfg, network, address)
}

conn, err := lc.ListenPacket(context.Background(), "udp", cfg.Addr)
if err != nil {
return err
}
Expand Down
15 changes: 15 additions & 0 deletions coremain/utilities_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//go:build !(linux || darwin || freebsd || netbsd || openbsd)

package coremain

import (
"errors"
"syscall"
)

func serverSocketOption(c syscall.RawConn, cfg *ServerListenerConfig, network, address string) error {
if cfg.ReuseAddr {
return errors.New("reuseaddr not supported on this platform")
}
return nil
}
20 changes: 20 additions & 0 deletions coremain/utilities_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build linux || darwin || freebsd || netbsd || openbsd

package coremain

import (
"syscall"
)

func serverSocketOption(c syscall.RawConn, cfg *ServerListenerConfig, network, address string) error {
var errSysCall error
errControl := c.Control(func(fd uintptr) {
if cfg.ReuseAddr {
errSysCall = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
}
})
if errSysCall != nil {
return errSysCall
}
return errControl
}

0 comments on commit d7afe4f

Please sign in to comment.