|
|
@@ -322,11 +322,6 @@ type Conn struct {
|
|
|
// bind is the wireguard-go conn.Bind for Conn.
|
|
|
bind *connBind
|
|
|
|
|
|
- // ippEndpoint4 and ippEndpoint6 are owned by receiveIPv4 and
|
|
|
- // receiveIPv6, respectively, to cache an IPPort->endpoint for
|
|
|
- // hot flows.
|
|
|
- ippEndpoint4, ippEndpoint6 ippEndpointCache
|
|
|
-
|
|
|
// ============================================================
|
|
|
// Fields that must be accessed via atomic load/stores.
|
|
|
|
|
|
@@ -1851,80 +1846,64 @@ func (c *Conn) putReceiveBatch(batch *receiveBatch) {
|
|
|
c.receiveBatchPool.Put(batch)
|
|
|
}
|
|
|
|
|
|
-func (c *Conn) receiveIPv6(buffs [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
|
|
|
- health.ReceiveIPv6.Enter()
|
|
|
- defer health.ReceiveIPv6.Exit()
|
|
|
+// receiveIPv4 creates an IPv4 ReceiveFunc reading from c.pconn4.
|
|
|
+func (c *Conn) receiveIPv4() conn.ReceiveFunc {
|
|
|
+ return c.mkReceiveFunc(&c.pconn4, &health.ReceiveIPv4, metricRecvDataIPv4)
|
|
|
+}
|
|
|
|
|
|
- batch := c.getReceiveBatchForBuffs(buffs)
|
|
|
- defer c.putReceiveBatch(batch)
|
|
|
- for {
|
|
|
- numMsgs, err := c.pconn6.ReadBatch(batch.msgs[:len(buffs)], 0)
|
|
|
- if err != nil {
|
|
|
- if neterror.PacketWasTruncated(err) {
|
|
|
- // TODO(raggi): discuss whether to log?
|
|
|
- continue
|
|
|
- }
|
|
|
- return 0, err
|
|
|
- }
|
|
|
+// receiveIPv6 creates an IPv6 ReceiveFunc reading from c.pconn6.
|
|
|
+func (c *Conn) receiveIPv6() conn.ReceiveFunc {
|
|
|
+ return c.mkReceiveFunc(&c.pconn6, &health.ReceiveIPv6, metricRecvDataIPv6)
|
|
|
+}
|
|
|
|
|
|
- reportToCaller := false
|
|
|
- for i, msg := range batch.msgs[:numMsgs] {
|
|
|
- if msg.N == 0 {
|
|
|
- sizes[i] = 0
|
|
|
- continue
|
|
|
- }
|
|
|
- ipp := msg.Addr.(*net.UDPAddr).AddrPort()
|
|
|
- if ep, ok := c.receiveIP(msg.Buffers[0][:msg.N], ipp, &c.ippEndpoint6); ok {
|
|
|
- metricRecvDataIPv6.Add(1)
|
|
|
- eps[i] = ep
|
|
|
- sizes[i] = msg.N
|
|
|
- reportToCaller = true
|
|
|
- } else {
|
|
|
- sizes[i] = 0
|
|
|
- }
|
|
|
- }
|
|
|
+// mkReceiveFunc creates a ReceiveFunc reading from ruc.
|
|
|
+// The provided healthItem and metric are updated if non-nil.
|
|
|
+func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFuncStats, metric *clientmetric.Metric) conn.ReceiveFunc {
|
|
|
+ // epCache caches an IPPort->endpoint for hot flows.
|
|
|
+ var epCache ippEndpointCache
|
|
|
|
|
|
- if reportToCaller {
|
|
|
- return numMsgs, nil
|
|
|
+ return func(buffs [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
|
|
|
+ if healthItem != nil {
|
|
|
+ healthItem.Enter()
|
|
|
+ defer healthItem.Exit()
|
|
|
+ }
|
|
|
+ if ruc == nil {
|
|
|
+ panic("nil RebindingUDPConn")
|
|
|
}
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (c *Conn) receiveIPv4(buffs [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
|
|
|
- health.ReceiveIPv4.Enter()
|
|
|
- defer health.ReceiveIPv4.Exit()
|
|
|
|
|
|
- batch := c.getReceiveBatchForBuffs(buffs)
|
|
|
- defer c.putReceiveBatch(batch)
|
|
|
- for {
|
|
|
- numMsgs, err := c.pconn4.ReadBatch(batch.msgs[:len(buffs)], 0)
|
|
|
- if err != nil {
|
|
|
- if neterror.PacketWasTruncated(err) {
|
|
|
- // TODO(raggi): discuss whether to log?
|
|
|
- continue
|
|
|
+ batch := c.getReceiveBatchForBuffs(buffs)
|
|
|
+ defer c.putReceiveBatch(batch)
|
|
|
+ for {
|
|
|
+ numMsgs, err := ruc.ReadBatch(batch.msgs[:len(buffs)], 0)
|
|
|
+ if err != nil {
|
|
|
+ if neterror.PacketWasTruncated(err) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ return 0, err
|
|
|
}
|
|
|
- return 0, err
|
|
|
- }
|
|
|
|
|
|
- reportToCaller := false
|
|
|
- for i, msg := range batch.msgs[:numMsgs] {
|
|
|
- if msg.N == 0 {
|
|
|
- sizes[i] = 0
|
|
|
- continue
|
|
|
+ reportToCaller := false
|
|
|
+ for i, msg := range batch.msgs[:numMsgs] {
|
|
|
+ if msg.N == 0 {
|
|
|
+ sizes[i] = 0
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ ipp := msg.Addr.(*net.UDPAddr).AddrPort()
|
|
|
+ if ep, ok := c.receiveIP(msg.Buffers[0][:msg.N], ipp, &epCache); ok {
|
|
|
+ if metric != nil {
|
|
|
+ metric.Add(1)
|
|
|
+ }
|
|
|
+ eps[i] = ep
|
|
|
+ sizes[i] = msg.N
|
|
|
+ reportToCaller = true
|
|
|
+ } else {
|
|
|
+ sizes[i] = 0
|
|
|
+ }
|
|
|
}
|
|
|
- ipp := msg.Addr.(*net.UDPAddr).AddrPort()
|
|
|
- if ep, ok := c.receiveIP(msg.Buffers[0][:msg.N], ipp, &c.ippEndpoint4); ok {
|
|
|
- metricRecvDataIPv4.Add(1)
|
|
|
- eps[i] = ep
|
|
|
- sizes[i] = msg.N
|
|
|
- reportToCaller = true
|
|
|
- } else {
|
|
|
- sizes[i] = 0
|
|
|
+ if reportToCaller {
|
|
|
+ return numMsgs, nil
|
|
|
}
|
|
|
}
|
|
|
- if reportToCaller {
|
|
|
- return numMsgs, nil
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -3044,7 +3023,7 @@ func (c *connBind) Open(ignoredPort uint16) ([]conn.ReceiveFunc, uint16, error)
|
|
|
return nil, 0, errors.New("magicsock: connBind already open")
|
|
|
}
|
|
|
c.closed = false
|
|
|
- fns := []conn.ReceiveFunc{c.receiveIPv4, c.receiveIPv6, c.receiveDERP}
|
|
|
+ fns := []conn.ReceiveFunc{c.receiveIPv4(), c.receiveIPv6(), c.receiveDERP}
|
|
|
if runtime.GOOS == "js" {
|
|
|
fns = []conn.ReceiveFunc{c.receiveDERP}
|
|
|
}
|