github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/tcpip/transport/tcp/accept.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcp 16 17 import ( 18 "container/list" 19 "crypto/sha1" 20 "encoding/binary" 21 "fmt" 22 "hash" 23 "io" 24 "time" 25 26 "github.com/nicocha30/gvisor-ligolo/pkg/sync" 27 "github.com/nicocha30/gvisor-ligolo/pkg/tcpip" 28 "github.com/nicocha30/gvisor-ligolo/pkg/tcpip/header" 29 "github.com/nicocha30/gvisor-ligolo/pkg/tcpip/ports" 30 "github.com/nicocha30/gvisor-ligolo/pkg/tcpip/seqnum" 31 "github.com/nicocha30/gvisor-ligolo/pkg/tcpip/stack" 32 "github.com/nicocha30/gvisor-ligolo/pkg/waiter" 33 ) 34 35 const ( 36 // tsLen is the length, in bits, of the timestamp in the SYN cookie. 37 tsLen = 8 38 39 // tsMask is a mask for timestamp values (i.e., tsLen bits). 40 tsMask = (1 << tsLen) - 1 41 42 // tsOffset is the offset, in bits, of the timestamp in the SYN cookie. 43 tsOffset = 24 44 45 // hashMask is the mask for hash values (i.e., tsOffset bits). 46 hashMask = (1 << tsOffset) - 1 47 48 // maxTSDiff is the maximum allowed difference between a received cookie 49 // timestamp and the current timestamp. If the difference is greater 50 // than maxTSDiff, the cookie is expired. 51 maxTSDiff = 2 52 ) 53 54 var ( 55 // mssTable is a slice containing the possible MSS values that we 56 // encode in the SYN cookie with two bits. 57 mssTable = []uint16{536, 1300, 1440, 1460} 58 ) 59 60 func encodeMSS(mss uint16) uint32 { 61 for i := len(mssTable) - 1; i > 0; i-- { 62 if mss >= mssTable[i] { 63 return uint32(i) 64 } 65 } 66 return 0 67 } 68 69 // listenContext is used by a listening endpoint to store state used while 70 // listening for connections. This struct is allocated by the listen goroutine 71 // and must not be accessed or have its methods called concurrently as they 72 // may mutate the stored objects. 73 type listenContext struct { 74 stack *stack.Stack 75 protocol *protocol 76 77 // rcvWnd is the receive window that is sent by this listening context 78 // in the initial SYN-ACK. 79 rcvWnd seqnum.Size 80 81 // nonce are random bytes that are initialized once when the context 82 // is created and used to seed the hash function when generating 83 // the SYN cookie. 84 nonce [2][sha1.BlockSize]byte 85 86 // listenEP is a reference to the listening endpoint associated with 87 // this context. Can be nil if the context is created by the forwarder. 88 listenEP *endpoint 89 90 // hasherMu protects hasher. 91 hasherMu sync.Mutex 92 // hasher is the hash function used to generate a SYN cookie. 93 hasher hash.Hash 94 95 // v6Only is true if listenEP is a dual stack socket and has the 96 // IPV6_V6ONLY option set. 97 v6Only bool 98 99 // netProto indicates the network protocol(IPv4/v6) for the listening 100 // endpoint. 101 netProto tcpip.NetworkProtocolNumber 102 } 103 104 // timeStamp returns an 8-bit timestamp with a granularity of 64 seconds. 105 func timeStamp(clock tcpip.Clock) uint32 { 106 return uint32(clock.NowMonotonic().Sub(tcpip.MonotonicTime{}).Seconds()) >> 6 & tsMask 107 } 108 109 // newListenContext creates a new listen context. 110 func newListenContext(stk *stack.Stack, protocol *protocol, listenEP *endpoint, rcvWnd seqnum.Size, v6Only bool, netProto tcpip.NetworkProtocolNumber) *listenContext { 111 l := &listenContext{ 112 stack: stk, 113 protocol: protocol, 114 rcvWnd: rcvWnd, 115 hasher: sha1.New(), 116 v6Only: v6Only, 117 netProto: netProto, 118 listenEP: listenEP, 119 } 120 121 for i := range l.nonce { 122 if _, err := io.ReadFull(stk.SecureRNG(), l.nonce[i][:]); err != nil { 123 panic(err) 124 } 125 } 126 127 return l 128 } 129 130 // cookieHash calculates the cookieHash for the given id, timestamp and nonce 131 // index. The hash is used to create and validate cookies. 132 func (l *listenContext) cookieHash(id stack.TransportEndpointID, ts uint32, nonceIndex int) uint32 { 133 134 // Initialize block with fixed-size data: local ports and v. 135 var payload [8]byte 136 binary.BigEndian.PutUint16(payload[0:], id.LocalPort) 137 binary.BigEndian.PutUint16(payload[2:], id.RemotePort) 138 binary.BigEndian.PutUint32(payload[4:], ts) 139 140 // Feed everything to the hasher. 141 l.hasherMu.Lock() 142 l.hasher.Reset() 143 144 // Per hash.Hash.Writer: 145 // 146 // It never returns an error. 147 l.hasher.Write(payload[:]) 148 l.hasher.Write(l.nonce[nonceIndex][:]) 149 l.hasher.Write(id.LocalAddress.AsSlice()) 150 l.hasher.Write(id.RemoteAddress.AsSlice()) 151 152 // Finalize the calculation of the hash and return the first 4 bytes. 153 h := l.hasher.Sum(nil) 154 l.hasherMu.Unlock() 155 156 return binary.BigEndian.Uint32(h[:]) 157 } 158 159 // createCookie creates a SYN cookie for the given id and incoming sequence 160 // number. 161 func (l *listenContext) createCookie(id stack.TransportEndpointID, seq seqnum.Value, data uint32) seqnum.Value { 162 ts := timeStamp(l.stack.Clock()) 163 v := l.cookieHash(id, 0, 0) + uint32(seq) + (ts << tsOffset) 164 v += (l.cookieHash(id, ts, 1) + data) & hashMask 165 return seqnum.Value(v) 166 } 167 168 // isCookieValid checks if the supplied cookie is valid for the given id and 169 // sequence number. If it is, it also returns the data originally encoded in the 170 // cookie when createCookie was called. 171 func (l *listenContext) isCookieValid(id stack.TransportEndpointID, cookie seqnum.Value, seq seqnum.Value) (uint32, bool) { 172 ts := timeStamp(l.stack.Clock()) 173 v := uint32(cookie) - l.cookieHash(id, 0, 0) - uint32(seq) 174 cookieTS := v >> tsOffset 175 if ((ts - cookieTS) & tsMask) > maxTSDiff { 176 return 0, false 177 } 178 179 return (v - l.cookieHash(id, cookieTS, 1)) & hashMask, true 180 } 181 182 // createConnectingEndpoint creates a new endpoint in a connecting state, with 183 // the connection parameters given by the arguments. The newly created endpoint 184 // will be locked. 185 // +checklocksacquire:n.mu 186 func (l *listenContext) createConnectingEndpoint(s *segment, rcvdSynOpts header.TCPSynOptions, queue *waiter.Queue) (n *endpoint, _ tcpip.Error) { 187 // Create a new endpoint. 188 netProto := l.netProto 189 if netProto == 0 { 190 netProto = s.pkt.NetworkProtocolNumber 191 } 192 193 route, err := l.stack.FindRoute(s.pkt.NICID, s.pkt.Network().DestinationAddress(), s.pkt.Network().SourceAddress(), s.pkt.NetworkProtocolNumber, false /* multicastLoop */) 194 if err != nil { 195 return nil, err // +checklocksignore 196 } 197 198 n = newEndpoint(l.stack, l.protocol, netProto, queue) 199 n.mu.Lock() 200 n.ops.SetV6Only(l.v6Only) 201 n.TransportEndpointInfo.ID = s.id 202 n.boundNICID = s.pkt.NICID 203 n.route = route 204 n.effectiveNetProtos = []tcpip.NetworkProtocolNumber{s.pkt.NetworkProtocolNumber} 205 n.ops.SetReceiveBufferSize(int64(l.rcvWnd), false /* notify */) 206 n.amss = calculateAdvertisedMSS(n.userMSS, n.route) 207 n.setEndpointState(StateConnecting) 208 209 n.maybeEnableTimestamp(rcvdSynOpts) 210 n.maybeEnableSACKPermitted(rcvdSynOpts) 211 212 n.initGSO() 213 214 // Bootstrap the auto tuning algorithm. Starting at zero will result in 215 // a large step function on the first window adjustment causing the 216 // window to grow to a really large value. 217 initWnd := n.initialReceiveWindow() 218 n.rcvQueueMu.Lock() 219 n.RcvAutoParams.PrevCopiedBytes = initWnd 220 n.rcvQueueMu.Unlock() 221 222 return n, nil 223 } 224 225 // startHandshake creates a new endpoint in connecting state and then sends 226 // the SYN-ACK for the TCP 3-way handshake. It returns the state of the 227 // handshake in progress, which includes the new endpoint in the SYN-RCVD 228 // state. 229 // 230 // On success, a handshake h is returned. 231 // 232 // NOTE: h.ep.mu is not held and must be acquired if any state needs to be 233 // modified. 234 // 235 // Precondition: if l.listenEP != nil, l.listenEP.mu must be locked. 236 func (l *listenContext) startHandshake(s *segment, opts header.TCPSynOptions, queue *waiter.Queue, owner tcpip.PacketOwner) (h *handshake, _ tcpip.Error) { 237 // Create new endpoint. 238 irs := s.sequenceNumber 239 isn := generateSecureISN(s.id, l.stack.Clock(), l.protocol.seqnumSecret) 240 ep, err := l.createConnectingEndpoint(s, opts, queue) 241 if err != nil { 242 return nil, err // +checklocksignore 243 } 244 245 ep.owner = owner 246 247 // listenEP is nil when listenContext is used by tcp.Forwarder. 248 deferAccept := time.Duration(0) 249 if l.listenEP != nil { 250 if l.listenEP.EndpointState() != StateListen { 251 252 // Ensure we release any registrations done by the newly 253 // created endpoint. 254 ep.mu.Unlock() 255 ep.Close() 256 257 return nil, &tcpip.ErrConnectionAborted{} // +checklocksignore 258 } 259 260 // Propagate any inheritable options from the listening endpoint 261 // to the newly created endpoint. 262 l.listenEP.propagateInheritableOptionsLocked(ep) // +checklocksforce 263 264 if !ep.reserveTupleLocked() { 265 ep.mu.Unlock() 266 ep.Close() 267 268 return nil, &tcpip.ErrConnectionAborted{} // +checklocksignore 269 } 270 271 deferAccept = l.listenEP.deferAccept 272 } 273 274 // Register new endpoint so that packets are routed to it. 275 if err := ep.stack.RegisterTransportEndpoint( 276 ep.effectiveNetProtos, 277 ProtocolNumber, 278 ep.TransportEndpointInfo.ID, 279 ep, 280 ep.boundPortFlags, 281 ep.boundBindToDevice, 282 ); err != nil { 283 ep.mu.Unlock() 284 ep.Close() 285 286 ep.drainClosingSegmentQueue() 287 288 return nil, err // +checklocksignore 289 } 290 291 ep.isRegistered = true 292 293 // Initialize and start the handshake. 294 h = ep.newPassiveHandshake(isn, irs, opts, deferAccept) 295 h.listenEP = l.listenEP 296 h.start() 297 h.ep.mu.Unlock() 298 return h, nil 299 } 300 301 // performHandshake performs a TCP 3-way handshake. On success, the new 302 // established endpoint is returned. 303 // 304 // Precondition: if l.listenEP != nil, l.listenEP.mu must be locked. 305 func (l *listenContext) performHandshake(s *segment, opts header.TCPSynOptions, queue *waiter.Queue, owner tcpip.PacketOwner) (*endpoint, tcpip.Error) { 306 waitEntry, notifyCh := waiter.NewChannelEntry(waiter.WritableEvents) 307 queue.EventRegister(&waitEntry) 308 defer queue.EventUnregister(&waitEntry) 309 310 h, err := l.startHandshake(s, opts, queue, owner) 311 if err != nil { 312 return nil, err 313 } 314 315 // performHandshake is used by the Forwarder which will block till the 316 // handshake either succeeds or fails. We do this by registering for 317 // events above and block on the notification channel. 318 <-notifyCh 319 320 ep := h.ep 321 ep.mu.Lock() 322 if !ep.EndpointState().connected() { 323 ep.stack.Stats().TCP.FailedConnectionAttempts.Increment() 324 ep.stats.FailedConnectionAttempts.Increment() 325 ep.h = nil 326 ep.mu.Unlock() 327 ep.Close() 328 ep.notifyAborted() 329 ep.drainClosingSegmentQueue() 330 err := ep.LastError() 331 if err == nil { 332 // If err was nil then return the best error we can to indicate 333 // a connection failure. 334 err = &tcpip.ErrConnectionAborted{} 335 } 336 return nil, err 337 } 338 339 ep.isConnectNotified = true 340 341 // Transfer any state from the completed handshake to the endpoint. 342 // 343 // Update the receive window scaling. We can't do it before the 344 // handshake because it's possible that the peer doesn't support window 345 // scaling. 346 ep.rcv.RcvWndScale = ep.h.effectiveRcvWndScale() 347 348 // Clean up handshake state stored in the endpoint so that it can be 349 // GCed. 350 ep.h = nil 351 ep.mu.Unlock() 352 return ep, nil 353 } 354 355 // propagateInheritableOptionsLocked propagates any options set on the listening 356 // endpoint to the newly created endpoint. 357 // 358 // +checklocks:e.mu 359 // +checklocks:n.mu 360 func (e *endpoint) propagateInheritableOptionsLocked(n *endpoint) { 361 n.userTimeout = e.userTimeout 362 n.portFlags = e.portFlags 363 n.boundBindToDevice = e.boundBindToDevice 364 n.boundPortFlags = e.boundPortFlags 365 n.userMSS = e.userMSS 366 } 367 368 // reserveTupleLocked reserves an accepted endpoint's tuple. 369 // 370 // Precondition: e.propagateInheritableOptionsLocked has been called. 371 // 372 // +checklocks:e.mu 373 func (e *endpoint) reserveTupleLocked() bool { 374 dest := tcpip.FullAddress{ 375 Addr: e.TransportEndpointInfo.ID.RemoteAddress, 376 Port: e.TransportEndpointInfo.ID.RemotePort, 377 } 378 portRes := ports.Reservation{ 379 Networks: e.effectiveNetProtos, 380 Transport: ProtocolNumber, 381 Addr: e.TransportEndpointInfo.ID.LocalAddress, 382 Port: e.TransportEndpointInfo.ID.LocalPort, 383 Flags: e.boundPortFlags, 384 BindToDevice: e.boundBindToDevice, 385 Dest: dest, 386 } 387 if !e.stack.ReserveTuple(portRes) { 388 e.stack.Stats().TCP.FailedPortReservations.Increment() 389 return false 390 } 391 392 e.isPortReserved = true 393 e.boundDest = dest 394 return true 395 } 396 397 // notifyAborted wakes up any waiters on registered, but not accepted 398 // endpoints. 399 // 400 // This is strictly not required normally as a socket that was never accepted 401 // can't really have any registered waiters except when stack.Wait() is called 402 // which waits for all registered endpoints to stop and expects an EventHUp. 403 func (e *endpoint) notifyAborted() { 404 e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.ReadableEvents | waiter.WritableEvents) 405 } 406 407 func (e *endpoint) acceptQueueIsFull() bool { 408 e.acceptMu.Lock() 409 full := e.acceptQueue.isFull() 410 e.acceptMu.Unlock() 411 return full 412 } 413 414 // +stateify savable 415 type acceptQueue struct { 416 // NB: this could be an endpointList, but ilist only permits endpoints to 417 // belong to one list at a time, and endpoints are already stored in the 418 // dispatcher's list. 419 endpoints list.List `state:".([]*endpoint)"` 420 421 // pendingEndpoints is a set of all endpoints for which a handshake is 422 // in progress. 423 pendingEndpoints map[*endpoint]struct{} 424 425 // capacity is the maximum number of endpoints that can be in endpoints. 426 capacity int 427 } 428 429 func (a *acceptQueue) isFull() bool { 430 return a.endpoints.Len() >= a.capacity 431 } 432 433 // handleListenSegment is called when a listening endpoint receives a segment 434 // and needs to handle it. 435 // 436 // +checklocks:e.mu 437 func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) tcpip.Error { 438 e.rcvQueueMu.Lock() 439 rcvClosed := e.RcvClosed 440 e.rcvQueueMu.Unlock() 441 if rcvClosed || s.flags.Contains(header.TCPFlagSyn|header.TCPFlagAck) { 442 // If the endpoint is shutdown, reply with reset. 443 // 444 // RFC 793 section 3.4 page 35 (figure 12) outlines that a RST 445 // must be sent in response to a SYN-ACK while in the listen 446 // state to prevent completing a handshake from an old SYN. 447 return replyWithReset(e.stack, s, e.sendTOS, e.ipv4TTL, e.ipv6HopLimit) 448 } 449 450 switch { 451 case s.flags.Contains(header.TCPFlagRst): 452 e.stack.Stats().DroppedPackets.Increment() 453 return nil 454 455 case s.flags.Contains(header.TCPFlagSyn): 456 if e.acceptQueueIsFull() { 457 e.stack.Stats().TCP.ListenOverflowSynDrop.Increment() 458 e.stats.ReceiveErrors.ListenOverflowSynDrop.Increment() 459 e.stack.Stats().DroppedPackets.Increment() 460 return nil 461 } 462 463 opts := parseSynSegmentOptions(s) 464 465 useSynCookies, err := func() (bool, tcpip.Error) { 466 var alwaysUseSynCookies tcpip.TCPAlwaysUseSynCookies 467 if err := e.stack.TransportProtocolOption(header.TCPProtocolNumber, &alwaysUseSynCookies); err != nil { 468 panic(fmt.Sprintf("TransportProtocolOption(%d, %T) = %s", header.TCPProtocolNumber, alwaysUseSynCookies, err)) 469 } 470 if alwaysUseSynCookies { 471 return true, nil 472 } 473 e.acceptMu.Lock() 474 defer e.acceptMu.Unlock() 475 476 // The capacity of the accepted queue would always be one greater than the 477 // listen backlog. But, the SYNRCVD connections count is always checked 478 // against the listen backlog value for Linux parity reason. 479 // https://github.com/torvalds/linux/blob/7acac4b3196/include/net/inet_connection_sock.h#L280 480 if len(e.acceptQueue.pendingEndpoints) == e.acceptQueue.capacity-1 { 481 return true, nil 482 } 483 484 h, err := ctx.startHandshake(s, opts, &waiter.Queue{}, e.owner) 485 if err != nil { 486 e.stack.Stats().TCP.FailedConnectionAttempts.Increment() 487 e.stats.FailedConnectionAttempts.Increment() 488 return false, err 489 } 490 e.acceptQueue.pendingEndpoints[h.ep] = struct{}{} 491 492 return false, nil 493 }() 494 if err != nil { 495 return err 496 } 497 if !useSynCookies { 498 return nil 499 } 500 501 net := s.pkt.Network() 502 route, err := e.stack.FindRoute(s.pkt.NICID, net.DestinationAddress(), net.SourceAddress(), s.pkt.NetworkProtocolNumber, false /* multicastLoop */) 503 if err != nil { 504 return err 505 } 506 defer route.Release() 507 508 // Send SYN without window scaling because we currently 509 // don't encode this information in the cookie. 510 // 511 // Enable Timestamp option if the original syn did have 512 // the timestamp option specified. 513 // 514 // Use the user supplied MSS on the listening socket for 515 // new connections, if available. 516 synOpts := header.TCPSynOptions{ 517 WS: -1, 518 TS: opts.TS, 519 TSEcr: opts.TSVal, 520 MSS: calculateAdvertisedMSS(e.userMSS, route), 521 } 522 if opts.TS { 523 offset := e.protocol.tsOffset(net.DestinationAddress(), net.SourceAddress()) 524 now := e.stack.Clock().NowMonotonic() 525 synOpts.TSVal = offset.TSVal(now) 526 } 527 cookie := ctx.createCookie(s.id, s.sequenceNumber, encodeMSS(opts.MSS)) 528 fields := tcpFields{ 529 id: s.id, 530 ttl: calculateTTL(route, e.ipv4TTL, e.ipv6HopLimit), 531 tos: e.sendTOS, 532 flags: header.TCPFlagSyn | header.TCPFlagAck, 533 seq: cookie, 534 ack: s.sequenceNumber + 1, 535 rcvWnd: ctx.rcvWnd, 536 } 537 if err := e.sendSynTCP(route, fields, synOpts); err != nil { 538 return err 539 } 540 e.stack.Stats().TCP.ListenOverflowSynCookieSent.Increment() 541 return nil 542 543 case s.flags.Contains(header.TCPFlagAck): 544 iss := s.ackNumber - 1 545 irs := s.sequenceNumber - 1 546 547 // Since SYN cookies are in use this is potentially an ACK to a 548 // SYN-ACK we sent but don't have a half open connection state 549 // as cookies are being used to protect against a potential SYN 550 // flood. In such cases validate the cookie and if valid create 551 // a fully connected endpoint and deliver to the accept queue. 552 // 553 // If not, silently drop the ACK to avoid leaking information 554 // when under a potential syn flood attack. 555 // 556 // Validate the cookie. 557 data, ok := ctx.isCookieValid(s.id, iss, irs) 558 if !ok || int(data) >= len(mssTable) { 559 e.stack.Stats().TCP.ListenOverflowInvalidSynCookieRcvd.Increment() 560 e.stack.Stats().DroppedPackets.Increment() 561 562 // When not using SYN cookies, as per RFC 793, section 3.9, page 64: 563 // Any acknowledgment is bad if it arrives on a connection still in 564 // the LISTEN state. An acceptable reset segment should be formed 565 // for any arriving ACK-bearing segment. The RST should be 566 // formatted as follows: 567 // 568 // <SEQ=SEG.ACK><CTL=RST> 569 // 570 // Send a reset as this is an ACK for which there is no 571 // half open connections and we are not using cookies 572 // yet. 573 // 574 // The only time we should reach here when a connection 575 // was opened and closed really quickly and a delayed 576 // ACK was received from the sender. 577 return replyWithReset(e.stack, s, e.sendTOS, e.ipv4TTL, e.ipv6HopLimit) 578 } 579 580 // As an edge case when SYN-COOKIES are in use and we receive a 581 // segment that has data and is valid we should check if it 582 // already matches a created endpoint and redirect the segment 583 // rather than try and create a new endpoint. This can happen 584 // where the final ACK for the handshake and other data packets 585 // arrive at the same time and are queued to the listening 586 // endpoint before the listening endpoint has had time to 587 // process the first ACK and create the endpoint that matches 588 // the incoming packet's full 5 tuple. 589 netProtos := []tcpip.NetworkProtocolNumber{s.pkt.NetworkProtocolNumber} 590 // If the local address is an IPv4 Address then also look for IPv6 591 // dual stack endpoints. 592 if s.id.LocalAddress.To4() != (tcpip.Address{}) { 593 netProtos = []tcpip.NetworkProtocolNumber{header.IPv4ProtocolNumber, header.IPv6ProtocolNumber} 594 } 595 for _, netProto := range netProtos { 596 if newEP := e.stack.FindTransportEndpoint(netProto, ProtocolNumber, s.id, s.pkt.NICID); newEP != nil && newEP != e { 597 tcpEP := newEP.(*endpoint) 598 if !tcpEP.EndpointState().connected() { 599 continue 600 } 601 if !tcpEP.enqueueSegment(s) { 602 // Just silently drop the segment as we failed 603 // to queue, we don't want to generate a RST 604 // further below or try and create a new 605 // endpoint etc. 606 return nil 607 } 608 tcpEP.notifyProcessor() 609 return nil 610 } 611 } 612 613 // Keep hold of acceptMu until the new endpoint is in the accept queue (or 614 // if there is an error), to guarantee that we will keep our spot in the 615 // queue even if another handshake from the syn queue completes. 616 e.acceptMu.Lock() 617 if e.acceptQueue.isFull() { 618 // Silently drop the ack as the application can't accept 619 // the connection at this point. The ack will be 620 // retransmitted by the sender anyway and we can 621 // complete the connection at the time of retransmit if 622 // the backlog has space. 623 e.acceptMu.Unlock() 624 e.stack.Stats().TCP.ListenOverflowAckDrop.Increment() 625 e.stats.ReceiveErrors.ListenOverflowAckDrop.Increment() 626 e.stack.Stats().DroppedPackets.Increment() 627 return nil 628 } 629 630 e.stack.Stats().TCP.ListenOverflowSynCookieRcvd.Increment() 631 // Create newly accepted endpoint and deliver it. 632 rcvdSynOptions := header.TCPSynOptions{ 633 MSS: mssTable[data], 634 // Disable Window scaling as original SYN is 635 // lost. 636 WS: -1, 637 } 638 639 // When syn cookies are in use we enable timestamp only 640 // if the ack specifies the timestamp option assuming 641 // that the other end did in fact negotiate the 642 // timestamp option in the original SYN. 643 if s.parsedOptions.TS { 644 rcvdSynOptions.TS = true 645 rcvdSynOptions.TSVal = s.parsedOptions.TSVal 646 rcvdSynOptions.TSEcr = s.parsedOptions.TSEcr 647 } 648 649 n, err := ctx.createConnectingEndpoint(s, rcvdSynOptions, &waiter.Queue{}) 650 if err != nil { 651 e.acceptMu.Unlock() 652 return err 653 } 654 655 // Propagate any inheritable options from the listening endpoint 656 // to the newly created endpoint. 657 e.propagateInheritableOptionsLocked(n) 658 659 if !n.reserveTupleLocked() { 660 n.mu.Unlock() 661 e.acceptMu.Unlock() 662 n.Close() 663 664 e.stack.Stats().TCP.FailedConnectionAttempts.Increment() 665 e.stats.FailedConnectionAttempts.Increment() 666 return nil 667 } 668 669 // Register new endpoint so that packets are routed to it. 670 if err := n.stack.RegisterTransportEndpoint( 671 n.effectiveNetProtos, 672 ProtocolNumber, 673 n.TransportEndpointInfo.ID, 674 n, 675 n.boundPortFlags, 676 n.boundBindToDevice, 677 ); err != nil { 678 n.mu.Unlock() 679 e.acceptMu.Unlock() 680 n.Close() 681 682 e.stack.Stats().TCP.FailedConnectionAttempts.Increment() 683 e.stats.FailedConnectionAttempts.Increment() 684 return err 685 } 686 687 n.isRegistered = true 688 net := s.pkt.Network() 689 n.TSOffset = n.protocol.tsOffset(net.DestinationAddress(), net.SourceAddress()) 690 691 // Switch state to connected. 692 n.isConnectNotified = true 693 h := handshake{ 694 ep: n, 695 iss: iss, 696 ackNum: irs + 1, 697 rcvWnd: seqnum.Size(n.initialReceiveWindow()), 698 sndWnd: s.window, 699 rcvWndScale: e.rcvWndScaleForHandshake(), 700 sndWndScale: rcvdSynOptions.WS, 701 mss: rcvdSynOptions.MSS, 702 sampleRTTWithTSOnly: true, 703 } 704 h.ep.AssertLockHeld(n) 705 h.transitionToStateEstablishedLocked(s) 706 n.mu.Unlock() 707 708 // Requeue the segment if the ACK completing the handshake has more info 709 // to be processed by the newly established endpoint. 710 if (s.flags.Contains(header.TCPFlagFin) || s.payloadSize() > 0) && n.enqueueSegment(s) { 711 n.notifyProcessor() 712 } 713 714 e.stack.Stats().TCP.PassiveConnectionOpenings.Increment() 715 716 // Deliver the endpoint to the accept queue. 717 e.acceptQueue.endpoints.PushBack(n) 718 e.acceptMu.Unlock() 719 720 e.waiterQueue.Notify(waiter.ReadableEvents) 721 return nil 722 723 default: 724 e.stack.Stats().DroppedPackets.Increment() 725 return nil 726 } 727 }