diff --git a/conf.go b/conf.go index e8f7233..9dd22ff 100644 --- a/conf.go +++ b/conf.go @@ -38,6 +38,7 @@ type Configuration struct { LogAllPrinterAttrs bool // Get *all* printer attrs, for logging ColorConsole bool // Enable ANSI colors on console Quirks QuirksDb // Quirks data base + Interface int // index of the interface to use } // Conf contains a global instance of program configuration @@ -55,6 +56,7 @@ var Conf = Configuration{ LogMaxBackupFiles: 5, LogAllPrinterAttrs: false, ColorConsole: true, + Interface: -1, } // ConfLoad loads the program configuration @@ -113,7 +115,7 @@ func confLoadInternal(path string) error { case confMatchName(rec.Key, "dns-sd"): err = rec.LoadNamedBool(&Conf.DNSSdEnable, "disable", "enable") case confMatchName(rec.Key, "interface"): - err = rec.LoadNamedBool(&Conf.LoopbackOnly, "all", "loopback") + err = rec.LoadInetInterface(&Conf.Interface) case confMatchName(rec.Key, "ipv6"): err = rec.LoadNamedBool(&Conf.IPV6Enable, "disable", "enable") } diff --git a/dnssd_avahi.go b/dnssd_avahi.go index a0a9bac..2993876 100644 --- a/dnssd_avahi.go +++ b/dnssd_avahi.go @@ -1,5 +1,4 @@ //go:build linux || freebsd -// +build linux freebsd /* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device * @@ -76,10 +75,10 @@ func newDnssdSysdep(log *Logger, instance string, } // Obtain index of loopback interface - loopback, err := Loopback() - if err != nil { - goto ERROR // Very unlikely to happen - } + // loopback, err := Loopback() + // if err != nil { + // goto ERROR // Very unlikely to happen + // } // Obtain AvahiPoll poll, err = avahiGetPoll() @@ -124,14 +123,7 @@ func newDnssdSysdep(log *Logger, instance string, avahiEgroupMap[sysdep.egroup] = sysdep // Compute iface and proto, adjust fqdn - iface = C.AVAHI_IF_UNSPEC - if Conf.LoopbackOnly { - iface = loopback - old := sysdep.fqdn - sysdep.fqdn = "localhost" - sysdep.log.Debug(' ', "DNS-SD: FQDN: %q->%q", old, sysdep.fqdn) - } - + iface = Conf.Interface proto = C.AVAHI_PROTO_UNSPEC if !Conf.IPV6Enable { proto = C.AVAHI_PROTO_INET @@ -156,16 +148,10 @@ func newDnssdSysdep(log *Logger, instance string, cInstance = C.CString(instance) } - // Handle loopback-only mode - ifaceInUse := iface - if svc.Loopback { - ifaceInUse = loopback - } - // Register service type rc = C.avahi_entry_group_add_service_strlst( sysdep.egroup, - C.AvahiIfIndex(ifaceInUse), + C.AvahiIfIndex(iface), C.AvahiProtocol(proto), 0, cInstance, @@ -187,7 +173,7 @@ func newDnssdSysdep(log *Logger, instance string, cSubtype := C.CString(subtype) rc = C.avahi_entry_group_add_service_subtype( sysdep.egroup, - C.AvahiIfIndex(ifaceInUse), + C.AvahiIfIndex(iface), C.AvahiProtocol(proto), 0, cInstance, diff --git a/inet_interface.go b/inet_interface.go new file mode 100644 index 0000000..0715d01 --- /dev/null +++ b/inet_interface.go @@ -0,0 +1,51 @@ +//go:build linux || freebsd + +/* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device + * + * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) + * See LICENSE for license terms and conditions + * + * INET interface index discovery + */ + +package main + +// #cgo pkg-config: avahi-client +// +// #include +// #include +// #include +// #include +// #include +import "C" + +import ( + "errors" + "fmt" + "net" +) + +// InetInterface returns index of named interface +func InetInterface(name string) (int, error) { + switch name { + case "all": + return C.AVAHI_IF_UNSPEC, nil + case "lo": + case "loopback": + return Loopback() + default: + break + } + + interfaces, err := net.Interfaces() + if err == nil { + for _, iface := range interfaces { + if iface.Name == name { + return iface.Index, nil + } + } + err = errors.New("not found") + } + + return 0, fmt.Errorf("Inet interface discovery: %s", err) +} diff --git a/inifile.go b/inifile.go index b992e23..ec9e381 100644 --- a/inifile.go +++ b/inifile.go @@ -418,6 +418,16 @@ func (rec *IniRecord) LoadIPPort(out *int) error { return nil } +func (rec *IniRecord) LoadInetInterface(out *int) error { + iFaceIndex, err := InetInterface(rec.Value) + if err == nil { + Conf.LoopbackOnly = rec.Value == "lo" || rec.Value == "loopback" + *out = iFaceIndex + return err + } + return rec.errBadValue(" %s not found", rec.Value) +} + // LoadBool loads boolean value // The destination remains untouched in a case of an error func (rec *IniRecord) LoadBool(out *bool) error { diff --git a/ipp-usb.conf b/ipp-usb.conf index 1879396..848bb0d 100644 --- a/ipp-usb.conf +++ b/ipp-usb.conf @@ -13,7 +13,8 @@ # printer to the local network. This way you can share your printer # with other computers in the network, as well as with iOS and Android # devices. - interface = loopback # all | loopback + # Name of the interface (eg. eth0 or lo) or all or loopback + interface = loopback # all | loopback | eth0 | vlan.1 # Enable or disable IPv6 ipv6 = enable # enable | disable diff --git a/systemd-udev/ipp-usb.service b/systemd-udev/ipp-usb.service index e6488bf..ba9ab06 100644 --- a/systemd-udev/ipp-usb.service +++ b/systemd-udev/ipp-usb.service @@ -1,7 +1,7 @@ [Unit] Description=Daemon for IPP over USB printer support Documentation=man:ipp-usb(8) -After=cups.service avahi-daemon.service +After=cups.service avahi-daemon.service network-online.target Wants=avahi-daemon.service [Service]