further work on converting logging engine to zerolog

This commit is contained in:
kayos 2021-05-18 15:19:02 -07:00
parent 2dccfa0aea
commit 117fc49e26
20 changed files with 101 additions and 213 deletions

View File

@ -55,7 +55,7 @@ type PluginConfig struct {
// Load reads a configuration file and returns a Config object, or an error if
// any.
func Load(pathOverride string) (*Config, error) {
log.Print("Loading configuration")
log.Info().Msg("Loading configuration")
c := New()
c.v.SetConfigType("toml")
if pathOverride != "" {
@ -214,7 +214,7 @@ func (c *Config) parseConfig(ver protocolVersion) error {
return err
}
for _, p := range plugins {
log.Printf("DHCPv%d: found plugin `%s` with %d args: %v", ver, p.Name, len(p.Args), p.Args)
log.Info().Interface("DHCPv", ver).Strs("Args", p.Args).Msg("found plugin: " + p.Name)
}
listeners, err := c.parseListen(ver)

View File

@ -2,17 +2,26 @@ package logger
import (
"os"
"git.tcp.direct/kayos/tr4proute-dhcp/config"
"github.com/rs/zerolog"
"time"
)
var LogDirPrefix string = "./.logs/"
var LogDir string
var LogFile *os.File
var log zerolog.Logger
var err error
func GetLogger(name string) zerolog.Logger {
if err := os.MkdirAll(config.LogDir, 0755); err != nil {
panic("cannot create log directory: " + config.LogDir + " (" + err.Error() + ")")
}
if logFile, err = os.OpenFile(config.LogDir+time.Now().Format(time.RFC3339)+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
panic("cannot create log file: " + err.Error())
}
multi := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr}, logFile)
return zerolog.New(multi).With().Timestamp().Str("Origin", name).Logger()
LogDir = LogDirPrefix + "/" + LogDir
if err := os.MkdirAll(LogDir, 0755); err != nil {
panic("cannot create log directory: " + LogDir + " (" + err.Error() + ")")
}
if LogFile, err = os.OpenFile(LogDir+time.Now().Format(time.RFC3339)+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
panic("cannot create log file: " + err.Error())
}
multi := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr}, LogFile)
return zerolog.New(multi).With().Timestamp().Str("Origin", name).Logger()
}

View File

