summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r--pkg/tcpip/transport/ping/endpoint.go7
-rw-r--r--pkg/tcpip/transport/tcp/connect.go34
-rw-r--r--pkg/tcpip/transport/tcp/protocol.go2
-rw-r--r--pkg/tcpip/transport/tcp/snd.go18
-rw-r--r--pkg/tcpip/transport/udp/endpoint.go12
5 files changed, 32 insertions, 41 deletions
diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go
index 7e10c0aae..fc98c41eb 100644
--- a/pkg/tcpip/transport/ping/endpoint.go
+++ b/pkg/tcpip/transport/ping/endpoint.go
@@ -384,7 +384,8 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error {
icmpv4.SetChecksum(0)
icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0)))
- return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber)
+ vv := buffer.NewVectorisedView(len(data), []buffer.View{data})
+ return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber)
}
func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error {
@@ -407,8 +408,8 @@ func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error {
icmpv6.SetChecksum(0)
icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0)))
-
- return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber)
+ vv := buffer.NewVectorisedView(len(data), []buffer.View{data})
+ return r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber)
}
func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) {
diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go
index 558dbc50a..de5f963cf 100644
--- a/pkg/tcpip/transport/tcp/connect.go
+++ b/pkg/tcpip/transport/tcp/connect.go
@@ -166,7 +166,7 @@ func (h *handshake) checkAck(s *segment) bool {
// incoming segment acknowledges something not yet sent. The
// connection remains in the same state.
ack := s.sequenceNumber.Add(s.logicalLen())
- h.ep.sendRaw(nil, flagRst|flagAck, s.ackNumber, ack, 0)
+ h.ep.sendRaw(buffer.VectorisedView{}, flagRst|flagAck, s.ackNumber, ack, 0)
return false
}
@@ -214,7 +214,7 @@ func (h *handshake) synSentState(s *segment) *tcpip.Error {
// and the handshake is completed.
if s.flagIsSet(flagAck) {
h.state = handshakeCompleted
- h.ep.sendRaw(nil, flagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale())
+ h.ep.sendRaw(buffer.VectorisedView{}, flagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale())
return nil
}
@@ -263,7 +263,7 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error {
if s.flagIsSet(flagAck) {
seq = s.ackNumber
}
- h.ep.sendRaw(nil, flagRst|flagAck, seq, ack, 0)
+ h.ep.sendRaw(buffer.VectorisedView{}, flagRst|flagAck, seq, ack, 0)
if !h.active {
return tcpip.ErrInvalidEndpointState
@@ -563,14 +563,14 @@ func sendSynTCP(r *stack.Route, id stack.TransportEndpointID, flags byte, seq, a
}
options := makeSynOptions(opts)
- err := sendTCPWithOptions(r, id, nil, flags, seq, ack, rcvWnd, options)
+ err := sendTCPWithOptions(r, id, buffer.VectorisedView{}, flags, seq, ack, rcvWnd, options)
putOptions(options)
return err
}
// sendTCPWithOptions sends a TCP segment with the provided options via the
// provided network endpoint and under the provided identity.
-func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error {
+func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error {
optLen := len(opts)
// Allocate a buffer for the TCP header.
hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()) + optLen)
@@ -594,11 +594,10 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe
// Only calculate the checksum if offloading isn't supported.
if r.Capabilities()&stack.CapabilityChecksumOffload == 0 {
- length := uint16(hdr.UsedLength())
+ length := uint16(hdr.UsedLength() + data.Size())
xsum := r.PseudoHeaderChecksum(ProtocolNumber)
- if data != nil {
- length += uint16(len(data))
- xsum = header.Checksum(data, xsum)
+ for _, v := range data.Views() {
+ xsum = header.Checksum(v, xsum)
}
tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length))
@@ -614,7 +613,7 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe
// sendTCP sends a TCP segment via the provided network endpoint and under the
// provided identity.
-func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error {
+func sendTCP(r *stack.Route, id stack.TransportEndpointID, payload buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error {
// Allocate a buffer for the TCP header.
hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()))
@@ -636,11 +635,10 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, fla
// Only calculate the checksum if offloading isn't supported.
if r.Capabilities()&stack.CapabilityChecksumOffload == 0 {
- length := uint16(hdr.UsedLength())
+ length := uint16(hdr.UsedLength() + payload.Size())
xsum := r.PseudoHeaderChecksum(ProtocolNumber)
- if data != nil {
- length += uint16(len(data))
- xsum = header.Checksum(data, xsum)
+ for _, v := range payload.Views() {
+ xsum = header.Checksum(v, xsum)
}
tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length))
@@ -651,7 +649,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, fla
r.Stats().TCP.ResetsSent.Increment()
}
- return r.WritePacket(&hdr, data, ProtocolNumber)
+ return r.WritePacket(&hdr, payload, ProtocolNumber)
}
// makeOptions makes an options slice.
@@ -694,7 +692,7 @@ func (e *endpoint) makeOptions(sackBlocks []header.SACKBlock) []byte {
}
// sendRaw sends a TCP segment to the endpoint's peer.
-func (e *endpoint) sendRaw(data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error {
+func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error {
var sackBlocks []header.SACKBlock
if e.state == stateConnected && e.rcv.pendingBufSize > 0 && (flags&flagAck != 0) {
sackBlocks = e.sack.Blocks[:e.sack.NumBlocks]
@@ -751,7 +749,7 @@ func (e *endpoint) handleClose() *tcpip.Error {
// state with the given error code. This method must only be called from the
// protocol goroutine.
func (e *endpoint) resetConnectionLocked(err *tcpip.Error) {
- e.sendRaw(nil, flagAck|flagRst, e.snd.sndUna, e.rcv.rcvNxt, 0)
+ e.sendRaw(buffer.VectorisedView{}, flagAck|flagRst, e.snd.sndUna, e.rcv.rcvNxt, 0)
e.state = stateError
e.hardError = err
@@ -851,7 +849,7 @@ func (e *endpoint) keepaliveTimerExpired() *tcpip.Error {
// seg.seq = snd.nxt-1.
e.keepalive.unacked++
e.keepalive.Unlock()
- e.snd.sendSegment(nil, flagAck, e.snd.sndNxt-1)
+ e.snd.sendSegment(buffer.VectorisedView{}, flagAck, e.snd.sndNxt-1)
e.resetKeepaliveTimer(false)
return nil
}
diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go
index 194d3f41d..006b2f074 100644
--- a/pkg/tcpip/transport/tcp/protocol.go
+++ b/pkg/tcpip/transport/tcp/protocol.go
@@ -147,7 +147,7 @@ func replyWithReset(s *segment) {
ack := s.sequenceNumber.Add(s.logicalLen())
- sendTCP(&s.route, s.id, nil, flagRst|flagAck, seq, ack, 0)
+ sendTCP(&s.route, s.id, buffer.VectorisedView{}, flagRst|flagAck, seq, ack, 0)
}
// SetOption implements TransportProtocol.SetOption.
diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go
index e4fa89912..284e720c6 100644
--- a/pkg/tcpip/transport/tcp/snd.go
+++ b/pkg/tcpip/transport/tcp/snd.go
@@ -270,7 +270,7 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) {
// sendAck sends an ACK segment.
func (s *sender) sendAck() {
- s.sendSegment(nil, flagAck, s.sndNxt)
+ s.sendSegment(buffer.VectorisedView{}, flagAck, s.sndNxt)
}
// updateRTO updates the retransmit timeout when a new roud-trip time is
@@ -305,7 +305,7 @@ func (s *sender) resendSegment() {
// Resend the segment.
if seg := s.writeList.Front(); seg != nil {
- s.sendSegment(&seg.data, seg.flags, seg.sequenceNumber)
+ s.sendSegment(seg.data, seg.flags, seg.sequenceNumber)
}
}
@@ -419,7 +419,7 @@ func (s *sender) sendData() {
segEnd = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size()))
}
- s.sendSegment(&seg.data, seg.flags, seg.sequenceNumber)
+ s.sendSegment(seg.data, seg.flags, seg.sequenceNumber)
// Update sndNxt if we actually sent new data (as opposed to
// retransmitting some previously sent data).
@@ -642,7 +642,7 @@ func (s *sender) handleRcvdSegment(seg *segment) {
// sendSegment sends a new segment containing the given payload, flags and
// sequence number.
-func (s *sender) sendSegment(data *buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error {
+func (s *sender) sendSegment(data buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error {
s.lastSendTime = time.Now()
if seq == s.rttMeasureSeqNum {
s.rttMeasureTime = s.lastSendTime
@@ -653,13 +653,5 @@ func (s *sender) sendSegment(data *buffer.VectorisedView, flags byte, seq seqnum
// Remember the max sent ack.
s.maxSentAck = rcvNxt
- if data == nil {
- return s.ep.sendRaw(nil, flags, seq, rcvNxt, rcvWnd)
- }
-
- if len(data.Views()) > 1 {
- panic("send path does not support views with multiple buffers")
- }
-
- return s.ep.sendRaw(data.First(), flags, seq, rcvNxt, rcvWnd)
+ return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd)
}
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go
index 6a12c2f08..283379a28 100644
--- a/pkg/tcpip/transport/udp/endpoint.go
+++ b/pkg/tcpip/transport/udp/endpoint.go
@@ -328,7 +328,8 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc
return 0, err
}
- if err := sendUDP(route, v, e.id.LocalPort, dstPort); err != nil {
+ vv := buffer.NewVectorisedView(len(v), []buffer.View{v})
+ if err := sendUDP(route, vv, e.id.LocalPort, dstPort); err != nil {
return 0, err
}
return uintptr(len(v)), nil
@@ -426,14 +427,14 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
// sendUDP sends a UDP segment via the provided network endpoint and under the
// provided identity.
-func sendUDP(r *stack.Route, data buffer.View, localPort, remotePort uint16) *tcpip.Error {
+func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16) *tcpip.Error {
// Allocate a buffer for the UDP header.
hdr := buffer.NewPrependable(header.UDPMinimumSize + int(r.MaxHeaderLength()))
// Initialize the header.
udp := header.UDP(hdr.Prepend(header.UDPMinimumSize))
- length := uint16(hdr.UsedLength()) + uint16(len(data))
+ length := uint16(hdr.UsedLength() + data.Size())
udp.Encode(&header.UDPFields{
SrcPort: localPort,
DstPort: remotePort,
@@ -443,10 +444,9 @@ func sendUDP(r *stack.Route, data buffer.View, localPort, remotePort uint16) *tc
// Only calculate the checksum if offloading isn't supported.
if r.Capabilities()&stack.CapabilityChecksumOffload == 0 {
xsum := r.PseudoHeaderChecksum(ProtocolNumber)
- if data != nil {
- xsum = header.Checksum(data, xsum)
+ for _, v := range data.Views() {
+ xsum = header.Checksum(v, xsum)
}
-
udp.SetChecksum(^udp.CalculateChecksum(xsum, length))
}