diff --git a/conn/bind_linux.go b/conn/bind_linux.go
index 9eec384..c10d8b6 100644
--- a/conn/bind_linux.go
+++ b/conn/bind_linux.go
@@ -148,11 +148,11 @@ again:
 
 	var fns []ReceiveFunc
 	if sock4 != -1 {
-		fns = append(fns, makeReceiveIPv4(sock4))
+		fns = append(fns, bind.makeReceiveIPv4(sock4))
 		bind.sock4 = sock4
 	}
 	if sock6 != -1 {
-		fns = append(fns, makeReceiveIPv6(sock6))
+		fns = append(fns, bind.makeReceiveIPv6(sock6))
 		bind.sock6 = sock6
 	}
 	if len(fns) == 0 {
@@ -224,7 +224,7 @@ func (bind *LinuxSocketBind) Close() error {
 	return err2
 }
 
-func makeReceiveIPv6(sock int) ReceiveFunc {
+func (*LinuxSocketBind) makeReceiveIPv6(sock int) ReceiveFunc {
 	return func(buff []byte) (int, Endpoint, error) {
 		var end LinuxSocketEndpoint
 		n, err := receive6(sock, buff, &end)
@@ -232,7 +232,7 @@ func makeReceiveIPv6(sock int) ReceiveFunc {
 	}
 }
 
-func makeReceiveIPv4(sock int) ReceiveFunc {
+func (*LinuxSocketBind) makeReceiveIPv4(sock int) ReceiveFunc {
 	return func(buff []byte) (int, Endpoint, error) {
 		var end LinuxSocketEndpoint
 		n, err := receive4(sock, buff, &end)
diff --git a/conn/bind_std.go b/conn/bind_std.go
index 5261779..cb85cfd 100644
--- a/conn/bind_std.go
+++ b/conn/bind_std.go
@@ -118,11 +118,11 @@ again:
 	}
 	var fns []ReceiveFunc
 	if ipv4 != nil {
-		fns = append(fns, makeReceiveFunc(ipv4, true))
+		fns = append(fns, bind.makeReceiveIPv4(ipv4))
 		bind.ipv4 = ipv4
 	}
 	if ipv6 != nil {
-		fns = append(fns, makeReceiveFunc(ipv6, false))
+		fns = append(fns, bind.makeReceiveIPv6(ipv6))
 		bind.ipv6 = ipv6
 	}
 	if len(fns) == 0 {
@@ -152,16 +152,23 @@ func (bind *StdNetBind) Close() error {
 	return err2
 }
 
-func makeReceiveFunc(conn *net.UDPConn, isIPv4 bool) ReceiveFunc {
+func (*StdNetBind) makeReceiveIPv4(conn *net.UDPConn) ReceiveFunc {
 	return func(buff []byte) (int, Endpoint, error) {
 		n, endpoint, err := conn.ReadFromUDP(buff)
-		if isIPv4 && endpoint != nil {
+		if endpoint != nil {
 			endpoint.IP = endpoint.IP.To4()
 		}
 		return n, (*StdNetEndpoint)(endpoint), err
 	}
 }
 
+func (*StdNetBind) makeReceiveIPv6(conn *net.UDPConn) ReceiveFunc {
+	return func(buff []byte) (int, Endpoint, error) {
+		n, endpoint, err := conn.ReadFromUDP(buff)
+		return n, (*StdNetEndpoint)(endpoint), err
+	}
+}
+
 func (bind *StdNetBind) Send(buff []byte, endpoint Endpoint) error {
 	var err error
 	nend, ok := endpoint.(*StdNetEndpoint)
diff --git a/conn/conn.go b/conn/conn.go
index 3c7fcd0..9cce9ad 100644
--- a/conn/conn.go
+++ b/conn/conn.go
@@ -8,7 +8,10 @@ package conn
 
 import (
 	"errors"
+	"fmt"
 	"net"
+	"reflect"
+	"runtime"
 	"strings"
 )
 
@@ -69,6 +72,54 @@ type Endpoint interface {
 	SrcIP() net.IP
 }
 
+var (
+	ErrBindAlreadyOpen   = errors.New("bind is already open")
+	ErrWrongEndpointType = errors.New("endpoint type does not correspond with bind type")
+)
+
+func (fn ReceiveFunc) PrettyName() string {
+	name := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
+	// 0. cheese/taco.beansIPv6.func12.func21218-fm
+	name = strings.TrimSuffix(name, "-fm")
+	// 1. cheese/taco.beansIPv6.func12.func21218
+	if idx := strings.LastIndexByte(name, '/'); idx != -1 {
+		name = name[idx+1:]
+		// 2. taco.beansIPv6.func12.func21218
+	}
+	for {
+		var idx int
+		for idx = len(name) - 1; idx >= 0; idx-- {
+			if name[idx] < '0' || name[idx] > '9' {
+				break
+			}
+		}
+		if idx == len(name)-1 {
+			break
+		}
+		const dotFunc = ".func"
+		if !strings.HasSuffix(name[:idx+1], dotFunc) {
+			break
+		}
+		name = name[:idx+1-len(dotFunc)]
+		// 3. taco.beansIPv6.func12
+		// 4. taco.beansIPv6
+	}
+	if idx := strings.LastIndexByte(name, '.'); idx != -1 {
+		name = name[idx+1:]
+		// 5. beansIPv6
+	}
+	if name == "" {
+		return fmt.Sprintf("%p", fn)
+	}
+	if strings.HasSuffix(name, "IPv4") {
+		return "v4"
+	}
+	if strings.HasSuffix(name, "IPv6") {
+		return "v6"
+	}
+	return name
+}
+
 func parseEndpoint(s string) (*net.UDPAddr, error) {
 	// ensure that the host is an IP address
 
@@ -98,8 +149,3 @@ func parseEndpoint(s string) (*net.UDPAddr, error) {
 	}
 	return addr, err
 }
-
-var (
-	ErrBindAlreadyOpen   = errors.New("bind is already open")
-	ErrWrongEndpointType = errors.New("endpoint type does not correspond with bind type")
-)
diff --git a/device/receive.go b/device/receive.go
index 3aa4458..9af0e18 100644
--- a/device/receive.go
+++ b/device/receive.go
@@ -69,14 +69,15 @@ func (peer *Peer) keepKeyFreshReceiving() {
  * IPv4 and IPv6 (separately)
  */
 func (device *Device) RoutineReceiveIncoming(recv conn.ReceiveFunc) {
+	recvName := recv.PrettyName()
 	defer func() {
-		device.log.Verbosef("Routine: receive incoming %p - stopped", recv)
+		device.log.Verbosef("Routine: receive incoming %s - stopped", recvName)
 		device.queue.decryption.wg.Done()
 		device.queue.handshake.wg.Done()
 		device.net.stopping.Done()
 	}()
 
-	device.log.Verbosef("Routine: receive incoming %p - started", recv)
+	device.log.Verbosef("Routine: receive incoming %s - started", recvName)
 
 	// receive datagrams until conn is closed