From a96cf856f575a44a9750ff45029da949ef2b2499 Mon Sep 17 00:00:00 2001 From: tracyfyzhou Date: Sat, 8 Jun 2019 10:07:00 +0800 Subject: [PATCH 1/4] Create a forward structure to call the endpoint --- tcpip/transport/icmp/endpoint.go | 22 +++---- tcpip/transport/icmp/forwarder.go | 97 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 tcpip/transport/icmp/forwarder.go diff --git a/tcpip/transport/icmp/endpoint.go b/tcpip/transport/icmp/endpoint.go index d6bdda7d..2d266355 100644 --- a/tcpip/transport/icmp/endpoint.go +++ b/tcpip/transport/icmp/endpoint.go @@ -86,7 +86,7 @@ type endpoint struct { route stack.Route } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (*endpoint, *tcpip.Error) { return &endpoint{ stack: stack, netProto: netProto, @@ -365,7 +365,7 @@ func (e *endpoint) send4(r *stack.Route, data buffer.View) *tcpip.Error { data = data[header.ICMPv4EchoMinimumSize:] // Linux performs these basic checks. - if icmpv4.Type() != header.ICMPv4Echo || icmpv4.Code() != 0 { + if (icmpv4.Type() != header.ICMPv4Echo && icmpv4.Type() != header.ICMPv4EchoReply) || icmpv4.Code() != 0 { return tcpip.ErrInvalidEndpointState } @@ -658,11 +658,13 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv // Only accept echo replies. switch e.netProto { case header.IPv4ProtocolNumber: - h := header.ICMPv4(vv.First()) - if h.Type() != header.ICMPv4EchoReply { - e.stack.Stats().DroppedPackets.Increment() - return - } + // h := header.ICMPv4(vv.First()) + /* if h.Type() != header.ICMPv4EchoReply && h.Type() != header.ICMPv4Echo { + typea := h.Type() + log.Printf("type:%v", string(typea)) + e.stack.Stats().DroppedPackets.Increment() + return + }*/ case header.IPv6ProtocolNumber: h := header.ICMPv6(vv.First()) if h.Type() != header.ICMPv6EchoReply { @@ -708,9 +710,3 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { } - -// State implements tcpip.Endpoint.State. The ICMP endpoint currently doesn't -// expose internal socket state. -func (e *endpoint) State() uint32 { - return 0 -} diff --git a/tcpip/transport/icmp/forwarder.go b/tcpip/transport/icmp/forwarder.go new file mode 100644 index 00000000..c16b6eba --- /dev/null +++ b/tcpip/transport/icmp/forwarder.go @@ -0,0 +1,97 @@ +// Copyright 2019 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package icmp + +import ( + "github.com/google/netstack/tcpip" + "github.com/google/netstack/tcpip/buffer" + "github.com/google/netstack/tcpip/stack" + "github.com/google/netstack/waiter" +) + +// Forwarder is a session request forwarder, which allows clients to decide +// what to do with a session request, for example: ignore it, or process it. +// +// The canonical way of using it is to pass the Forwarder.HandlePacket function +// to stack.SetTransportProtocolHandler. +type Forwarder struct { + handler func(*ForwarderRequest) + + stack *stack.Stack +} + +// NewForwarder allocates and initializes a new forwarder. +func NewForwarder(s *stack.Stack, handler func(*ForwarderRequest)) *Forwarder { + return &Forwarder{ + stack: s, + handler: handler, + } +} + +// HandlePacket handles all packets. +// +// This function is expected to be passed as an argument to the +// stack.SetTransportProtocolHandler function. +func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) bool { + + f.handler(&ForwarderRequest{ + stack: f.stack, + route: r, + id: id, + vv: vv, + }) + + return true +} + +// ForwarderRequest represents a session request received by the forwarder and +// passed to the client. Clients may optionally create an endpoint to represent +// it via CreateEndpoint. +type ForwarderRequest struct { + stack *stack.Stack + route *stack.Route + id stack.TransportEndpointID + vv buffer.VectorisedView +} + +// ID returns the 4-tuple (src address, src port, dst address, dst port) that +// represents the session request. +func (r *ForwarderRequest) ID() stack.TransportEndpointID { + return r.id +} + +// CreateEndpoint creates a connected UDP endpoint for the session request. +func (r *ForwarderRequest) CreateEndpoint(queue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + ep, _ := newEndpoint(r.stack, r.route.NetProto, ProtocolNumber4, queue) + if err := r.stack.RegisterTransportEndpoint(r.route.NICID(), []tcpip.NetworkProtocolNumber{r.route.NetProto}, ProtocolNumber4, r.id, ep, true); err != nil { + ep.Close() + return nil, err + } + + ep.id = r.id + ep.route = r.route.Clone() + // ep.dstPort = r.id.RemotePort + ep.regNICID = r.route.NICID() + + ep.state = stateConnected + + ep.rcvMu.Lock() + ep.rcvReady = true + ep.rcvMu.Unlock() + + ep.HandlePacket(r.route, r.id, r.vv) + + return ep, nil +} From af6888f6a78dd597fb19ff14ec305e6e31c862bd Mon Sep 17 00:00:00 2001 From: tracyfyzhou Date: Sat, 8 Jun 2019 10:18:58 +0800 Subject: [PATCH 2/4] remove log --- tcpip/transport/icmp/endpoint.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tcpip/transport/icmp/endpoint.go b/tcpip/transport/icmp/endpoint.go index 2d266355..8463554b 100644 --- a/tcpip/transport/icmp/endpoint.go +++ b/tcpip/transport/icmp/endpoint.go @@ -658,13 +658,12 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv // Only accept echo replies. switch e.netProto { case header.IPv4ProtocolNumber: - // h := header.ICMPv4(vv.First()) - /* if h.Type() != header.ICMPv4EchoReply && h.Type() != header.ICMPv4Echo { - typea := h.Type() - log.Printf("type:%v", string(typea)) - e.stack.Stats().DroppedPackets.Increment() - return - }*/ + h := header.ICMPv4(vv.First()) + if h.Type() != header.ICMPv4EchoReply && h.Type() != header.ICMPv4Echo { + typea := h.Type() + e.stack.Stats().DroppedPackets.Increment() + return + } case header.IPv6ProtocolNumber: h := header.ICMPv6(vv.First()) if h.Type() != header.ICMPv6EchoReply { From e9c78ced071a45fdcd8584b1e5f223c3467cee12 Mon Sep 17 00:00:00 2001 From: tracyfyzhou Date: Sat, 8 Jun 2019 10:20:16 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E8=AF=AF=E5=88=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tcpip/transport/icmp/endpoint.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tcpip/transport/icmp/endpoint.go b/tcpip/transport/icmp/endpoint.go index 8463554b..42a3ccd0 100644 --- a/tcpip/transport/icmp/endpoint.go +++ b/tcpip/transport/icmp/endpoint.go @@ -709,3 +709,9 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { } + +// State implements tcpip.Endpoint.State. The ICMP endpoint currently doesn't +// expose internal socket state. +func (e *endpoint) State() uint32 { + return 0 +} From 888aab295af05de1720446c0f6d4f11543f988c7 Mon Sep 17 00:00:00 2001 From: tracyfyzhou Date: Sat, 8 Jun 2019 10:30:00 +0800 Subject: [PATCH 4/4] remove test code --- tcpip/transport/icmp/endpoint.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tcpip/transport/icmp/endpoint.go b/tcpip/transport/icmp/endpoint.go index 42a3ccd0..6a8a777a 100644 --- a/tcpip/transport/icmp/endpoint.go +++ b/tcpip/transport/icmp/endpoint.go @@ -660,7 +660,6 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv case header.IPv4ProtocolNumber: h := header.ICMPv4(vv.First()) if h.Type() != header.ICMPv4EchoReply && h.Type() != header.ICMPv4Echo { - typea := h.Type() e.stack.Stats().DroppedPackets.Increment() return }