From f18510726850c78711d7b41397a82f700dbf0dac Mon Sep 17 00:00:00 2001 From: Zoltan Papp Date: Wed, 26 Jul 2023 13:43:44 +0200 Subject: [PATCH] Add forwarder logic --- client/internal/dns/forwarder/bpf_bpfeb.go | 119 ++++++++++++++++++ client/internal/dns/forwarder/bpf_bpfeb.o | Bin 0 -> 6312 bytes client/internal/dns/forwarder/bpf_bpfel.go | 119 ++++++++++++++++++ client/internal/dns/forwarder/bpf_bpfel.o | Bin 0 -> 6312 bytes client/internal/dns/forwarder/port_fwd.c | 89 +++++++++++++ .../dns/forwarder/traffic_forwarder.go | 89 +++++++++++++ client/internal/dns/server.go | 13 +- client/internal/dns/server_test.go | 8 +- client/internal/dns/service.go | 4 +- client/internal/dns/service_listener.go | 24 +++- client/internal/dns/service_memory.go | 6 +- go.mod | 1 + go.sum | 19 +-- iface/iface.go | 2 +- 14 files changed, 452 insertions(+), 41 deletions(-) create mode 100644 client/internal/dns/forwarder/bpf_bpfeb.go create mode 100644 client/internal/dns/forwarder/bpf_bpfeb.o create mode 100644 client/internal/dns/forwarder/bpf_bpfel.go create mode 100644 client/internal/dns/forwarder/bpf_bpfel.o create mode 100644 client/internal/dns/forwarder/port_fwd.c create mode 100644 client/internal/dns/forwarder/traffic_forwarder.go diff --git a/client/internal/dns/forwarder/bpf_bpfeb.go b/client/internal/dns/forwarder/bpf_bpfeb.go new file mode 100644 index 000000000..9ae89aa99 --- /dev/null +++ b/client/internal/dns/forwarder/bpf_bpfeb.go @@ -0,0 +1,119 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build arm64be || armbe || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 +// +build arm64be armbe mips mips64 mips64p32 ppc64 s390 s390x sparc sparc64 + +package forwarder + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +// loadBpf returns the embedded CollectionSpec for bpf. +func loadBpf() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_BpfBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf: %w", err) + } + + return spec, err +} + +// loadBpfObjects loads bpf and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpfObjects +// *bpfPrograms +// *bpfMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpfSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfSpecs struct { + bpfProgramSpecs + bpfMapSpecs +} + +// bpfSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfProgramSpecs struct { + XdpDnsPortFwd *ebpf.ProgramSpec `ebpf:"xdp_dns_port_fwd"` +} + +// bpfMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfMapSpecs struct { + XdpPortMap *ebpf.MapSpec `ebpf:"xdp_port_map"` +} + +// bpfObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfObjects struct { + bpfPrograms + bpfMaps +} + +func (o *bpfObjects) Close() error { + return _BpfClose( + &o.bpfPrograms, + &o.bpfMaps, + ) +} + +// bpfMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfMaps struct { + XdpPortMap *ebpf.Map `ebpf:"xdp_port_map"` +} + +func (m *bpfMaps) Close() error { + return _BpfClose( + m.XdpPortMap, + ) +} + +// bpfPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfPrograms struct { + XdpDnsPortFwd *ebpf.Program `ebpf:"xdp_dns_port_fwd"` +} + +func (p *bpfPrograms) Close() error { + return _BpfClose( + p.XdpDnsPortFwd, + ) +} + +func _BpfClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +//go:embed bpf_bpfeb.o +var _BpfBytes []byte diff --git a/client/internal/dns/forwarder/bpf_bpfeb.o b/client/internal/dns/forwarder/bpf_bpfeb.o new file mode 100644 index 0000000000000000000000000000000000000000..fe59e6aa21b9175130840933fa2cb91329232b04 GIT binary patch literal 6312 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 literal 0 HcmV?d00001 diff --git a/client/internal/dns/forwarder/port_fwd.c b/client/internal/dns/forwarder/port_fwd.c new file mode 100644 index 000000000..fc594bdf0 --- /dev/null +++ b/client/internal/dns/forwarder/port_fwd.c @@ -0,0 +1,89 @@ +#include +#include // ETH_P_IP +#include +#include +#include +#include +#include + +#define bpf_printk(fmt, ...) \ + ({ \ + char ____fmt[] = fmt; \ + bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ + }) + +const __u32 map_key_dns_ip = 0; +const __u32 map_key_dns_port = 1; + +struct bpf_map_def SEC("maps") xdp_port_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(__u16), + .max_entries = 10, +}; + +__be32 dns_ip = 0; +__be16 dns_port = 0; + +bool read_port_settings() { + __u16 *value; + __be32 *ip_value; + value = bpf_map_lookup_elem(&xdp_port_map, &map_key_dns_port); + if(!value) { + return false; + } + + dns_port = htons(*value); + + ip_value = bpf_map_lookup_elem(&xdp_port_map, &map_key_dns_ip); + if(!ip_value) { + return false; + } + dns_ip = htonl(*ip_value); + return true; +} + +SEC("xdp") +int xdp_dns_port_fwd(struct xdp_md *ctx) { + if(dns_port == 0) { + if(!read_port_settings()){ + return XDP_PASS; + } + bpf_printk("dns port: %d", dns_port); + bpf_printk("dns ip: %d", dns_ip); + } + + void *data = (void *)(long)ctx->data; + void *data_end = (void *)(long)ctx->data_end; + struct ethhdr *eth = data; + struct iphdr *ip = (data + sizeof(struct ethhdr)); + struct udphdr *udp = (data + sizeof(struct ethhdr) + sizeof(struct iphdr)); + + // return early if not enough data + if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end){ + return XDP_PASS; + } + + // skip non IPv4 packages + if (eth->h_proto != htons(ETH_P_IP)) { + return XDP_PASS; + } + + if (ip->protocol != IPPROTO_UDP) { + return XDP_PASS; + } + + // 2130706433 = 127.0.0.1 + if (ip->daddr != dns_ip) { + return XDP_PASS; + } + + // skip non dns ports + if (udp->source != htons(53)){ + return XDP_PASS; + } + + udp->dest = dns_port; + return XDP_PASS; +} +char _license[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/client/internal/dns/forwarder/traffic_forwarder.go b/client/internal/dns/forwarder/traffic_forwarder.go new file mode 100644 index 000000000..3270b3124 --- /dev/null +++ b/client/internal/dns/forwarder/traffic_forwarder.go @@ -0,0 +1,89 @@ +package forwarder + +import ( + _ "embed" + "encoding/binary" + log "github.com/sirupsen/logrus" + "net" + + "github.com/cilium/ebpf/link" + "github.com/cilium/ebpf/rlimit" +) + +const ( + mapKeyDNSIP uint32 = 0 + mapKeyDNSPort uint32 = 1 +) + +// libbpf-dev, libc6-dev-i386-amd64-cross +// +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang-14 bpf port_fwd.c -- -I /usr/x86_64-linux-gnu/include +type TrafficForwarder struct { + link link.Link + iFaceName string +} + +func NewTrafficForwarder(iFace string) *TrafficForwarder { + return &TrafficForwarder{ + iFaceName: iFace, + } +} + +func (tf *TrafficForwarder) Start(ip string, dnsPort int) error { + log.Debugf("start DNS port forwarder") + // it required for Docker + err := rlimit.RemoveMemlock() + if err != nil { + return err + } + + iFace, err := net.InterfaceByName(tf.iFaceName) + if err != nil { + return err + } + + // load pre-compiled programs into the kernel. + objs := bpfObjects{} + err = loadBpfObjects(&objs, nil) + if err != nil { + return err + } + defer func() { + _ = objs.Close() + }() + + err = objs.XdpPortMap.Put(mapKeyDNSIP, tf.ip2int(ip)) + if err != nil { + return err + } + + err = objs.XdpPortMap.Put(mapKeyDNSPort, uint16(dnsPort)) + if err != nil { + return err + } + + defer func() { + _ = objs.XdpPortMap.Close() + }() + + tf.link, err = link.AttachXDP(link.XDPOptions{ + Program: objs.XdpDnsPortFwd, + Interface: iFace.Index, + }) + return err +} + +func (tf *TrafficForwarder) Free() error { + if tf.link == nil { + return nil + } + + err := tf.link.Close() + tf.link = nil + return err +} + +func (tf *TrafficForwarder) ip2int(ipString string) uint32 { + ip := net.ParseIP(ipString) + return binary.BigEndian.Uint32(ip.To4()) +} diff --git a/client/internal/dns/server.go b/client/internal/dns/server.go index 6dd8f1904..db4b6c542 100644 --- a/client/internal/dns/server.go +++ b/client/internal/dns/server.go @@ -132,7 +132,7 @@ func (s *DefaultServer) Initialize() (err error) { // When kernel space interface used it return real DNS server listener IP address // For bind interface, fake DNS resolver address returned (second last IP address from Nebird network) func (s *DefaultServer) DnsIP() string { - return s.service.RuntimeIP() + return s.service.ListenIp() } // Stop stops the server @@ -233,16 +233,9 @@ func (s *DefaultServer) applyConfiguration(update nbdns.Config) error { s.updateMux(muxUpdates) s.updateLocalResolver(localRecords) - s.currentConfig = dnsConfigToHostDNSConfig(update, s.service.RuntimeIP(), s.service.RuntimePort()) + s.currentConfig = dnsConfigToHostDNSConfig(update, s.service.ListenIp(), s.service.ListenPort()) - hostUpdate := s.currentConfig - if s.service.RuntimePort() != defaultPort && !s.hostManager.supportCustomPort() { - log.Warnf("the DNS manager of this peer doesn't support custom port. Disabling primary DNS setup. " + - "Learn more at: https://netbird.io/docs/how-to-guides/nameservers#local-resolver") - hostUpdate.routeAll = false - } - - if err = s.hostManager.applyDNSConfig(hostUpdate); err != nil { + if err = s.hostManager.applyDNSConfig(s.currentConfig); err != nil { log.Error(err) } diff --git a/client/internal/dns/server_test.go b/client/internal/dns/server_test.go index 73349de89..a5889a60c 100644 --- a/client/internal/dns/server_test.go +++ b/client/internal/dns/server_test.go @@ -487,7 +487,7 @@ func TestDNSServerStartStop(t *testing.T) { d := net.Dialer{ Timeout: time.Second * 5, } - addr := fmt.Sprintf("%s:%d", dnsServer.service.RuntimeIP(), dnsServer.service.RuntimePort()) + addr := fmt.Sprintf("%s:%d", dnsServer.service.ListenIp(), dnsServer.service.ListenPort()) conn, err := d.DialContext(ctx, network, addr) if err != nil { t.Log(err) @@ -603,7 +603,7 @@ func TestDNSPermanent_updateHostDNS_emptyUpstream(t *testing.T) { dnsServer.OnUpdatedHostDNSServer([]string{"8.8.8.8"}) - resolver := newDnsResolver(dnsServer.service.RuntimeIP(), dnsServer.service.RuntimePort()) + resolver := newDnsResolver(dnsServer.service.ListenIp(), dnsServer.service.ListenPort()) _, err = resolver.LookupHost(context.Background(), "netbird.io") if err != nil { t.Errorf("failed to resolve: %s", err) @@ -626,7 +626,7 @@ func TestDNSPermanent_updateUpstream(t *testing.T) { defer dnsServer.Stop() // check initial state - resolver := newDnsResolver(dnsServer.service.RuntimeIP(), dnsServer.service.RuntimePort()) + resolver := newDnsResolver(dnsServer.service.ListenIp(), dnsServer.service.ListenPort()) _, err = resolver.LookupHost(context.Background(), "netbird.io") if err != nil { t.Errorf("failed to resolve: %s", err) @@ -718,7 +718,7 @@ func TestDNSPermanent_matchOnly(t *testing.T) { defer dnsServer.Stop() // check initial state - resolver := newDnsResolver(dnsServer.service.RuntimeIP(), dnsServer.service.RuntimePort()) + resolver := newDnsResolver(dnsServer.service.ListenIp(), dnsServer.service.ListenPort()) _, err = resolver.LookupHost(context.Background(), "netbird.io") if err != nil { t.Errorf("failed to resolve: %s", err) diff --git a/client/internal/dns/service.go b/client/internal/dns/service.go index 523976e54..2e2a7443c 100644 --- a/client/internal/dns/service.go +++ b/client/internal/dns/service.go @@ -13,6 +13,6 @@ type service interface { Stop() RegisterMux(domain string, handler dns.Handler) DeregisterMux(key string) - RuntimePort() int - RuntimeIP() string + ListenPort() int + ListenIp() string } diff --git a/client/internal/dns/service_listener.go b/client/internal/dns/service_listener.go index 687ca2459..21777520f 100644 --- a/client/internal/dns/service_listener.go +++ b/client/internal/dns/service_listener.go @@ -3,6 +3,7 @@ package dns import ( "context" "fmt" + "github.com/netbirdio/netbird/client/internal/dns/forwarder" "net" "net/netip" "runtime" @@ -28,6 +29,7 @@ type serviceViaListener struct { runtimePort int listenerIsRunning bool listenerFlagLock sync.Mutex + trafficForwarder *forwarder.TrafficForwarder } func newServiceViaListener(wgIface WGIface, customAddr *netip.AddrPort) *serviceViaListener { @@ -42,6 +44,7 @@ func newServiceViaListener(wgIface WGIface, customAddr *netip.AddrPort) *service Handler: mux, UDPSize: 65535, }, + trafficForwarder: forwarder.NewTrafficForwarder(wgIface.Name()), } return s } @@ -72,6 +75,13 @@ func (s *serviceViaListener) Listen() error { log.Errorf("dns server running with %d port returned an error: %v. Will not retry", s.runtimePort, err) } }() + + if s.runtimePort != defaultPort { + err = s.trafficForwarder.Start(s.runtimeIP, s.runtimePort) + if err != nil { + return err + } + } return nil } @@ -90,6 +100,11 @@ func (s *serviceViaListener) Stop() { if err != nil { log.Errorf("stopping dns server listener returned an error: %v", err) } + + err = s.trafficForwarder.Free() + if err != nil { + log.Errorf("stopping traffic forwarder returned an error: %v", err) + } } func (s *serviceViaListener) RegisterMux(pattern string, handler dns.Handler) { @@ -100,11 +115,11 @@ func (s *serviceViaListener) DeregisterMux(pattern string) { s.dnsMux.HandleRemove(pattern) } -func (s *serviceViaListener) RuntimePort() int { - return s.runtimePort +func (s *serviceViaListener) ListenPort() int { + return defaultPort } -func (s *serviceViaListener) RuntimeIP() string { +func (s *serviceViaListener) ListenIp() string { return s.runtimeIP } @@ -117,7 +132,8 @@ func (s *serviceViaListener) getFirstListenerAvailable() (string, int, error) { if runtime.GOOS != "darwin" { ips = append([]string{s.wgInterface.Address().IP.String()}, ips...) } - ports := []int{defaultPort, customPort} + //todo change the order back + ports := []int{customPort, defaultPort} for _, port := range ports { for _, ip := range ips { addrString := fmt.Sprintf("%s:%d", ip, port) diff --git a/client/internal/dns/service_memory.go b/client/internal/dns/service_memory.go index 128dda840..8607cdf39 100644 --- a/client/internal/dns/service_memory.go +++ b/client/internal/dns/service_memory.go @@ -48,7 +48,7 @@ func (s *serviceViaMemory) Listen() error { } s.listenerIsRunning = true - log.Debugf("dns service listening on: %s", s.RuntimeIP()) + log.Debugf("dns service listening on: %s", s.ListenIp()) return nil } @@ -75,11 +75,11 @@ func (s *serviceViaMemory) DeregisterMux(pattern string) { s.dnsMux.HandleRemove(pattern) } -func (s *serviceViaMemory) RuntimePort() int { +func (s *serviceViaMemory) ListenPort() int { return s.runtimePort } -func (s *serviceViaMemory) RuntimeIP() string { +func (s *serviceViaMemory) ListenIp() string { return s.runtimeIP } diff --git a/go.mod b/go.mod index 7ecf61584..57bf9cf83 100644 --- a/go.mod +++ b/go.mod @@ -126,6 +126,7 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 // indirect diff --git a/go.sum b/go.sum index 1eb9d243d..1f19d4721 100644 --- a/go.sum +++ b/go.sum @@ -100,6 +100,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ= github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE= @@ -597,8 +598,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -615,8 +615,6 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0 github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN23diwyr69Qs= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -633,9 +631,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 h1:HunZiaEKNGVdhTRQOVpMmj5MQnGnv+e8uZNu3xFLgyM= github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= -github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCEzJNy71UkeF4XIx2EVmL9KLwDQdmM= github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -651,7 +647,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -677,7 +672,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -739,7 +733,6 @@ golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf/go.mod h1:yh0Ynu2b5ZUe3MQfp2 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -753,7 +746,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -982,7 +974,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1109,8 +1100,6 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1156,7 +1145,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1168,7 +1156,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= @@ -1180,7 +1167,6 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1189,7 +1175,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= -gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0 h1:Wobr37noukisGxpKo5jAsLREcpj61RxrWYzD8uwveOY= gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0/go.mod h1:Dn5idtptoW1dIos9U6A2rpebLs/MtTwFacjKb8jLdQA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/iface/iface.go b/iface/iface.go index 58167d1e8..55891d047 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -112,7 +112,7 @@ func (w *WGIface) Close() error { return w.tun.Close() } -// SetFilter sets packet filters for the userspace impelemntation +// SetFilter sets packet filters for the userspace implementation func (w *WGIface) SetFilter(filter PacketFilter) error { w.mu.Lock() defer w.mu.Unlock()