1
0
Fork 0
mirror of https://github.com/SamTherapy/dnscrypt.git synced 2024-11-19 20:43:45 +00:00
dnscrypt/cmd/server.go
Sam Therapy 3459b621a6
change import URL
Signed-off-by: Sam Therapy <sam@samtherapy.net>
2023-03-06 23:26:40 +01:00

113 lines
2.8 KiB
Go

package main
import (
"net"
"os"
"os/signal"
"syscall"
"dns.froth.zone/dnscrypt"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"
"gopkg.in/yaml.v3"
)
// ServerArgs is the "server" command arguments
type ServerArgs struct {
Config string `short:"c" long:"config" description:"Path to the DNSCrypt configuration file. Param is required." required:"true"`
Forward string `short:"f" long:"forward" description:"Forwards DNS queries to the specified address" default:"94.140.14.140:53"`
ListenAddrs []string `short:"l" long:"listen" description:"Listening addresses" default:"0.0.0.0"`
ListenPorts []int `short:"p" long:"port" description:"Listening ports" default:"443"`
}
// server runs a DNSCrypt server
func server(args ServerArgs) {
log.Info("Starting DNSCrypt server")
b, err := os.ReadFile(args.Config)
if err != nil {
log.Fatalf("failed to read the configuration: %v", err)
}
rc := dnscrypt.ResolverConfig{}
err = yaml.Unmarshal(b, &rc)
if err != nil {
log.Fatalf("failed to deserialize configuration: %v", err)
}
cert, err := rc.CreateCert()
if err != nil {
log.Fatalf("failed to generate certificate: %v", err)
}
s := &dnscrypt.Server{
ProviderName: rc.ProviderName,
ResolverCert: cert,
Handler: &forwardHandler{addr: args.Forward},
}
tcp, udp := createListeners(args)
for _, t := range tcp {
log.Info("Listening to tcp://%s", t.Addr().String())
listen := t
go func() { _ = s.ServeTCP(listen) }()
}
for _, u := range udp {
log.Info("Listening to udp://%s", u.LocalAddr().String())
listen := u
go func() { _ = s.ServeUDP(listen) }()
}
signalChannel := make(chan os.Signal, 1)
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
<-signalChannel
log.Info("Closing all listeners")
for _, t := range tcp {
_ = t.Close()
}
for _, u := range udp {
_ = u.Close()
}
}
// createListeners creates listeners for our server
func createListeners(args ServerArgs) (tcp []net.Listener, udp []*net.UDPConn) {
for _, addr := range args.ListenAddrs {
ip := net.ParseIP(addr)
if ip == nil {
log.Fatalf("invalid listen address: %s", addr)
}
for _, port := range args.ListenPorts {
tcpListen, err := net.ListenTCP("tcp", &net.TCPAddr{IP: ip, Port: port})
if err != nil {
log.Fatalf("failed to start TCP listener: %v", err)
}
udpListen, err := net.ListenUDP("udp", &net.UDPAddr{IP: ip, Port: port})
if err != nil {
log.Fatalf("failed to start UDP listener: %v", err)
}
tcp = append(tcp, tcpListen)
udp = append(udp, udpListen)
}
}
return
}
type forwardHandler struct {
addr string
}
// type check
var _ dnscrypt.Handler = &forwardHandler{}
// ServeDNS implements Handler interface
func (f *forwardHandler) ServeDNS(rw dnscrypt.ResponseWriter, r *dns.Msg) error {
res, err := dns.Exchange(r, f.addr)
if err != nil {
return err
}
return rw.WriteMsg(res)
}