@ -19,12 +19,11 @@ import (
"github.com/willf/bitset"
"git.tcp.direct/kayos/tr4proute-dhcp/logger"
"github.com/rs/zerolog/log"
"git.tcp.direct/kayos/tr4proute-dhcp/plugins/allocators"
)
var log = logger.GetLogger("plugins/allocators/bitmap")
// Allocator is a prefix allocator allocating in chunks of a fixed size
// regardless of the size requested by the client.
// It consumes an amount of memory proportional to the total amount of available prefixes
@ -108,7 +107,6 @@ func (a *Allocator) Free(prefix net.IPNet) error {
// NewBitmapAllocator creates a new allocator, allocating /`size` prefixes
// carved out of the given `pool` prefix
func NewBitmapAllocator(pool net.IPNet, size int) (*Allocator, error) {
poolSize, _ := pool.Mask.Size()
allocOrder := size - poolSize
@ -117,7 +115,7 @@ func NewBitmapAllocator(pool net.IPNet, size int) (*Allocator, error) {
} else if allocOrder >= strconv.IntSize {
return nil, fmt.Errorf("A pool with more than 2^%d items is not representable", size-poolSize)
} else if allocOrder >= 32 {
log.Warningln("Using a pool of more than 2^32 elements may result in large memory consumption")
log.Warn().Msg("Using a pool of more than 2^32 elements may result in large memory consumption")
}
if !(1<<uint(allocOrder) <= bitset.Cap()) {

View File

@ -40,12 +40,12 @@ func setup6(args ...string) (handler.Handler6, error) {
}
dnsServers6 = append(dnsServers6, server)
}
log.Infof("loaded %d DNS servers.", len(dnsServers6))
log.Info().Int("count", len(dnsServers6)).Msg("loaded ipv6 DNS servers")
return Handler6, nil
}
func setup4(args ...string) (handler.Handler4, error) {
log.Printf("loaded plugin for DHCPv4.")
log.Info().Msg("loaded plugin for DHCPv4.")
if len(args) < 1 {
return nil, errors.New("need at least one DNS server")
}
@ -56,7 +56,7 @@ func setup4(args ...string) (handler.Handler4, error) {
}
dnsServers4 = append(dnsServers4, DNSServer)
}
log.Infof("loaded %d DNS servers.", len(dnsServers4))
log.Info().Int("count", len(dnsServers4)).Msg("loaded ipv6 DNS servers")
return Handler4, nil
}
@ -64,7 +64,7 @@ func setup4(args ...string) (handler.Handler4, error) {
func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
decap, err := req.GetInnerMessage()
if err != nil {
log.Errorf("Could not decapsulate relayed message, aborting: %v", err)
log.Error().Err(err).Msg("Could not decapsulate relayed message, aborting")
return nil, true
}

View File

@ -75,14 +75,14 @@ var Plugin = plugins.Plugin{
// packet that the server receives. Remember that a handler may not be called
// for each packet, if the handler chain is interrupted before reaching it.
func setup6(args ...string) (handler.Handler6, error) {
log.Printf("loaded plugin for DHCPv6.")
log.Info().Msg("loaded plugin for DHCPv6.")
return exampleHandler6, nil
}
// setup4 behaves like setupExample6, but for DHCPv4 packets. It
// implements the `plugin.SetupFunc4` interface.
func setup4(args ...string) (handler.Handler4, error) {
log.Printf("loaded plugin for DHCPv4.")
log.Info().Msg("loaded plugin for DHCPv4.")
return exampleHandler4, nil
}
@ -100,7 +100,7 @@ func setup4(args ...string) (handler.Handler4, error) {
// will call the next plugin in the chan, using the returned response packet as
// input for the next plugin.
func exampleHandler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
log.Printf("received DHCPv6 packet: %s", req.Summary())
log.Info().Msg("received DHCPv6 packet: %s", req.Summary())
// return the unmodified response, and false. This means that the next
// plugin in the chain will be called, and the unmodified response packet
// will be used as its input.
@ -110,7 +110,7 @@ func exampleHandler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
// exampleHandler4 behaves like exampleHandler6, but for DHCPv4 packets. It
// implements the `handler.Handler4` interface.
func exampleHandler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
log.Printf("received DHCPv4 packet: %s", req.Summary())
log.Info().Msg("received DHCPv4 packet: %s", req.Summary())
// return the unmodified response, and false. This means that the next
// plugin in the chain will be called, and the unmodified response packet
// will be used as its input.

View File

@ -1,125 +0,0 @@
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
// Package file enable static mapping of MAC <--> IP addresses.
// The mapping is stored in a text file, where each mapping is described by one line containing
// two fields separated by spaces: MAC address, and IP address. For example:
//
// $ cat file_leases.txt
// 00:11:22:33:44:55 10.0.0.1
// 01:23:45:67:89:01 10.0.10.10
//
// To specify the plugin configuration in the server6/server4 sections of the config file, just
// pass the leases file name as plugin argument, e.g.:
//
// $ cat config.yml
//
// server6:
// ...
// plugins:
// - file: "file_leases.txt"
// ...
//
// If the file path is not absolute, it is relative to the cwd where coredhcp is run.
package file
import (
"bytes"
"errors"
"fmt"
"net"
"strings"
"time"
"github.com/prologic/bitcask"
"git.tcp.direct/kayos/tr4proute-dhcp/handler"
"git.tcp.direct/kayos/tr4proute-dhcp/logger"
"git.tcp.direct/kayos/tr4proute-dhcp/plugins"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv6"
)
var log = logger.GetLogger("plugins/file")
// Plugin wraps plugin registration information
var Plugin = plugins.Plugin{
Name: "bitcask",
Setup6: setup6,
Setup4: setup4,
}
// Handler6 handles DHCPv6 packets for the file plugin
func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
m, err := req.GetInnerMessage()
if err != nil {
log.Errorf("BUG: could not decapsulate: %v", err)
return nil, true
}
if m.Options.OneIANA() == nil {
log.Debug("No address requested")
return resp, false
}
mac, err := dhcpv6.ExtractMAC(req)
if err != nil {
log.Warningf("Could not find client MAC, passing")
return resp, false
}
log.Debugf("looking up an IP address for MAC %s", mac.String())
ipaddr, ok := StaticRecords[mac.String()]
if !ok {
log.Warningf("MAC address %s is unknown", mac.String())
return resp, false
}
log.Debugf("found IP address %s for MAC %s", ipaddr, mac.String())
resp.AddOption(&dhcpv6.OptIANA{
IaId: m.Options.OneIANA().IaId,
Options: dhcpv6.IdentityOptions{Options: []dhcpv6.Option{
&dhcpv6.OptIAAddress{
IPv6Addr: ipaddr,
PreferredLifetime: 3600 * time.Second,
ValidLifetime: 3600 * time.Second,
},
}},
})
return resp, false
}
// Handler4 handles DHCPv4 packets for the file plugin
func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
ipaddr, ok := StaticRecords[req.ClientHWAddr.String()]
if !ok {
log.Warningf("MAC address %s is unknown", req.ClientHWAddr.String())
return resp, false
}
resp.YourIPAddr = ipaddr
log.Debugf("found IP address %s for MAC %s", ipaddr, req.ClientHWAddr.String())
return resp, true
}
func setup6(args ...string) (handler.Handler6, error) {
h6, _, err := setupFile(true, args...)
return h6, err
}
func setup4(args ...string) (handler.Handler4, error) {
_, h4, err := setupFile(false, args...)
return h4, err
}
func setupFile(v6 bool, args ...string) (handler.Handler6, handler.Handler4, error) {
var err error
var records map[string]net.IP
if err != nil {
return nil, nil, fmt.Errorf("failed to load DHCPv6 records: %v", err)
}
StaticRecords = records
log.Infof("loaded %d leases from %s", len(records), filename)
return Handler6, Handler4, nil
}

View File

@ -40,15 +40,15 @@ func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
}
func setup4(args ...string) (handler.Handler4, error) {
log.Print("loading `lease_time` plugin for DHCPv4")
log.Info().Msg("loading lease_time plugin for DHCPv4")
if len(args) < 1 {
log.Error("No default lease time provided")
log.Error().Msg("No default lease time provided")
return nil, errors.New("lease_time failed to initialize")
}
leaseTime, err := time.ParseDuration(args[0])
if err != nil {
log.Errorf("invalid duration: %v", args[0])
log.Error().Msg("invalid duration argument: " + args[0])
return nil, errors.New("lease_time failed to initialize")
}
v4LeaseTime = leaseTime

View File

@ -73,7 +73,7 @@ func setup6(args ...string) (handler.Handler6, error) {
OptionData: []byte(params),
}
}
log.Printf("loaded NBP plugin for DHCPv6.")
log.Info().Msg("loaded NBP plugin for DHCPv6.")
return nbpHandler6, nil
}
@ -86,7 +86,7 @@ func setup4(args ...string) (handler.Handler4, error) {
opt66 = &otsn
obfn := dhcpv4.OptBootFileName(u.Path)
opt67 = &obfn
log.Printf("loaded NBP plugin for DHCPv4.")
log.Info().Msg("loaded NBP plugin for DHCPv4.")
return nbpHandler4, nil
}
@ -97,7 +97,7 @@ func nbpHandler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
}
decap, err := req.GetInnerMessage()
if err != nil {
log.Errorf("Could not decapsulate request: %v", err)
log.Error().Msg("Could not decapsulate request: %v", err)
// drop the request, this is probably a critical error in the packet.
return nil, true
}

