// HandlePacket implements stack.RawTransportEndpoint.HandlePacket.
HandlePacket implements stack.RawTransportEndpoint.HandlePacket.
// HandlePacket implements stack . RawTransportEndpoint . HandlePacket .
func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
	e.mu.RLock()
	e.rcvMu.Lock()
	    An IPPROTO_RAW socket is send only.  If you really want to receive
	    all IP packets, use a packet(7) socket with the ETH_P_IP protocol.
	    Note that packet sockets don't reassemble IP fragments, unlike raw
	    sockets.
	if e.rcvClosed || !e.associated {
		e.rcvMu.Unlock()
		e.mu.RUnlock()
		e.stack.Stats().DroppedPackets.Increment()
		e.stats.ReceiveErrors.ClosedReceiver.Increment()
		return
	}
	rcvBufSize := e.ops.GetReceiveBufferSize()
	if e.frozen || e.rcvBufSize >= int(rcvBufSize) {
		e.rcvMu.Unlock()
		e.mu.RUnlock()
		e.stack.Stats().DroppedPackets.Increment()
		e.stats.ReceiveErrors.ReceiveBufferOverflow.Increment()
		return
	}
	remoteAddr := pkt.Network().SourceAddress()
	if e.bound {
		 If bound to a NIC, only accept data for that NIC.
		if e.BindNICID != 0 && e.BindNICID != pkt.NICID {
			e.rcvMu.Unlock()
			e.mu.RUnlock()
			return
		}
		 If bound to an address, only accept data for that address.
		if e.BindAddr != "" && e.BindAddr != remoteAddr {
			e.rcvMu.Unlock()
			e.mu.RUnlock()
			return
		}
	}
	 If connected, only accept packets from the remote address we
	 connected to.
	if e.connected && e.route.RemoteAddress() != remoteAddr {
		e.rcvMu.Unlock()
		e.mu.RUnlock()
		return
	}
	wasEmpty := e.rcvBufSize == 0
	 Push new packet into receive list and increment the buffer size.
	packet := &rawPacket{
		senderAddr: tcpip.FullAddress{
			NIC:  pkt.NICID,
			Addr: remoteAddr,
		},
	}
	 Raw IPv4 endpoints return the IP header, but IPv6 endpoints do not.
	 We copy headers' underlying bytes because pkt.*Header may point to
	 the middle of a slice, and another struct may point to the "outer"
	 slice. Save/restore doesn't support overlapping slices and will fail.
	var combinedVV buffer.VectorisedView
	if e.TransportEndpointInfo.NetProto == header.IPv4ProtocolNumber {
		network, transport := pkt.NetworkHeader().View(), pkt.TransportHeader().View()
		headers := make(buffer.View, 0, len(network)+len(transport))
		headers = append(headers, network...)
		headers = append(headers, transport...)
		combinedVV = headers.ToVectorisedView()
	} else {
		combinedVV = append(buffer.View(nil), pkt.TransportHeader().View()...).ToVectorisedView()
	}
	combinedVV.Append(pkt.Data().ExtractVV())
	packet.data = combinedVV
	packet.receivedAt = e.stack.Clock().Now()
	e.rcvList.PushBack(packet)
	e.rcvBufSize += packet.data.Size()
	e.rcvMu.Unlock()
	e.mu.RUnlock()
	e.stats.PacketsReceived.Increment()
	 Notify waiters that there's data to be read.
	if wasEmpty {
		e.waiterQueue.Notify(waiter.ReadableEvents)
	}
}
func ( e * endpoint ) HandlePacket ( pkt * stack . PacketBuffer ) { e . mu . RLock ( ) e . rcvMu . Lock ( ) if e . rcvClosed || ! e . associated { e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) e . stack . Stats ( ) . DroppedPackets . Increment ( ) e . stats . ReceiveErrors . ClosedReceiver . Increment ( ) return } rcvBufSize := e . ops . GetReceiveBufferSize ( ) if e . frozen || e . rcvBufSize >= int ( rcvBufSize ) { e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) e . stack . Stats ( ) . DroppedPackets . Increment ( ) e . stats . ReceiveErrors . ReceiveBufferOverflow . Increment ( ) return } remoteAddr := pkt . Network ( ) . SourceAddress ( ) if e . bound { if e . BindNICID != 0 && e . BindNICID != pkt . NICID { e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) return } if e . BindAddr != " " && e . BindAddr != remoteAddr { e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) return } } if e . connected && e . route . RemoteAddress ( ) != remoteAddr { e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) return } wasEmpty := e . rcvBufSize == 0 packet := & rawPacket { senderAddr : tcpip . FullAddress { NIC : pkt . NICID , Addr : remoteAddr , } , } var combinedVV buffer . VectorisedView if e . TransportEndpointInfo . NetProto == header . IPv4ProtocolNumber { network , transport := pkt . NetworkHeader ( ) . View ( ) , pkt . TransportHeader ( ) . View ( ) headers := make ( buffer . View , 0 , len ( network ) + len ( transport ) ) headers = append ( headers , network ... ) headers = append ( headers , transport ... ) combinedVV = headers . ToVectorisedView ( ) } else { combinedVV = append ( buffer . View ( nil ) , pkt . TransportHeader ( ) . View ( ) ... ) . ToVectorisedView ( ) } combinedVV . Append ( pkt . Data ( ) . ExtractVV ( ) ) packet . data = combinedVV packet . receivedAt = e . stack . Clock ( ) . Now ( ) e . rcvList . PushBack ( packet ) e . rcvBufSize += packet . data . Size ( ) e . rcvMu . Unlock ( ) e . mu . RUnlock ( ) e . stats . PacketsReceived . Increment ( ) if wasEmpty { e . waiterQueue . Notify ( waiter . ReadableEvents ) } }
HandlePacket implements stack.RawTransportEndpoint.HandlePacket.
HandlePacket implements stack . RawTransportEndpoint . HandlePacket .
// Drop the packet if our buffer is currently full or if this is an unassociated // endpoint (i.e endpoint created  w/ IPPROTO_RAW). Such endpoints are send only // See: https://man7.org/linux/man-pages/man7/raw.7.html // //    An IPPROTO_RAW socket is send only.  If you really want to receive //    all IP packets, use a packet(7) socket with the ETH_P_IP protocol. //    Note that packet sockets don't reassemble IP fragments, unlike raw //    sockets. // If bound to a NIC, only accept data for that NIC. // If bound to an address, only accept data for that address. // If connected, only accept packets from the remote address we // connected to. // Push new packet into receive list and increment the buffer size. // Raw IPv4 endpoints return the IP header, but IPv6 endpoints do not. // We copy headers' underlying bytes because pkt.*Header may point to // the middle of a slice, and another struct may point to the "outer" // slice. Save/restore doesn't support overlapping slices and will fail. // Notify waiters that there's data to be read.