Skip to content

Commit 58beb0f

Browse files
committed
conn: reconstruct v4 vs v6 receive function based on symtab
This is kind of gross but it's better than the alternatives. Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent d2fd0c0 commit 58beb0f

File tree

4 files changed

+71
-15
lines changed

4 files changed

+71
-15
lines changed

conn/bind_linux.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ again:
148148

149149
var fns []ReceiveFunc
150150
if sock4 != -1 {
151-
fns = append(fns, makeReceiveIPv4(sock4))
151+
fns = append(fns, bind.makeReceiveIPv4(sock4))
152152
bind.sock4 = sock4
153153
}
154154
if sock6 != -1 {
155-
fns = append(fns, makeReceiveIPv6(sock6))
155+
fns = append(fns, bind.makeReceiveIPv6(sock6))
156156
bind.sock6 = sock6
157157
}
158158
if len(fns) == 0 {
@@ -224,15 +224,15 @@ func (bind *LinuxSocketBind) Close() error {
224224
return err2
225225
}
226226

227-
func makeReceiveIPv6(sock int) ReceiveFunc {
227+
func (*LinuxSocketBind) makeReceiveIPv6(sock int) ReceiveFunc {
228228
return func(buff []byte) (int, Endpoint, error) {
229229
var end LinuxSocketEndpoint
230230
n, err := receive6(sock, buff, &end)
231231
return n, &end, err
232232
}
233233
}
234234

235-
func makeReceiveIPv4(sock int) ReceiveFunc {
235+
func (*LinuxSocketBind) makeReceiveIPv4(sock int) ReceiveFunc {
236236
return func(buff []byte) (int, Endpoint, error) {
237237
var end LinuxSocketEndpoint
238238
n, err := receive4(sock, buff, &end)

conn/bind_std.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ again:
118118
}
119119
var fns []ReceiveFunc
120120
if ipv4 != nil {
121-
fns = append(fns, makeReceiveFunc(ipv4, true))
121+
fns = append(fns, bind.makeReceiveIPv4(ipv4))
122122
bind.ipv4 = ipv4
123123
}
124124
if ipv6 != nil {
125-
fns = append(fns, makeReceiveFunc(ipv6, false))
125+
fns = append(fns, bind.makeReceiveIPv6(ipv6))
126126
bind.ipv6 = ipv6
127127
}
128128
if len(fns) == 0 {
@@ -152,16 +152,23 @@ func (bind *StdNetBind) Close() error {
152152
return err2
153153
}
154154

155-
func makeReceiveFunc(conn *net.UDPConn, isIPv4 bool) ReceiveFunc {
155+
func (*StdNetBind) makeReceiveIPv4(conn *net.UDPConn) ReceiveFunc {
156156
return func(buff []byte) (int, Endpoint, error) {
157157
n, endpoint, err := conn.ReadFromUDP(buff)
158-
if isIPv4 && endpoint != nil {
158+
if endpoint != nil {
159159
endpoint.IP = endpoint.IP.To4()
160160
}
161161
return n, (*StdNetEndpoint)(endpoint), err
162162
}
163163
}
164164

165+
func (*StdNetBind) makeReceiveIPv6(conn *net.UDPConn) ReceiveFunc {
166+
return func(buff []byte) (int, Endpoint, error) {
167+
n, endpoint, err := conn.ReadFromUDP(buff)
168+
return n, (*StdNetEndpoint)(endpoint), err
169+
}
170+
}
171+
165172
func (bind *StdNetBind) Send(buff []byte, endpoint Endpoint) error {
166173
var err error
167174
nend, ok := endpoint.(*StdNetEndpoint)

conn/conn.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ package conn
88

99
import (
1010
"errors"
11+
"fmt"
1112
"net"
13+
"reflect"
14+
"runtime"
1215
"strings"
16+
"unsafe"
1317
)
1418

1519
// A ReceiveFunc receives a single inbound packet from the network.
@@ -69,6 +73,55 @@ type Endpoint interface {
6973
SrcIP() net.IP
7074
}
7175

76+
var (
77+
ErrBindAlreadyOpen = errors.New("bind is already open")
78+
ErrWrongEndpointType = errors.New("endpoint type does not correspond with bind type")
79+
)
80+
81+
func (fn ReceiveFunc) PrettyName() string {
82+
ptr := reflect.ValueOf(fn).Pointer()
83+
name := runtime.FuncForPC(ptr).Name()
84+
// 0. cheese/taco.beansIPv6.func12.func21218-fm
85+
name = strings.TrimSuffix(name, "-fm")
86+
// 1. cheese/taco.beansIPv6.func12.func21218
87+
if idx := strings.LastIndexByte(name, '/'); idx != -1 {
88+
name = name[idx+1:]
89+
// 2. taco.beansIPv6.func12.func21218
90+
}
91+
for {
92+
var idx int
93+
for idx = len(name) - 1; idx >= 0; idx-- {
94+
if name[idx] < '0' || name[idx] > '9' {
95+
break
96+
}
97+
}
98+
if idx == len(name)-1 {
99+
break
100+
}
101+
const dotFunc = ".func"
102+
if !strings.HasSuffix(name[:idx+1], dotFunc) {
103+
break
104+
}
105+
name = name[:idx+1-len(dotFunc)]
106+
// 3. taco.beansIPv6.func12
107+
// 4. taco.beansIPv6
108+
}
109+
if idx := strings.LastIndexByte(name, '.'); idx != -1 {
110+
name = name[idx+1:]
111+
// 5. beansIPv6
112+
}
113+
if name == "" {
114+
return fmt.Sprintf("%p", unsafe.Pointer(ptr))
115+
}
116+
if strings.HasSuffix(name, "IPv4") {
117+
return "v4"
118+
}
119+
if strings.HasSuffix(name, "IPv6") {
120+
return "v6"
121+
}
122+
return name
123+
}
124+
72125
func parseEndpoint(s string) (*net.UDPAddr, error) {
73126
// ensure that the host is an IP address
74127

@@ -98,8 +151,3 @@ func parseEndpoint(s string) (*net.UDPAddr, error) {
98151
}
99152
return addr, err
100153
}
101-
102-
var (
103-
ErrBindAlreadyOpen = errors.New("bind is already open")
104-
ErrWrongEndpointType = errors.New("endpoint type does not correspond with bind type")
105-
)

device/receive.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ func (peer *Peer) keepKeyFreshReceiving() {
6969
* IPv4 and IPv6 (separately)
7070
*/
7171
func (device *Device) RoutineReceiveIncoming(recv conn.ReceiveFunc) {
72+
recvName := recv.PrettyName()
7273
defer func() {
73-
device.log.Verbosef("Routine: receive incoming %p - stopped", recv)
74+
device.log.Verbosef("Routine: receive incoming %s - stopped", recvName)
7475
device.queue.decryption.wg.Done()
7576
device.queue.handshake.wg.Done()
7677
device.net.stopping.Done()
7778
}()
7879

79-
device.log.Verbosef("Routine: receive incoming %p - started", recv)
80+
device.log.Verbosef("Routine: receive incoming %s - started", recvName)
8081

8182
// receive datagrams until conn is closed
8283

0 commit comments

Comments
 (0)