View File

@ -28,7 +28,7 @@ var (
)
func setup4(args ...string) (handler.Handler4, error) {
log.Printf("loaded plugin for DHCPv4.")
log.Info().Msg("loaded plugin for DHCPv4.")
if len(args) != 1 {
return nil, errors.New("need at least one netmask IP address")
}
@ -44,7 +44,7 @@ func setup4(args ...string) (handler.Handler4, error) {
if !checkValidNetmask(netmask) {
return nil, errors.New("netmask is not valid, got: " + args[1])
}
log.Printf("loaded client netmask")
log.Info().Msg("loaded client netmask")
return Handler4, nil
}

View File

@ -37,11 +37,11 @@ func RegisterPlugin(plugin *Plugin) error {
if plugin == nil {
return errors.New("cannot register nil plugin")
}
log.Printf("Registering plugin '%s'", plugin.Name)
log.Info().Msg("Registering plugin: " + plugin.Name)
if _, ok := RegisteredPlugins[plugin.Name]; ok {
// TODO this highlights that asking the plugins to register themselves
// is not the right approach. Need to register them in the main program.
log.Panicf("Plugin '%s' is already registered", plugin.Name)
log.Panic().Msg("Plugin is already registered" + plugin.Name)
}
RegisteredPlugins[plugin.Name] = plugin
return nil
@ -70,9 +70,9 @@ func LoadPlugins(conf *config.Config) ([]handler.Handler4, []handler.Handler6, e
if conf.Server6 != nil {
for _, pluginConf := range conf.Server6.Plugins {
if plugin, ok := RegisteredPlugins[pluginConf.Name]; ok {
log.Printf("DHCPv6: loading plugin `%s`", pluginConf.Name)
log.Info().Msg("DHCPv6: loading plugin " + pluginConf.Name)
if plugin.Setup6 == nil {
log.Warningf("DHCPv6: plugin `%s` has no setup function for DHCPv6", pluginConf.Name)
log.Warn().Msg("DHCPv6: plugin " + pluginConf.Name + " has no setup function for DHCPv6")
continue
}
h6, err := plugin.Setup6(pluginConf.Args...)
@ -92,9 +92,9 @@ func LoadPlugins(conf *config.Config) ([]handler.Handler4, []handler.Handler6, e
if conf.Server4 != nil {
for _, pluginConf := range conf.Server4.Plugins {
if plugin, ok := RegisteredPlugins[pluginConf.Name]; ok {
log.Printf("DHCPv4: loading plugin `%s`", pluginConf.Name)
log.Info().Msg("DHCPv4: loading plugin " + pluginConf.Name)
if plugin.Setup4 == nil {
log.Warningf("DHCPv4: plugin `%s` has no setup function for DHCPv4", pluginConf.Name)
log.Warn().Msg("DHCPv4: plugin " + pluginConf.Name + "has no setup function for DHCPv4")
continue
}
h4, err := plugin.Setup4(pluginConf.Args...)

View File

@ -119,7 +119,7 @@ func (h *Handler) Handle(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
// Each request IA_PD requires an IA_PD response
for _, iapd := range msg.Options.IAPD() {
if err != nil {
log.Errorf("Malformed IAPD received: %v", err)
log.Error().Msg("Malformed IAPD received: %v", err)
resp.AddOption(&dhcpv6.OptStatusCode{StatusCode: dhcpIana.StatusMalformedQuery})
return resp, true
}

View File

@ -50,13 +50,19 @@ type PluginState struct {
func (p *PluginState) Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
p.Lock()
defer p.Unlock()
record, ok := p.Recordsv4[req.ClientHWAddr.String()]
reqmac := req.ClientHWAddr.String()
record, ok := p.Recordsv4[reqmac]
// sublogger for the specific request we are logging
rlog := log.With().Str("MAC", reqmac).Logger()
if !ok {
// Allocating new address since there isn't one allocated
log.Printf("MAC address %s is new, leasing new IPv4 address", req.ClientHWAddr.String())
rlog.Info().Msg("leasing new IPv4 address")
ip, err := p.allocator.Allocate(net.IPNet{})
if err != nil {
log.Errorf("Could not allocate IP for MAC %s: %v", req.ClientHWAddr.String(), err)
rlog.Error().Err(err).Msg("Could not allocate IP")
return nil, true
}
rec := Record{
@ -65,9 +71,9 @@ func (p *PluginState) Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool)
}
err = p.saveIPAddress(req.ClientHWAddr, &rec)
if err != nil {
log.Errorf("SaveIPAddress for MAC %s failed: %v", req.ClientHWAddr.String(), err)
rlog.Error().Err(err).Msg("SaveIPAddress for MAC failed")
}
p.Recordsv4[req.ClientHWAddr.String()] = &rec
p.Recordsv4[reqmac] = &rec
record = &rec
} else {
// Ensure we extend the existing lease at least past when the one we're giving expires
@ -75,13 +81,13 @@ func (p *PluginState) Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool)
record.expires = time.Now().Add(p.LeaseTime).Round(time.Second)
err := p.saveIPAddress(req.ClientHWAddr, record)
if err != nil {
log.Errorf("Could not persist lease for MAC %s: %v", req.ClientHWAddr.String(), err)
rlog.Error().Err(err).Msg("Could not persist lease")
}
}
}
resp.YourIPAddr = record.IP
resp.Options.Update(dhcpv4.OptIPAddressLeaseTime(p.LeaseTime.Round(time.Second)))
log.Printf("found IP address %s for MAC %s", record.IP, req.ClientHWAddr.String())
rlog.Info().Str("IP", record.IP).Msg("success: found IP")
return resp, false
}
@ -125,7 +131,7 @@ func setupRange(args ...string) (handler.Handler4, error) {
return nil, fmt.Errorf("could not load records from file: %v", err)
}
log.Printf("Loaded %d DHCPv4 leases from %s", len(p.Recordsv4), filename)
log.Info().Msg("Loaded %d DHCPv4 leases from %s", len(p.Recordsv4), filename)
if err := p.registerBackingFile(filename); err != nil {
return nil, fmt.Errorf("could not setup lease storage: %w", err)

View File

@ -51,7 +51,7 @@ func loadRecordsFromFile(filename string) (map[string]*Record, error) {
reader, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0640)
defer func() {
if err := reader.Close(); err != nil {
log.Warningf("Failed to close file %s: %v", filename, err)
log.Warn().Msg("Failed to close file %s: %v", filename, err)
}
}()
if err != nil {

View File

@ -27,7 +27,7 @@ var (
)
func setup4(args ...string) (handler.Handler4, error) {
log.Printf("Loaded plugin for DHCPv4.")
log.Info().Msg("Loaded plugin for DHCPv4.")
if len(args) < 1 {
return nil, errors.New("need at least one router IP address")
}
@ -38,7 +38,7 @@ func setup4(args ...string) (handler.Handler4, error) {
}
routers = append(routers, router)
}
log.Infof("loaded %d router IP addresses.", len(routers))
log.Info()("loaded %d router IP addresses.", len(routers))
return Handler4, nil
}

View File

@ -52,13 +52,13 @@ func copySlice(original []string) []string {
func setup6(args ...string) (handler.Handler6, error) {
v6SearchList = args
log.Printf("Registered domain search list (DHCPv6) %s", v6SearchList)
log.Info().Msg("Registered domain search list (DHCPv6) %s", v6SearchList)
return domainSearchListHandler6, nil
}
func setup4(args ...string) (handler.Handler4, error) {
v4SearchList = args
log.Printf("Registered domain search list (DHCPv4) %s", v4SearchList)
log.Info().Msg("Registered domain search list (DHCPv4) %s", v4SearchList)
return domainSearchListHandler4, nil
}

View File

@ -35,14 +35,14 @@ var (
// Handler6 handles DHCPv6 packets for the server_id plugin.
func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
if v6ServerID == nil {
log.Fatal("BUG: Plugin is running uninitialized!")
log.Fatal().Msg("BUG: Plugin is running uninitialized!")
return nil, true
}
msg, err := req.GetInnerMessage()
if err != nil {
// BUG: this should already have failed in the main handler. Abort
log.Error(err)
log.Error().Err(err).Msg("ERROR")
return nil, true
}
@ -57,7 +57,7 @@ func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
// Approximately all others MUST be discarded if the ServerID doesn't match
if !sid.Equal(*v6ServerID) {
log.Infof("requested server ID does not match this server's ID. Got %v, want %v", sid, *v6ServerID)
log.Info().Interface("wanted", sid).Interface("got", *v6ServerID).Msg("requested server ID does not match this server's ID.")
return nil, true
}
} else if msg.MessageType == dhcpv6.MessageTypeRequest ||
@ -75,18 +75,18 @@ func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
// Handler4 handles DHCPv4 packets for the server_id plugin.
func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
if v4ServerID == nil {
log.Fatal("BUG: Plugin is running uninitialized!")
log.Fatal().Msg("BUG: Plugin is running uninitialized!")
return nil, true
}
if req.OpCode != dhcpv4.OpcodeBootRequest {
log.Warningf("not a BootRequest, ignoring")
log.Warn().Msg("not a BootRequest, ignoring")
return resp, false
}
if req.ServerIPAddr != nil &&
!req.ServerIPAddr.Equal(net.IPv4zero) &&
!req.ServerIPAddr.Equal(v4ServerID) {
// This request is not for us, drop it.
log.Infof("requested server ID does not match this server's ID. Got %v, want %v", req.ServerIPAddr, v4ServerID)
log.Info()("requested server ID does not match this server's ID. Got %v, want %v", req.ServerIPAddr, v4ServerID)
return nil, true
}
resp.ServerIPAddr = make(net.IP, net.IPv4len)
@ -96,7 +96,7 @@ func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
}
func setup4(args ...string) (handler.Handler4, error) {
log.Printf("loading `server_id` plugin for DHCPv4 with args: %v", args)
log.Info().Msg("loading `server_id` plugin for DHCPv4 with args: %v", args)
if len(args) < 1 {
return nil, errors.New("need an argument")
}
@ -112,7 +112,7 @@ func setup4(args ...string) (handler.Handler4, error) {
}
func setup6(args ...string) (handler.Handler6, error) {
log.Printf("loading `server_id` plugin for DHCPv6 with args: %v", args)
log.Info().Msg("loading `server_id` plugin for DHCPv6 with args: %v", args)
if len(args) < 2 {
return nil, errors.New("need a DUID type and value")
}
@ -151,7 +151,7 @@ func setup6(args ...string) (handler.Handler6, error) {
default:
return nil, errors.New("Opaque DUID type not supported yet")
}
log.Printf("using %s %s", duidType, duidValue)
log.Info().Interface("type", duidType).Interface("value", duidValue).Msg("DUID_INFO")
return Handler6, nil
}

View File

@ -52,7 +52,7 @@ func setup6(args ...string) (handler.Handler6, error) {
if err != nil {
return nil, fmt.Errorf("failed to parse duration: %w", err)
}
log.Printf("loaded plugin for DHCPv6.")
log.Info().Msg("loaded plugin for DHCPv6.")
return makeSleepHandler6(delay), nil
}
@ -64,13 +64,13 @@ func setup4(args ...string) (handler.Handler4, error) {
if err != nil {
return nil, fmt.Errorf("failed to parse duration: %w", err)
}
log.Printf("loaded plugin for DHCPv4.")
log.Info().Msg("loaded plugin for DHCPv4.")
return makeSleepHandler4(delay), nil
}
func makeSleepHandler6(delay time.Duration) handler.Handler6 {
return func(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
log.Printf("introducing delay of %s in response", delay)
log.Info().Msg("introducing delay of %s in response", delay)
// return the unmodified response, and instruct coredhcp to continue to
// the next plugin.
time.Sleep(delay)
@ -80,7 +80,7 @@ func makeSleepHandler6(delay time.Duration) handler.Handler6 {
func makeSleepHandler4(delay time.Duration) handler.Handler4 {
return func(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
log.Printf("introducing delay of %s in response", delay)
log.Info().Msg("introducing delay of %s in response", delay)
// return the unmodified response, and instruct coredhcp to continue to
// the next plugin.
time.Sleep(delay)

View File

@ -23,14 +23,14 @@ func (l *listener6) HandleMsg6(buf []byte, oob *ipv6.ControlMessage, peer *net.U
d, err := dhcpv6.FromBytes(buf)
bufpool.Put(&buf)
if err != nil {
log.Printf("Error parsing DHCPv6 request: %v", err)
log.Info().Msg("Error parsing DHCPv6 request: %v", err)
return
}
// decapsulate the relay message
msg, err := d.GetInnerMessage()
if err != nil {
log.Warningf("DHCPv6: cannot get inner message: %v", err)
log.Warn().Msg("DHCPv6: cannot get inner message: %v", err)
return
}
@ -50,7 +50,7 @@ func (l *listener6) HandleMsg6(buf []byte, oob *ipv6.ControlMessage, peer *net.U
err = fmt.Errorf("MainHandler6: message type %d not supported", msg.Type())
}
if err != nil {
log.Printf("MainHandler6: NewReplyFromDHCPv6Message failed: %v", err)
log.Info().Msg("MainHandler6: NewReplyFromDHCPv6Message failed: %v", err)
return
}
@ -69,11 +69,11 @@ func (l *listener6) HandleMsg6(buf []byte, oob *ipv6.ControlMessage, peer *net.U
// if the request was relayed, re-encapsulate the response
if d.IsRelay() {
if rmsg, ok := resp.(*dhcpv6.Message); !ok {
log.Warningf("DHCPv6: response is a relayed message, not reencapsulating")
log.Warn().Msg("DHCPv6: response is a relayed message, not reencapsulating")
} else {
tmp, err := dhcpv6.NewRelayReplFromRelayForw(d.(*dhcpv6.RelayMessage), rmsg)
if err != nil {
log.Warningf("DHCPv6: cannot create relay-repl from relay-forw: %v", err)
log.Warn().Msg("DHCPv6: cannot create relay-repl from relay-forw: %v", err)
return
}
resp = tmp
@ -90,11 +90,11 @@ func (l *listener6) HandleMsg6(buf []byte, oob *ipv6.ControlMessage, peer *net.U
case oob != nil && oob.IfIndex != 0:
woob = &ipv6.ControlMessage{IfIndex: oob.IfIndex}
default:
log.Errorf("HandleMsg6: Did not receive interface information")
log.Error().Msg("HandleMsg6: Did not receive interface information")
}
}
if _, err := l.WriteTo(resp.ToBytes(), woob, peer); err != nil {
log.Printf("MainHandler6: conn.Write to %v failed: %v", peer, err)
log.Info().Msg("MainHandler6: conn.Write to %v failed: %v", peer, err)
}
}
@ -108,17 +108,17 @@ func (l *listener4) HandleMsg4(buf []byte, oob *ipv4.ControlMessage, _peer net.A
req, err := dhcpv4.FromBytes(buf)
bufpool.Put(&buf)
if err != nil {
log.Printf("Error parsing DHCPv4 request: %v", err)
log.Info().Msg("Error parsing DHCPv4 request: %v", err)
return
}
if req.OpCode != dhcpv4.OpcodeBootRequest {
log.Printf("MainHandler4: unsupported opcode %d. Only BootRequest (%d) is supported", req.OpCode, dhcpv4.OpcodeBootRequest)
log.Info().Msg("MainHandler4: unsupported opcode %d. Only BootRequest (%d) is supported", req.OpCode, dhcpv4.OpcodeBootRequest)
return
}
tmp, err = dhcpv4.NewReplyFromRequest(req)
if err != nil {
log.Printf("MainHandler4: failed to build reply: %v", err)
log.Info().Msg("MainHandler4: failed to build reply: %v", err)
return
}
switch mt := req.MessageType(); mt {
@ -127,7 +127,7 @@ func (l *listener4) HandleMsg4(buf []byte, oob *ipv4.ControlMessage, _peer net.A
case dhcpv4.MessageTypeRequest:
tmp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeAck))
default:
log.Printf("plugins/server: Unhandled message type: %v", mt)
log.Info().Msg("plugins/server: Unhandled message type: %v", mt)
return
}
@ -168,23 +168,23 @@ func (l *listener4) HandleMsg4(buf []byte, oob *ipv4.ControlMessage, _peer net.A
case oob != nil && oob.IfIndex != 0:
woob = &ipv4.ControlMessage{IfIndex: oob.IfIndex}
default:
log.Errorf("HandleMsg4: Did not receive interface information")
log.Error().Msg("HandleMsg4: Did not receive interface information")
}
}
if useEthernet {
intf, err := net.InterfaceByIndex(woob.IfIndex)
if err != nil {
log.Errorf("MainHandler4: Can not get Interface for index %d %v", woob.IfIndex, err)
log.Error().Msg("MainHandler4: Can not get Interface for index %d %v", woob.IfIndex, err)
return
}
err = sendEthernet(*intf, resp)
if err != nil {
log.Errorf("MainHandler4: Cannot send Ethernet packet: %v", err)
log.Error().Msg("MainHandler4: Cannot send Ethernet packet: %v", err)
}
} else {
if _, err := l.WriteTo(resp.ToBytes(), woob, peer); err != nil {
log.Errorf("MainHandler4: conn.Write to %v failed: %v", peer, err)
log.Error().Msg("MainHandler4: conn.Write to %v failed: %v", peer, err)
}
}
} else {
@ -203,14 +203,14 @@ const MaxDatagram = 1 << 16
// Serve6 handles datagrams received on conn and passes them to the pluginchain
func (l *listener6) Serve() error {
log.Printf("Listen %s", l.LocalAddr())
log.Info().Msg("Listen %s", l.LocalAddr())
for {
b := *bufpool.Get().(*[]byte)
b = b[:MaxDatagram] //Reslice to max capacity in case the buffer in pool was resliced smaller
n, oob, peer, err := l.ReadFrom(b)
if err != nil {
log.Printf("Error reading from connection: %v", err)
log.Info().Msg("Error reading from connection: %v", err)
return err
}
go l.HandleMsg6(b[:n], oob, peer.(*net.UDPAddr))
@ -219,14 +219,14 @@ func (l *listener6) Serve() error {
// Serve6 handles datagrams received on conn and passes them to the pluginchain
func (l *listener4) Serve() error {
log.Printf("Listen %s", l.LocalAddr())
log.Info().Msg("Listen %s", l.LocalAddr())
for {
b := *bufpool.Get().(*[]byte)
b = b[:MaxDatagram] //Reslice to max capacity in case the buffer in pool was resliced smaller
n, oob, peer, err := l.ReadFrom(b)
if err != nil {
log.Printf("Error reading from connection: %v", err)
log.Info().Msg("Error reading from connection: %v", err)
return err
}
go l.HandleMsg4(b[:n], oob, peer.(*net.UDPAddr))

View File

@ -71,13 +71,13 @@ func sendEthernet(iface net.Interface, resp *dhcpv4.DHCPv4) error {
defer func() {
err = syscall.Close(fd)
if err != nil {
log.Errorf("Send Ethernet: Cannot close socket: %v", err)
log.Error().Msg("Send Ethernet: Cannot close socket: %v", err)
}
}()
err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
if err != nil {
log.Errorf("Send Ethernet: Cannot set option for socket: %v", err)
log.Error().Msg("Send Ethernet: Cannot set option for socket: %v", err)
}
var hwAddr [8]byte

View File

@ -123,7 +123,7 @@ func Start(config *config.Config) (*Servers, error) {
// listen
if config.Server6 != nil {
log.Println("Starting DHCPv6 server")
log.Info().Msg("Starting DHCPv6 server")
for _, addr := range config.Server6.Addresses {
var l6 *listener6
l6, err = listen6(&addr)
@ -139,7 +139,7 @@ func Start(config *config.Config) (*Servers, error) {
}
if config.Server4 != nil {
log.Println("Starting DHCPv4 server")
log.Info().Msg("Starting DHCPv4 server")
for _, addr := range config.Server4.Addresses {
var l4 *listener4
l4, err = listen4(&addr)